DIY Lithium Battery Charger Shield for Arduino
In this project, we are building a programmable single/multi cell lithium battery charger shield for Arduino. The shield provides LCD and button interface which let the user set the battery cut-off voltage from 2V to 10V and charge current from 50mA to 1.1A. The charger also provides the ability to monitor the battery status before and during charge.
The charger is based on LT1510 Constant Current/Constant Voltage Battery charger IC and controlled by Arduino UNO. The display on the shield is Nokia 5110 LCD which is very simple to use and still available on the market. There are two different battery connectors available on the shield, a two contact screw terminal block and a right angle 2mm JST-PH connector.
Circuit Design
The schematic of the project is drawn in SoloCapture, the schematic editor of SoloPCB tools. SoloCapture makes the schematic drawing process very easy and fast. You can download SoloPCB tools at Fabstream.com for FREE.
You can download the SoloPCB design files of the project by using the link below.
Please check out this video to see how to import the project libraries, open and synchronize the schematic and PCB files.
The lithium battery charger circuit is designed as an Arduino Shield. But the battery charger IC on the board can also work without MCU control. R3 and R4 sets the charge cut-off voltage, R2 ,R24 and C5 adjusts the charge current limit. With those passive component configurations, LT1510 can charge the battery and know when to stop. But we want to build a user programmable charger. So we had to take control of these functions. Anyway, when no code is present on Arduino, the charger has default cut-off voltage of 4.2V and maximum charge current of 1.1A.
Pulling VC pin of LT1510 to ground stops charging immediately. The pin 5 of Arduino assigned to drive Q2 Mosfet to stop charging when required. The battery voltage is divided by ten over R7 and R8 resistors and read by the A1 analog input. By using these two features, we can read the battery voltage and stop charging when the battery reaches a pre-determined voltage level.
In LT1510 datasheet, in addition to fixed resistor configuration, controlling the charge current by PWM method is also explained. Pin 6 of Arduino has PWM function and it is used for this purpose. Adjusting the PWM duty cycle easily adjusts the charge current. The current flowing to the battery is sensed by ACS712-5A Hall Effect current sensor IC and the sensor output is read by A0 analog input of Arduino. ACS712-5A outputs 0.185mV per 1A in addition to 2.5V. For example when the battery draws 1A, the sensor outputs 2.685V. To read the current more accurately, the internal voltage reference 1.1V is used so 10 bit ADC reading will fit between 0V and 1.1V at 1024 step resolution.
The maximum sensor output difference will be 1.1A x 0.185V = 0.204V resulting an output of 2.704V. By using the LM258 op-amp, we subtracted 2.5V from the sensor output and multiply the result by 5. This maps the sensor output from 0V (@0A) to 1.02 (@1.1A) which fits nicely between the ADC limits of 0V and 1.1V. There is still 0.1V margin left which is meaningful when considering the op-amp offset voltage and current sensor noise and offset.
5110 LCD display uses SPI interface and requires 3.3V power supply. Since the Arduino I/O pins works at 5V, to protect the LCD module, it is recommendedto connect 10K or 1K resistors in series to the signal lines. The LCD module includes backlight LEDs. Those LEDs are driven by Pin 8 over 330R current limiting resistor.
There are four buttons (up, down, left, right) connected to Pin A2-A5 of Arduino. Those pins are set as inputs and the internal pull up resistors are activated. So simply pulling the pins to ground by using the buttons is enough to detect the button activity.
There are two SMD LEDs on the board reserved for any kind of indication. They are connected to Pin 3 and Pin 4. Those pins are set as outputs. Depending on the LED characteristics, current limiting resistors should be connected in series with the LEDs.
PCB Design
The PCB of the project is designed in SoloPCB. SoloPCB is a pack of powerful tools consisting of schematic capture, PCB layout, and integrated autorouting. You can download SoloPCB tools at Fabstream.com for FREE and start using immediately.
You can download the SoloPCB design files of the project by using the link below.
Please check out this video to see how to import the project libraries, open and synchronize the schematic and PCB files.
Since this is an Arduino shield, it should have similar dimensions with Arduino UNO. The expansion headers must be properly positioned. The LCD, buttons, LEDs and the battery connectors are placed on the top layer to make the interface usable. All the other components are placed on the bottom layer.
LT1510 requires PCB area which is connected to the GND pins to cool down the IC during operation. And there is a recommended PCB layout in its datasheet which maximizes the noise reduction performance.
Part List
The Bill of Materials of the Lithium Battery Charger shield is given below.
Quantity | Part Description | Designator |
---|---|---|
1 | LT1510 Constant Current/Constant Voltage Battery Charger SO-16 | U1 |
1 | REF03 2.5V Voltage Reference SO8 | U2 |
1 | ACS712-5A Hall Effect Based Current Sensor 8-SOIC | U3 |
1 | LM258 Low Noise Operational Amplifier SO-8 | U4 |
1 | 5110 LCD Module | LCD1 |
2 | SS14 1A 40V Schottky Rectifier SMA | D1 D2 |
1 | 1N4148 General Purpose Diode SOD80C | D5 |
3 | BSS138 Mosfet SOT-23 | Q1 Q2 Q3 |
1 | Red LED 0805 | D3 |
1 | Green LED 0805 | D4 |
1 | 220nF 50V 0805 X7R SMD Ceramic Capacitor | C1 |
5 | 100nF 50V 0805 X7R SMD Ceramic Capacitor | C4 C8 C9 C10 C11 |
2 | 1nF 50V 0805 X7R SMD Ceramic Capacitor | C6 C7 |
1 | 10uF 25V 1206 X7R SMD Ceramic Capacitor | C3 |
1 | 1uF 25V 1206 X7R SMD Ceramic Capacitor | C5 |
1 | 22uF 16V Tantalum Capacitor B-Case | C2 |
1 | MSS1260-333 330uH Coilcraft Power Inductor | L1 |
3 | 100R 1% 0805 Resistor | R5 R6 R23 |
3 | 20K 1% 0805 Resistor | R7 R19 R22 |
2 | 1K 1% 0805 Resistor | R1 R10 |
1 | 70.6K 1% 0805 Resistor | R4 |
6 | 10K 1% 0805 Resistor | R11 R12 R13 R14 R20 R21 |
2 | 0805 Resistor Value Depends on the LEDs | R15 R16 |
1 | 3K8 1% 0805 Resistor | R24 |
3 | 100K 1% 0805 Resistor | R3 R17 R18 |
1 | 330R 1% 0805 Resistor | R9 |
1 | 300R 1% 0805 Resistor | R2 |
1 | 180K 1% 0805 Resistor | R8 |
4 | Tact Push Button SMD | SW1 SW2 SW3 SW4 |
1 | 1×6 2.54mm pitch 15mm height Male Header | J2 |
2 | 1×8 2.54mm pitch 15mm height Male Header | J3 J4 |
1 | 1×10 2.54mm pitch 15mm height Male Header | J1 |
1 | JST-PH Connector 2 Pin Right Angle | J5 |
1 | 1×2 5.2mm Pitch Screw Terminal Block | J6 |
Software
Page based design is applied in the project. There are four pages that lets the user enter the charge parameters and monitor the battery status. Adafruit PCD8544 and GFX libraries are used to drive Nokia 5110 LCD.
The first page is the Set Parameters page. On this page the user can enter the battery cut-off voltage and the maximum charge current, go to battery status page, and start charging. Up and down buttons are used to travel between the options and right and left buttons are used to change values or select any option.
The second page is the Battery Status Page. While not charging, the user can enter this page from the Set Parameters page and see the current battery voltage. Pressing the left or the light button make the charger return to the Set Parameters page.
The third page shows the charging state of the battery. It shows the voltage and current status of the battery during charge. When right or left button is pressed, the charger stops charging and returns to the Set Parameters page.
When the battery voltage reaches to the set voltage, the charger stops charging and displays the Charge Complete page.To exit, pressing the left or the right button is required.
The charger keeps the last used parameters in the internal EEPROM. When charging process starts, the parameters are saved. At startup the charger reads the values from the EEPROM so the user don’t have to enter the values each time.
To read the battery voltage and the charge current, A0 and A1 pins are used as analog inputs. The details of the ADC steps are explained in the code. To change the charge current, PWM function is used via pin 6. Adjusting the duty cycle changes the charge current. A lookup table including the current vs. duty cycle is constructed manually and used. Since we can read the current, it is also possible to change the duty cycle dynamically.
At startup, the charger displays a bitmap logo. It was a bit challenging to display this bitmap so we wanted to explain the process for 5110 LCD users who want to use this feature.
How to Create and Use Bitmap Images on 5110 LCD
This example is prepared to be used with Adafruit PCD8544 and GFX Arduino libraries.
First of all, we need to create the image that will be displayed on the 5110 LCD. There are lots of graphics editors that can be used for this purpose but we will use the most basic one, MS Paint.
- Start paint and create a new file.
- Select “Resize” on the tool ribbon.
- Choose “Pixels” and uncheck “Maintain aspect ratio”
- We will create a full screen logo so enter the dimensions horizontal: 88 and vertical: 48. Actually the width of the screen is 84px but we experienced that the width should be a multiple of 8. The excess four bits in each line won’t be displayed.
- Save the image in “Monochrome Bitmap” type.
Now the blank image is ready for the design. The last four vertical columns on the image will be lost so don’t include them. You can see the image created for the charger project below.
To display this image on the LCD, we need to convert it to a bit matrix. LCD Assistant is a useful tool which will help us at this point.
- Open LCD Assistant and select “Load Image” from the ”File” menu.
- Choose the image you created.
- On the settings tab, choose “Horizontal” as byte orientation. The size of the picture will be automatically detected.
- Leave the other fields as they are.
- From the “File” menu, choose “Save Output” and type the file name such as Logo.txt.
- Open the .txt file and replace “const unsigned char” with “static const unsigned char PROGMEM”
The image bit matrix is ready to use in the Arduino sketch. Paste it before the “void Setup()” section. To display image on the screen, you can use the following code;
display.clearDisplay();
display.drawBitmap(0, 0, logo, 84, 48, 1);
display.display();
Arduino Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
|
#include
#include <adafruit_gfx.h>
#include <adafruit_pcd8544.h>
#include
#include
#include
Adafruit_PCD8544 display = Adafruit_PCD8544(13, 9,10, 12, 11);
#define OVP_DISABLE 7
#define CHARGE_OFF 5
#define SET_CURRENT 6
#define DISPLAY_BACKLIGHT 8
#define LED_GREEN 3
#define LED_RED 4
int vset;
byte vsetb1;
byte vsetb2;
float vsetfl;
int iset;
byte isetb1;
byte isetb2;
int dispupdate=1;
byte param=1;
byte page=1;
float vbat;
float ibat;
float vbat_offset=0.0069;
float vbat_gain=1.0146;
float ibat_offset=0;
float ibat_gain=1;
float reading;
char duty_cycle=0;
static const unsigned char PROGMEM logo[] =
{
0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
0x0F, 0x1F, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0x0F, 0x1F, 0x7E, 0xFF, 0xFF,
0xFF, 0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0x0F, 0x1F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0xFF, 0x7F,
0xFF, 0x0F, 0x1F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0x0F, 0x1F, 0x7E, 0xE1,
0xC6, 0x23, 0x87, 0xEF, 0x8B, 0x47, 0x9F, 0x0F, 0x1F, 0x06, 0xCC, 0xB7, 0x6F, 0xB7, 0xEF, 0x33,
0x33, 0x4F, 0x0F, 0x1F, 0x7E, 0xDE, 0x7F, 0x6F, 0x7B, 0xEF, 0x7B, 0x7B, 0x3F, 0x0F, 0x1F, 0x7E,
0xC0, 0x7F, 0x6F, 0x7A, 0x2F, 0x7B, 0x7B, 0x9F, 0x0F, 0x1F, 0x7E, 0xDF, 0x7F, 0x6F, 0x7B, 0xEF,
0x7B, 0x7B, 0xEF, 0x0F, 0x1F, 0x7E, 0xCE, 0xB7, 0x6F, 0xB7, 0xEF, 0x33, 0x73, 0x6F, 0x0F, 0x1F,
0x06, 0xE1, 0xC7, 0x6F, 0x87, 0xE1, 0x8B, 0x07, 0x1F, 0x0F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0F, 0x1C, 0x24, 0xC0, 0x80, 0x00, 0x0F, 0x80, 0x22, 0x00, 0x00, 0x0F, 0x08, 0x04, 0x40,
0x00, 0x00, 0x04, 0x40, 0x22, 0x00, 0x00, 0x0F, 0x08, 0x6E, 0x59, 0xB3, 0x69, 0x04, 0x4E, 0x77,
0x19, 0xBB, 0x0F, 0x08, 0x24, 0x64, 0x91, 0x36, 0x87, 0x91, 0x22, 0x24, 0xC9, 0x0F, 0x08, 0x24,
0x44, 0x91, 0x24, 0x84, 0x4F, 0x22, 0x3C, 0x8A, 0x0F, 0x08, 0xA4, 0x44, 0x93, 0x24, 0x84, 0x51,
0x22, 0x20, 0x86, 0x0F, 0x1F, 0x76, 0xEF, 0xCD, 0xFF, 0xCF, 0x8F, 0xB3, 0x1D, 0xC4, 0x0F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0F,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x60,
0x1A, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0x03, 0xFF, 0xFF, 0xE0, 0x60, 0x26, 0x40, 0x00, 0x00, 0x00,
0x0F, 0x02, 0x00, 0x00, 0x20, 0xE0, 0x40, 0x58, 0xE6, 0xF4, 0xCD, 0x0F, 0x02, 0xFF, 0xE0, 0x20,
0xE0, 0x40, 0x65, 0x13, 0x49, 0x26, 0x0F, 0x02, 0xFF, 0xE0, 0x39, 0xFC, 0x40, 0x44, 0xF2, 0x39,
0xE4, 0x0F, 0x02, 0xFF, 0xE0, 0x39, 0xF8, 0x22, 0x45, 0x12, 0x41, 0x04, 0x0F, 0x02, 0xFF, 0xE0,
0x38, 0x78, 0x1C, 0xEE, 0xFF, 0x38, 0xEE, 0x0F, 0x02, 0xFF, 0xE0, 0x38, 0x70, 0x00, 0x00, 0x00,
0x44, 0x00, 0x0F, 0x02, 0xFF, 0xE0, 0x20, 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0F, 0x02, 0x00,
0x00, 0x20, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x03, 0xFF, 0xFF, 0xE0, 0x43, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F};
void setup() {
// Set Pin6 PWM Frequency
//TCCR0B = TCCR0B & 0b11111000 | 0x02;
// Initialize Timer-1, period: 1 sec.
TCCR1A = 0;
TCCR1B = 0;
TIMSK1 |= (1 << TOIE1);
TCNT1=0x0BDC;
TCCR1B |= (1 << CS12);
// Set Analog to Digital Converter reference as internal 1.1V
analogReference(INTERNAL);
// Initialize button inputs
pinMode(A2, INPUT);
digitalWrite(A2, HIGH);
pinMode(A3, INPUT);
digitalWrite(A3, HIGH);
pinMode(A4, INPUT);
digitalWrite(A4, HIGH);
pinMode(A5, INPUT);
digitalWrite(A5, HIGH);
// Initialize LED outputs
pinMode(DISPLAY_BACKLIGHT, OUTPUT);
digitalWrite(DISPLAY_BACKLIGHT, HIGH);
pinMode(LED_GREEN, OUTPUT);
digitalWrite(LED_GREEN, LOW);
pinMode(LED_RED, OUTPUT);
digitalWrite(LED_RED, LOW);
//Initialize LT1510 control outputs
pinMode(OVP_DISABLE, OUTPUT);
digitalWrite(OVP_DISABLE, LOW);
pinMode(CHARGE_OFF, OUTPUT);
digitalWrite(CHARGE_OFF, HIGH);
pinMode(SET_CURRENT, OUTPUT);
digitalWrite(SET_CURRENT, LOW);
// Read the last saved Iset and Vset values from the internal EEPROM
vsetb1 = EEPROM.read(0);
vsetb2 = EEPROM.read(1);
vset = 0;
vset=((vsetb1 << 0) & 0xFF) + ((vsetb2 << 8) & 0xFF00);
isetb1 = EEPROM.read(2);
isetb2 = EEPROM.read(3);
iset = 0;
iset=((isetb1 << 0) & 0xFF) + ((isetb2 << 8) & 0xFF00);
// Initialize 5110 LCD
display.begin(60); // Set LCD contrast
display.clearDisplay();
display.setTextSize(0);
// Display the welcome logo
display.drawBitmap(0, 0, logo, 85, 48, 1);
display.display();
delay(2000);
}
// Timer 1 Interrupt Routine
ISR(TIMER1_OVF_vect) {
TCNT1=0x0BDC;
dispupdate=1;
reading=0;
byte i;
for (int i = 0; i < 100; i++){
reading = reading + analogRead(A1);
}
reading = (reading)/100; // Calculate the average of 100 cumulative readings.
reading = (reading*1.1)/1023; // Calculate the voltage with respect to 1.1V internal reference and 10 bit ADC resolution
reading = reading*10; // Calculate the actual battery voltage which was divided by 10 over a resistor divider.
vbat = reading;
vbat = ((vbat – vbat_offset)/vbat_gain)–0.02; // Perform the offset and gain correction
reading=0;
for (int i = 0; i < 100; i++){
reading = reading + analogRead(A0);
}
reading = (reading)/100; // Calculate the average of 100 cumulative readings.
reading = (reading*1.1)/1023; // Calculate the voltage with respect to 1.1V internal reference and 10 bit ADC resolution
reading = reading/5; // Calculate the actual ACS712 output voltage which was amplified by 5 over the opamp.
reading = reading/0.185; //ACS712 outputs 0.185V per ampere. So calculate the current.
ibat = reading;
//ibat = ibat_offset + ibat_gain*ibat; // Perform the offset and gain correction
float vsetf=vset;
if ((page==3) && (vbat >= (vsetf/1000))) {
digitalWrite(CHARGE_OFF, HIGH); // Stop charging
page=4;
dispupdate=1;
}
}
void loop() {
// If dispupdate is set, then there is something new to display on the LCD
if (dispupdate==1) {
dispupdate=0;
// Page 1: Set parameters page. Display the Page 1 content.
if (page==1){
display.clearDisplay();
display.setCursor(14, 0);
display.print(“SET PARAM”);
display.drawFastHLine(0,10,83,BLACK);
display.setCursor(0, 14);
display.print(“V-Set:”);
if (param==1) {
display.setTextColor(WHITE, BLACK);
}
display.setCursor(50, 14);
vsetfl = vset;
vsetfl = vsetfl/1000;
display.print(vsetfl,1);
display.setTextColor(BLACK, WHITE);
display.setCursor(70, 14);
display.print(“V”);
display.setCursor(0, 26);
display.print(“I-Set:”);
if (param==2) {
display.setTextColor(WHITE, BLACK);
}
if (iset >=1000) {
display.setCursor(44, 26);
}
else if (iset >=100) {
display.setCursor(50, 26);
}
else {
display.setCursor(56, 26);
}
display.print(iset,1);
display.setTextColor(BLACK, WHITE);
display.setCursor(70, 26);
display.print(“mA”);
if (param==3) {
display.setTextColor(WHITE, BLACK);
}
display.setCursor(5, 38);
display.print(“STATUS”);
display.setTextColor(BLACK, WHITE);
if (param==4) {
display.setTextColor(WHITE, BLACK);
}
display.setCursor(50, 38);
display.print(“START”);
display.setTextColor(BLACK, WHITE);
display.display();
}
// Page 2: Battery voltage status page. Display the Page 2 content.
else if (page==2) {
byte i;
sei();
display.clearDisplay();
display.setCursor(22, 0);
display.print(“STATUS”);
display.drawFastHLine(0,10,83,BLACK);
display.setCursor(0, 18);
display.print(“V-Bat:”);
display.setCursor(44, 18);
display.print(vbat,2);
display.setCursor(70, 18);
display.print(“V”);
display.setCursor(0, 40);
display.print(“<< Return”);
display.display();
delay(250);
}
// Page 3: Charging state page. Display the Page 3 content.
else if (page==3){
display.clearDisplay();
display.setCursor(16, 0);
display.print(“CHARGING”);
display.drawFastHLine(0,10,83,BLACK);
display.setCursor(0, 14);
display.print(“V-Bat:”);
display.setCursor(44, 14);
display.print(vbat,2);
display.setCursor(70, 14);
display.print(“V”);
display.setCursor(0, 26);
display.print(“I-Bat:”);
display.setCursor(44, 26);
display.print(ibat,2);
display.setCursor(70, 26);
display.print(“A”);
display.setCursor(0, 40);
display.print(“<< Return”);
display.display();
}
else if (page==4){
display.clearDisplay();
display.setCursor(25, 10);
display.print(“CHARGE”);
display.setCursor(20, 20);
display.print(“COMPLETE!”);
display.setCursor(0, 40);
display.print(“<< Return”);
display.display();
}
}
// When Down button is pressed
if (digitalRead(A5) == LOW) {
if (param==1) {
param=2;
}
else if (param==2) {
param=3;
}
else if (param==3) {
param=4;
}
else {
param=1;
}
dispupdate=1;
while (digitalRead(A5) == LOW) {
}
delay(100);
}
// When Up button is pressed
if (digitalRead(A3) == LOW) {
if (param==1) {
param=4;
}
else if (param==2) {
param=1;
}
else if (param==3) {
param=2;
}
else {
param=3;
}
dispupdate=1;
while (digitalRead(A3) == LOW) {
}
delay(100);
}
// When Right button is pressed
if (digitalRead(A4) == LOW) {
if (page==1) {
if ((param==1) && (vset <= 9800)) {
vset = vset + 100;
}
else if ((param==2) && (iset <= 1100)) {
iset = iset + 50;
}
else if (param==3) {
page=2;
}
else if (param==4) {
page=3;
//Save the last used parameters to internal EEPROM
vsetb1 = vset & 0xFF;
vsetb2 = (vset >> 8) & 0xFF;
EEPROM.write(0,vsetb1);
EEPROM.write(1,vsetb2);
isetb1 = iset & 0xFF;
isetb2 = (iset >> 8) & 0xFF;
EEPROM.write(2,isetb1);
EEPROM.write(3,isetb2);
switch (iset) {
case 50: duty_cycle=22; break;
case 100: duty_cycle=33; break;
case 150: duty_cycle=43; break;
case 200: duty_cycle=55; break;
case 250: duty_cycle=64; break;
case 300: duty_cycle=73; break;
case 350: duty_cycle=82; break;
case 400: duty_cycle=93; break;
case 450: duty_cycle=105; break;
case 500: duty_cycle=115; break;
case 550: duty_cycle=122; break;
case 600: duty_cycle=132; break;
case 650: duty_cycle=142; break;
case 700: duty_cycle=152; break;
case 750: duty_cycle=162; break;
case 800: duty_cycle=172; break;
case 850: duty_cycle=182; break;
case 900: duty_cycle=192; break;
case 950: duty_cycle=202; break;
case 1000: duty_cycle=212; break;
case 1050: duty_cycle=220; break;
case 1100: duty_cycle=235; break;
case 1150: duty_cycle=245; break;
default: duty_cycle=10; break;
}
analogWrite(6, duty_cycle); // Set charge current by assigning the Pin 6 PWM duty cycle
digitalWrite(CHARGE_OFF, LOW); // Start charging
digitalWrite(OVP_DISABLE, HIGH); // Disable LT1510 Overvoltage protection
sei();
}
}
else if (page==2) {
page=1;}
else if (page==3) {
digitalWrite(CHARGE_OFF, HIGH); // Stop charging
page=1;}
else if (page==4) {
page=1;}
delay(250);
dispupdate=1;
}
if (digitalRead(A2) == LOW) {
if (page==1) {
if ((param==1) && (vset >= 2100)) {
vset = vset – 100;
}
else if ((param==2) && (iset >= 100)) {
iset = iset – 50;
}
else if (param==3) {
page=2;
}
else if (param==4) {
page=3;
//Save the last used parameters to internal EEPROM
vsetb1 = vset & 0xFF;
vsetb2 = (vset >> 8) & 0xFF;
EEPROM.write(0,vsetb1);
EEPROM.write(1,vsetb2);
isetb1 = iset & 0xFF;
isetb2 = (iset >> 8) & 0xFF;
EEPROM.write(2,isetb1);
EEPROM.write(3,isetb2);
switch (iset) {
case 50: duty_cycle=22; break;
case 100: duty_cycle=33; break;
case 150: duty_cycle=43; break;
case 200: duty_cycle=55; break;
case 250: duty_cycle=64; break;
case 300: duty_cycle=73; break;
case 350: duty_cycle=82; break;
case 400: duty_cycle=93; break;
case 450: duty_cycle=105; break;
case 500: duty_cycle=115; break;
case 550: duty_cycle=122; break;
case 600: duty_cycle=132; break;
case 650: duty_cycle=142; break;
case 700: duty_cycle=152; break;
case 750: duty_cycle=162; break;
case 800: duty_cycle=172; break;
case 850: duty_cycle=182; break;
case 900: duty_cycle=192; break;
case 950: duty_cycle=202; break;
case 1000: duty_cycle=212; break;
case 1050: duty_cycle=220; break;
case 1100: duty_cycle=235; break;
case 1150: duty_cycle=245; break;
default: duty_cycle=10; break;
}
analogWrite(6, duty_cycle); // Set charge current by assigning the Pin 6 PWM duty cycle
digitalWrite(CHARGE_OFF, LOW); // Start charging
digitalWrite(OVP_DISABLE, HIGH); // Disable LT1510 Overvoltage protection
sei();
}
}
else if (page==2) {
page=1;}
else if (page==3) {
digitalWrite(CHARGE_OFF, HIGH); // Stop charging
page=1;}
else if (page==4) {
page=1;}
delay(250);
dispupdate=1;
}
}
|