Jag har två drontyper som jag regelbundet flyger med. DJI:s Phantom samt Yuneec Typhoon. Dronerna är rätt likvärdiga ur flygsynvinkel och kamerornas kvalitet är mycket lika. Det finns dock en betydande skillnad mellan dronfamiljerna.
Dji använder intelligenta batterier d.v.s. laddningslogiken finns i själva batteriet. Batteriet kan alltså helt autonomt följa med sin egen användning vilket är viktigt då man använder moderna LitiumPolymer (LiPo) batterier. Ett LiPo batteri tycker inte om att vara tomt men det skadas också på sikt av att vara fulladdat. Egenskaperna hos ett felbehandlat batteri förändras bl.a. så att batteriets inre motstånd stiger vilket ur dronens synvinkel syns som höjd batteritemperatur under flygningen och kortare flygtid. Dji:s batterier laddar själja ur sig till ca. 60% laddningsnivå inom några dagar om batteriet inte används efter laddning.
Yuneecs batterier är inte intelligenta d.v.s. hela underhållsansvaret faller på användaren. Det är på mitt asnsvar att se till att batterier då de lagras har en laddningsgrad kring 60% för att livslängden skall bli så lång som möjligt. Ett hjälpmedel som jag har för detta ändamål är en intelligent laddare (inte Yuneecs laddare) som har olika program för laddning, urladdning och underhållsladdning. Det jag har saknat är ett enkelt sätt att mäta batteriernas inre motstånd och det är detta denna artikel kommer att handla om.
Då ett batteri belastas kommer det att ske ett inre spänningsfall i batteriet d.v.s. den spänning man ser över batteriets poler kommer att sjunka vilket betyder att t.e.x. en drons varningssystem för låg batterispänning slår på allt tidigare ju högre det inre motståndet blir. Om dronen vid flygning behöver t.e.x. 2A ström kommer ett inre motstånd på 70 milliohm att sänka batteriets spänning med 0,14 V vilket motsvarar flera minuters flygning.
När skall jag kasta ett batteri
Ett batteri är slut då flygtiden blir för kort samt då batteriet eventuellt börja uppföra sig konstigt d.v.s. det kan efter någon minuts flygning ge en batterivarning som tvingar fram en plötslig påtvingad landning för att undvika krasch. Ett sätt att se när ett batteri börjar nå slutet av sitt liv är att mäta det inre motståndet samt naturligtvis ibland mäta den effektiva flygtiden med ett batteri.
Mätning av det inre motståndet
Bilden visar, i form av ett kretsschema, ett batteri som belastas över ett motstånd. För att kunna beräkna det inre motståndet måste vi mäta batteriets spänning obelastat (i vila) samt spänningen då batteriet är belastat. Vi vill också undvika lång urladdning innan vi mäter det belastade batteriets spänning eftersom belastningen också medför att spänningen sjunker till följd av att batteriet laddas ur.

Då batteriet är obelastat så går det nästan ingen ström genom batteriet, endast en mycket liten läckström går genom voltmätaren kanske 1 uA. Detta betyder att den spänning voltmätaren mäter är batteriets spänning eftersom spänningsfallet över Ri är ungefär lika med noll.
Då man sluter switchen SW kommer batteriet att laddas ur med en ström som beroende av batterityp är mellan 1 och 1.5 A. Batteriets inre motstånd kommer då att leda till ett spänningsfall inne i batteriet med storleken strömmen*inre_motståndet eller Ui=I*Ri . I prktiken kan man se detta så att spänningen sjunker då batteriet laddas ur.
Då batteriet är obelastat är den mätta spänningen:
Vb = det obelastade batteriets polspänning
Då batteriet belastas mäter vi en spänning:
(1) Vl = Vb – I*Ri
Där:
I = strömmen genom lastmotståndet som vi i mitt fall vet att det är 10 ohm
Rl = lastmotståndet 10 ohm
Ri = batteriets okända inre motstånd
Vb = det obelastade batteriets spänning.
Strömmen kan vi beräkna ur den mätta spänningen med last:
(2) I = Vl/Rl
Vi kan lösa Ri ur ekvation (1) och får då:
(3) Ri = (Vb-Vl)/I
Vi byter ut I ekvation (3) mot I taget ur (2) och får då:
(4) Ri = Rl * (Vb-Vl)/Vl
Vi ser alltså att vi helt änkelt gör två spänningsmätningar den första med obelastat batteri och den andra med ett belastat batteri och därefter lägger vi in värdet i (4) tillsammans med det kända vädet på Rl=10 ohm. Lätt som en plätt där inget kan gå fel eller hur?
En Arduino Uno är ett billigt litet mikroprocessorkort med en trevlig utvecklingsomgivning. Processorn har en AD-konverter (voltmätare) med upplösningen 10 bitar d.v.s. mätområdet 0 … 5V delas in i 1024 spänningssteg. Den enklaste mätaren kunde således byggas utgående från en Arduino Uno kopplad till ett 5V relä som styr mätning av obelastat respektive belastat batteri.

Jag skrev ett litet program som gjorde ovanstående mätningar med hjälp av Uno:s AD-konverter. Resultatet blev negativa värden på den inre resistansen. Hur kan jag få negativa värden på den inre resistansen? Då vi tittar på ekvation (4) så ser vi att spänningen med last då måste vara större än det obelastade batteriets polspänning! Hur är detta möjligt?
Uno:s AD-konverter tar sin referensspänning från processorkortets 5V matningsspänning. Ett relä drar rätt mycket ström d.v.s. när relät aktiveras d.v.s. SW är slutet kommer hela processorkortets spänning att sjunka till ca. 4,5V. Plötsligt blev referensspänningen 4,5 i stället för 5V och resultatet är att det ryms 1024 spänningssteg i 0…4,5V i stället för 0…5V d.v.s. steglängden minskar och då processorn mäter det belastade batteriets spänning tror den sig mäta en spänning som är större än det obelastade batteriets spänning.
Lösningen som samtidigt testar diagnosen var att mata relät med ett separat spänningsaggregat. Processorns spänning hålls bättre konstant och felen minskar radikalt.
Nu dyker följande problem upp. Mätningar av riktiga batterier tyder på att upplösningen d.v.s. den precision vi kan uppnå vid mätningen blir av storleksorningen 10 milliOhm vilket är nästan 25% av det inre motståndet i ett typiskt batteri. En enkel kontroll visar vad detta problem beror på.
Antag att inspänningen till AD-konvertern är något över halva maxspänningen t.ex. 3.5 volt vilket motsvarar ett mätvärde på 716 enheter av 1024. Antag nu att Vb och Vl skiljer med endast en enhet och att lastmotståndet är 10 ohm. Det minsta resistansvärdet vi då kan mäta får vi genom att beräkna:
Ri = 10*(716-715)/715 = 14 milliohm … inte bra!
Slutsatsen blev att mätaren måste få en bättre AD-konverter. Ett alternativ kunde ha varit att gå över till en ARM-baserad ”BluePill” processor som erbjuder en 12-bitars AD-konverter d.v.s. med samma uppställning som för Uno och omkompilering av programkoden kunde jag få fyra gånger bättre upplösning d.v.s. ungefär 3.5 milliOhm vilket är betydligt bättre. Ett annat alternativ hittade jag i miljonlådan i form av ett litet kretskort som jag nångång skaffade för ett annat projekt. Kretsen ADS1115 erbjuder en fyrkanalig 16-bitars AD-konverter som kontrolleras över en seriebus I2C. Genom att använda ADS1115 kunde jag fortsätta att använda Arduino Uno men mäta spänningar med god precision. Voltmätaren ADS1115 marknadsförs som 16-bitars men i praktiken är det en 15-bitars konverter då jag mäter positiva spänningar. 15 bitar ger 32768 spänningssteg d.v.s. 32 ggr bättre än Uno.
Mätprogrammet går på 60-rader vilket väl ryms i en Arduino Uno som erbjuder 32k minne för program (en Commodore 64 från ungefär 1980 hade ungefär den här kapaciteten). Programmet använder ett färdigt bibliotek för kontroll av ADS1115 vilket gör programmeringen mycket enklare …
// Name= resistance_ADS1115
// Lars Silen 2022
// This is free source code. Feel free to copy and modify.
#include "Arduino.h"
#include "ADS1115-Driver.h"
#define Rly 6
uint16_t V_battery;
uint16_t V_load;
float R;
float loadResistance=10.1;
ADS1115 ads1115 = ADS1115(ADS1115_I2C_ADDR_GND);
uint16_t readValue(uint8_t input) {
ads1115.setMultiplexer(input);
ads1115.startSingleConvertion();
delayMicroseconds(25); // The ADS1115 needs to wake up from sleep mode and usually it takes 25 uS to do that
while (ads1115.getOperationalStatus() == 0);
return ads1115.readConvertedValue();
}
void setup() {
Serial.begin(9600);
ads1115.reset();
ads1115.setDeviceMode(ADS1115_MODE_SINGLE);
ads1115.setDataRate(ADS1115_DR_250_SPS);
ads1115.setPga(ADS1115_PGA_6_144); // +/- 6.144 V
ads1115.setMultiplexer(ADS1115_MUX_AIN0_GND);
pinMode(Rly, OUTPUT);
}
void loop() {
Serial.println("Program to measure the internal resistance of 3s and 4s Yuneec LiPo batteries");
Serial.println("Ensure there is a very good contact to the battery.");
Serial.println("Keep your finger on the battery side connector!");
delay(1000);
digitalWrite(Rly,LOW); // Measure battery voltage
delay(100);
uint16_t V_battery = readValue(ADS1115_MUX_AIN0_GND);
Serial.print("V_battery: ");
Serial.println(V_battery);
Serial.println("Switch load to ON");
digitalWrite(Rly,HIGH); // Measure load voltage, switch load ON
delay(10);
uint16_t V_load = readValue(ADS1115_MUX_AIN0_GND);
digitalWrite(Rly,LOW);
Serial.print("V_load: ");
Serial.println(V_load);
R = (loadResistance*(V_battery-V_load)/V_load)*1000.0;
Serial.print("Internal resdistance milliohm:");
Serial.println(R,0);
Serial.println();
Serial.println();
delay(5000);
}
Det färdiga mätsystemet visas i bilden nedan. Den alternativa plattformen ”Blue Pill” är det lilla processorkortet som ligger på det silverfärgade lilla nätaggregatet som används för att driva reläet. ”Blue Pill” används inte utan finns endast med som illustration. Blue Pill är sannolikt 10 ggr kraftfullare än en Arduino Uno. Både en Uno och Blue Pill kostar sannolikt kring en tia. En Arduino Uno, Mega eller Due är dock mycket lättare att komma igång med eftersom de har skräddarsytts för Arduino utvecklingsomgivningen.

Programmet körs från Arduino IDE så att utskrift sker till ”Serial monitor”. Det vore enkelt att ansluta en LCD-skärm på vilken resultatet kunde visas. Att lägga till en skärm och på detta sätt göra mätaren oberoende av en PC lämnas som övningsuppgift till läsaren!
