2016-03-08 21:40:11 -08:00
/*
Speeduino - Simple engine management for the Arduino Mega 2560 platform
Copyright ( C ) Josh Stewart
A full copy of the license may be found in the projects root directory
*/
2017-01-17 22:37:55 -08:00
# include "sensors.h"
2016-06-10 05:38:05 -07:00
2016-11-17 17:57:11 -08:00
void initialiseADC ( )
{
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
# if defined(ANALOG_ISR)
//This sets the ADC (Analog to Digitial Converter) to run at 250KHz, greatly reducing analog read times (MAP/TPS)
//the code on ISR run each conversion every 25 ADC clock, conversion run about 100KHz effectively
//making a 6250 conversions/s on 16 channels and 12500 on 8 channels devices.
noInterrupts ( ) ; //Interrupts should be turned off when playing with any of these registers
2017-02-08 19:17:20 -08:00
2016-11-17 17:57:11 -08:00
ADCSRB = 0x00 ; //ADC Auto Trigger Source is in Free Running mode
ADMUX = 0x40 ; //Select AREF as reference, ADC Left Adjust Result, Starting at channel 0
//All of the below is the longhand version of: ADCSRA = 0xEE;
# define ADFR 5 //Why the HELL isn't this defined in the same place as everything else (wiring.h)?!?!
BIT_SET ( ADCSRA , ADFR ) ; //Set free running mode
BIT_SET ( ADCSRA , ADIE ) ; //Set ADC interrupt enabled
BIT_CLEAR ( ADCSRA , ADIF ) ; //Clear interrupt flag
2016-11-17 18:42:51 -08:00
// Set ADC clock to 125KHz (Prescaler = 128)
2016-11-17 17:57:11 -08:00
BIT_SET ( ADCSRA , ADPS2 ) ;
BIT_SET ( ADCSRA , ADPS1 ) ;
BIT_SET ( ADCSRA , ADPS0 ) ;
2017-02-08 19:17:20 -08:00
2016-11-17 17:57:11 -08:00
BIT_SET ( ADCSRA , ADEN ) ; //Enable ADC
2017-02-08 19:17:20 -08:00
2016-11-17 17:57:11 -08:00
interrupts ( ) ;
BIT_SET ( ADCSRA , ADSC ) ; //Start conversion
2017-02-08 19:17:20 -08:00
2016-11-17 17:57:11 -08:00
# else
2016-11-17 18:42:51 -08:00
//This sets the ADC (Analog to Digitial Converter) to run at 1Mhz, greatly reducing analog read times (MAP/TPS) when using the standard analogRead() function
2016-11-17 17:57:11 -08:00
//1Mhz is the fastest speed permitted by the CPU without affecting accuracy
2016-11-17 18:42:51 -08:00
//Please see chapter 11 of 'Practical Arduino' (http://books.google.com.au/books?id=HsTxON1L6D4C&printsec=frontcover#v=onepage&q&f=false) for more detail
2016-11-17 17:57:11 -08:00
BIT_SET ( ADCSRA , ADPS2 ) ;
BIT_CLEAR ( ADCSRA , ADPS1 ) ;
BIT_CLEAR ( ADCSRA , ADPS0 ) ;
# endif
# endif
2017-04-20 23:33:24 -07:00
MAPcurRev = 0 ;
MAPcount = 0 ;
2016-11-17 17:57:11 -08:00
}
2016-03-08 21:40:11 -08:00
void instanteneousMAPReading ( )
{
//Instantaneous MAP readings
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2016-11-06 05:31:18 -08:00
tempReading = AnChannel [ pinMAP - A0 ] ;
# else
tempReading = analogRead ( pinMAP ) ;
tempReading = analogRead ( pinMAP ) ;
2017-02-08 19:17:20 -08:00
# endif
2016-03-08 21:40:11 -08:00
//Error checking
if ( tempReading > = VALID_MAP_MAX | | tempReading < = VALID_MAP_MIN ) { mapErrorCount + = 1 ; }
2017-02-11 17:43:18 -08:00
else { mapErrorCount = 0 ; }
2017-02-08 19:17:20 -08:00
2017-02-11 17:43:18 -08:00
currentStatus . mapADC = ADC_FILTER ( tempReading , ADCFILTER_MAP , currentStatus . mapADC ) ; //Very weak filter
2017-04-20 23:33:24 -07:00
2016-10-05 09:53:11 -07:00
currentStatus . MAP = fastMap1023toX ( currentStatus . mapADC , configPage1 . mapMax ) ; //Get the current MAP value
2017-04-20 23:33:24 -07:00
2016-03-08 21:40:11 -08:00
}
void readMAP ( )
{
2016-06-10 05:38:05 -07:00
//MAP Sampling system
switch ( configPage1 . mapSample )
{
case 0 :
//Instantaneous MAP readings
instanteneousMAPReading ( ) ;
break ;
2017-02-08 19:17:20 -08:00
2016-06-10 05:38:05 -07:00
case 1 :
//Average of a cycle
2017-02-08 19:17:20 -08:00
if ( currentStatus . RPM < 1 | | ! currentStatus . hasSync ) { instanteneousMAPReading ( ) ; return ; } //If the engine isn't running, fall back to instantaneous reads
if ( ( MAPcurRev = = currentStatus . startRevolutions ) | | ( MAPcurRev = = currentStatus . startRevolutions + 1 ) ) //2 revolutions are looked at for 4 stroke. 2 stroke not currently catered for.
2016-06-10 05:38:05 -07:00
{
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2016-11-06 05:31:18 -08:00
tempReading = AnChannel [ pinMAP - A0 ] ;
# else
tempReading = analogRead ( pinMAP ) ;
tempReading = analogRead ( pinMAP ) ;
# endif
2017-02-08 19:17:20 -08:00
2016-06-10 05:38:05 -07:00
//Error check
if ( tempReading < VALID_MAP_MAX & & tempReading > VALID_MAP_MIN )
2016-03-08 21:40:11 -08:00
{
2016-06-10 05:38:05 -07:00
MAPrunningValue = MAPrunningValue + tempReading ; //Add the current reading onto the total
MAPcount + + ;
2016-03-08 21:40:11 -08:00
}
2016-06-10 05:38:05 -07:00
else { mapErrorCount + = 1 ; }
}
else
{
//Reaching here means that the last cylce has completed and the MAP value should be calculated
2017-02-08 19:17:20 -08:00
//Sanity check
if ( MAPrunningValue = = 0 | | MAPcount = = 0 ) { instanteneousMAPReading ( ) ; return ; }
2016-06-10 05:38:05 -07:00
currentStatus . mapADC = ldiv ( MAPrunningValue , MAPcount ) . quot ;
2016-10-05 09:53:11 -07:00
currentStatus . MAP = fastMap1023toX ( currentStatus . mapADC , configPage1 . mapMax ) ; //Get the current MAP value
2017-01-17 22:37:55 -08:00
MAPcurRev = currentStatus . startRevolutions ; //Reset the current rev count
2016-06-10 05:38:05 -07:00
MAPrunningValue = 0 ;
MAPcount = 0 ;
}
break ;
2017-02-08 19:17:20 -08:00
2016-06-10 05:38:05 -07:00
case 2 :
//Minimum reading in a cycle
if ( currentStatus . RPM < 1 ) { instanteneousMAPReading ( ) ; return ; } //If the engine isn't running, fall back to instantaneous reads
2017-02-08 19:17:20 -08:00
if ( ( MAPcurRev = = currentStatus . startRevolutions ) | | ( MAPcurRev = = currentStatus . startRevolutions + 1 ) ) //2 revolutions are looked at for 4 stroke. 2 stroke not currently catered for.
2016-06-10 05:38:05 -07:00
{
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2016-11-06 05:31:18 -08:00
tempReading = AnChannel [ pinMAP - A0 ] ;
# else
tempReading = analogRead ( pinMAP ) ;
tempReading = analogRead ( pinMAP ) ;
# endif
2016-06-10 05:38:05 -07:00
//Error check
if ( tempReading < VALID_MAP_MAX & & tempReading > VALID_MAP_MIN )
2016-03-08 21:40:11 -08:00
{
2016-06-10 05:38:05 -07:00
if ( tempReading < MAPrunningValue ) { MAPrunningValue = tempReading ; } //Check whether the current reading is lower than the running minimum
2016-03-08 21:40:11 -08:00
}
2016-06-10 05:38:05 -07:00
else { mapErrorCount + = 1 ; }
}
else
{
//Reaching here means that the last cylce has completed and the MAP value should be calculated
currentStatus . mapADC = MAPrunningValue ;
2016-10-05 09:53:11 -07:00
currentStatus . MAP = fastMap1023toX ( currentStatus . mapADC , configPage1 . mapMax ) ; //Get the current MAP value
2017-01-17 22:37:55 -08:00
MAPcurRev = currentStatus . startRevolutions ; //Reset the current rev count
2016-06-10 05:38:05 -07:00
MAPrunningValue = 1023 ; //Reset the latest value so the next reading will always be lower
}
break ;
}
2016-03-08 21:40:11 -08:00
}
2016-03-23 04:09:04 -07:00
void readTPS ( )
{
2016-06-10 05:38:05 -07:00
currentStatus . TPSlast = currentStatus . TPS ;
currentStatus . TPSlast_time = currentStatus . TPS_time ;
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2016-11-06 05:31:18 -08:00
byte tempTPS = fastMap1023toX ( AnChannel [ pinTPS - A0 ] , 255 ) ; //Get the current raw TPS ADC value and map it into a byte
# else
analogRead ( pinTPS ) ;
byte tempTPS = fastMap1023toX ( analogRead ( pinTPS ) , 255 ) ; //Get the current raw TPS ADC value and map it into a byte
# endif
2016-06-10 05:38:05 -07:00
currentStatus . tpsADC = ADC_FILTER ( tempTPS , ADCFILTER_TPS , currentStatus . tpsADC ) ;
2017-02-08 19:17:20 -08:00
//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).
2016-06-10 05:38:05 -07:00
byte tempADC = currentStatus . tpsADC ; //The tempADC value is used in order to allow TunerStudio to recover and redo the TPS calibration if this somehow gets corrupted
if ( currentStatus . tpsADC < configPage1 . tpsMin ) { tempADC = configPage1 . tpsMin ; }
else if ( currentStatus . tpsADC > configPage1 . tpsMax ) { tempADC = configPage1 . tpsMax ; }
currentStatus . TPS = map ( tempADC , configPage1 . tpsMin , configPage1 . tpsMax , 0 , 100 ) ; //Take the raw TPS ADC value and convert it into a TPS% based on the calibrated values
2017-02-08 19:17:20 -08:00
currentStatus . TPS_time = currentLoopTime ;
2016-03-23 04:09:04 -07:00
}
void readCLT ( )
{
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2016-11-06 05:31:18 -08:00
tempReading = fastMap1023toX ( AnChannel [ pinCLT - A0 ] , 511 ) ; //Get the current raw CLT value
# else
tempReading = analogRead ( pinCLT ) ;
tempReading = fastMap1023toX ( analogRead ( pinCLT ) , 511 ) ; //Get the current raw CLT value
# endif
2016-06-10 05:38:05 -07:00
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
2016-03-23 04:09:04 -07:00
}
void readIAT ( )
{
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2016-11-06 05:31:18 -08:00
tempReading = fastMap1023toX ( AnChannel [ pinIAT - A0 ] , 511 ) ; //Get the current raw IAT value
# else
tempReading = analogRead ( pinIAT ) ;
tempReading = fastMap1023toX ( analogRead ( pinIAT ) , 511 ) ; //Get the current raw IAT value
# endif
2016-06-10 05:38:05 -07:00
currentStatus . iatADC = ADC_FILTER ( tempReading , ADCFILTER_IAT , currentStatus . iatADC ) ;
currentStatus . IAT = iatCalibrationTable [ currentStatus . iatADC ] - CALIBRATION_TEMPERATURE_OFFSET ;
2016-03-23 04:09:04 -07:00
}
void readO2 ( )
{
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
tempReading = fastMap1023toX ( AnChannel [ pinO2 - A0 ] , 511 ) ; //Get the current O2 value.
2016-11-06 05:31:18 -08:00
# else
tempReading = analogRead ( pinO2 ) ;
2017-02-08 19:17:20 -08:00
tempReading = fastMap1023toX ( analogRead ( pinO2 ) , 511 ) ; //Get the current O2 value.
2016-11-06 05:31:18 -08:00
# endif
2016-06-10 05:38:05 -07:00
currentStatus . O2ADC = ADC_FILTER ( tempReading , ADCFILTER_O2 , currentStatus . O2ADC ) ;
currentStatus . O2 = o2CalibrationTable [ currentStatus . O2ADC ] ;
2016-03-23 04:09:04 -07:00
}
2017-02-08 19:17:20 -08:00
2016-06-10 05:38:05 -07:00
/* Second O2 currently disabled as its not being used
currentStatus . O2_2ADC = map ( analogRead ( pinO2_2 ) , 0 , 1023 , 0 , 511 ) ; //Get the current O2 value.
currentStatus . O2_2ADC = ADC_FILTER ( tempReading , ADCFILTER_O2 , currentStatus . O2_2ADC ) ;
currentStatus . O2_2 = o2CalibrationTable [ currentStatus . O2_2ADC ] ;
*/
2016-03-23 04:09:04 -07:00
void readBat ( )
{
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2016-11-06 05:31:18 -08:00
tempReading = fastMap1023toX ( AnChannel [ pinBat - A0 ] , 245 ) ; //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245)
# else
tempReading = analogRead ( pinBat ) ;
tempReading = fastMap1023toX ( analogRead ( pinBat ) , 245 ) ; //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245)
# endif
2016-06-10 05:38:05 -07:00
currentStatus . battery10 = ADC_FILTER ( tempReading , ADCFILTER_BAT , currentStatus . battery10 ) ;
2016-03-23 04:09:04 -07:00
}
2016-06-24 01:02:53 -07:00
/*
* The interrupt function for reading the flex sensor frequency
* This value is incremented with every pulse and reset back to 0 once per second
*/
2016-10-25 07:04:37 -07:00
void flexPulse ( )
2016-06-24 01:02:53 -07:00
{
+ + flexCounter ;
}