Final project repo for ECE 495
Dependencies: Adafruit_GFX_MBED Adafruit_ILI9341 BurstSPI DS1820 mbed mbed-rtos ltc2991_lib
main.cpp@0:7ba4e0775670, 2016-11-29 (annotated)
- Committer:
- bdk9
- Date:
- Tue Nov 29 16:56:43 2016 +0000
- Revision:
- 0:7ba4e0775670
- Child:
- 2:0a07f99e32c9
published
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bdk9 | 0:7ba4e0775670 | 1 | |
bdk9 | 0:7ba4e0775670 | 2 | #include "mbed.h" |
bdk9 | 0:7ba4e0775670 | 3 | #include "rtos.h" |
bdk9 | 0:7ba4e0775670 | 4 | #include "DS1820.h" |
bdk9 | 0:7ba4e0775670 | 5 | #include "TemperatureScreen.h" |
bdk9 | 0:7ba4e0775670 | 6 | #include "VoltageScreen.h" |
bdk9 | 0:7ba4e0775670 | 7 | #include "CurrentScreen.h" |
bdk9 | 0:7ba4e0775670 | 8 | #include "Display.h" |
bdk9 | 0:7ba4e0775670 | 9 | |
bdk9 | 0:7ba4e0775670 | 10 | #define NUM_DS1820 3 |
bdk9 | 0:7ba4e0775670 | 11 | #define PIN_DS1820 D2 |
bdk9 | 0:7ba4e0775670 | 12 | |
bdk9 | 0:7ba4e0775670 | 13 | // DEVICES |
bdk9 | 0:7ba4e0775670 | 14 | DS1820* thermometers[NUM_DS1820]; |
bdk9 | 0:7ba4e0775670 | 15 | Adafruit_ILI9341 tft(D6, D7, D8); |
bdk9 | 0:7ba4e0775670 | 16 | Display disp; |
bdk9 | 0:7ba4e0775670 | 17 | |
bdk9 | 0:7ba4e0775670 | 18 | // IO |
bdk9 | 0:7ba4e0775670 | 19 | RawSerial pc(USBTX, USBRX); |
bdk9 | 0:7ba4e0775670 | 20 | DigitalOut led(LED1); |
bdk9 | 0:7ba4e0775670 | 21 | InterruptIn display_interrupt(PC_13); |
bdk9 | 0:7ba4e0775670 | 22 | |
bdk9 | 0:7ba4e0775670 | 23 | // THREADS |
bdk9 | 0:7ba4e0775670 | 24 | Thread display_thread(osPriorityNormal, DEFAULT_STACK_SIZE, NULL); |
bdk9 | 0:7ba4e0775670 | 25 | Thread slow_data_thread(osPriorityNormal, DEFAULT_STACK_SIZE, NULL); |
bdk9 | 0:7ba4e0775670 | 26 | |
bdk9 | 0:7ba4e0775670 | 27 | // DATA VARIABLES |
bdk9 | 0:7ba4e0775670 | 28 | double temperatures[NUM_DS1820]; |
bdk9 | 0:7ba4e0775670 | 29 | double old_temperatures[NUM_DS1820]; |
bdk9 | 0:7ba4e0775670 | 30 | |
bdk9 | 0:7ba4e0775670 | 31 | // DRAWING VARIABLES |
bdk9 | 0:7ba4e0775670 | 32 | int margin; |
bdk9 | 0:7ba4e0775670 | 33 | int axes_x_cur; |
bdk9 | 0:7ba4e0775670 | 34 | int axes_x_min, axes_x_max; |
bdk9 | 0:7ba4e0775670 | 35 | int axes_y_bot, axes_y_top; |
bdk9 | 0:7ba4e0775670 | 36 | int temp_colors[3]; |
bdk9 | 0:7ba4e0775670 | 37 | int temp_label_y_pos[3]; |
bdk9 | 0:7ba4e0775670 | 38 | int temp_str_y_pos[3]; |
bdk9 | 0:7ba4e0775670 | 39 | bool plotFlag; |
bdk9 | 0:7ba4e0775670 | 40 | |
bdk9 | 0:7ba4e0775670 | 41 | |
bdk9 | 0:7ba4e0775670 | 42 | // FUNCTION DECLARATIONS |
bdk9 | 0:7ba4e0775670 | 43 | int main(); |
bdk9 | 0:7ba4e0775670 | 44 | |
bdk9 | 0:7ba4e0775670 | 45 | // setup |
bdk9 | 0:7ba4e0775670 | 46 | void ds1820_init(); |
bdk9 | 0:7ba4e0775670 | 47 | // thread drivers |
bdk9 | 0:7ba4e0775670 | 48 | void display_cycle(); |
bdk9 | 0:7ba4e0775670 | 49 | void slow_data_task(); |
bdk9 | 0:7ba4e0775670 | 50 | // data read functions |
bdk9 | 0:7ba4e0775670 | 51 | void read_temps(); |
bdk9 | 0:7ba4e0775670 | 52 | // ISRs |
bdk9 | 0:7ba4e0775670 | 53 | void display_swap(); |
bdk9 | 0:7ba4e0775670 | 54 | void parse_command(); |
bdk9 | 0:7ba4e0775670 | 55 | // helpers |
bdk9 | 0:7ba4e0775670 | 56 | int scale_temp(double val, int min_domain, int max_domain, int min_range, int max_range); |
bdk9 | 0:7ba4e0775670 | 57 | char *int2bin(int x); |
bdk9 | 0:7ba4e0775670 | 58 | |
bdk9 | 0:7ba4e0775670 | 59 | void display_swap() { |
bdk9 | 0:7ba4e0775670 | 60 | if (display_interrupt) |
bdk9 | 0:7ba4e0775670 | 61 | disp.next_screen(); |
bdk9 | 0:7ba4e0775670 | 62 | } |
bdk9 | 0:7ba4e0775670 | 63 | |
bdk9 | 0:7ba4e0775670 | 64 | void display_cycle() { |
bdk9 | 0:7ba4e0775670 | 65 | while(1) { |
bdk9 | 0:7ba4e0775670 | 66 | disp.update(); |
bdk9 | 0:7ba4e0775670 | 67 | Thread::wait(1000); |
bdk9 | 0:7ba4e0775670 | 68 | } |
bdk9 | 0:7ba4e0775670 | 69 | } |
bdk9 | 0:7ba4e0775670 | 70 | |
bdk9 | 0:7ba4e0775670 | 71 | void read_temps() { |
bdk9 | 0:7ba4e0775670 | 72 | double temp; |
bdk9 | 0:7ba4e0775670 | 73 | thermometers[0]->convertTemperature(false, DS1820::all_devices); |
bdk9 | 0:7ba4e0775670 | 74 | for (int i=0; i<NUM_DS1820; i++) { |
bdk9 | 0:7ba4e0775670 | 75 | temp = (double) thermometers[i]->temperature(); |
bdk9 | 0:7ba4e0775670 | 76 | if (temp > 0 && temp < 150) { |
bdk9 | 0:7ba4e0775670 | 77 | old_temperatures[i] = temperatures[i]; |
bdk9 | 0:7ba4e0775670 | 78 | temperatures[i] = temp; |
bdk9 | 0:7ba4e0775670 | 79 | } |
bdk9 | 0:7ba4e0775670 | 80 | } |
bdk9 | 0:7ba4e0775670 | 81 | } |
bdk9 | 0:7ba4e0775670 | 82 | |
bdk9 | 0:7ba4e0775670 | 83 | void slow_data_task() { |
bdk9 | 0:7ba4e0775670 | 84 | //get initial reading |
bdk9 | 0:7ba4e0775670 | 85 | read_temps(); |
bdk9 | 0:7ba4e0775670 | 86 | |
bdk9 | 0:7ba4e0775670 | 87 | while(1) { |
bdk9 | 0:7ba4e0775670 | 88 | read_temps(); |
bdk9 | 0:7ba4e0775670 | 89 | Thread::wait(500); |
bdk9 | 0:7ba4e0775670 | 90 | } |
bdk9 | 0:7ba4e0775670 | 91 | } |
bdk9 | 0:7ba4e0775670 | 92 | |
bdk9 | 0:7ba4e0775670 | 93 | // Discover DS1820 probes on pin defined by PIN_DS1820 |
bdk9 | 0:7ba4e0775670 | 94 | void ds1820_init() { |
bdk9 | 0:7ba4e0775670 | 95 | // Initialize the thermometer array to DS1820 objects |
bdk9 | 0:7ba4e0775670 | 96 | int num_devices = 0; |
bdk9 | 0:7ba4e0775670 | 97 | while(DS1820::unassignedProbe(PIN_DS1820)) { |
bdk9 | 0:7ba4e0775670 | 98 | thermometers[num_devices] = new DS1820(PIN_DS1820); |
bdk9 | 0:7ba4e0775670 | 99 | num_devices++; |
bdk9 | 0:7ba4e0775670 | 100 | if (num_devices == NUM_DS1820) |
bdk9 | 0:7ba4e0775670 | 101 | break; |
bdk9 | 0:7ba4e0775670 | 102 | } |
bdk9 | 0:7ba4e0775670 | 103 | pc.printf("Found %d device(s)\r\n\n", num_devices); |
bdk9 | 0:7ba4e0775670 | 104 | } |
bdk9 | 0:7ba4e0775670 | 105 | |
bdk9 | 0:7ba4e0775670 | 106 | char *int2bin(int x) { |
bdk9 | 0:7ba4e0775670 | 107 | static char b[33]; |
bdk9 | 0:7ba4e0775670 | 108 | b[0] = '\0'; |
bdk9 | 0:7ba4e0775670 | 109 | uint32_t z; |
bdk9 | 0:7ba4e0775670 | 110 | for (z = 2147483648; z > 0; z >>= 1) { |
bdk9 | 0:7ba4e0775670 | 111 | strcat(b, ((x & z) == z) ? "1" : "0"); |
bdk9 | 0:7ba4e0775670 | 112 | } |
bdk9 | 0:7ba4e0775670 | 113 | return b; |
bdk9 | 0:7ba4e0775670 | 114 | } |
bdk9 | 0:7ba4e0775670 | 115 | |
bdk9 | 0:7ba4e0775670 | 116 | char buff[5]; |
bdk9 | 0:7ba4e0775670 | 117 | int loc = 0; |
bdk9 | 0:7ba4e0775670 | 118 | |
bdk9 | 0:7ba4e0775670 | 119 | void execute_command(char *cmd) { |
bdk9 | 0:7ba4e0775670 | 120 | pc.printf("%s\n", cmd); |
bdk9 | 0:7ba4e0775670 | 121 | } |
bdk9 | 0:7ba4e0775670 | 122 | |
bdk9 | 0:7ba4e0775670 | 123 | void parse_command() { |
bdk9 | 0:7ba4e0775670 | 124 | buff[loc] = USART2->DR; |
bdk9 | 0:7ba4e0775670 | 125 | loc += 1; |
bdk9 | 0:7ba4e0775670 | 126 | if (loc > 3) { |
bdk9 | 0:7ba4e0775670 | 127 | execute_command(buff); |
bdk9 | 0:7ba4e0775670 | 128 | loc = 0; |
bdk9 | 0:7ba4e0775670 | 129 | } |
bdk9 | 0:7ba4e0775670 | 130 | } |
bdk9 | 0:7ba4e0775670 | 131 | |
bdk9 | 0:7ba4e0775670 | 132 | |
bdk9 | 0:7ba4e0775670 | 133 | int main() { |
bdk9 | 0:7ba4e0775670 | 134 | // Setup serial interrupts, temperature sensors |
bdk9 | 0:7ba4e0775670 | 135 | pc.attach(&parse_command); |
bdk9 | 0:7ba4e0775670 | 136 | ds1820_init(); |
bdk9 | 0:7ba4e0775670 | 137 | |
bdk9 | 0:7ba4e0775670 | 138 | // initialize display |
bdk9 | 0:7ba4e0775670 | 139 | tft.begin(); |
bdk9 | 0:7ba4e0775670 | 140 | tft.fillScreen(BLACK); |
bdk9 | 0:7ba4e0775670 | 141 | tft.setRotation(1); |
bdk9 | 0:7ba4e0775670 | 142 | |
bdk9 | 0:7ba4e0775670 | 143 | // setup display screens |
bdk9 | 0:7ba4e0775670 | 144 | TemperatureScreen ts(0, &tft); |
bdk9 | 0:7ba4e0775670 | 145 | VoltageScreen vs(1, &tft); |
bdk9 | 0:7ba4e0775670 | 146 | CurrentScreen cs(2, &tft); |
bdk9 | 0:7ba4e0775670 | 147 | Screen *s[3] = {&ts, &vs, &cs}; |
bdk9 | 0:7ba4e0775670 | 148 | disp.set_screens(s, 3); |
bdk9 | 0:7ba4e0775670 | 149 | |
bdk9 | 0:7ba4e0775670 | 150 | // setup display switcher |
bdk9 | 0:7ba4e0775670 | 151 | display_interrupt.rise(&display_swap); |
bdk9 | 0:7ba4e0775670 | 152 | |
bdk9 | 0:7ba4e0775670 | 153 | // Kick off our threads |
bdk9 | 0:7ba4e0775670 | 154 | slow_data_thread.start(slow_data_task); |
bdk9 | 0:7ba4e0775670 | 155 | wait_ms(1000); |
bdk9 | 0:7ba4e0775670 | 156 | display_thread.start(display_cycle); |
bdk9 | 0:7ba4e0775670 | 157 | } |
bdk9 | 0:7ba4e0775670 | 158 | |
bdk9 | 0:7ba4e0775670 | 159 | |
bdk9 | 0:7ba4e0775670 | 160 | |
bdk9 | 0:7ba4e0775670 | 161 | |
bdk9 | 0:7ba4e0775670 | 162 | |
bdk9 | 0:7ba4e0775670 | 163 | |
bdk9 | 0:7ba4e0775670 | 164 | |
bdk9 | 0:7ba4e0775670 | 165 | // TEMPERATURE DISPLAY |
bdk9 | 0:7ba4e0775670 | 166 | TemperatureScreen::TemperatureScreen(int id, Adafruit_ILI9341 *tft) : Screen(id, tft) { } |
bdk9 | 0:7ba4e0775670 | 167 | |
bdk9 | 0:7ba4e0775670 | 168 | void TemperatureScreen::init() { |
bdk9 | 0:7ba4e0775670 | 169 | margin = 10; |
bdk9 | 0:7ba4e0775670 | 170 | |
bdk9 | 0:7ba4e0775670 | 171 | axes_x_min = 120; |
bdk9 | 0:7ba4e0775670 | 172 | axes_x_max = _tft->width() - margin; |
bdk9 | 0:7ba4e0775670 | 173 | axes_y_bot = _tft->height() - margin; |
bdk9 | 0:7ba4e0775670 | 174 | axes_y_top = 40; |
bdk9 | 0:7ba4e0775670 | 175 | |
bdk9 | 0:7ba4e0775670 | 176 | temp_colors[0] = CYAN; |
bdk9 | 0:7ba4e0775670 | 177 | temp_colors[1] = YELLOW; |
bdk9 | 0:7ba4e0775670 | 178 | temp_colors[2] = GREEN; |
bdk9 | 0:7ba4e0775670 | 179 | temp_label_y_pos[0] = margin+9; |
bdk9 | 0:7ba4e0775670 | 180 | temp_label_y_pos[1] = margin+88; |
bdk9 | 0:7ba4e0775670 | 181 | temp_label_y_pos[2] = margin+168; |
bdk9 | 0:7ba4e0775670 | 182 | temp_str_y_pos[0] = margin+40; |
bdk9 | 0:7ba4e0775670 | 183 | temp_str_y_pos[1] = margin+120; |
bdk9 | 0:7ba4e0775670 | 184 | temp_str_y_pos[2] = margin+200; |
bdk9 | 0:7ba4e0775670 | 185 | |
bdk9 | 0:7ba4e0775670 | 186 | // draw background |
bdk9 | 0:7ba4e0775670 | 187 | _tft->fillScreen(BLACK); |
bdk9 | 0:7ba4e0775670 | 188 | _tft->setTextSize(2); |
bdk9 | 0:7ba4e0775670 | 189 | _tft->setTextColor(WHITE); |
bdk9 | 0:7ba4e0775670 | 190 | _tft->setCursor(155, margin); |
bdk9 | 0:7ba4e0775670 | 191 | _tft->print("TEMPERATURE"); |
bdk9 | 0:7ba4e0775670 | 192 | |
bdk9 | 0:7ba4e0775670 | 193 | _tft->fillRect(margin, margin, axes_x_min-2*margin, 30, temp_colors[0]); |
bdk9 | 0:7ba4e0775670 | 194 | _tft->setCursor(margin+33, temp_label_y_pos[0]); |
bdk9 | 0:7ba4e0775670 | 195 | _tft->setTextColor(BLACK); |
bdk9 | 0:7ba4e0775670 | 196 | _tft->print("CPU"); |
bdk9 | 0:7ba4e0775670 | 197 | |
bdk9 | 0:7ba4e0775670 | 198 | _tft->fillRect(margin, margin+80, axes_x_min-2*margin, 30, temp_colors[1]); |
bdk9 | 0:7ba4e0775670 | 199 | _tft->setCursor(margin+20, temp_label_y_pos[1]); |
bdk9 | 0:7ba4e0775670 | 200 | _tft->setTextColor(BLACK); |
bdk9 | 0:7ba4e0775670 | 201 | _tft->print("MOTOR"); |
bdk9 | 0:7ba4e0775670 | 202 | |
bdk9 | 0:7ba4e0775670 | 203 | _tft->fillRect(margin, margin+160, axes_x_min-2*margin, 30, temp_colors[2]); |
bdk9 | 0:7ba4e0775670 | 204 | _tft->setCursor(margin+10, temp_label_y_pos[2]); |
bdk9 | 0:7ba4e0775670 | 205 | _tft->setTextColor(BLACK); |
bdk9 | 0:7ba4e0775670 | 206 | _tft->print("AMBIENT"); |
bdk9 | 0:7ba4e0775670 | 207 | _tft->setTextSize(2); |
bdk9 | 0:7ba4e0775670 | 208 | |
bdk9 | 0:7ba4e0775670 | 209 | // x-axis |
bdk9 | 0:7ba4e0775670 | 210 | _tft->drawFastHLine(axes_x_min, axes_y_bot, axes_x_max-axes_x_min, WHITE); |
bdk9 | 0:7ba4e0775670 | 211 | // y-axis |
bdk9 | 0:7ba4e0775670 | 212 | _tft->drawFastVLine(axes_x_min, axes_y_top, axes_y_bot-axes_y_top, WHITE); |
bdk9 | 0:7ba4e0775670 | 213 | |
bdk9 | 0:7ba4e0775670 | 214 | axes_x_min += 1; |
bdk9 | 0:7ba4e0775670 | 215 | axes_x_max -= 1; |
bdk9 | 0:7ba4e0775670 | 216 | axes_y_bot -= 1; |
bdk9 | 0:7ba4e0775670 | 217 | axes_y_top += 1; |
bdk9 | 0:7ba4e0775670 | 218 | axes_x_cur = axes_x_min; |
bdk9 | 0:7ba4e0775670 | 219 | } |
bdk9 | 0:7ba4e0775670 | 220 | |
bdk9 | 0:7ba4e0775670 | 221 | int scale_temp(double val, int min_domain, int max_domain, int min_range, int max_range) { |
bdk9 | 0:7ba4e0775670 | 222 | return (int) max_range - ((val - (min_domain)) / (max_domain - min_domain)) * (max_range - min_range); |
bdk9 | 0:7ba4e0775670 | 223 | } |
bdk9 | 0:7ba4e0775670 | 224 | |
bdk9 | 0:7ba4e0775670 | 225 | void TemperatureScreen::update() { |
bdk9 | 0:7ba4e0775670 | 226 | if (plotFlag) { |
bdk9 | 0:7ba4e0775670 | 227 | _tft->fillRect(axes_x_min, axes_y_top, _tft->width()-axes_x_min, axes_y_bot-axes_y_top, BLACK); |
bdk9 | 0:7ba4e0775670 | 228 | plotFlag = false; |
bdk9 | 0:7ba4e0775670 | 229 | } |
bdk9 | 0:7ba4e0775670 | 230 | int y_new, y_old; |
bdk9 | 0:7ba4e0775670 | 231 | for (int i=0; i<NUM_DS1820; i++) { |
bdk9 | 0:7ba4e0775670 | 232 | _tft->fillRect(margin, temp_str_y_pos[i], axes_x_min-2*margin, 30, BLACK); |
bdk9 | 0:7ba4e0775670 | 233 | char str[10]; |
bdk9 | 0:7ba4e0775670 | 234 | sprintf(str, "%.2f C", temperatures[i]); |
bdk9 | 0:7ba4e0775670 | 235 | _tft->setCursor(margin, temp_str_y_pos[i]); |
bdk9 | 0:7ba4e0775670 | 236 | _tft->setTextColor(temp_colors[i]); |
bdk9 | 0:7ba4e0775670 | 237 | _tft->print(str); |
bdk9 | 0:7ba4e0775670 | 238 | y_new = scale_temp(temperatures[i], 0, 150, axes_y_top, axes_y_bot); |
bdk9 | 0:7ba4e0775670 | 239 | y_old = scale_temp(old_temperatures[i], 0, 150, axes_y_top, axes_y_bot); |
bdk9 | 0:7ba4e0775670 | 240 | _tft->drawLine(axes_x_cur, y_old, axes_x_cur+3, y_new, temp_colors[i]); |
bdk9 | 0:7ba4e0775670 | 241 | } |
bdk9 | 0:7ba4e0775670 | 242 | axes_x_cur += 3; |
bdk9 | 0:7ba4e0775670 | 243 | if (axes_x_cur >= axes_x_max) { |
bdk9 | 0:7ba4e0775670 | 244 | plotFlag = true; |
bdk9 | 0:7ba4e0775670 | 245 | axes_x_cur = axes_x_min; |
bdk9 | 0:7ba4e0775670 | 246 | } |
bdk9 | 0:7ba4e0775670 | 247 | } |
bdk9 | 0:7ba4e0775670 | 248 | |
bdk9 | 0:7ba4e0775670 | 249 | |
bdk9 | 0:7ba4e0775670 | 250 | |
bdk9 | 0:7ba4e0775670 | 251 | // VOLTAGE DISPLAY |
bdk9 | 0:7ba4e0775670 | 252 | VoltageScreen::VoltageScreen(int id, Adafruit_ILI9341 *tft) : Screen(id, tft) { } |
bdk9 | 0:7ba4e0775670 | 253 | |
bdk9 | 0:7ba4e0775670 | 254 | void VoltageScreen::init() { |
bdk9 | 0:7ba4e0775670 | 255 | _tft->fillScreen(RED); |
bdk9 | 0:7ba4e0775670 | 256 | } |
bdk9 | 0:7ba4e0775670 | 257 | |
bdk9 | 0:7ba4e0775670 | 258 | void VoltageScreen::update() { |
bdk9 | 0:7ba4e0775670 | 259 | } |
bdk9 | 0:7ba4e0775670 | 260 | |
bdk9 | 0:7ba4e0775670 | 261 | |
bdk9 | 0:7ba4e0775670 | 262 | |
bdk9 | 0:7ba4e0775670 | 263 | |
bdk9 | 0:7ba4e0775670 | 264 | // CURRENT DISPLAY |
bdk9 | 0:7ba4e0775670 | 265 | CurrentScreen::CurrentScreen(int id, Adafruit_ILI9341 *tft) : Screen(id, tft) { } |
bdk9 | 0:7ba4e0775670 | 266 | |
bdk9 | 0:7ba4e0775670 | 267 | void CurrentScreen::init() { |
bdk9 | 0:7ba4e0775670 | 268 | _tft->fillScreen(BLUE); |
bdk9 | 0:7ba4e0775670 | 269 | } |
bdk9 | 0:7ba4e0775670 | 270 | |
bdk9 | 0:7ba4e0775670 | 271 | void CurrentScreen::update() { |
bdk9 | 0:7ba4e0775670 | 272 | } |