Final project repo for ECE 495
Dependencies: Adafruit_GFX_MBED Adafruit_ILI9341 BurstSPI DS1820 mbed mbed-rtos ltc2991_lib
Diff: main.cpp
- Revision:
- 0:7ba4e0775670
- Child:
- 2:0a07f99e32c9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Nov 29 16:56:43 2016 +0000 @@ -0,0 +1,272 @@ + +#include "mbed.h" +#include "rtos.h" +#include "DS1820.h" +#include "TemperatureScreen.h" +#include "VoltageScreen.h" +#include "CurrentScreen.h" +#include "Display.h" + +#define NUM_DS1820 3 +#define PIN_DS1820 D2 + +// DEVICES +DS1820* thermometers[NUM_DS1820]; +Adafruit_ILI9341 tft(D6, D7, D8); +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); + +// 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_cycle(); +void slow_data_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_cycle() { + 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); + } +} + +// 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[5]; +int loc = 0; + +void execute_command(char *cmd) { + pc.printf("%s\n", cmd); +} + +void parse_command() { + buff[loc] = USART2->DR; + loc += 1; + if (loc > 3) { + execute_command(buff); + loc = 0; + } +} + + +int main() { + // Setup serial interrupts, temperature sensors + pc.attach(&parse_command); + ds1820_init(); + + // initialize display + tft.begin(); + tft.fillScreen(BLACK); + tft.setRotation(1); + + // setup display screens + TemperatureScreen ts(0, &tft); + VoltageScreen vs(1, &tft); + CurrentScreen cs(2, &tft); + Screen *s[3] = {&ts, &vs, &cs}; + disp.set_screens(s, 3); + + // setup display switcher + display_interrupt.rise(&display_swap); + + // Kick off our threads + slow_data_thread.start(slow_data_task); + wait_ms(1000); + display_thread.start(display_cycle); +} + + + + + + + +// 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() { +} \ No newline at end of file