bluetooth device with current sensor that analyzes devices and determines whether they are chargeable or not
Dependencies: 4DGL-uLCD-SE mbed
main.cpp@3:88c08566c2cd, 2016-05-04 (annotated)
- Committer:
- mave3
- Date:
- Wed May 04 19:04:49 2016 +0000
- Revision:
- 3:88c08566c2cd
- Parent:
- 2:23dffdc354f1
Finished
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mave3 | 0:37ee1a85bd8f | 1 | #include "mbed.h" |
mave3 | 2:23dffdc354f1 | 2 | //#include "SDFileSystem.h" |
mave3 | 0:37ee1a85bd8f | 3 | #include "uLCD_4DGL.h" |
mave3 | 0:37ee1a85bd8f | 4 | #include <stdlib.h> // abs |
mave3 | 0:37ee1a85bd8f | 5 | #include <stdio.h> // sprintf |
mave3 | 0:37ee1a85bd8f | 6 | |
mave3 | 3:88c08566c2cd | 7 | |
mave3 | 0:37ee1a85bd8f | 8 | AnalogIn sensor(p18); |
mave3 | 0:37ee1a85bd8f | 9 | uLCD_4DGL uLCD(p9,p10,p11); |
mave3 | 2:23dffdc354f1 | 10 | Serial Blue(p13, p14); |
mave3 | 0:37ee1a85bd8f | 11 | DigitalOut led1(LED1); |
mave3 | 1:90e6613efc60 | 12 | DigitalOut led2(LED2); |
mave3 | 0:37ee1a85bd8f | 13 | //Mutex lcd_mutex; |
mave3 | 0:37ee1a85bd8f | 14 | |
mave3 | 3:88c08566c2cd | 15 | //Initialization of variables |
mave3 | 0:37ee1a85bd8f | 16 | float voltage = sensor; |
mave3 | 0:37ee1a85bd8f | 17 | float current = 0; |
mave3 | 0:37ee1a85bd8f | 18 | float average_voltage = 0.0f; |
mave3 | 0:37ee1a85bd8f | 19 | //const float offset = .10f; |
mave3 | 0:37ee1a85bd8f | 20 | //const float factor = 1.6f; |
mave3 | 0:37ee1a85bd8f | 21 | float offset = -2.37f; |
mave3 | 0:37ee1a85bd8f | 22 | const float factor = 8.0f; //7.69 |
mave3 | 2:23dffdc354f1 | 23 | // .54s for 25000 samples |
mave3 | 0:37ee1a85bd8f | 24 | const int sample_size = 25000; |
mave3 | 3:88c08566c2cd | 25 | const int max_sample_count = 20; |
mave3 | 3:88c08566c2cd | 26 | int sample_count = 0; |
mave3 | 3:88c08566c2cd | 27 | float sample_sum = 0.0f; |
mave3 | 3:88c08566c2cd | 28 | float initial_current = -1.0f; |
mave3 | 3:88c08566c2cd | 29 | float last_current = -1.0f; |
mave3 | 3:88c08566c2cd | 30 | bool enough_samples_taken = 0; |
mave3 | 3:88c08566c2cd | 31 | int samples_lt = 0; |
mave3 | 3:88c08566c2cd | 32 | int total_samples_lt = 0; |
mave3 | 3:88c08566c2cd | 33 | int device_chargeable = 0; |
mave3 | 3:88c08566c2cd | 34 | int device_not_chargeable = 0; |
mave3 | 0:37ee1a85bd8f | 35 | char buffer[10]; |
mave3 | 0:37ee1a85bd8f | 36 | char input_char; |
mave3 | 0:37ee1a85bd8f | 37 | |
mave3 | 3:88c08566c2cd | 38 | //Timer t; |
mave3 | 1:90e6613efc60 | 39 | |
mave3 | 2:23dffdc354f1 | 40 | volatile int menu = 0; |
mave3 | 1:90e6613efc60 | 41 | |
mave3 | 3:88c08566c2cd | 42 | //function that receives character from bluetooth on serial |
mave3 | 3:88c08566c2cd | 43 | //and then determines what command is being requested with a switch statement |
mave3 | 2:23dffdc354f1 | 44 | void parse_message() |
mave3 | 0:37ee1a85bd8f | 45 | { |
mave3 | 1:90e6613efc60 | 46 | led2 = !led2; |
mave3 | 1:90e6613efc60 | 47 | |
mave3 | 2:23dffdc354f1 | 48 | switch (Blue.getc()) |
mave3 | 2:23dffdc354f1 | 49 | { |
mave3 | 2:23dffdc354f1 | 50 | case '1': |
mave3 | 2:23dffdc354f1 | 51 | menu = 1; |
mave3 | 2:23dffdc354f1 | 52 | break; |
mave3 | 2:23dffdc354f1 | 53 | case 'q': |
mave3 | 2:23dffdc354f1 | 54 | menu = 2; |
mave3 | 2:23dffdc354f1 | 55 | break; |
mave3 | 2:23dffdc354f1 | 56 | case '3': |
mave3 | 2:23dffdc354f1 | 57 | menu = 3; |
mave3 | 2:23dffdc354f1 | 58 | break; |
mave3 | 2:23dffdc354f1 | 59 | default: |
mave3 | 2:23dffdc354f1 | 60 | menu = 0; |
mave3 | 2:23dffdc354f1 | 61 | |
mave3 | 2:23dffdc354f1 | 62 | |
mave3 | 1:90e6613efc60 | 63 | |
mave3 | 1:90e6613efc60 | 64 | } |
mave3 | 0:37ee1a85bd8f | 65 | } |
mave3 | 0:37ee1a85bd8f | 66 | |
mave3 | 0:37ee1a85bd8f | 67 | // calibrate offset s.t. the current output is 0 |
mave3 | 0:37ee1a85bd8f | 68 | void calibrate() |
mave3 | 0:37ee1a85bd8f | 69 | { |
mave3 | 0:37ee1a85bd8f | 70 | float average_voltage = 0.0f; |
mave3 | 0:37ee1a85bd8f | 71 | for (int j = 0; j < 100000; j++) |
mave3 | 0:37ee1a85bd8f | 72 | { |
mave3 | 0:37ee1a85bd8f | 73 | voltage = sensor; |
mave3 | 0:37ee1a85bd8f | 74 | average_voltage += voltage/float(100000); |
mave3 | 0:37ee1a85bd8f | 75 | } |
mave3 | 0:37ee1a85bd8f | 76 | //voltage=sensor; |
mave3 | 0:37ee1a85bd8f | 77 | average_voltage = average_voltage * 3.3f; |
mave3 | 0:37ee1a85bd8f | 78 | offset = -1.0f * average_voltage; |
mave3 | 0:37ee1a85bd8f | 79 | } |
mave3 | 0:37ee1a85bd8f | 80 | |
mave3 | 0:37ee1a85bd8f | 81 | int main() |
mave3 | 0:37ee1a85bd8f | 82 | { |
mave3 | 2:23dffdc354f1 | 83 | //Blue.baud(9600); |
mave3 | 2:23dffdc354f1 | 84 | |
mave3 | 3:88c08566c2cd | 85 | Blue.attach(&parse_message,Serial::RxIrq);//serial interrupt with bluetooth |
mave3 | 3:88c08566c2cd | 86 | |
mave3 | 2:23dffdc354f1 | 87 | int length = 0; |
mave3 | 2:23dffdc354f1 | 88 | |
mave3 | 2:23dffdc354f1 | 89 | uLCD.printf("Calibrating...\nPlease wait...\n \nMake sure no \ncurrent is \nconnected.\n"); |
mave3 | 2:23dffdc354f1 | 90 | |
mave3 | 2:23dffdc354f1 | 91 | //Enter device identification |
mave3 | 2:23dffdc354f1 | 92 | //press 1 for current and voltage |
mave3 | 2:23dffdc354f1 | 93 | //press q to quit |
mave3 | 2:23dffdc354f1 | 94 | //press 2 to recalibrate |
mave3 | 2:23dffdc354f1 | 95 | menu = 0;//0 is device identification |
mave3 | 0:37ee1a85bd8f | 96 | calibrate(); |
mave3 | 2:23dffdc354f1 | 97 | wait(1.0f); |
mave3 | 2:23dffdc354f1 | 98 | uLCD.cls(); |
mave3 | 0:37ee1a85bd8f | 99 | //mkdir("/sd/mydir", 0777); |
mave3 | 0:37ee1a85bd8f | 100 | while(1){ |
mave3 | 2:23dffdc354f1 | 101 | |
mave3 | 3:88c08566c2cd | 102 | //switch case that handles menu navigation |
mave3 | 3:88c08566c2cd | 103 | //case 0 is the starting case, which is shown after initial calibration. |
mave3 | 3:88c08566c2cd | 104 | //case 1 is when a '1' is received from the bluetooth. It contains the algorthm for detecting |
mave3 | 3:88c08566c2cd | 105 | //whether a device is chargeable or not, and whether a chargable device is fully charged. |
mave3 | 3:88c08566c2cd | 106 | //Algorithm done by taking several samples and comparing to an initial value over time to determine |
mave3 | 3:88c08566c2cd | 107 | //if the current is changing or not. |
mave3 | 3:88c08566c2cd | 108 | //case 3 is recalibration of the current sensor. |
mave3 | 2:23dffdc354f1 | 109 | switch(menu) |
mave3 | 2:23dffdc354f1 | 110 | { |
mave3 | 2:23dffdc354f1 | 111 | case 0: |
mave3 | 2:23dffdc354f1 | 112 | uLCD.cls(); |
mave3 | 3:88c08566c2cd | 113 | |
mave3 | 3:88c08566c2cd | 114 | uLCD.printf("Please plug \nin a device \nand press 1\n\n\n\n"); |
mave3 | 2:23dffdc354f1 | 115 | //DO device calculations here. |
mave3 | 2:23dffdc354f1 | 116 | uLCD.printf("To see Voltage andCurrent, press '1'\n"); |
mave3 | 2:23dffdc354f1 | 117 | uLCD.printf("To recalibrate,\npress '3'"); |
mave3 | 2:23dffdc354f1 | 118 | |
mave3 | 2:23dffdc354f1 | 119 | while (menu==0) |
mave3 | 2:23dffdc354f1 | 120 | { |
mave3 | 2:23dffdc354f1 | 121 | } |
mave3 | 2:23dffdc354f1 | 122 | break; |
mave3 | 2:23dffdc354f1 | 123 | |
mave3 | 2:23dffdc354f1 | 124 | case 1: |
mave3 | 3:88c08566c2cd | 125 | wait(5); |
mave3 | 2:23dffdc354f1 | 126 | uLCD.cls(); |
mave3 | 3:88c08566c2cd | 127 | uLCD.printf("Identifying\nDevice\n\nPlease wait...\nDo not touch \nthe device!!\n\n"); |
mave3 | 2:23dffdc354f1 | 128 | uLCD.printf("To quit, press 'q'\n"); |
mave3 | 2:23dffdc354f1 | 129 | while (menu == 1) |
mave3 | 2:23dffdc354f1 | 130 | { |
mave3 | 3:88c08566c2cd | 131 | //voltage and current calculations |
mave3 | 2:23dffdc354f1 | 132 | average_voltage = 0.0f; |
mave3 | 2:23dffdc354f1 | 133 | for (int j = 0; j < sample_size; j++) |
mave3 | 2:23dffdc354f1 | 134 | { |
mave3 | 2:23dffdc354f1 | 135 | voltage = sensor; |
mave3 | 2:23dffdc354f1 | 136 | average_voltage += voltage/float(sample_size); |
mave3 | 2:23dffdc354f1 | 137 | } |
mave3 | 2:23dffdc354f1 | 138 | average_voltage = average_voltage * 3.3f; |
mave3 | 2:23dffdc354f1 | 139 | current = (average_voltage + offset) * factor; |
mave3 | 3:88c08566c2cd | 140 | sample_sum += current; |
mave3 | 3:88c08566c2cd | 141 | sample_count++; |
mave3 | 3:88c08566c2cd | 142 | //sampling current and voltage for value comparison |
mave3 | 3:88c08566c2cd | 143 | if (sample_count >= max_sample_count) |
mave3 | 3:88c08566c2cd | 144 | { |
mave3 | 3:88c08566c2cd | 145 | if (initial_current == -1.0f) |
mave3 | 3:88c08566c2cd | 146 | { |
mave3 | 3:88c08566c2cd | 147 | initial_current = sample_sum / float(max_sample_count); |
mave3 | 3:88c08566c2cd | 148 | } |
mave3 | 3:88c08566c2cd | 149 | else |
mave3 | 3:88c08566c2cd | 150 | { |
mave3 | 3:88c08566c2cd | 151 | last_current = sample_sum / float(max_sample_count); |
mave3 | 3:88c08566c2cd | 152 | enough_samples_taken = 1; |
mave3 | 3:88c08566c2cd | 153 | } |
mave3 | 3:88c08566c2cd | 154 | sample_count = 0; |
mave3 | 3:88c08566c2cd | 155 | sample_sum = 0.0f; |
mave3 | 3:88c08566c2cd | 156 | } |
mave3 | 3:88c08566c2cd | 157 | uLCD.locate(0,12); |
mave3 | 3:88c08566c2cd | 158 | uLCD.printf("%f\n%f", abs(initial_current), abs(last_current)); |
mave3 | 3:88c08566c2cd | 159 | //actual comparisons. done once enough samples have been taken |
mave3 | 3:88c08566c2cd | 160 | if (enough_samples_taken) |
mave3 | 3:88c08566c2cd | 161 | { |
mave3 | 3:88c08566c2cd | 162 | total_samples_lt++; |
mave3 | 3:88c08566c2cd | 163 | if (abs(last_current) < abs(initial_current)) |
mave3 | 3:88c08566c2cd | 164 | { |
mave3 | 3:88c08566c2cd | 165 | samples_lt++; |
mave3 | 3:88c08566c2cd | 166 | enough_samples_taken = 0; |
mave3 | 3:88c08566c2cd | 167 | } |
mave3 | 3:88c08566c2cd | 168 | else |
mave3 | 3:88c08566c2cd | 169 | { |
mave3 | 3:88c08566c2cd | 170 | samples_lt = 0; |
mave3 | 3:88c08566c2cd | 171 | enough_samples_taken = 0; |
mave3 | 3:88c08566c2cd | 172 | } |
mave3 | 3:88c08566c2cd | 173 | if (samples_lt >= 5) |
mave3 | 3:88c08566c2cd | 174 | { |
mave3 | 3:88c08566c2cd | 175 | device_chargeable = 1; |
mave3 | 3:88c08566c2cd | 176 | samples_lt = 0; |
mave3 | 3:88c08566c2cd | 177 | } |
mave3 | 3:88c08566c2cd | 178 | } |
mave3 | 3:88c08566c2cd | 179 | if (total_samples_lt >= 10 && !device_chargeable && !(device_not_chargeable==-1)) |
mave3 | 3:88c08566c2cd | 180 | { |
mave3 | 3:88c08566c2cd | 181 | device_not_chargeable = 1; |
mave3 | 3:88c08566c2cd | 182 | } |
mave3 | 3:88c08566c2cd | 183 | //Prints out current through bluetooth. |
mave3 | 3:88c08566c2cd | 184 | length = sprintf(buffer, "Current: "); |
mave3 | 2:23dffdc354f1 | 185 | for (unsigned int j = 0; j < length; j++) |
mave3 | 2:23dffdc354f1 | 186 | { |
mave3 | 2:23dffdc354f1 | 187 | Blue.putc(buffer[j]); |
mave3 | 2:23dffdc354f1 | 188 | } |
mave3 | 2:23dffdc354f1 | 189 | |
mave3 | 2:23dffdc354f1 | 190 | wait(1.0f); |
mave3 | 2:23dffdc354f1 | 191 | |
mave3 | 2:23dffdc354f1 | 192 | |
mave3 | 2:23dffdc354f1 | 193 | |
mave3 | 2:23dffdc354f1 | 194 | length = sprintf(buffer, "%.2f A", abs(current)); |
mave3 | 2:23dffdc354f1 | 195 | for (unsigned int j = 0; j < length; j++) |
mave3 | 2:23dffdc354f1 | 196 | { |
mave3 | 2:23dffdc354f1 | 197 | Blue.putc(buffer[j]); |
mave3 | 2:23dffdc354f1 | 198 | } |
mave3 | 3:88c08566c2cd | 199 | //prints for if a device is chargeable or not, and whether |
mave3 | 3:88c08566c2cd | 200 | //a chargeable device is fully charged. |
mave3 | 3:88c08566c2cd | 201 | if (device_chargeable == 1) |
mave3 | 3:88c08566c2cd | 202 | { |
mave3 | 3:88c08566c2cd | 203 | uLCD.cls(); |
mave3 | 3:88c08566c2cd | 204 | uLCD.printf("The device is\nchargable!\n"); |
mave3 | 3:88c08566c2cd | 205 | uLCD.printf("To quit, press 'q'\n"); |
mave3 | 3:88c08566c2cd | 206 | device_chargeable = -1; |
mave3 | 3:88c08566c2cd | 207 | } |
mave3 | 3:88c08566c2cd | 208 | else if(device_not_chargeable == 1) |
mave3 | 3:88c08566c2cd | 209 | { |
mave3 | 3:88c08566c2cd | 210 | uLCD.cls(); |
mave3 | 3:88c08566c2cd | 211 | uLCD.printf("The device is not chargable\n"); |
mave3 | 3:88c08566c2cd | 212 | uLCD.printf("To quit, press 'q'\n"); |
mave3 | 3:88c08566c2cd | 213 | device_not_chargeable = -1; |
mave3 | 3:88c08566c2cd | 214 | } |
mave3 | 3:88c08566c2cd | 215 | if(device_chargeable == -1 && abs(current) <= 0.1f) |
mave3 | 3:88c08566c2cd | 216 | { |
mave3 | 3:88c08566c2cd | 217 | uLCD.locate(0, 8); |
mave3 | 3:88c08566c2cd | 218 | uLCD.printf("Device charged!"); |
mave3 | 3:88c08566c2cd | 219 | } |
mave3 | 2:23dffdc354f1 | 220 | wait(1.0f); |
mave3 | 2:23dffdc354f1 | 221 | Blue.putc('-'); |
mave3 | 2:23dffdc354f1 | 222 | Blue.putc('-'); |
mave3 | 2:23dffdc354f1 | 223 | Blue.putc('-'); |
mave3 | 2:23dffdc354f1 | 224 | |
mave3 | 3:88c08566c2cd | 225 | |
mave3 | 3:88c08566c2cd | 226 | //resets variables if exiting loop |
mave3 | 2:23dffdc354f1 | 227 | if (menu != 1)//menu is changed to 2 through interrupts. |
mave3 | 2:23dffdc354f1 | 228 | { |
mave3 | 2:23dffdc354f1 | 229 | menu = 0; |
mave3 | 3:88c08566c2cd | 230 | |
mave3 | 3:88c08566c2cd | 231 | sample_count = 0; |
mave3 | 3:88c08566c2cd | 232 | sample_sum = 0.0f; |
mave3 | 3:88c08566c2cd | 233 | initial_current = -1.0f; |
mave3 | 3:88c08566c2cd | 234 | last_current = -1.0f; |
mave3 | 3:88c08566c2cd | 235 | enough_samples_taken = 0; |
mave3 | 3:88c08566c2cd | 236 | samples_lt = 0; |
mave3 | 3:88c08566c2cd | 237 | device_chargeable = 0; |
mave3 | 3:88c08566c2cd | 238 | total_samples_lt = 0; |
mave3 | 3:88c08566c2cd | 239 | device_not_chargeable = 0; |
mave3 | 2:23dffdc354f1 | 240 | } |
mave3 | 2:23dffdc354f1 | 241 | } |
mave3 | 2:23dffdc354f1 | 242 | break; |
mave3 | 3:88c08566c2cd | 243 | //recalibration |
mave3 | 2:23dffdc354f1 | 244 | case 3: |
mave3 | 2:23dffdc354f1 | 245 | uLCD.cls(); |
mave3 | 2:23dffdc354f1 | 246 | uLCD.printf("Recalibrating...\nPlease wait...\n \nMake sure no \ncurrent is \nconnected.\n\n"); |
mave3 | 2:23dffdc354f1 | 247 | calibrate(); |
mave3 | 2:23dffdc354f1 | 248 | wait(1.0f); |
mave3 | 2:23dffdc354f1 | 249 | |
mave3 | 2:23dffdc354f1 | 250 | uLCD.printf("Calibration\ncomplete!!"); |
mave3 | 2:23dffdc354f1 | 251 | wait(2.0f); |
mave3 | 2:23dffdc354f1 | 252 | menu = 0; |
mave3 | 2:23dffdc354f1 | 253 | break; |
mave3 | 2:23dffdc354f1 | 254 | |
mave3 | 2:23dffdc354f1 | 255 | default: |
mave3 | 2:23dffdc354f1 | 256 | menu = 0; |
mave3 | 2:23dffdc354f1 | 257 | } |
mave3 | 2:23dffdc354f1 | 258 | |
mave3 | 0:37ee1a85bd8f | 259 | } |
mave3 | 0:37ee1a85bd8f | 260 | } |