/************************************************************************* * Sample sketch based on OBD-II library for Arduino * Using a LCD4884 shield to display realtime vehicle data * Distributed under GPL v2.0 * Copyright (c) 2012 Stanley Huang * All rights reserved. *************************************************************************/ #include #include "OBD.h" #include "LCD4884.h" //keypad debounce parameter #define DEBOUNCE_MAX 15 #define DEBOUNCE_ON 10 #define DEBOUNCE_OFF 3 #define NUM_KEYS 5 #define NUM_MODES 3 // joystick number #define LEFT_KEY 0 #define CENTER_KEY 1 #define DOWN_KEY 2 #define RIGHT_KEY 3 #define UP_KEY 4 int adc_key_val[5] ={ 50, 200, 400, 600, 800 }; // debounce counters byte button_count[NUM_KEYS]; // button status - pressed/released byte button_status[NUM_KEYS]; // button on flags for user program byte button_flag[NUM_KEYS]; // initial gauge mode char mode = 0; // The followinging are interrupt-driven keypad reading functions // which includes DEBOUNCE ON/OFF mechanism, and continuous pressing detection // Convert ADC value to key number char get_key(unsigned int input) { char k; for (k = 0; k < NUM_KEYS; k++) { if (input < adc_key_val[k]) { return k; } } if (k >= NUM_KEYS) k = -1; // No valid key pressed return k; } void update_adc_key(){ int adc_key_in; char key_in; byte i; adc_key_in = analogRead(0); key_in = get_key(adc_key_in); for(i=0; iDEBOUNCE_ON) { if(button_status[i] == 0) { button_flag[i] = 1; button_status[i] = 1; //button debounced to 'pressed' status } } } } else // no button pressed { if (button_count[i] >0) { button_flag[i] = 0; button_count[i]--; if(button_count[i]> 1; y1 >= 0; y1--) { lcd.LCD_set_XY(x, y1 + y); for (byte x = 0; x < 14; x++) { lcd.LCD_write_byte(0, 1); } } if (j & 1 == 1) { j >>= 1; lcd.LCD_set_XY(x, y + j); for (byte x = 0; x < 14; x++) { lcd.LCD_write_byte(0xE0, 1); } j++; } else { j >>= 1; } for (byte y1 = j; y1 <= 5; y1++) { lcd.LCD_set_XY(x, y1 + y); for (byte x = 0; x < 14; x++) { lcd.LCD_write_byte(0xEE, 1); } } } byte CheckPressedKey() { for(int i=0; i 0) { mode--; DisplayBG(mode); count = 0; } break; case RIGHT_KEY: if (mode < NUM_MODES - 1) { mode++; DisplayBG(mode); count = 0; } break; case UP_KEY: lcd.backlight(ON); break; case DOWN_KEY: lcd.backlight(OFF); break; } } if (millis() - lastTime < 250) { continue; } lastTime = millis(); switch (mode) { case 0: DisplayData1(); break; case 1: DisplayData2(); switch (count) { case 0: DisplayData21(); break; case 5: DisplayData22(); break; case 10: DisplayData23(); break; } break; case 2: DisplayData3(); break; } if (errors > 5) { lcd.backlight(OFF); return; } count++; } } private: void DisplayData1() { if (readSensor(PID_RPM, value)) { ShowRPM(value); } if (readSensor(PID_SPEED, value)) { ShowSpeed(value); } if (readSensor(PID_ENGINE_LOAD, value)) { ShowEngineLoad(value); } } void DisplayData2() { if (readSensor(PID_RPM, value)) { ShowRPM(value); } if (readSensor(PID_SPEED, value)) { ShowSpeed2(value); } } void DisplayData21() { if (readSensor(PID_COOLANT_TEMP, value)) { ShowTemperature(value, 42, 3); } } void DisplayData22() { if (readSensor(PID_INTAKE_TEMP, value)) { ShowTemperature(value, 42, 4); } } void DisplayData23() { if (readSensor(PID_AMBIENT_TEMP, value)) { ShowTemperature(value, 42, 5); } } void DisplayData3() { if (readSensor(PID_SPEED, value)) { ShowSpeed2(value); } if (readSensor(PID_INTAKE_MAP, value)) { char buf[8]; sprintf(buf, "%3u", value); lcd.LCD_write_string(24, 4, buf, MENU_NORMAL); int boost = (value - 101); if (boost < 0) boost = 0; sprintf(buf, "%d.%02d", boost / 100, boost % 100); lcd.LCD_write_string_big(0, 0, buf, MENU_NORMAL); } if (readSensor(PID_FUEL_PRESSURE, value)) { char buf[8]; sprintf(buf, "%3u", value); lcd.LCD_write_string(24, 5, buf, MENU_NORMAL); } } void ShowEngineLoad(uint8_t value) { ShowProgressBarV(70, 1, value / 10); lcd.LCD_write_string(78, 1, "%", MENU_NORMAL); } void ShowRPM(int value) { char buf[15]; if (value <= 9999) { sprintf(buf, "%4u", value); lcd.LCD_write_string_big(0, 0, buf, MENU_NORMAL); lcd.LCD_write_string(48, 2, "R", MENU_NORMAL); } } void ShowSpeed(uint8_t value) { char buf[8]; sprintf(buf, "%3u", value); lcd.LCD_write_string_big(6, 3, buf, MENU_NORMAL); lcd.LCD_write_string(42, 5, "k", MENU_NORMAL); } void ShowSpeed2(uint8_t value) { char buf[8]; ShowProgressBarV(70, 1, value / 25); sprintf(buf, "%3u", value); lcd.LCD_write_string(66, 0, buf, MENU_NORMAL); lcd.LCD_write_string(66, 1, "kph", MENU_NORMAL); } void ShowTemperature(uint8_t value, byte x, byte y) { char buf[8]; sprintf(buf, "%3d", value); lcd.LCD_write_string(x, y, buf, MENU_NORMAL); } void DisplayBG(char mode) { lcd.LCD_clear(); switch (mode) { case 0: lcd.LCD_write_string(48, 2, "RPM", MENU_NORMAL); lcd.LCD_write_string(42, 5, "kph", MENU_NORMAL); lcd.LCD_write_string(66, 0, "ENG", MENU_NORMAL); break; case 1: lcd.LCD_write_string(48, 2, "RPM", MENU_NORMAL); lcd.LCD_write_string(0, 3, "COOLANT C", MENU_NORMAL); lcd.LCD_write_string(0, 4, "INTAKE C", MENU_NORMAL); lcd.LCD_write_string(0, 5, "AMBIENT C", MENU_NORMAL); break; case 2: lcd.LCD_write_string(48, 2, "bar", MENU_NORMAL); lcd.LCD_write_string(0, 3, "PRESSURES", MENU_NORMAL); lcd.LCD_write_string(0, 4, "AIR kpa", MENU_NORMAL); lcd.LCD_write_string(0, 5, "FUEL kpa", MENU_NORMAL); break; } } #ifdef USE_SOFTSERIAL // override data communication functions bool DataAvailable() { return mySerial.available(); } char ReadData() { char c = mySerial.read(); Serial.write(c); return c; } void WriteData(const char* s) { mySerial.write(s); } void WriteData(const char c) { mySerial.write(c); } #endif char displayMode; int value; }; COBDDash obd; void loop() { obd.Loop(); } void setup() { // setup interrupt-driven keypad arrays // reset button arrays for(byte i=0; i