Just wanted to update this thread with my code. There's a LOT of things to do still but it's getting very very close. I'm about to go to sleep, so I figured I'd update this thread (maybe just to have another copy of the code available somewhere...).
Current known issues:
- speaker is way too quiet. seemed to work fine when it was the only thing connected via hardware.
- need to figure out how to deal with peak displays.
- i guess warnings should be enough?
- other things i'm forgetting since my liver has been more functional than my brain for the past few hours
- clean up/ document code/ orgainze etc.
/*
Abhishek Shinde
Multigauge LCD (c) 2009
*/
// define analog inputs as constants : 0v = 0, 5v = 1023
const int oiltPin = 1; // oil temperature signal wire <- voltage divider from Prosport oilt sensor 32F = 4550ohm, 104F = 925ohm, 176F = 224ohm, 212 = 120ohm
const int oilpPin = 2; // oil pressure signal wire <- voltage divider from Prosport oilp sensor 0-145psi, 3-160ohm
const int mrpPin = 3; // manifold absolute pressure signal wire <- 0-5v input from ECU pin
const int afrPin = 4; // wideband oxygen sensor <- 0-5v input from LC-1
const int h2oPin = 5; // factory coolant temperature sensor <- 0-5v input from ECU pin
const int oiltMax = 230; // maximum oil temp (Fahrenheit)
const int mrpMax = 20; // maximum boost pressure (psi)
const int h2oMax = 220; // maximum water temp (Fahrenheit)
// define peak and warn variables
boolean oiltWarn = false;
boolean mrpWarn = false;
boolean h2oWarn = false;
int oiltPeak = 0;
int mrpPeak = 0;
int h2oPeak = 0;
// TESTING CRAP
int ledPin = 13; // test
int ledState = LOW; // test
long previousMillis = 0; // test
int pinSpeaker = 13; // speaker output
// Setup
void setup() {
delay(500); // delay before program start. may not be needed
Serial.begin(9600);
pinMode(ledPin,OUTPUT); // test
pinMode(pinSpeaker, OUTPUT);
// LCD stuff
initLCD (); // one time intialization of LCD
}
// check warning code
int read_oilt () { // returns actual oil temperature in Fahrenheit
float raw = (analogRead(oiltPin) + 1) * .00488; // read digital value and convert to actual analog volt value, analogRead() : 0v = 0, 5v = 1023 (1024 steps) : .00488v = 1 step
//Serial.print("volt = "); //debug to serial monitor
//Serial.print(raw); //debug to serial monitor
//Serial.print(" temp = "); //debug to serial monitor
// oil temp = 6.298x^3 - 45.72x^2 + 139.8x - 60.4 - derived equation using temp sensor and '1000' ohm voltage divider
int oiltValue = ((6.298 * raw * raw * raw) - (45.72 * raw * raw) + (139.8 * raw) - 60.4); // convert to actual temperature reading in fahrenheit
if (oiltValue >= oiltMax) { // check if oil level is above Max
oiltWarn = true; // set warning level
if (oiltValue > oiltPeak) oiltPeak = oiltValue; // update peak oil temp if above current peak
} else { // do this if oil level is below Max
oiltWarn = false;
}
return oiltValue;
}
// done
int read_oilp () { // return actual oil pressure in psi
float raw = (analogRead(oilpPin) + 1) * .00488; // read digital value and convert to actual analog volt value
//Serial.print(" volt = "); //debug to serial monitor
//Serial.print(raw); //debug to serial monitor
//Serial.print(" pressure = "); //debug to serial monitor
// oil pressure = -.322x^3 + 4.278x^2 -20.59x + 35.98 - derived equation using 3-160ohm pressure sensor and '100' ohm voltage divider
int oilpValue = ((-4.698 * raw * raw * raw) + (61.9 * raw * raw) - (295.5* raw) + 513.1); // convert to actual pressure reading in psi
return oilpValue;
}
int read_mrp () { // return actual boost pressure in psi at 'sea level'
float raw = (analogRead(mrpPin) + 1) * .00488; // read digital value and convert to actual analog volt value
int mrpValue = raw * 9.943 - 8.005 - 14.7; // equation from factory map scaling and subtracted 'sea level' pressure
if (mrpValue >= mrpMax) {
mrpWarn = true;
if (mrpValue >= mrpMax) mrpPeak = mrpValue; // update peak oil temp if above current peak
} else { // do if oil level is below Max
mrpWarn = false;
}
return mrpValue;
}
int read_h2o () {
float raw = (analogRead(h2oPin) + 1) * .00488;
int h2oValue = (-6.445 * raw * raw * raw) + (50.11 * raw * raw) + (-167.0 * raw) + (313.4);
if (h2oValue >= h2oMax) {
h2oWarn = true; // set warning level
h2oPeak = h2oValue; // error check
}
return h2oValue;
}
boolean flip = true;
//simulation variables
int simoilt = 44;
int simoilp = 125;
int simmrp = -.8;
int simwt = 50;
float simafr = 14.7;
// Main program
void loop() {
//dispDebug (); // debug to serial monitor
//dispData();
doSim();
dispData();
checkWarn();
}
void doSim() {
if (millis() - previousMillis > 2000) {
// save the last time you blinked the LED
previousMillis = millis();
simoilt++;
simoilp--;
simmrp += 1;
simwt += 1;
simafr = 14.7;
}
}
//if (millis() < 1000) delay(1000); // wait atleast one second to start the program
/*
if (oiltWarn || mrpWarn || h2oWarn) { // blink LED if any Warn = true
if (millis() - previousMillis > 250) {
// save the last time you blinked the LED
previousMillis = millis();
oiltMax++;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) ledState = HIGH;
else ledState = LOW;
}
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState); // set the LED with the ledState of the variable:
//playTone(150, 1000);
//playTone(150, 2500);
//playTone(50, 1800);
//playTone(750, 3000);
*/
void checkWarn () { // sound siren if any warning flags are set true
if (oiltWarn || mrpWarn || h2oWarn) {
if (flip) {
playTone(100,2500);
flip = false;
} else {
playTone(100,2000); // LOUD!!!
flip=true;
}
}
}
//delay(5000);
// ********** DEBUG OUTPUT *************************8
void dispDebug() {
Serial.println();
Serial.println("TEST");
Serial.print("temperature ");
Serial.print(read_oilt());
Serial.println(" F");
Serial.print("pressure ");
Serial.print(read_oilp());
Serial.println(" psi");
Serial.print("elapsed time = ");
Serial.println(millis());
Serial.println();
delay(5000);
}
// ************* SPEAKER STUFF ****************************
// duration in mSecs, frequency in hertz
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(pinSpeaker,HIGH);
delayMicroseconds(period / 2);
digitalWrite(pinSpeaker, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
// ************** LCD STUFF ******************************
void clearLCD () {
Serial.print(254, BYTE);
Serial.print(81, BYTE);
//delay(50);
}
// done
void dispLogo () {
clearLCD();
goTo(1, 4); // Row 1, Column 2
Serial.print("MultiGauge LCD");
goTo(2,1);
Serial.print("(c) Abhishek Shinde");
}
void dispLabels () {
clearLCD();
goTo(1,1);
Serial.print ("*FoilPSI mrp h2o wbo2");
}
void dispData () {
goTo(2,1);
Serial.print(simoilt);
if (simoilt < 100) {
goTo(2,3);
Serial.print(" ");
}
goTo(2,5);
Serial.print(simoilp);
if (simoilp < 100) {
goTo(2,7);
Serial.print(" ");
}
goTo(2,9);
//Serial.print(simmrp);
Serial.print(
//goTo(2, 12);
//Serial.print(" ");
goTo(2, 13);
Serial.print(simwt);
goTo(2,17);
Serial.print(simafr);
}
// done
void goTo (int row, int col) { // moves cursor to indicated position - row/column
int rowcol = 0;
switch (row) {
case 1:
rowcol = col-1;
break;
case 2:
rowcol = col - 1 + 64;
break;
}
Serial.print(254, BYTE); // use command
Serial.print(69, BYTE); // "Set Cursor Position"
Serial.print(rowcol, BYTE); // row/col value
//delay(40);
}
// done
void LCDBright(int bright) { // set LCD brightness : 8 = Brightest, 1 = Lightest
Serial.print(254, BYTE);
Serial.print(83, BYTE);
Serial.print(bright, BYTE);
}
void initLCD () { // initalize LCD for the first time
//delay(100); // delay to let the LCD initialize
clearLCD();
dispLogo();
delay(3000);
dispLabels();
}