diff --git a/globals.h b/globals.h index 22e5c63e..4a0e2024 100644 --- a/globals.h +++ b/globals.h @@ -39,6 +39,14 @@ const int map_page_size = 288; #define TOOTH_LOG_SIZE 128 #define TOOTH_LOG_BUFFER 256 +// The following are alpha values for the ADC filters. +// Their values are from 0 to 255 with 0 being no filtering and 255 being maximum +#define ADCFILTER_TPS 128 +#define ADCFILTER_CLT 210 +#define ADCFILTER_IAT 128 +#define ADCFILTER_O2 128 +#define ADCFILTER_BAT 128 + #define SIZE_BYTE 8 #define SIZE_INT 16 diff --git a/speeduino.ino b/speeduino.ino index 6475fe93..c7587ac3 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -680,7 +680,8 @@ void loop() { currentStatus.TPSlast = currentStatus.TPS; currentStatus.TPSlast_time = currentStatus.TPS_time; - currentStatus.tpsADC = fastMap1023toX(analogRead(pinTPS), 0, 1023, 0, 255); //Get the current raw TPS ADC value and map it into a byte + byte tempTPS = fastMap1023toX(analogRead(pinTPS), 0, 1023, 0, 255); //Get the current raw TPS ADC value and map it into a byte + currentStatus.tpsADC = ADC_FILTER(tempTPS, ADCFILTER_TPS, currentStatus.tpsADC); //Check that the ADC values fall within the min and max ranges (Should always be the case, but noise can cause these to fluctuate outside the defined range). if (currentStatus.tpsADC < configPage1.tpsMin) { currentStatus.tpsADC = configPage1.tpsMin; } else if(currentStatus.tpsADC > configPage1.tpsMax) { currentStatus.tpsADC = configPage1.tpsMax; } @@ -696,23 +697,31 @@ void loop() //The IAT and CLT readings can be done less frequently. This still runs about 4 times per second if ((mainLoopCount & 255) == 1) { - //currentStatus.cltADC = map(analogRead(pinCLT), 0, 1023, 0, 511); //Get the current raw CLT value - currentStatus.cltADC = fastMap1023toX(analogRead(pinCLT), 0, 1023, 0, 511); //Get the current raw CLT value - currentStatus.iatADC = map(analogRead(pinIAT), 0, 1023, 0, 511); //Get the current raw IAT value - currentStatus.O2ADC = map(analogRead(pinO2), 0, 1023, 0, 511); //Get the current O2 value. Calibration is from AFR values 7.35 to 22.4. This is the correct calibration for an Innovate Wideband 0v - 5V unit. Proper calibration is still a WIP - currentStatus.O2_2ADC = map(analogRead(pinO2_2), 0, 1023, 0, 511); //Get the current O2 value. Calibration is from AFR values 7.35 to 22.4. This is the correct calibration for an Innovate Wideband 0v - 5V unit. Proper calibration is still a WIP - //currentStatus.battery10 = map(analogRead(pinBat), 0, 1023, 0, 245); //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245) - currentStatus.battery10 = fastMap1023toX(analogRead(pinBat), 0, 1023, 0, 245); //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245) - //currentStatus.batADC = map(analogRead(pinBat), 0, 1023, 0, 255); //Get the current raw Battery value + int tempReading; + tempReading = fastMap1023toX(analogRead(pinCLT), 0, 1023, 0, 511); //Get the current raw CLT value + currentStatus.cltADC = ADC_FILTER(tempReading, ADCFILTER_CLT, currentStatus.cltADC); currentStatus.coolant = cltCalibrationTable[currentStatus.cltADC] - CALIBRATION_TEMPERATURE_OFFSET; //Temperature calibration values are stored as positive bytes. We subtract 40 from them to allow for negative temperatures + + tempReading = map(analogRead(pinIAT), 0, 1023, 0, 511); //Get the current raw IAT value + currentStatus.iatADC = ADC_FILTER(tempReading, ADCFILTER_IAT, currentStatus.iatADC); currentStatus.IAT = iatCalibrationTable[currentStatus.iatADC] - CALIBRATION_TEMPERATURE_OFFSET; + + tempReading = map(analogRead(pinO2), 0, 1023, 0, 511); //Get the current O2 value. Calibration is from AFR values 7.35 to 22.4. This is the correct calibration for an Innovate Wideband 0v - 5V unit. Proper calibration is still a WIP + currentStatus.O2ADC = ADC_FILTER(tempReading, ADCFILTER_O2, currentStatus.O2ADC); currentStatus.O2 = o2CalibrationTable[currentStatus.O2ADC]; - currentStatus.O2_2 = o2CalibrationTable[currentStatus.O2_2ADC]; - vvtControl(); - boostControl(); //Most boost tends to run at about 30Hz, so placing it here ensures a new target time is fetched frequently enough - idleControl(); //Perform any idle related actions. Even at higher frequencies, running 4x per second is sufficient. + currentStatus.O2_2ADC = map(analogRead(pinO2_2), 0, 1023, 0, 511); //Get the current O2 value. Calibration is from AFR values 7.35 to 22.4. This is the correct calibration for an Innovate Wideband 0v - 5V unit. Proper calibration is still a WIP + currentStatus.O2_2ADC = ADC_FILTER(tempReading, ADCFILTER_O2, currentStatus.O2_2ADC); + currentStatus.O2_2 = o2CalibrationTable[currentStatus.O2_2ADC]; + + tempReading = fastMap1023toX(analogRead(pinBat), 0, 1023, 0, 245); //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245) + currentStatus.battery10 = ADC_FILTER(tempReading, ADCFILTER_BAT, currentStatus.battery10); + + + vvtControl(); + boostControl(); //Most boost tends to run at about 30Hz, so placing it here ensures a new target time is fetched frequently enough + idleControl(); //Perform any idle related actions. Even at higher frequencies, running 4x per second is sufficient. } //Always check for sync diff --git a/utils.h b/utils.h index f869895a..d8bf59fa 100644 --- a/utils.h +++ b/utils.h @@ -8,6 +8,13 @@ These are some utility functions and variables used through the main code #define MS_IN_MINUTE 60000 #define US_IN_MINUTE 60000000 +/* + * Simple low pass IIR filter macro for the analog inputs + * This is effectively implementing the smooth filter from http://playground.arduino.cc/Main/Smooth + * But removes the use of floats and uses 8 bits of fixed precision. + */ +#define ADC_FILTER(input, alpha, prior) (((long)input * (256 - alpha) + ((long)prior * alpha))) >> 8 + int freeRam (); void setPinMapping(byte boardID); unsigned int PW();