Code for Mbed Dashboard project. http://developer.mbed.org/users/julieefreeman/notebook/mbed-dashboard---obdii/
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed
main.cpp
- Committer:
- julieefreeman
- Date:
- 2014-12-09
- Revision:
- 0:2fa4b8d8fbd0
File content as of revision 0:2fa4b8d8fbd0:
/*
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);
}