MPPT_Code.ino 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. //----------------------------------------------------------------------------------------------------
  2. // ARDUINO MPPT SOLAR CHARGE CONTROLLER (Version-3)
  3. // Author: Debasish Dutta/deba168
  4. // www.opengreenenergy.in
  5. //
  6. // This code is for an arduino Nano based Solar MPPT charge controller.
  7. // This code is a modified version of sample code from www.timnolan.com
  8. // updated on 15/06/2015
  9. //// Specifications : //////////////////////////////////////////////////////////////////////////////////////////////////////
  10. //
  11. // 1.Solar panel power = 50W
  12. // 2.Rated Battery Voltage= 12V ( lead acid type )
  13. // 3.Maximum current = 5A //
  14. // 4.Maximum load current =10A //
  15. // 5. In put Voltage = Solar panel with Open circuit voltage from 17 to 25V //
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. #include "TimerOne.h" // using Timer1 library from http://www.arduino.cc/playground/Code/Timer1
  18. #include <LiquidCrystal_I2C.h> // using the LCD I2C Library from https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
  19. #include <Wire.h>
  20. //----------------------------------------------------------------------------------------------------------
  21. //////// Arduino pins Connections//////////////////////////////////////////////////////////////////////////////////
  22. // A0 - Voltage divider (solar)
  23. // A1 - ACS 712 Out
  24. // A2 - Voltage divider (battery)
  25. // A4 - LCD SDA
  26. // A5 - LCD SCL
  27. // D2 - ESP8266 Tx
  28. // D3 - ESP8266 Rx through the voltage divider
  29. // D5 - LCD back control button
  30. // D6 - Load Control
  31. // D8 - 2104 MOSFET driver SD
  32. // D9 - 2104 MOSFET driver IN
  33. // D11- Green LED
  34. // D12- Yellow LED
  35. // D13- Red LED
  36. // Full scheatic is given at http://www.instructables.com/files/orig/F9A/LLR8/IAPASVA1/F9ALLR8IAPASVA1.pdf
  37. ///////// Definitions /////////////////////////////////////////////////////////////////////////////////////////////////
  38. #define SOL_VOLTS_CHAN 0 // defining the adc channel to read solar volts
  39. #define SOL_AMPS_CHAN 1 // Defining the adc channel to read solar amps
  40. #define BAT_VOLTS_CHAN 2 // defining the adc channel to read battery volts
  41. #define AVG_NUM 8 // number of iterations of the adc routine to average the adc readings
  42. // ACS 712 Current Sensor is used. Current Measured = (5/(1024 *0.185))*ADC - (2.5/0.185)
  43. #define SOL_AMPS_SCALE 0.026393581 // the scaling value for raw adc reading to get solar amps // 5/(1024*0.185)
  44. #define SOL_VOLTS_SCALE 0.029296875 // the scaling value for raw adc reading to get solar volts // (5/1024)*(R1+R2)/R2 // R1=100k and R2=20k
  45. #define BAT_VOLTS_SCALE 0.029442815 // the scaling value for raw adc reading to get battery volts
  46. #define PWM_PIN 9 // the output pin for the pwm (only pin 9 avaliable for timer 1 at 50kHz)
  47. #define PWM_ENABLE_PIN 8 // pin used to control shutoff function of the IR2104 MOSFET driver (hight the mosfet driver is on)
  48. #define PWM_FULL 1023 // the actual value used by the Timer1 routines for 100% pwm duty cycle
  49. #define PWM_MAX 100 // the value for pwm duty cyle 0-100%
  50. #define PWM_MIN 60 // the value for pwm duty cyle 0-100% (below this value the current running in the system is = 0)
  51. #define PWM_START 90 // the value for pwm duty cyle 0-100%
  52. #define PWM_INC 1 //the value the increment to the pwm value for the ppt algorithm
  53. #define TRUE 1
  54. #define FALSE 0
  55. #define ON TRUE
  56. #define OFF FALSE
  57. #define TURN_ON_MOSFETS digitalWrite(PWM_ENABLE_PIN, HIGH) // enable MOSFET driver
  58. #define TURN_OFF_MOSFETS digitalWrite(PWM_ENABLE_PIN, LOW) // disable MOSFET driver
  59. #define ONE_SECOND 50000 //count for number of interrupt in 1 second on interrupt period of 20us
  60. #define LOW_SOL_WATTS 5.00 //value of solar watts // this is 5.00 watts
  61. #define MIN_SOL_WATTS 1.00 //value of solar watts // this is 1.00 watts
  62. #define MIN_BAT_VOLTS 11.00 //value of battery voltage // this is 11.00 volts
  63. #define MAX_BAT_VOLTS 14.10 //value of battery voltage// this is 14.10 volts
  64. #define HIGH_BAT_VOLTS 13.00 //value of battery voltage // this is 13.00 volts
  65. #define LVD 11.5 //Low voltage disconnect setting for a 12V system
  66. #define OFF_NUM 9 // number of iterations of off charger state
  67. //------------------------------------------------------------------------------------------------------
  68. //Defining led pins for indication
  69. #define LED_RED 11
  70. #define LED_GREEN 12
  71. #define LED_YELLOW 13
  72. //-----------------------------------------------------------------------------------------------------
  73. // Defining load control pin
  74. #define LOAD_PIN 6 // pin-2 is used to control the load
  75. //-----------------------------------------------------------------------------------------------------
  76. // Defining lcd back light pin
  77. #define BACK_LIGHT_PIN 5 // pin-5 is used to control the lcd back light
  78. //------------------------------------------------------------------------------------------------------
  79. /////////////////////////////////////////BIT MAP ARRAY//////////////////////////////////////////////////
  80. //-------------------------------------------------------------------------------------------------------
  81. byte solar[8] = //icon for termometer
  82. {
  83. 0b11111,
  84. 0b10101,
  85. 0b11111,
  86. 0b10101,
  87. 0b11111,
  88. 0b10101,
  89. 0b11111,
  90. 0b00000
  91. };
  92. byte battery[8]=
  93. {
  94. 0b01110,
  95. 0b11011,
  96. 0b10001,
  97. 0b10001,
  98. 0b11111,
  99. 0b11111,
  100. 0b11111,
  101. 0b11111,
  102. };
  103. byte _PWM [8]=
  104. {
  105. 0b11101,
  106. 0b10101,
  107. 0b10101,
  108. 0b10101,
  109. 0b10101,
  110. 0b10101,
  111. 0b10101,
  112. 0b10111,
  113. };
  114. //-------------------------------------------------------------------------------------------------------
  115. // global variables
  116. int count = 0;
  117. int pwm = 0; //pwm duty cycle 0-100%
  118. float sol_amps; // solar amps
  119. float sol_volts; // solar volts
  120. float bat_volts; // battery volts
  121. float sol_watts; // solar watts
  122. float old_sol_watts = 0; // solar watts from previous time through ppt routine
  123. unsigned int seconds = 0; // seconds from timer routine
  124. unsigned int prev_seconds = 0; // seconds value from previous pass
  125. unsigned int interrupt_counter = 0; // counter for 20us interrrupt
  126. boolean led_on = TRUE;
  127. int led_counter = 0;
  128. int delta = PWM_INC; // variable used to modify pwm duty cycle for the ppt algorithm
  129. enum charger_mode {off, on, bulk, bat_float} charger_state; // enumerated variable that holds state for charger state machine
  130. // set the LCD address to 0x27 for a 20 chars 4 line display
  131. // Set the pins on the I2C chip used for LCD connections:
  132. // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
  133. LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
  134. long time = 0; // variable to store time the back light control button was pressed in millis
  135. int load_pin = 6;
  136. int back_light_pin_State = 0;
  137. int load_status=0;
  138. //------------------------------------------------------------------------------------------------------
  139. // This routine is automatically called at powerup/reset
  140. //------------------------------------------------------------------------------------------------------
  141. void setup() // run once, when the sketch starts
  142. {
  143. pinMode(LED_RED, OUTPUT);
  144. pinMode(LED_GREEN, OUTPUT);
  145. pinMode(LED_YELLOW, OUTPUT);
  146. pinMode(PWM_ENABLE_PIN, OUTPUT); // sets the digital pin as output
  147. Timer1.initialize(20); // initialize timer1, and set a 20uS period
  148. Timer1.pwm(PWM_PIN, 0); // setup pwm on pin 9, 0% duty cycle
  149. TURN_OFF_MOSFETS; //turn off MOSFET driver chip
  150. Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
  151. Serial.begin(9600); // open the serial port at 38400 bps:
  152. pwm = PWM_START; //starting value for pwm
  153. charger_state = off; // start with charger state as off
  154. pinMode(BACK_LIGHT_PIN, INPUT);
  155. pinMode(LOAD_PIN,OUTPUT);
  156. digitalWrite(LOAD_PIN,LOW); // default load state is OFF
  157. lcd.begin(20,4); // initialize the lcd for 16 chars 2 lines, turn on backlight
  158. lcd.noBacklight();
  159. lcd.createChar(1,solar);
  160. lcd.createChar(2,battery);
  161. lcd.createChar(3,_PWM);
  162. }
  163. //------------------------------------------------------------------------------------------------------
  164. // Main loop
  165. //------------------------------------------------------------------------------------------------------
  166. void loop()
  167. {
  168. read_data(); //read data from inputs
  169. run_charger(); //run the charger state machine
  170. print_data(); //print data
  171. load_control(); // control the connected load
  172. led_output(); // led indication
  173. lcd_display(); // lcd display
  174. }
  175. //------------------------------------------------------------------------------------------------------
  176. // This routine reads and averages the analog inputs for this system, solar volts, solar amps and
  177. // battery volts.
  178. //------------------------------------------------------------------------------------------------------
  179. int read_adc(int channel){
  180. int sum = 0;
  181. int temp;
  182. int i;
  183. for (i=0; i<AVG_NUM; i++) { // loop through reading raw adc values AVG_NUM number of times
  184. temp = analogRead(channel); // read the input pin
  185. sum += temp; // store sum for averaging
  186. delayMicroseconds(50); // pauses for 50 microseconds
  187. }
  188. return(sum / AVG_NUM); // divide sum by AVG_NUM to get average and return it
  189. }
  190. //------------------------------------------------------------------------------------------------------
  191. // This routine reads all the analog input values for the system. Then it multiplies them by the scale
  192. // factor to get actual value in volts or amps.
  193. //------------------------------------------------------------------------------------------------------
  194. void read_data(void) {
  195. sol_amps = (read_adc(SOL_AMPS_CHAN) * SOL_AMPS_SCALE -13.51); //input of solar amps
  196. sol_volts = read_adc(SOL_VOLTS_CHAN) * SOL_VOLTS_SCALE; //input of solar volts
  197. bat_volts = read_adc(BAT_VOLTS_CHAN) * BAT_VOLTS_SCALE; //input of battery volts
  198. sol_watts = sol_amps * sol_volts ; //calculations of solar watts
  199. }
  200. //------------------------------------------------------------------------------------------------------
  201. // This is interrupt service routine for Timer1 that occurs every 20uS.
  202. //
  203. //------------------------------------------------------------------------------------------------------
  204. void callback()
  205. {
  206. if (interrupt_counter++ > ONE_SECOND) { //increment interrupt_counter until one second has passed
  207. interrupt_counter = 0;
  208. seconds++; //then increment seconds counter
  209. }
  210. }
  211. //------------------------------------------------------------------------------------------------------
  212. // This routine uses the Timer1.pwm function to set the pwm duty cycle.
  213. //------------------------------------------------------------------------------------------------------
  214. void set_pwm_duty(void) {
  215. if (pwm > PWM_MAX) { // check limits of PWM duty cyle and set to PWM_MAX
  216. pwm = PWM_MAX;
  217. }
  218. else if (pwm < PWM_MIN) { // if pwm is less than PWM_MIN then set it to PWM_MIN
  219. pwm = PWM_MIN;
  220. }
  221. if (pwm < PWM_MAX) {
  222. Timer1.pwm(PWM_PIN,(PWM_FULL * (long)pwm / 100), 20); // use Timer1 routine to set pwm duty cycle at 20uS period
  223. //Timer1.pwm(PWM_PIN,(PWM_FULL * (long)pwm / 100));
  224. }
  225. else if (pwm == PWM_MAX) { // if pwm set to 100% it will be on full but we have
  226. Timer1.pwm(PWM_PIN,(PWM_FULL - 1), 1000); // keep switching so set duty cycle at 99.9% and slow down to 1000uS period
  227. //Timer1.pwm(PWM_PIN,(PWM_FULL - 1));
  228. }
  229. }
  230. //------------------------------------------------------------------------------------------------------
  231. // This routine is the charger state machine. It has four states on, off, bulk and float.
  232. // It's called once each time through the main loop to see what state the charger should be in.
  233. // The battery charger can be in one of the following four states:
  234. //
  235. // On State - this is charger state for MIN_SOL_WATTS < solar watts < LOW_SOL_WATTS. In this state isthe solar
  236. // watts input is too low for the bulk charging state but not low enough to go into the off state.
  237. // In this state we just set the pwm = 99.9% to get the most of low amount of power available.
  238. // Bulk State - this is charger state for solar watts > MIN_SOL_WATTS. This is where we do the bulk of the battery
  239. // charging and where we run the Peak Power Tracking alogorithm. In this state we try and run the maximum amount
  240. // of current that the solar panels are generating into the battery.
  241. // Float State - As the battery charges it's voltage rises. When it gets to the MAX_BAT_VOLTS we are done with the
  242. // bulk battery charging and enter the battery float state. In this state we try and keep the battery voltage
  243. // at MAX_BAT_VOLTS by adjusting the pwm value. If we get to pwm = 100% it means we can't keep the battery
  244. // voltage at MAX_BAT_VOLTS which probably means the battery is being drawn down by some load so we need to back
  245. // into the bulk charging mode.
  246. // Off State - This is state that the charger enters when solar watts < MIN_SOL_WATTS. The charger goes into this
  247. // state when there is no more power being generated by the solar panels. The MOSFETs are turned
  248. // off in this state so that power from the battery doesn't leak back into the solar panel.
  249. //------------------------------------------------------------------------------------------------------
  250. void run_charger(void) {
  251. static int off_count = OFF_NUM;
  252. switch (charger_state) {
  253. case on:
  254. if (sol_watts < MIN_SOL_WATTS) { //if watts input from the solar panel is less than
  255. charger_state = off; //the minimum solar watts then
  256. off_count = OFF_NUM; //go to the charger off state
  257. TURN_OFF_MOSFETS;
  258. }
  259. else if (bat_volts > MAX_BAT_VOLTS) { //else if the battery voltage has gotten above the float
  260. charger_state = bat_float; //battery float voltage go to the charger battery float state
  261. }
  262. else if (sol_watts < LOW_SOL_WATTS) { //else if the solar input watts is less than low solar watts
  263. pwm = PWM_MAX; //it means there is not much power being generated by the solar panel
  264. set_pwm_duty(); //so we just set the pwm = 100% so we can get as much of this power as possible
  265. } //and stay in the charger on state
  266. else {
  267. pwm = ((bat_volts * 10) / (sol_volts / 10)) + 5; //else if we are making more power than low solar watts figure out what the pwm
  268. charger_state = bulk; //value should be and change the charger to bulk state
  269. }
  270. break;
  271. case bulk:
  272. if (sol_watts < MIN_SOL_WATTS) { //if watts input from the solar panel is less than
  273. charger_state = off; //the minimum solar watts then it is getting dark so
  274. off_count = OFF_NUM; //go to the charger off state
  275. TURN_OFF_MOSFETS;
  276. }
  277. else if (bat_volts > MAX_BAT_VOLTS) { //else if the battery voltage has gotten above the float
  278. charger_state = bat_float; //battery float voltage go to the charger battery float state
  279. }
  280. else if (sol_watts < LOW_SOL_WATTS) { //else if the solar input watts is less than low solar watts
  281. charger_state = on; //it means there is not much power being generated by the solar panel
  282. TURN_ON_MOSFETS; //so go to charger on state
  283. }
  284. else { // this is where we do the Peak Power Tracking ro Maximum Power Point algorithm
  285. if (old_sol_watts >= sol_watts) { // if previous watts are greater change the value of
  286. delta = -delta; // delta to make pwm increase or decrease to maximize watts
  287. }
  288. pwm += delta; // add delta to change PWM duty cycle for PPT algorythm (compound addition)
  289. old_sol_watts = sol_watts; // load old_watts with current watts value for next time
  290. set_pwm_duty(); // set pwm duty cycle to pwm value
  291. }
  292. break;
  293. case bat_float:
  294. if (sol_watts < MIN_SOL_WATTS) { //if watts input from the solar panel is less than
  295. charger_state = off; //the minimum solar watts then it is getting dark so
  296. off_count = OFF_NUM; //go to the charger off state
  297. set_pwm_duty();
  298. TURN_OFF_MOSFETS;
  299. }
  300. else if (bat_volts > MAX_BAT_VOLTS) { //since we're in the battery float state if the battery voltage
  301. pwm -= 1; //is above the float voltage back off the pwm to lower it
  302. set_pwm_duty();
  303. }
  304. else if (bat_volts < MAX_BAT_VOLTS) { //else if the battery voltage is less than the float voltage
  305. pwm += 1; //increment the pwm to get it back up to the float voltage
  306. set_pwm_duty();
  307. if (pwm >= 100) { //if pwm gets up to 100 it means we can't keep the battery at
  308. charger_state = bulk; //float voltage so jump to charger bulk state to charge the battery
  309. }
  310. }
  311. break;
  312. case off: //when we jump into the charger off state, off_count is set with OFF_NUM
  313. if (off_count > 0) { //this means that we run through the off state OFF_NUM of times with out doing
  314. off_count--; //anything, this is to allow the battery voltage to settle down to see if the
  315. } //battery has been disconnected
  316. else if ((bat_volts > HIGH_BAT_VOLTS) && (bat_volts < MAX_BAT_VOLTS) && (sol_volts > bat_volts)) {
  317. charger_state = bat_float; //if battery voltage is still high and solar volts are high
  318. set_pwm_duty(); //change charger state to battery float
  319. TURN_ON_MOSFETS;
  320. }
  321. else if ((bat_volts > MIN_BAT_VOLTS) && (bat_volts < MAX_BAT_VOLTS) && (sol_volts > bat_volts)) {
  322. pwm = PWM_START; //if battery volts aren't quite so high but we have solar volts
  323. set_pwm_duty(); //greater than battery volts showing it is day light then
  324. charger_state = on; //change charger state to on so we start charging
  325. TURN_ON_MOSFETS;
  326. } //else stay in the off state
  327. break;
  328. default:
  329. TURN_OFF_MOSFETS;
  330. break;
  331. }
  332. }
  333. //----------------------------------------------------------------------------------------------------------------------
  334. /////////////////////////////////////////////LOAD CONTROL/////////////////////////////////////////////////////
  335. //----------------------------------------------------------------------------------------------------------------------
  336. void load_control()
  337. {
  338. if (sol_watts < MIN_SOL_WATTS) // load will on when night
  339. {
  340. if(bat_volts >LVD) // check if battery is healthy
  341. {
  342. load_status=1;
  343. digitalWrite(LOAD_PIN, LOW); // load is ON
  344. }
  345. else if(bat_volts < LVD)
  346. {
  347. load_status=0;
  348. digitalWrite(LOAD_PIN, HIGH); //load is OFF
  349. }
  350. }
  351. else // load will off during day
  352. {
  353. load_status=0;
  354. digitalWrite(LOAD_PIN, HIGH);
  355. }
  356. }
  357. //------------------------------------------------------------------------------------------------------
  358. // This routine prints all the data out to the serial port.
  359. //------------------------------------------------------------------------------------------------------
  360. void print_data(void) {
  361. Serial.print(seconds,DEC);
  362. Serial.print(" ");
  363. Serial.print("Charging = ");
  364. if (charger_state == on) Serial.print("on ");
  365. else if (charger_state == off) Serial.print("off ");
  366. else if (charger_state == bulk) Serial.print("bulk ");
  367. else if (charger_state == bat_float) Serial.print("float");
  368. Serial.print(" ");
  369. Serial.print("pwm = ");
  370. Serial.print(pwm,DEC);
  371. Serial.print(" ");
  372. Serial.print("Current (panel) = ");
  373. //print_int100_dec2(sol_amps);
  374. Serial.print(sol_amps);
  375. Serial.print(" ");
  376. Serial.print("Voltage (panel) = ");
  377. Serial.print(sol_volts);
  378. //print_int100_dec2(sol_volts);
  379. Serial.print(" ");
  380. Serial.print("Power (panel) = ");
  381. Serial.print(sol_volts);
  382. // print_int100_dec2(sol_watts);
  383. Serial.print(" ");
  384. Serial.print("Battery Voltage = ");
  385. Serial.print(bat_volts);
  386. //print_int100_dec2(bat_volts);
  387. Serial.print(" ");
  388. Serial.print("\n\r");
  389. delay(100);
  390. }
  391. //-------------------------------------------------------------------------------------------------
  392. //---------------------------------Led Indication--------------------------------------------------
  393. //-------------------------------------------------------------------------------------------------
  394. void led_output(void)
  395. {
  396. if(bat_volts > 14.1 )
  397. {
  398. leds_off_all();
  399. digitalWrite(LED_YELLOW, HIGH);
  400. }
  401. else if(bat_volts > 11.9 && bat_volts < 14.1)
  402. {
  403. leds_off_all();
  404. digitalWrite(LED_GREEN, HIGH);
  405. }
  406. else if(bat_volts < 11.8)
  407. {
  408. leds_off_all;
  409. digitalWrite(LED_RED, HIGH);
  410. }
  411. }
  412. //------------------------------------------------------------------------------------------------------
  413. //
  414. // This function is used to turn all the leds off
  415. //
  416. //------------------------------------------------------------------------------------------------------
  417. void leds_off_all(void)
  418. {
  419. digitalWrite(LED_GREEN, LOW);
  420. digitalWrite(LED_RED, LOW);
  421. digitalWrite(LED_YELLOW, LOW);
  422. }
  423. //------------------------------------------------------------------------------------------------------
  424. //-------------------------- LCD DISPLAY --------------------------------------------------------------
  425. //-------------------------------------------------------------------------------------------------------
  426. void lcd_display()
  427. {
  428. back_light_pin_State = digitalRead(BACK_LIGHT_PIN);
  429. if (back_light_pin_State == HIGH)
  430. {
  431. time = millis(); // If any of the buttons are pressed, save the time in millis to "time"
  432. }
  433. lcd.setCursor(0, 0);
  434. lcd.print("SOL");
  435. lcd.setCursor(4, 0);
  436. lcd.write(1);
  437. lcd.setCursor(0, 1);
  438. lcd.print(sol_volts);
  439. lcd.print("V");
  440. lcd.setCursor(0, 2);
  441. lcd.print(sol_amps);
  442. lcd.print("A");
  443. lcd.setCursor(0, 3);
  444. lcd.print(sol_watts);
  445. lcd.print("W ");
  446. lcd.setCursor(8, 0);
  447. lcd.print("BAT");
  448. lcd.setCursor(12, 0);
  449. lcd.write(2);
  450. lcd.setCursor(8, 1);
  451. lcd.print(bat_volts);
  452. lcd.setCursor(8,2);
  453. if (charger_state == on)
  454. lcd.print("on");
  455. else if (charger_state == off)
  456. lcd.print("off");
  457. else if (charger_state == bulk)
  458. lcd.print("bulk");
  459. else if (charger_state == bat_float)
  460. lcd.print("float");
  461. //-----------------------------------------------------------
  462. //--------------------Battery State Of Charge ---------------
  463. //-----------------------------------------------------------
  464. lcd.setCursor(8,3);
  465. if ( bat_volts >= 12.7)
  466. lcd.print( "100%");
  467. else if (bat_volts >= 12.5 && bat_volts < 12.7)
  468. lcd.print( "90%");
  469. else if (bat_volts >= 12.42 && bat_volts < 12.5)
  470. lcd.print( "80%");
  471. else if (bat_volts >= 12.32 && bat_volts < 12.42)
  472. lcd.print( "70%");
  473. else if (bat_volts >= 12.2 && bat_volts < 12.32)
  474. lcd.print( "60%");
  475. else if (bat_volts >= 12.06 && bat_volts < 12.2)
  476. lcd.print( "50%");
  477. else if (bat_volts >= 11.90 && bat_volts < 12.06)
  478. lcd.print( "40%");
  479. else if (bat_volts >= 11.75 && bat_volts < 11.90)
  480. lcd.print( "30%");
  481. else if (bat_volts >= 11.58 && bat_volts < 11.75)
  482. lcd.print( "20%");
  483. else if (bat_volts >= 11.31 && bat_volts < 11.58)
  484. lcd.print( "10%");
  485. else if (bat_volts < 11.3)
  486. lcd.print( "0%");
  487. //---------------------------------------------------------------------
  488. //------------------Duty Cycle-----------------------------------------
  489. //---------------------------------------------------------------------
  490. lcd.setCursor(15,0);
  491. lcd.print("PWM");
  492. lcd.setCursor(19,0);
  493. lcd.write(3);
  494. lcd.setCursor(15,1);
  495. lcd.print(pwm);
  496. lcd.print("%");
  497. //----------------------------------------------------------------------
  498. //------------------------Load Status-----------------------------------
  499. //----------------------------------------------------------------------
  500. lcd.setCursor(15,2);
  501. lcd.print("Load");
  502. lcd.setCursor(15,3);
  503. if (load_status == 1)
  504. {
  505. lcd.print("On");
  506. }
  507. else
  508. {
  509. lcd.print("Off");
  510. }
  511. backLight_timer(); // call the backlight timer function in every loop
  512. }
  513. void backLight_timer(){
  514. if((millis() - time) <= 15000) // if it's been less than the 15 secs, turn the backlight on
  515. lcd.backlight(); // finish with backlight on
  516. else
  517. lcd.noBacklight(); // if it's been more than 15 secs, turn the backlight off
  518. }