Final project repo for ECE 495

Dependencies:   Adafruit_GFX_MBED Adafruit_ILI9341 BurstSPI DS1820 mbed mbed-rtos ltc2991_lib

Committer:
bdk9
Date:
Thu Dec 08 20:46:50 2016 +0000
Revision:
3:a1b5d7541c69
Parent:
2:0a07f99e32c9
Child:
5:c1c710391df2
update

Who changed what in which revision?

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