Components and supplies
Arduino Nano R3
Project description
Code
BTMonitor for Android (.apk)
batchfile
Copy the file on your mobile phone or tablet and install it
1inary file (no preview
BTMonitor source code (.aia)
batchfile
To edit the .aia file import it at ai2.appinventor.mit.edu website
1inary file (no preview
BTMonitor source code (.aia)
batchfile
To edit the .aia file import it at ai2.appinventor.mit.edu website
1inary file (no preview
BTMonitor for Android (.apk)
batchfile
Copy the file on your mobile phone or tablet and install it
1inary file (no preview
Arduino .INO Charger sketch
arduino
1/* 2 CHARGER for 2S Lipo battery 3 by Marco Zonca, 2022 4 5 This sketch works as 2S LiPo Charger, originally made for Autopilot2 for small sailing boats 6 Arduino Nano as MCU, 3 relais, LM317, ua7812, 3 Thermistors TMP36, DAC module, 2 fuses, 4 BC337 NPN, 5W ceramic resistor, 2 RGB LED, 7 resistors and capacitors, Buzzer, JST connectors, Cooling Fan, Bluetooth HC-05, etc.; 8 9/* 10 WARNING: before switching Relais2 ON or OFF, 11 switch OFF Relais1 first, then Relais2, then Relais1 ON again if necessary; 12 This circuit KEEPS SEPARATED the battery ground from any other ground because during balanced charging 13 the pins Cells, (-) and (+), are necessarily switched from one CELL to another, and inverted polarity at common wire! 14 15 LETS CONNECT the load only by the way of X1-LOAD connector; the X1-LOAD power is automatically full disconnected when charging (both wires (-) and (+)) 16 17*/ 18 19#include <Wire.h> 20#include <Adafruit_MCP4725.h> 21 22Adafruit_MCP4725 DAC; 23 24//--------------------------------------------------Charging constant Values 25const float CBatt = 2.600; // put here the battery power A/h 26const float VCmin = 3.20; // absolute minimum cell Voltage 27const float VCMax = 4.22; // absolute max cell voltage 28const float VCfinalize = 4.18; // finalize charging cell voltage (after this it will charge at fixed voltage and limited current) 29const float VCchgd = 4.18; // already charged cell voltage (skip charging) 30const float ETAdd = 60; // additionally time in minutes for charging (finalize) 31const float ETFact = 1.20; // coefficent estimated charging time (plus additionally ETAdd) 32const float ETFactAlarm = 2.00; // coefficent estimated charging time sets Alarm too (plus additionally ETAdd) 33const float CellChgCurrent = CBatt/5; // charging current 1/5 of battery (cell) A/h i.e. 2.600 / 5 = 0.520 A 34const float CellFinalizeCurrent = CellChgCurrent / 100 * 20; // % of charging current in finalizing mode, if below then stop charging (see VCfinalize) 35const float CellSlowDownCurrent = CellChgCurrent / 100 * 50; // % of charging current in slow down mode (LM317 or uA7812 or Battery high temperature) 36const float VPower = 5.0; // max DAC voltage 37const byte HighTRegH = 60; // LM317 or uA7812 high (threshold H) temperature C 38const byte HighTRegL = 50; // LM317 or uA7812 high (threshold L) temperature C 39const byte HighTBatH = 40; // battery high (threshold H) temperature C 40const byte HighTBatL = 30; // battery high (threshold L) temperature C 41const byte FanTRHigh = 55; // Fan (threshold H) LM317 or uA7812 temperature C 42const byte FanTRLow = 45; // Fan (threshold L) LM317 or uA7812 temperature C 43const byte FanTBHigh = 36; // Fan (threshold H) battery temperature C 44const byte FanTBLow = 32; // Fan (threshold L) battery temperature C 45const byte RegulatorTAlarm = 70; // regulators TC alarm (STOP charging) 46const byte BatteryTAlarm = 45; // battery TC alarm (STOP charging) 47//--------------------------------------------------Charging constant Values 48 49const byte Relais1ConnectCellsPin = 2; 50const byte Relais2SwitchCellsPin = 3; 51const byte RGBledBluePin[3] = {0,4,6}; 52const byte RGBledRedPin[3] = {0,5,7}; 53const byte FanPWMPin = 9; 54const byte VcellPin = 14; 55const byte VoutPin = 15; 56const byte BuzzerPin = 16; 57const byte TMP36_BatteryPin = 17; 58const byte TMP36_7812Pin = 20; 59const byte TMP36_317Pin = 21; 60const byte Set_OFF = LOW; 61const byte Set_ON = HIGH; 62const int PrintDebugInterval = 4000; 63const int CheckChargeInterval = 10000; 64const byte DAC_Address = 0x60; 65const float DAC_InitialV = 3.0; // charger Volt to cell (it is an initial/parking value, should not charge at this value!) 66const boolean IsDEBUG = true; // set this as TRUE for Serial Monitor debug data output 67const float Rload = 0.47; // shunt resistor 68 69boolean IsCharging = false; 70boolean IsOverTime = false; 71boolean IsAlreadyCharged = false; 72boolean IsSlowDown = false; 73boolean IsALARM = false; 74 75byte PhaseNr = 0; 76byte WhichCellIsOn = 0; 77byte WhichFanSpeedIsOn = 0; 78int FanSpeed[3] = {255*0/100, 255*90/100, 255*100/100}; // % of max speed, 0% normal TC, 90% high TC, 100% ALARM 79 80float TempBattery = 0; 81float Temp7812 = 0; 82float Temp317 = 0; 83float Vcell = 0; 84float Voutput = 0; 85float Vload = 0; 86float Aload = 0; 87float SetVOutput = 0; 88float SetDAC = 0; 89float TFull = 0; // estimated charge time in minutes 90float TRemain[3] = {0,0,0}; // estimated remaining time of charging in minutes 91float TScale = 0; // time ETAdd reduction factor 92float C_OverTime[3] = {0,0,0}; // estimated time of charging in minutes 93float C_AlarmTime[3] = {0,0,0}; // estimated time of charging in minutes sets Alarm 94float SoC[3] = {0,0,0}; // state of charge in % 95float VInitCell[3] = {0,0,0}; // initial charging cell voltage 96float VFinalCell[3] = {0,0,0}; // final charging cell voltage 97 98unsigned long lastPrintDebugMillis = 0; 99unsigned long lastCheckChargeMillis = 0; 100unsigned long ChTimeStart[3] = {0,0,0}; // charging start time, time elapsed as minutes from power-up 101unsigned long ChTimeEnd[3] = {0,0,0}; // charging start time, time elapsed as minutes from power-up 102unsigned long ChTimeNow = 0; // now time, time elapsed as minutes from power-up 103 104void setup() { 105 if (IsDEBUG) Serial.begin(38400); // output both serial monitor & bluetooth HC-05 106 DAC.begin(DAC_Address); 107 pinMode(RGBledBluePin[1], OUTPUT); 108 pinMode(RGBledRedPin[1], OUTPUT); 109 pinMode(RGBledBluePin[2], OUTPUT); 110 pinMode(RGBledRedPin[2], OUTPUT); 111 pinMode(TMP36_BatteryPin, INPUT); 112 pinMode(TMP36_7812Pin, INPUT); 113 pinMode(TMP36_317Pin, INPUT); 114 pinMode(VcellPin, INPUT); 115 pinMode(VoutPin, INPUT); 116 pinMode(Relais1ConnectCellsPin,OUTPUT); 117 pinMode(Relais2SwitchCellsPin,OUTPUT); 118 pinMode(BuzzerPin,OUTPUT); 119 pinMode(FanPWMPin,OUTPUT); 120 DisconnectAllCells(); 121 WriteDACVOutput(DAC_InitialV); 122 buzzerBips(1); 123 ledShow(); 124}//setup() 125 126void loop() { 127 readTemperatures(); 128 readVAvalues(); 129 if ((IsDEBUG) && (lastPrintDebugMillis + PrintDebugInterval) < millis()) serialPrintDebug(); 130 if (IsALARM==false) { 131 if ((lastCheckChargeMillis + CheckChargeInterval) < millis()) checkCharge(); 132 if (WhichCellIsOn) display(); 133 } else { // ALARM 134 if (WhichCellIsOn) DisconnectAllCells(); 135 display(); 136 buzzerBips(5); 137 }//IsALARM 138}//loop() 139 140void checkCharge() { // ----------------------------------------------------------------------------------- start, charge or skip, finish 141 float ri = 0; 142 float current = 0; 143 float c = 0; 144 TFull = roundZeroDec(CBatt / CellChgCurrent) * 60; 145 current=CellChgCurrent; 146 if (IsSlowDown == true) { // limiting current during high TC 147 TFull = roundZeroDec(CBatt / CellSlowDownCurrent) * 60; 148 current=CellSlowDownCurrent; 149 } 150 if (Vcell > VCfinalize) { 151 TFull = roundZeroDec(CBatt / CellFinalizeCurrent) * 60; 152 TScale=(((Aload - CellFinalizeCurrent) * 100) / (current - CellFinalizeCurrent)) / 100; 153 } else { 154 TScale=1; 155 } 156 157 if (IsCharging == true) { // ----------------------------------------------------- charging 158 if (Vcell > VCMax) { // ======== stop charging, over VCMax... 159 ChTimeEnd[WhichCellIsOn]=roundZeroDec(((millis()/1000)/60)+1); 160 VFinalCell[WhichCellIsOn]=Vcell; // final cell voltage 161 DisconnectAllCells(); 162 WriteDACVOutput(DAC_InitialV); 163 IsCharging=false; 164 if (PhaseNr==1) buzzerBips(2); 165 if (PhaseNr==2) buzzerBips(3); 166 if (IsDEBUG) Serial.println("STOP, over VCMax..."); 167 } else { 168 if (Vcell <= VCfinalize) { // ========== tuning, fixed current 169 for (ri=(SetVOutput - 0.06);ri=ri+0.02;ri<VPower) { // increment DAC voltage till reaching "current" 170 WriteDACVOutput(ri); 171 readVAvalues(); 172 if (IsDEBUG) serialPrintChg("TUNE"); 173 if ((Aload >= current) || (Vcell>=(VCMax - 0.02))) break; 174 } 175 }//IfVcell<=Finalize 176 if (Vcell > VCfinalize) { // ============ finalize, fixed voltage and limited current 177 for ((ri=SetVOutput - 0.03);ri=ri+0.01;ri<=VCMax) { // increment DAC voltage till reaching "VCMax-0.02" 178 WriteDACVOutput(ri); 179 readVAvalues(); 180 if (IsDEBUG) serialPrintChg("FINAL"); 181 if ((Aload >= current) || (Vcell>=(VCMax - 0.02))) break; 182 } 183 if (Aload < CellFinalizeCurrent) { // === stop charging, below finalizing current, perfect 184 ChTimeEnd[WhichCellIsOn]=roundZeroDec(((millis()/1000)/60)+1); 185 VFinalCell[WhichCellIsOn]=Vcell; // final cell voltage 186 DisconnectAllCells(); 187 WriteDACVOutput(DAC_InitialV); 188 IsCharging=false; 189 if (PhaseNr==1) buzzerBips(2); 190 if (PhaseNr==2) buzzerBips(3); 191 if (IsDEBUG) Serial.println("END, current finalized"); 192 } 193 }//IfVcell>=Finalize 194 }//ifVCell>=VCMax 195 }//IfIsCharging==true 196 197 if (IsCharging == false) { // ----------------------------------------------------- phase and start 198 if (PhaseNr < 2) { // =============== switch Cell -> 1 -> 2 199 PhaseNr++; 200 ConnectCell_N(PhaseNr); 201 readVAvalues(); 202 if (Vcell >= VCchgd) { 203 IsAlreadyCharged=true; 204 } else { 205 IsAlreadyCharged=false; 206 } 207 IsOverTime=false; 208 if (IsAlreadyCharged == false) { // ================ start charging, fixed current 209 ChTimeStart[WhichCellIsOn]=roundZeroDec(((millis()/1000)/60)+1); 210 VInitCell[WhichCellIsOn]=Vcell; // initial cell voltage 211 C_OverTime[WhichCellIsOn] = roundZeroDec(((((CBatt / CellChgCurrent) * 60) * (VCMax - 0.02 - VInitCell[WhichCellIsOn])) * ETFact) + ETAdd); // estimated maximum time of charging 212 C_AlarmTime[WhichCellIsOn] = roundZeroDec(((((CBatt / CellChgCurrent) * 60) * (VCMax - 0.02 - VInitCell[WhichCellIsOn])) * ETFactAlarm) + ETAdd); // estimated maximum time of charging then setes Alarm 213 for (ri=Vcell;ri=ri+0.02;ri<VPower) { // increment DAC voltage till reaching "current" 214 WriteDACVOutput(ri); 215 readVAvalues(); 216 if (IsDEBUG) serialPrintChg("START"); 217 if ((Aload >= current) || (Vcell>=(VCMax-0.02))) break; 218 } 219 IsCharging=true; 220 } else { 221 ChTimeStart[WhichCellIsOn]=roundZeroDec(((millis()/1000)/60)+1); // ======== charging not necessary, already charged... 222 VInitCell[WhichCellIsOn]=Vcell; // initial cell voltage 223 C_OverTime[WhichCellIsOn] = roundZeroDec(((((CBatt / CellChgCurrent) * 60) * (VCMax - 0.02 - VInitCell[WhichCellIsOn])) * ETFact) + ETAdd); // estimated maximum time of charging 224 C_AlarmTime[WhichCellIsOn] = roundZeroDec(((((CBatt / CellChgCurrent) * 60) * (VCMax - 0.02 - VInitCell[WhichCellIsOn])) * ETFactAlarm) + ETAdd); // estimated maximum time of charging then sets Alarm 225 ChTimeEnd[WhichCellIsOn]=roundZeroDec(((millis()/1000)/60)+1); 226 VFinalCell[WhichCellIsOn]=Vcell; // final cell voltage 227 display(); 228 DisconnectAllCells(); 229 WriteDACVOutput(DAC_InitialV); 230 if (PhaseNr==1) buzzerBips(2); 231 if (PhaseNr==2) buzzerBips(3); 232 if (IsDEBUG) Serial.println("END, already charged"); 233 }//IsAlreadyCharged==false 234 }//IfPhase<2 235 }//IsCharging==false 236 237 if (WhichCellIsOn) { 238 SoC[WhichCellIsOn] = roundZeroDec(100 - ((VCMax - 0.02 - Vcell) * 100)); // state of charge in % 239 ChTimeNow=roundZeroDec(((millis()/1000)/60)+1); // now time as minutes from power-up +1 240 if ((ChTimeNow-ChTimeStart[WhichCellIsOn]) > C_OverTime[WhichCellIsOn]) IsOverTime=true; 241 if ((ChTimeNow-ChTimeStart[WhichCellIsOn]) > C_AlarmTime[WhichCellIsOn]) IsALARM=true; 242 TRemain[WhichCellIsOn] = roundZeroDec(((TFull * (VCMax - 0.02 - Vcell)) * ETFact) + (ETAdd * TScale)); // estimated remaining time of charging in minutes 243 } 244 lastCheckChargeMillis=millis(); 245}//checkCharge() 246 247void buzzerBips(byte n) { 248 byte q=0; 249 for (q=1;q<=n;q++) { 250 digitalWrite(BuzzerPin, HIGH); 251 delay(100); 252 digitalWrite(BuzzerPin, LOW); 253 delay(100); 254 } 255}//buzzerBips() 256 257/* 258 WARNING: before switching Relais2 ON or OFF, 259 switch OFF Relais1 first, then Relais2, then Relais1 ON again if necessary; 260 This circuit KEEPS SEPARATED the battery ground from any other ground because during balanced charging 261 the pins Cells, (-) and (+), are necessarely switched from one CELL to another, and inverted polarity at common wire! 262*/ 263void DisconnectAllCells() { // ------------------------------ disconnect Cells by Relais 264 digitalWrite(Relais1ConnectCellsPin, Set_OFF); 265 delay(1000); 266 digitalWrite(Relais2SwitchCellsPin, Set_OFF); 267 delay(1000); 268 WhichCellIsOn = 0; 269}//DisconnectAllCells() 270 271void ConnectCell_N(byte c) { // ----------------------------- connect Cell by Relais 272 switch (c) { 273 case 1: 274 digitalWrite(Relais1ConnectCellsPin, Set_OFF); 275 delay(1000); 276 digitalWrite(Relais2SwitchCellsPin, Set_OFF); 277 delay(1000); 278 digitalWrite(Relais1ConnectCellsPin, Set_ON); 279 delay(1000); 280 break; 281 case 2: 282 digitalWrite(Relais1ConnectCellsPin, Set_OFF); 283 delay(1000); 284 digitalWrite(Relais2SwitchCellsPin, Set_ON); 285 delay(1000); 286 digitalWrite(Relais1ConnectCellsPin, Set_ON); 287 delay(1000); 288 break; 289 } 290 WhichCellIsOn = c; 291}//ConnectCell_N() 292 293void WriteDACVOutput(float v) { // ------------------------- write DAC 294 SetVOutput = v; 295 SetDAC = ((SetVOutput - 1.25 + 0.75) * (4095.0 / 5.0)); // (Vdac - VdacADD + Vdiod) * (Res / Vref) 296 DAC.setVoltage(SetDAC, false); 297 delay(1000); 298}//WriteDACVOutput() 299 300void display() { // ---------------------------------------- display LED status 301 digitalWrite(RGBledBluePin[WhichCellIsOn],LOW); 302 digitalWrite(RGBledRedPin[WhichCellIsOn],LOW); 303 if (IsALARM==true) { 304 blink_redALARM(); 305 } else { 306 if (IsAlreadyCharged==false) { 307 if ((IsCharging==true)) { 308 if (IsOverTime==false) { 309 if (SoC[WhichCellIsOn] <= 20) blink_red(); 310 if (SoC[WhichCellIsOn] > 20 && SoC[WhichCellIsOn] <=40) blink_red_purple(); 311 if (SoC[WhichCellIsOn] > 40 && SoC[WhichCellIsOn] <=60) blink_purple(); 312 if (SoC[WhichCellIsOn] > 60 && SoC[WhichCellIsOn] <=80) blink_purple_blue(); 313 if (SoC[WhichCellIsOn] > 80 && SoC[WhichCellIsOn] <=90) blink_blue(); 314 if (SoC[WhichCellIsOn] > 90) blink_slowblue(); 315 } else { 316 blink_quickblue(); //overtime warning 317 }//over 318 } else { 319 steady_red(); //deciding what to do 320 }//charging 321 } else { 322 steady_blue(); //charged 323 }//already 324 }//IsALARM 325}//display() 326 327void readVAvalues() { // ---------------------------------- read V, A, values 328 float n=0; 329 float s=0; 330 float VCmem=0; 331 float VOmem=0; 332 int x=0; 333 for (x=1;x<=100;x++) { // x nr. of readings as average filter 334 n = analogRead(VcellPin); 335 s = ((5.0 * n) / 1023); // from cell 336 VCmem=VCmem+s; 337 n = analogRead(VoutPin); 338 s = ((5.0 * n) / 1023); // from LM317 339 VOmem=VOmem+s; 340 } 341 s=(VCmem/(x-1)); 342 Vcell = (s + ((s * 1.40) /100)); // +- % arbitrary correction (not active if = 0.00) 343 Vcell = roundThreeDec(Vcell); 344 s=(VOmem/(x-1)); 345 Voutput = (s + ((s * 1.40) /100)); // +- % arbitrary correction (not active if = 0.00) 346 Voutput = roundThreeDec(Voutput); 347 s=(Voutput-Vcell); 348 Vload = roundThreeDec(s); 349 n=(Vload/Rload); 350 Aload = roundThreeDec(n); 351}//readVAvalues() 352 353void readTemperatures() { // --------------------------------- read temperatures 354 int n=0; 355 n = analogRead(TMP36_BatteryPin); 356 TempBattery = (((5.0 * n) / 1023) - 0.500 ) * 100; // (-500mV=offset) 0 to 500 = below zero values 357 TempBattery = roundZeroDec(TempBattery); 358 n = analogRead(TMP36_7812Pin); 359 Temp7812 = (((5.0 * n) / 1023) - 0.500 ) * 100; 360 Temp7812 = roundZeroDec(Temp7812); 361 n = analogRead(TMP36_317Pin); 362 Temp317 = (((5.0 * n) / 1023) - 0.500 ) * 100; 363 Temp317 = roundZeroDec(Temp317); 364 if ((Temp7812 < HighTRegL) && (Temp317 < HighTRegL) && (TempBattery < HighTBatL)) { // current 365 IsSlowDown = false; // will normal chg current 366 } 367 if ((Temp7812 > HighTRegH) || (Temp317 > HighTRegH) || (TempBattery > HighTBatH)) { 368 IsSlowDown = true; // will decrease chg current 369 } 370 if (IsALARM==false) { 371 if ((Temp7812 < FanTRLow) && (Temp317 < FanTRLow) && (TempBattery < FanTBLow)) { // fan 372 analogWrite(FanPWMPin, FanSpeed[0]); // Fan normal temperatures 373 WhichFanSpeedIsOn=FanSpeed[0]; 374 } 375 if ((Temp7812 > FanTRHigh) || (Temp317 > FanTRHigh) || (TempBattery > FanTBHigh)) { 376 analogWrite(FanPWMPin, FanSpeed[1]); // Fan high temperatures 377 WhichFanSpeedIsOn=FanSpeed[1]; 378 } 379 if ((Temp7812 > RegulatorTAlarm) || (Temp317 > RegulatorTAlarm) || (TempBattery > BatteryTAlarm)) { // ALARM 380 IsALARM = true; // will STOP charging etc. 381 analogWrite(FanPWMPin, FanSpeed[2]); // Fan ALARM temperatures 382 WhichFanSpeedIsOn=FanSpeed[2]; 383 } 384 } else { 385 analogWrite(FanPWMPin, FanSpeed[2]); // Fan ALARM 386 WhichFanSpeedIsOn=FanSpeed[2]; 387 } 388}//readTemperatures() 389 390void blink_red() { // ----------------------------------------- led 391 delay(500); 392 digitalWrite(RGBledRedPin[WhichCellIsOn], HIGH); 393} 394void blink_redALARM() { 395 digitalWrite(RGBledRedPin[1], LOW); 396 digitalWrite(RGBledRedPin[2], LOW); 397 digitalWrite(RGBledBluePin[1], LOW); 398 digitalWrite(RGBledBluePin[2], LOW); 399 delay(100); 400 digitalWrite(RGBledRedPin[1], HIGH); 401 delay(100); 402 digitalWrite(RGBledRedPin[1], LOW); 403 digitalWrite(RGBledRedPin[2], HIGH); 404 delay(100); 405} 406void blink_blue() { 407 delay(500); 408 digitalWrite(RGBledBluePin[WhichCellIsOn], HIGH); 409 delay(500); 410} 411void blink_purple() { 412 delay(500); 413 digitalWrite(RGBledRedPin[WhichCellIsOn], HIGH); 414 digitalWrite(RGBledBluePin[WhichCellIsOn], HIGH); 415 delay(500); 416} 417void blink_red_purple() { 418 delay(500); 419 digitalWrite(RGBledRedPin[WhichCellIsOn], HIGH); 420 delay(1000); 421 digitalWrite(RGBledBluePin[WhichCellIsOn], HIGH); 422 delay(500); 423} 424void blink_purple_blue() { 425 delay(500); 426 digitalWrite(RGBledRedPin[WhichCellIsOn], HIGH); 427 digitalWrite(RGBledBluePin[WhichCellIsOn], HIGH); 428 delay(1000); 429 digitalWrite(RGBledRedPin[WhichCellIsOn], LOW); 430 digitalWrite(RGBledBluePin[WhichCellIsOn], HIGH); 431 delay(500); 432} 433void blink_slowblue() { 434 delay(1000); 435 digitalWrite(RGBledBluePin[WhichCellIsOn], HIGH); 436 delay(2000); 437} 438void blink_quickblue() { 439 delay(100); 440 digitalWrite(RGBledBluePin[WhichCellIsOn], HIGH); 441 delay(100); 442} 443void steady_blue() { 444 digitalWrite(RGBledBluePin[WhichCellIsOn], HIGH); 445} 446void steady_red() { 447 digitalWrite(RGBledRedPin[WhichCellIsOn], HIGH); 448} 449 450void ledShow() { // -------------------------------------------- initial show & Fan 451 digitalWrite(RGBledBluePin[1], HIGH); 452 digitalWrite(RGBledRedPin[1], LOW); 453 digitalWrite(RGBledBluePin[2], LOW); 454 digitalWrite(RGBledRedPin[2], LOW); 455 delay(500); 456 digitalWrite(RGBledBluePin[1], HIGH); 457 digitalWrite(RGBledRedPin[1], HIGH); 458 digitalWrite(RGBledBluePin[2], LOW); 459 digitalWrite(RGBledRedPin[2], LOW); 460 delay(500); 461 digitalWrite(RGBledBluePin[1], LOW); 462 digitalWrite(RGBledRedPin[1], HIGH); 463 digitalWrite(RGBledBluePin[2], LOW); 464 digitalWrite(RGBledRedPin[2], LOW); 465 delay(500); 466 digitalWrite(RGBledBluePin[1], LOW); 467 digitalWrite(RGBledRedPin[1], LOW); 468 digitalWrite(RGBledBluePin[2], HIGH); 469 digitalWrite(RGBledRedPin[2], LOW); 470 delay(500); 471 digitalWrite(RGBledBluePin[1], LOW); 472 digitalWrite(RGBledRedPin[1], LOW); 473 digitalWrite(RGBledBluePin[2], HIGH); 474 digitalWrite(RGBledRedPin[2], HIGH); 475 delay(500); 476 digitalWrite(RGBledBluePin[1], LOW); 477 digitalWrite(RGBledRedPin[1], LOW); 478 digitalWrite(RGBledBluePin[2], LOW); 479 digitalWrite(RGBledRedPin[2], HIGH); 480 delay(500); 481 digitalWrite(RGBledBluePin[1], LOW); 482 digitalWrite(RGBledRedPin[1], HIGH); 483 digitalWrite(RGBledBluePin[2], LOW); 484 digitalWrite(RGBledRedPin[2], HIGH); 485 analogWrite(FanPWMPin, FanSpeed[1]); // Fan high temperatures test 486 delay(5000); 487 analogWrite(FanPWMPin, FanSpeed[0]); 488}//ledShow() 489 490void serialPrintChg(const char msg[]) { // -------------------------------- print charging 491 Serial.print(msg); 492 Serial.print(":"); 493 Serial.print(" Cell="); 494 Serial.print(WhichCellIsOn); 495 Serial.print(" Vdac="); 496 Serial.print(SetVOutput,3); 497 Serial.print(" Vcel="); 498 Serial.print(Vcell,3); 499 Serial.print(" Acel="); 500 Serial.println(Aload,3); 501} 502 503void serialPrintDebug() { // ----------------------------------------------- print debug serial & bluetooth 504 Serial.print("TBatt="); // temperatures 505 Serial.print(TempBattery,0); 506 Serial.print(" T7812="); 507 Serial.print(Temp7812,0); 508 Serial.print(" T317="); 509 510 Serial.print(Temp317,0); 511 Serial.print(" Fan="); 512 Serial.print(WhichFanSpeedIsOn); 513 Serial.println("/255"); 514 515 Serial.print("Cell="); // VA values 516 Serial.print(WhichCellIsOn); 517 Serial.print(" VCel="); 518 Serial.print(Vcell,3); 519 Serial.print(" Vdac="); 520 Serial.print(Voutput,3); 521 Serial.print(" ACel="); 522 Serial.println(Aload,3); 523 524 Serial.print("IsAlrdy="); // status 525 Serial.print(IsAlreadyCharged); 526 Serial.print(" IsCharg="); 527 Serial.print(IsCharging); 528 Serial.print(" IsOver="); 529 Serial.print(IsOverTime); 530 Serial.print(" IsALRM="); 531 Serial.print(IsALARM); 532 Serial.print(" IsSlow="); 533 Serial.println(IsSlowDown); 534 535 Serial.print("Start[1]="); // charging times [1] 536 Serial.print(ChTimeStart[1]); 537 Serial.print(" End[1]="); 538 if (ChTimeEnd[1] > 0) { 539 Serial.print(ChTimeEnd[1]); 540 } else { 541 Serial.print("?"); 542 } 543 Serial.print(" Time[1]="); 544 if (ChTimeEnd[1] > 0) { 545 Serial.print(long(ChTimeEnd[1] - ChTimeStart[1])); 546 } else { 547 Serial.print("?"); 548 } 549 Serial.print(" VInit[1]="); 550 Serial.print(VInitCell[1],3); 551 Serial.print(" VFinal[1]="); 552 Serial.print(VFinalCell[1],3); 553 Serial.print(" Over[1]="); 554 Serial.print(C_OverTime[1]); 555 Serial.print(" Alarm[1]="); 556 Serial.print(C_AlarmTime[1]); 557 Serial.print(" Remain[1]="); 558 Serial.print(TRemain[1]); 559 Serial.print(" SoC%[1]="); 560 Serial.println(SoC[1]); 561 562 Serial.print("Start[2]="); // charging times [2] 563 Serial.print(ChTimeStart[2]); 564 Serial.print(" End[2]="); 565 if (ChTimeEnd[2] > 0) { 566 Serial.print(ChTimeEnd[2]); 567 } else { 568 Serial.print("?"); 569 } 570 Serial.print(" Time[2]="); 571 if (ChTimeEnd[2] > 0) { 572 Serial.print(long(ChTimeEnd[2] - ChTimeStart[2])); 573 } else { 574 Serial.print("?"); 575 } 576 Serial.print(" VInit[2]="); 577 Serial.print(VInitCell[2],3); 578 Serial.print(" VFinal[2]="); 579 Serial.print(VFinalCell[2],3); 580 Serial.print(" Over[2]="); 581 Serial.print(C_OverTime[2]); 582 Serial.print(" Alarm[2]="); 583 Serial.print(C_AlarmTime[2]); 584 Serial.print(" Remain[2]="); 585 Serial.print(TRemain[2]); 586 Serial.print(" SoC%[2]="); 587 Serial.println(SoC[2]); 588 589 Serial.print("TimeNow="); 590 Serial.println(ChTimeNow); 591 592 lastPrintDebugMillis=millis(); 593}//serialPrintDebug() 594 595// round zero decimal // ----------------------------------------------- rounds 596float roundZeroDec(float f) { 597 float y, d; 598 y = f*1; 599 d = y - (int)y; 600 y = (float)(int)(f*1)/1; 601 if (d >= 0.5) { 602 y += 1; 603 } else { 604 if (d < -0.5) { 605 y -= 1; 606 } 607 } 608 return y; 609} 610// round three decimals 611float roundThreeDec(float f) { 612 float y, d; 613 y = f*1000; 614 d = y - (int)y; 615 y = (float)(int)(f*1000)/1000; 616 if (d >= 0.5) { 617 y += 0.001; 618 } else { 619 if (d < -0.5) { 620 y -= 0.001; 621 } 622 } 623 return y; 624} 625
Downloadable files
Charger schematic diagram (Fritzing)
Charger schematic diagram (Fritzing)
PCB bottom (small LED board)
PCB bottom (small LED board)
PCB bottom
PCB bottom
PCB top (small LED board)
PCB top (small LED board)
PCB top
PCB top
PCB silk (components)
PCB silk (components)
PCB silk, components (small LED board)
PCB silk, components (small LED board)
PCB silk, components (small LED board)
PCB silk, components (small LED board)
PCB top (small LED board)
PCB top (small LED board)
Charger schematic diagram (Fritzing)
Charger schematic diagram (Fritzing)
PCB bottom (small LED board)
PCB bottom (small LED board)
PCB bottom
PCB bottom
PCB top
PCB top
PCB silk (components)
PCB silk (components)
Comments
Only logged in users can leave comments