This is the code used on my video series "Hybrid Supercapacitor Car Battery" for my own hardware monitoring system. THe videos can be found on madelectronengineering.com
Dependencies: BurstSPI Fonts INA219 mbed LPC1114_WakeInterruptIn
Fork of SharpMemoryLCD by
main.cpp@2:0c49a8f32f6e, 2017-12-26 (annotated)
- Committer:
- madelectroneng
- Date:
- Tue Dec 26 21:30:09 2017 +0000
- Revision:
- 2:0c49a8f32f6e
Inital setup
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
madelectroneng | 2:0c49a8f32f6e | 1 | /* This is a project for madelectronengineering.com |
madelectroneng | 2:0c49a8f32f6e | 2 | This code is used for a hardware monitoring system for the Hybrid Supercapacitor Car Battery to monitor the supercap voltage, the LiFeP04 voltage, |
madelectroneng | 2:0c49a8f32f6e | 3 | current, and wattage, plus also monitor 3 seperate temperature points. |
madelectroneng | 2:0c49a8f32f6e | 4 | |
madelectroneng | 2:0c49a8f32f6e | 5 | Required hardware: |
madelectroneng | 2:0c49a8f32f6e | 6 | STM32 NUCLEO-L073RZ |
madelectroneng | 2:0c49a8f32f6e | 7 | TMP36 Temperature Sensors (x3) |
madelectroneng | 2:0c49a8f32f6e | 8 | INA219 Current & Voltage Breakout (modify by removing 0.1Ohm resistor and replacing with 0.01Ohm Resistor to measure up to 32Amps |
madelectroneng | 2:0c49a8f32f6e | 9 | ST NUCLEO Protoboard |
madelectroneng | 2:0c49a8f32f6e | 10 | 30k & 7.5k resistors for voltage divider to measure supercap voltage |
madelectroneng | 2:0c49a8f32f6e | 11 | 0.1Ohm 25W current limiting power resistor in between supercap array and LiFeP04 battery |
madelectroneng | 2:0c49a8f32f6e | 12 | Sharp Memory LCD 400x240 |
madelectroneng | 2:0c49a8f32f6e | 13 | |
madelectroneng | 2:0c49a8f32f6e | 14 | The INA219 measures the current and amperage on the battery side of the current limiting resistor to keep an eye on the LiFeP04 battery. |
madelectroneng | 2:0c49a8f32f6e | 15 | voltage divider connects directly to + of supercap array |
madelectroneng | 2:0c49a8f32f6e | 16 | |
madelectroneng | 2:0c49a8f32f6e | 17 | Arduino equivelant connections: |
madelectroneng | 2:0c49a8f32f6e | 18 | A0 - TMP36 #1 |
madelectroneng | 2:0c49a8f32f6e | 19 | A1 - TMP36 #2 |
madelectroneng | 2:0c49a8f32f6e | 20 | A2 - TMP36 #3 |
madelectroneng | 2:0c49a8f32f6e | 21 | A3 - Voltage divider Input |
madelectroneng | 2:0c49a8f32f6e | 22 | A4&A5 - I2C for INA219 |
madelectroneng | 2:0c49a8f32f6e | 23 | |
madelectroneng | 2:0c49a8f32f6e | 24 | Arduino equivelant connections for LCD Screen: |
madelectroneng | 2:0c49a8f32f6e | 25 | D13 - SClk |
madelectroneng | 2:0c49a8f32f6e | 26 | D11 - MOSI |
madelectroneng | 2:0c49a8f32f6e | 27 | D10 - CD |
madelectroneng | 2:0c49a8f32f6e | 28 | D9 - Enable |
madelectroneng | 2:0c49a8f32f6e | 29 | D8 - Extcom |
madelectroneng | 2:0c49a8f32f6e | 30 | |
madelectroneng | 2:0c49a8f32f6e | 31 | */ |
madelectroneng | 2:0c49a8f32f6e | 32 | #include "mbed.h" |
madelectroneng | 2:0c49a8f32f6e | 33 | #include "SharpLCD.h" |
madelectroneng | 2:0c49a8f32f6e | 34 | #include "INA219.hpp" |
madelectroneng | 2:0c49a8f32f6e | 35 | #include "Neu44x36.h" |
madelectroneng | 2:0c49a8f32f6e | 36 | #include "Neu31x26.h" |
madelectroneng | 2:0c49a8f32f6e | 37 | #include "WakeUp.h" |
madelectroneng | 2:0c49a8f32f6e | 38 | |
madelectroneng | 2:0c49a8f32f6e | 39 | SharpLCD display(PA_7, NC, PA_5, PB_6, PC_7, PA_9); //mosi, miso(not used), sck, cs, enable, extcom |
madelectroneng | 2:0c49a8f32f6e | 40 | INA219 ina219(PC_1, PC_0, 0x40, 400000, RES_12BITS); |
madelectroneng | 2:0c49a8f32f6e | 41 | AnalogIn ain1(PA_0); // connect A0 to Vout(Temp36) |
madelectroneng | 2:0c49a8f32f6e | 42 | AnalogIn ain2(PA_1); // connect A1 to Vout(Temp36) |
madelectroneng | 2:0c49a8f32f6e | 43 | AnalogIn ain3(PA_4); // connect A2 to Vout(Temp36) |
madelectroneng | 2:0c49a8f32f6e | 44 | AnalogIn ain4(PB_0); // Connect A3 to Voltage Divider |
madelectroneng | 2:0c49a8f32f6e | 45 | |
madelectroneng | 2:0c49a8f32f6e | 46 | int main() |
madelectroneng | 2:0c49a8f32f6e | 47 | { |
madelectroneng | 2:0c49a8f32f6e | 48 | display.enableDisplay(); //enable sharp memory lcd |
madelectroneng | 2:0c49a8f32f6e | 49 | display.clearImmediate(); //clear the screen buffer and screen |
madelectroneng | 2:0c49a8f32f6e | 50 | |
madelectroneng | 2:0c49a8f32f6e | 51 | display.set_font(Neu44x36); |
madelectroneng | 2:0c49a8f32f6e | 52 | |
madelectroneng | 2:0c49a8f32f6e | 53 | //only send graphics and text once to the screen during bootup |
madelectroneng | 2:0c49a8f32f6e | 54 | display.locate(17,0); |
madelectroneng | 2:0c49a8f32f6e | 55 | display.printf("Hybrid Supercap"); |
madelectroneng | 2:0c49a8f32f6e | 56 | display.locate(75,35); |
madelectroneng | 2:0c49a8f32f6e | 57 | display.printf("Car Battery"); |
madelectroneng | 2:0c49a8f32f6e | 58 | |
madelectroneng | 2:0c49a8f32f6e | 59 | display.rect(0,73,195,239, Black); |
madelectroneng | 2:0c49a8f32f6e | 60 | display.rect(205,73,399,239, Black); |
madelectroneng | 2:0c49a8f32f6e | 61 | display.fillrect(195,73,10,167, Black); |
madelectroneng | 2:0c49a8f32f6e | 62 | display.line(1,174,194,174, Black); |
madelectroneng | 2:0c49a8f32f6e | 63 | display.line(1,176,194,176, Black); |
madelectroneng | 2:0c49a8f32f6e | 64 | display.line(1,107,194,107, Black); |
madelectroneng | 2:0c49a8f32f6e | 65 | display.line(206,107,399,107, Black); |
madelectroneng | 2:0c49a8f32f6e | 66 | display.line(1,141,194,141, Black); |
madelectroneng | 2:0c49a8f32f6e | 67 | display.line(206,141,399,141, Black); |
madelectroneng | 2:0c49a8f32f6e | 68 | display.line(1,175,194,175, Black); |
madelectroneng | 2:0c49a8f32f6e | 69 | display.line(206,175,399,175, Black); |
madelectroneng | 2:0c49a8f32f6e | 70 | display.line(1,209,194,209, Black); |
madelectroneng | 2:0c49a8f32f6e | 71 | display.line(206,209,399,209, Black); |
madelectroneng | 2:0c49a8f32f6e | 72 | |
madelectroneng | 2:0c49a8f32f6e | 73 | display.set_font(Neu31x26); |
madelectroneng | 2:0c49a8f32f6e | 74 | display.locate(15,76); |
madelectroneng | 2:0c49a8f32f6e | 75 | display.printf("Supercaps"); |
madelectroneng | 2:0c49a8f32f6e | 76 | display.locate(240,76); |
madelectroneng | 2:0c49a8f32f6e | 77 | display.printf("LiFePo4"); |
madelectroneng | 2:0c49a8f32f6e | 78 | display.locate(30,179); |
madelectroneng | 2:0c49a8f32f6e | 79 | display.printf("Resistor"); |
madelectroneng | 2:0c49a8f32f6e | 80 | |
madelectroneng | 2:0c49a8f32f6e | 81 | display.locate(360,110); |
madelectroneng | 2:0c49a8f32f6e | 82 | display.printf("V"); |
madelectroneng | 2:0c49a8f32f6e | 83 | display.locate(360,143); |
madelectroneng | 2:0c49a8f32f6e | 84 | display.printf("A"); |
madelectroneng | 2:0c49a8f32f6e | 85 | display.locate(360,177); |
madelectroneng | 2:0c49a8f32f6e | 86 | display.printf("W"); |
madelectroneng | 2:0c49a8f32f6e | 87 | display.locate(155,212); |
madelectroneng | 2:0c49a8f32f6e | 88 | display.printf("'F"); |
madelectroneng | 2:0c49a8f32f6e | 89 | display.locate(360,212); |
madelectroneng | 2:0c49a8f32f6e | 90 | display.printf("'F"); |
madelectroneng | 2:0c49a8f32f6e | 91 | display.locate(155,143); |
madelectroneng | 2:0c49a8f32f6e | 92 | display.printf("'F"); |
madelectroneng | 2:0c49a8f32f6e | 93 | display.locate(155,110); |
madelectroneng | 2:0c49a8f32f6e | 94 | display.printf("V"); |
madelectroneng | 2:0c49a8f32f6e | 95 | |
madelectroneng | 2:0c49a8f32f6e | 96 | while(1) { |
madelectroneng | 2:0c49a8f32f6e | 97 | |
madelectroneng | 2:0c49a8f32f6e | 98 | float volt; |
madelectroneng | 2:0c49a8f32f6e | 99 | float current_ma; |
madelectroneng | 2:0c49a8f32f6e | 100 | float power; |
madelectroneng | 2:0c49a8f32f6e | 101 | |
madelectroneng | 2:0c49a8f32f6e | 102 | volt = ina219.read_bus_voltage(); |
madelectroneng | 2:0c49a8f32f6e | 103 | current_ma = ina219.read_current_mA() / 1000; |
madelectroneng | 2:0c49a8f32f6e | 104 | power = volt * current_ma; |
madelectroneng | 2:0c49a8f32f6e | 105 | |
madelectroneng | 2:0c49a8f32f6e | 106 | float V1 = ain1.read() * 3.3; // connect Vs(Tmp36) to 3.3V |
madelectroneng | 2:0c49a8f32f6e | 107 | float tempC1 = (V1-0.5) * 100; // calculate temperature C |
madelectroneng | 2:0c49a8f32f6e | 108 | float tempF1 = (tempC1 * 9 / 5) + 32.0; // calculate temperature F |
madelectroneng | 2:0c49a8f32f6e | 109 | |
madelectroneng | 2:0c49a8f32f6e | 110 | float V2 = ain2.read() * 3.3; // connect Vs(Tmp36) to 3.3V |
madelectroneng | 2:0c49a8f32f6e | 111 | float tempC2 = (V2-0.5) * 100; // calculate temperature C |
madelectroneng | 2:0c49a8f32f6e | 112 | float tempF2 = (tempC2 * 9 / 5) + 32.0; // calculate temperature F |
madelectroneng | 2:0c49a8f32f6e | 113 | |
madelectroneng | 2:0c49a8f32f6e | 114 | float V3 = ain3.read() * 3.3; // connect Vs(Tmp36) to 3.3V |
madelectroneng | 2:0c49a8f32f6e | 115 | float tempC3 = (V3-0.5) * 100; // calculate temperature C |
madelectroneng | 2:0c49a8f32f6e | 116 | float tempF3 = (tempC3 * 9 / 5) + 32.0; // calculate temperature F |
madelectroneng | 2:0c49a8f32f6e | 117 | |
madelectroneng | 2:0c49a8f32f6e | 118 | float V4 = (ain4.read()) * 3.3; // Voltage divider for supercap voltage |
madelectroneng | 2:0c49a8f32f6e | 119 | float voltage = (V4 * 5); // Voltage divider is 1 to 5 ratio |
madelectroneng | 2:0c49a8f32f6e | 120 | |
madelectroneng | 2:0c49a8f32f6e | 121 | display.set_font(Neu31x26); |
madelectroneng | 2:0c49a8f32f6e | 122 | display.locate(210,110); |
madelectroneng | 2:0c49a8f32f6e | 123 | display.printf(" "); |
madelectroneng | 2:0c49a8f32f6e | 124 | display.locate(210,110); |
madelectroneng | 2:0c49a8f32f6e | 125 | display.printf("%+05.2f", volt); |
madelectroneng | 2:0c49a8f32f6e | 126 | display.locate(210,143); |
madelectroneng | 2:0c49a8f32f6e | 127 | display.printf(" "); |
madelectroneng | 2:0c49a8f32f6e | 128 | display.locate(210,143); |
madelectroneng | 2:0c49a8f32f6e | 129 | display.printf("%+04.1f", current_ma); |
madelectroneng | 2:0c49a8f32f6e | 130 | display.locate(210,177); |
madelectroneng | 2:0c49a8f32f6e | 131 | display.printf(" "); |
madelectroneng | 2:0c49a8f32f6e | 132 | display.locate(210,177); |
madelectroneng | 2:0c49a8f32f6e | 133 | display.printf("%+05.1f", power); |
madelectroneng | 2:0c49a8f32f6e | 134 | display.locate(20,212); |
madelectroneng | 2:0c49a8f32f6e | 135 | display.printf(" "); |
madelectroneng | 2:0c49a8f32f6e | 136 | display.locate(20,212); |
madelectroneng | 2:0c49a8f32f6e | 137 | display.printf("%+03.0f", tempF1); |
madelectroneng | 2:0c49a8f32f6e | 138 | display.locate(210,212); |
madelectroneng | 2:0c49a8f32f6e | 139 | display.printf(" "); |
madelectroneng | 2:0c49a8f32f6e | 140 | display.locate(210,212); |
madelectroneng | 2:0c49a8f32f6e | 141 | display.printf("%+03.0f", tempF2); |
madelectroneng | 2:0c49a8f32f6e | 142 | display.locate(20,143); |
madelectroneng | 2:0c49a8f32f6e | 143 | display.printf(" "); |
madelectroneng | 2:0c49a8f32f6e | 144 | display.locate(20,143); |
madelectroneng | 2:0c49a8f32f6e | 145 | display.printf("%+03.0f", tempF3); |
madelectroneng | 2:0c49a8f32f6e | 146 | display.locate(20,110); |
madelectroneng | 2:0c49a8f32f6e | 147 | display.printf(" "); |
madelectroneng | 2:0c49a8f32f6e | 148 | display.locate(20,110); |
madelectroneng | 2:0c49a8f32f6e | 149 | display.printf("%+05.2f", voltage); |
madelectroneng | 2:0c49a8f32f6e | 150 | |
madelectroneng | 2:0c49a8f32f6e | 151 | display.update(); |
madelectroneng | 2:0c49a8f32f6e | 152 | |
madelectroneng | 2:0c49a8f32f6e | 153 | //Set wakeup time for 1 second |
madelectroneng | 2:0c49a8f32f6e | 154 | // WakeUp::set_ms(500); |
madelectroneng | 2:0c49a8f32f6e | 155 | |
madelectroneng | 2:0c49a8f32f6e | 156 | //Enter deepsleep, the program won't go beyond this point until it is woken up |
madelectroneng | 2:0c49a8f32f6e | 157 | // deepsleep(); |
madelectroneng | 2:0c49a8f32f6e | 158 | } |
madelectroneng | 2:0c49a8f32f6e | 159 | } |