Final project repo for ECE 495
Dependencies: Adafruit_GFX_MBED Adafruit_ILI9341 BurstSPI DS1820 mbed mbed-rtos ltc2991_lib
main.cpp
- Committer:
- bdk9
- Date:
- 2016-12-08
- Revision:
- 3:a1b5d7541c69
- Parent:
- 2:0a07f99e32c9
- Child:
- 5:c1c710391df2
File content as of revision 3:a1b5d7541c69:
#include "mbed.h" #include "rtos.h" #include "DS1820.h" #include "TemperatureScreen.h" #include "VoltageScreen.h" #include "CurrentScreen.h" #include "Display.h" #define NUM_DS1820 1 #define PIN_DS1820 PC_0 // DEVICES DS1820* thermometers[NUM_DS1820]; Adafruit_ILI9341 tft(PA_13, PA_15, PA_14); Display disp; // IO RawSerial pc(USBTX, USBRX); DigitalOut led(LED1); InterruptIn display_interrupt(PC_13); // THREADS Thread display_thread(osPriorityNormal, DEFAULT_STACK_SIZE, NULL); Thread slow_data_thread(osPriorityNormal, DEFAULT_STACK_SIZE, NULL); Thread serial_thread(osPriorityNormal, DEFAULT_STACK_SIZE, NULL); // DATA VARIABLES double temperatures[NUM_DS1820]; double old_temperatures[NUM_DS1820]; // DRAWING VARIABLES int margin; int axes_x_cur; int axes_x_min, axes_x_max; int axes_y_bot, axes_y_top; int temp_colors[3]; int temp_label_y_pos[3]; int temp_str_y_pos[3]; bool plotFlag; // FUNCTION DECLARATIONS int main(); // setup void ds1820_init(); // thread drivers void display_task(); void slow_data_task(); void fast_data_task(); void serial_task(); // data read functions void read_temps(); // ISRs void display_swap(); void parse_command(); // helpers int scale_temp(double val, int min_domain, int max_domain, int min_range, int max_range); char *int2bin(int x); void display_swap() { if (display_interrupt) disp.next_screen(); } void display_task() { while(1) { disp.update(); Thread::wait(1000); } } void read_temps() { double temp; thermometers[0]->convertTemperature(false, DS1820::all_devices); for (int i=0; i<NUM_DS1820; i++) { temp = (double) thermometers[i]->temperature(); if (temp > 0 && temp < 150) { old_temperatures[i] = temperatures[i]; temperatures[i] = temp; } } } void slow_data_task() { //get initial reading read_temps(); while(1) { read_temps(); Thread::wait(500); } } void fast_data_task() { } void serial_task() { while(1) { pc.printf("PWR: hey"); Thread::wait(5000); } } // Discover DS1820 probes on pin defined by PIN_DS1820 void ds1820_init() { // Initialize the thermometer array to DS1820 objects int num_devices = 0; while(DS1820::unassignedProbe(PIN_DS1820)) { thermometers[num_devices] = new DS1820(PIN_DS1820); num_devices++; if (num_devices == NUM_DS1820) break; } pc.printf("Found %d device(s)\r\n\n", num_devices); } char *int2bin(int x) { static char b[33]; b[0] = '\0'; uint32_t z; for (z = 2147483648; z > 0; z >>= 1) { strcat(b, ((x & z) == z) ? "1" : "0"); } return b; } char buff[64]; int loc = 0; void execute_command(char *cmd) { pc.printf("%s\n", cmd); } void parse_command() { buff[loc] = USART2->DR; loc += 1; if (buff[loc-1] == '\n') { execute_command(buff); memset(&buff[0], 0, sizeof(buff)); loc = 0; } } int main() { // Setup serial interrupts pc.attach(&parse_command); // Setup temperature sensors ds1820_init(); // Setup display tft.begin(); tft.fillScreen(BLACK); tft.setRotation(1); TemperatureScreen ts(0, &tft); VoltageScreen vs(1, &tft); CurrentScreen cs(2, &tft); Screen *s[3] = {&ts, &vs, &cs}; disp.set_screens(s, 3); display_interrupt.rise(&display_swap); // Setup RTOS threads slow_data_thread.start(slow_data_task); wait_ms(1000); display_thread.start(display_task); serial_thread.start(serial_task); } // TEMPERATURE DISPLAY TemperatureScreen::TemperatureScreen(int id, Adafruit_ILI9341 *tft) : Screen(id, tft) { } void TemperatureScreen::init() { margin = 10; axes_x_min = 120; axes_x_max = _tft->width() - margin; axes_y_bot = _tft->height() - margin; axes_y_top = 40; temp_colors[0] = CYAN; temp_colors[1] = YELLOW; temp_colors[2] = GREEN; temp_label_y_pos[0] = margin+9; temp_label_y_pos[1] = margin+88; temp_label_y_pos[2] = margin+168; temp_str_y_pos[0] = margin+40; temp_str_y_pos[1] = margin+120; temp_str_y_pos[2] = margin+200; // draw background _tft->fillScreen(BLACK); _tft->setTextSize(2); _tft->setTextColor(WHITE); _tft->setCursor(155, margin); _tft->print("TEMPERATURE"); _tft->fillRect(margin, margin, axes_x_min-2*margin, 30, temp_colors[0]); _tft->setCursor(margin+33, temp_label_y_pos[0]); _tft->setTextColor(BLACK); _tft->print("CPU"); _tft->fillRect(margin, margin+80, axes_x_min-2*margin, 30, temp_colors[1]); _tft->setCursor(margin+20, temp_label_y_pos[1]); _tft->setTextColor(BLACK); _tft->print("MOTOR"); _tft->fillRect(margin, margin+160, axes_x_min-2*margin, 30, temp_colors[2]); _tft->setCursor(margin+10, temp_label_y_pos[2]); _tft->setTextColor(BLACK); _tft->print("AMBIENT"); _tft->setTextSize(2); // x-axis _tft->drawFastHLine(axes_x_min, axes_y_bot, axes_x_max-axes_x_min, WHITE); // y-axis _tft->drawFastVLine(axes_x_min, axes_y_top, axes_y_bot-axes_y_top, WHITE); axes_x_min += 1; axes_x_max -= 1; axes_y_bot -= 1; axes_y_top += 1; axes_x_cur = axes_x_min; } int scale_temp(double val, int min_domain, int max_domain, int min_range, int max_range) { return (int) max_range - ((val - (min_domain)) / (max_domain - min_domain)) * (max_range - min_range); } void TemperatureScreen::update() { if (plotFlag) { _tft->fillRect(axes_x_min, axes_y_top, _tft->width()-axes_x_min, axes_y_bot-axes_y_top, BLACK); plotFlag = false; } int y_new, y_old; for (int i=0; i<NUM_DS1820; i++) { _tft->fillRect(margin, temp_str_y_pos[i], axes_x_min-2*margin, 30, BLACK); char str[10]; sprintf(str, "%.2f C", temperatures[i]); _tft->setCursor(margin, temp_str_y_pos[i]); _tft->setTextColor(temp_colors[i]); _tft->print(str); y_new = scale_temp(temperatures[i], 0, 150, axes_y_top, axes_y_bot); y_old = scale_temp(old_temperatures[i], 0, 150, axes_y_top, axes_y_bot); _tft->drawLine(axes_x_cur, y_old, axes_x_cur+3, y_new, temp_colors[i]); } axes_x_cur += 3; if (axes_x_cur >= axes_x_max) { plotFlag = true; axes_x_cur = axes_x_min; } } // VOLTAGE DISPLAY VoltageScreen::VoltageScreen(int id, Adafruit_ILI9341 *tft) : Screen(id, tft) { } void VoltageScreen::init() { _tft->fillScreen(RED); } void VoltageScreen::update() { } // CURRENT DISPLAY CurrentScreen::CurrentScreen(int id, Adafruit_ILI9341 *tft) : Screen(id, tft) { } void CurrentScreen::init() { _tft->fillScreen(BLUE); } void CurrentScreen::update() { }