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() {
}