Code for Mbed Dashboard project. http://developer.mbed.org/users/julieefreeman/notebook/mbed-dashboard---obdii/
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed
Diff: main.cpp
- Revision:
- 0:2fa4b8d8fbd0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Dec 09 18:12:57 2014 +0000 @@ -0,0 +1,348 @@ +/* +mbed Dashboard trip computer +December 2014 +******************************************************************************** +WARNING: Use at your own risk, sadly this software comes with no guarantees. +This software is provided 'free' and in good faith, but the author does not +accept liability for any damage arising from its use. +******************************************************************************** +*/ + +#include "mbed.h" +#include "ecu_reader.h" +#include "globals.h" +#include "rtos.h" +#include "SDFileSystem.h" + +Mutex stdio_mutex; +ecu_reader obdii1(CANSPEED_125); //supports different CAN speeds +ecu_reader obdii2(CANSPEED_250); +ecu_reader obdii3(CANSPEED_500); +InterruptIn switch_reading(p8); +SDFileSystem sd(p5, p6, p7, p12, "sd"); +DigitalOut myled4(LED4); +DigitalOut myled3(LED3); + +int flag; //indicates which reading to get from vehicle +int change; //signifies that the system is switching readings +char temp_buffer[20]; //buffers for readings from vehicle +char rpm_buffer[20]; +char speed_buffer[20]; +char time_buff[32]; +char buffer[20]; +float dial_len; +int ui_temp, ui_rpm; +float ui_speed; +int dist_init; +float dist; +time_t seconds; +int testing_temp; //not connected to car +int testing_rpm; //not connected to car +int testing_speed; + +void display_coolant_temp(); +void display_rpm(); +void draw_tachometer(); +void draw_thermometer(); +void display_speed(); +void draw_speedometer(); +void display_trip(); + +void pb_hit_interrupt (void) { + myled4 = 1; + flag = flag+1; + if (flag>3) { + flag = 0; + ui_temp = -1; + } + else if (flag == 1) + ui_rpm = -1; + else if (flag == 2) + ui_speed = -1; + wait(0.5); + myled4 = 0; + change = 1; +} +void testingThread(void const *args) { // run this thread and set main OBD request conditions to 0 to test UI + ui_temp = -1; + ui_rpm = -1; + testing_temp = 100; + testing_rpm = 0; + dist_init = 0; + testing_speed = 0; + while(1){ + // --- TESTING ONLY - WITHOUT CAR --- + sprintf(temp_buffer,"%d",testing_temp); + sprintf(rpm_buffer,"%d",testing_rpm); + sprintf(speed_buffer,"%d", testing_speed); + dist += 0.1; + testing_temp -= 1; + testing_rpm += 100; + testing_speed +=5; + if (testing_temp<5) { + testing_temp = 100; + } + if (testing_rpm>5000) { + testing_rpm = 900; + } + // --- TESTING ONLY - WITHOUT CAR --- + Thread::wait(1000); + } +} + +void sdThread(void const *args) { + dist = -1; + dist_init = -1; + set_time(0); + char file[35]; + char buffer[32]; + char hours[5]; + char minutes[5]; + float hrs = 0; + FILE *fp; + + mkdir("/sd/tripStats",0777); + sprintf(file, "/sd/tripStats/log.txt"); + while (dist_init == -1){ // + stdio_mutex.lock(); + if(obdii3.request(DIST_SINCE_CLR, buffer) == 1){ + dist_init = atoi(buffer); + } + stdio_mutex.unlock(); + } + + while (1){ + fp = fopen(file, "w"); + myled3 = 1; + seconds = time(NULL); + strftime(time_buff, 32, "%R:%S", localtime(&seconds)); + strftime(hours, 5, "%H", localtime(&seconds)); + strftime(minutes, 5, "%M", localtime(&seconds)); + hrs = atoi(hours) + ((float)atoi(minutes))/60; + if(fp == NULL) { + error("Could not open file for write\n"); + } + stdio_mutex.lock(); + if(obdii3.request(DIST_SINCE_CLR, buffer) == 1){ + dist = ((float)atoi(buffer)-dist_init)*0.62; + } + stdio_mutex.unlock(); + fprintf(fp, "Time since mbed start: %s\n\n", time_buff); + fprintf(fp, "Distance Traveled: %2.2f miles\n", dist); + fprintf(fp, "Average Speed: %2.2f mph\n", dist/hrs); + fclose(fp); + myled3 = 0; + Thread::wait(30000); //write to SD card every 30 seconds + } +} + +int main() { + ui_temp = -1; //initialize default values + ui_rpm = -1; + ui_speed = -1; + change = 0; + flag = 0; + dial_len = 60.0; + lcd.cls(); + lcd.baudrate(3000000); + switch_reading.mode(PullUp); + wait(0.2); + switch_reading.fall(&pb_hit_interrupt); + Thread t2(sdThread); + //Thread test(testingThread); //run this thread and change OBD request conditions to 0 to test UI + + while (1) { //main thread + if (change == 0) { //update LCD only when not in process of switching screens + switch (flag){ + case 0: //engine coolant temperature + if(obdii3.request(ENGINE_COOLANT_TEMP, temp_buffer) == 1){ //set to 1 for car, 0 for testing UI + stdio_mutex.lock(); + display_coolant_temp(); + stdio_mutex.unlock(); + } + else { + can2.reset(); + wait(0.5); + } + break; + case 1: //engine rpm + if (obdii3.request(ENGINE_RPM, rpm_buffer) == 1){ //set to 1 for car, 0 for testing UI + stdio_mutex.lock(); + display_rpm(); + stdio_mutex.unlock(); + } + else { + can2.reset(); + wait(0.5); + } + break; + case 2: //vehicle speed + if (obdii3.request(VEHICLE_SPEED, speed_buffer) == 1){ //set to 1 for car, 0 for testing UI + stdio_mutex.lock(); + display_speed(); + stdio_mutex.unlock(); + } + else { + can2.reset(); + wait(0.5); + } + break; + case 3: //distance since codes last cleared + if(obdii3.request(DIST_SINCE_CLR, buffer) == 1){ + dist = ((float)atoi(buffer)-(float)dist_init)*0.62; + stdio_mutex.lock(); + display_trip(); + stdio_mutex.unlock(); + } + else { + stdio_mutex.lock(); + display_trip(); + stdio_mutex.unlock(); + can2.reset(); + wait(0.5); + } + break; + } + } + else { + lcd.cls(); + change = 0; + } + } +} + +void display_coolant_temp(){ //displays temperature + float farenheit = atoi(temp_buffer) * 9/5 +32; + draw_thermometer(); + lcd.color(0x909090); + lcd.text_width(2); + lcd.text_height(2); + lcd.locate(1,0); + lcd.printf("%s\n\r", "COOLANT\n TEMP."); + lcd.color(0x66CCFF); + lcd.locate(0,3); + lcd.printf("%3.0f \n\r", farenheit); + lcd.locate(0,4); + lcd.printf("oF\n\r"); +} + +void draw_thermometer(){ //draws temperature animation + lcd.rectangle(73,47,119,128,0xFFFFFF); + int new_temp = atoi(temp_buffer); + int height = 128-ceil((float)new_temp*.8); + + if (new_temp > 100 && ui_temp!=new_temp) { //red + lcd.filled_rectangle(74,48,118,67,0xFF0000); + } + else if (new_temp > 75 && ui_temp!=new_temp) { + if (ui_temp>new_temp) lcd.filled_rectangle(74,48,118,height,0x000000); + lcd.filled_rectangle(74,height,118,67,0xFF0000); + } + else lcd.filled_rectangle(74,48,118,67,0x000000); + if (new_temp > 75 && ui_temp!=new_temp) { //dark orange + lcd.filled_rectangle(74,68,118,87,0xFF4719); + } + else if (new_temp > 50 && ui_temp!=new_temp) { + if (ui_temp>new_temp) lcd.filled_rectangle(74,68,118,height,0x000000); + lcd.filled_rectangle(74,height,118,87,0xFF4719); + } + else lcd.filled_rectangle(74,68,118,87,0x000000); + if (new_temp > 50 && ui_temp!=new_temp) { //orange + lcd.filled_rectangle(74,88,118,107,0xFF9933); + } + else if (new_temp > 25 && ui_temp!=new_temp) { + if (ui_temp>new_temp) lcd.filled_rectangle(74,88,118,height,0x000000); + lcd.filled_rectangle(74,height,118,107,0xFF9933); + } + else lcd.filled_rectangle(74,88,118,107,0x000000); + if (new_temp > 25 && ui_temp!=new_temp) { //yellow + lcd.filled_rectangle(74,108,118,128,0xFFFF99); + } + else if (new_temp > 0 && ui_temp!=new_temp) { + if (ui_temp>new_temp) lcd.filled_rectangle(74,108,118,height,0x000000); + lcd.filled_rectangle(74,height,118,128,0xFFFF99); + } + else lcd.filled_rectangle(74,108,118,128,0x000000); + ui_temp = new_temp; +} + +void display_rpm(){ //displays rpm + draw_tachometer(); + lcd.color(0x909090); + lcd.text_width(2); + lcd.text_height(2); + lcd.locate(1,0); + lcd.printf("%s\n\r", "ENG RPM"); + lcd.color(0x66CCFF); + lcd.text_width(3); + lcd.text_height(3); + lcd.locate(1,1); + lcd.printf("%s \n\r", rpm_buffer); +} + +void draw_tachometer(){ //draws rpm gauge + lcd.circle(64,120,60,0xFFFFFF); + int new_rpm = atoi(rpm_buffer); + int x = int(cos(float(new_rpm)*0.00041887902)*dial_len); + int y = int(sin(float(new_rpm)*0.00041887902)*dial_len); + if (ui_rpm!=new_rpm && ui_rpm!=-1) { + int old_x = int(cos(float(ui_rpm)*0.00041887902)*dial_len); + int old_y = int(sin(float(ui_rpm)*0.00041887902)*dial_len); + lcd.line(64-old_x,120-old_y,64,120,0x000000); + } + lcd.line(64-x,120-y,64,120,0xFF8C00); + ui_rpm = new_rpm; +} + +void display_speed() { //displays speed + draw_speedometer(); + lcd.color(0x909090); + lcd.text_width(2); + lcd.text_height(2); + lcd.locate(1,0); + lcd.printf("%s\n\r", "SPEED"); + lcd.color(0x66CCFF); + lcd.text_width(3); + lcd.text_height(3); + lcd.locate(1,1); + lcd.printf("%3.0f \n\r", (((float)atoi(speed_buffer))*0.62)); +} + +void draw_speedometer(){ //draws gauge for speed + lcd.circle(64,120,60,0xFFFFFF); + float new_speed = atoi(speed_buffer) * 0.62; + int x = int(cos(new_speed*0.0314159265)*dial_len); + int y = int(sin(new_speed*0.0314159265)*dial_len); + if (ui_speed!=new_speed && ui_speed!=-1) { + int old_x = int(cos(ui_speed*0.0314159265)*dial_len); + int old_y = int(sin(ui_speed*0.0314159265)*dial_len); + lcd.line(64-old_x,120-old_y,64,120,0x000000); + } + lcd.line(64-x,120-y,64,120,0xFF8C00); + ui_speed = new_speed; +} + +void display_trip() { //displays data being output to SD card + lcd.color(0x909090); + lcd.text_width(2); + lcd.text_height(2); + lcd.locate(0,0); + lcd.printf("%s\n\r", "TOTALTIME"); + lcd.color(0x66CCFF); + lcd.text_width(3); + lcd.text_height(3); + lcd.locate(0,1); + strftime(time_buff, 32, "%R", localtime(&seconds)); + lcd.printf("%s \n\r", time_buff); + + lcd.color(0x909090); + lcd.text_width(2); + lcd.text_height(2); + lcd.locate(0,4); + lcd.printf("%s\n\r", "DISTANCE"); + lcd.color(0x66CCFF); + lcd.text_width(3); + lcd.text_height(3); + lcd.locate(0,4); + lcd.printf("%3.1f \n\r", dist); +} \ No newline at end of file