ADC interrupt routine
Introducing ADC interrupt routine tor atmel devices
This commit is contained in:
parent
0a6be57aa6
commit
0a1cadc504
40
sensors.h
40
sensors.h
|
@ -14,6 +14,15 @@
|
|||
|
||||
volatile byte flexCounter = 0;
|
||||
|
||||
#define ANALOG_ISR //Comment this line to disable the ADC interrupt routine
|
||||
#if defined(ANALOG_ISR)
|
||||
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
||||
int AnChannel[7];
|
||||
#else
|
||||
int AnChannel[15];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simple low pass IIR filter macro for the analog inputs
|
||||
* This is effectively implementing the smooth filter from http://playground.arduino.cc/Main/Smooth
|
||||
|
@ -27,4 +36,35 @@ void flexPulse();
|
|||
|
||||
unsigned int tempReading;
|
||||
|
||||
#if defined(ANALOG_ISR)
|
||||
//Analog ISR interrupt routine
|
||||
ISR(ADC_vect)
|
||||
{
|
||||
byte nChannel;
|
||||
int result = ADCL | (ADCH << 8);
|
||||
|
||||
ADCSRA = 0x6E; // ADC disabled by clearing bit 7(ADEN)
|
||||
nChannel = ADMUX & 0x07;
|
||||
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
||||
if (nChannel==7) { ADMUX = 0x40; }
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
if(ADCSRB & 0x08) { nChannel+=8; } //8 to 15
|
||||
if(nChannel==15)
|
||||
{
|
||||
ADMUX = 0x40; //channel 0
|
||||
ADCSRB = 0x00; //clear MUX5 bit
|
||||
}
|
||||
else if (nChannel==7) //channel 7
|
||||
{
|
||||
ADMUX = 0x40;
|
||||
ADCSRB = 0x08; //Set MUX5 bit
|
||||
}
|
||||
#endif
|
||||
else { ADMUX++; }
|
||||
AnChannel[nChannel] = result;
|
||||
|
||||
ADCSRA = 0xEE; // ADC Interrupt Flag enabled
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SENSORS_H
|
||||
|
|
65
sensors.ino
65
sensors.ino
|
@ -7,9 +7,12 @@ A full copy of the license may be found in the projects root directory
|
|||
void instanteneousMAPReading()
|
||||
{
|
||||
//Instantaneous MAP readings
|
||||
tempReading = analogRead(pinMAP);
|
||||
tempReading = analogRead(pinMAP);
|
||||
|
||||
#if defined(ANALOG_ISR)
|
||||
tempReading = AnChannel[pinMAP-A0];
|
||||
#else
|
||||
tempReading = analogRead(pinMAP);
|
||||
tempReading = analogRead(pinMAP);
|
||||
#endif
|
||||
//Error checking
|
||||
if(tempReading >= VALID_MAP_MAX || tempReading <= VALID_MAP_MIN) { mapErrorCount += 1; }
|
||||
else { currentStatus.mapADC = tempReading; mapErrorCount = 0; }
|
||||
|
@ -34,8 +37,12 @@ void readMAP()
|
|||
|
||||
if( (MAPcurRev == startRevolutions) || (MAPcurRev == startRevolutions+1) ) //2 revolutions are looked at for 4 stroke. 2 stroke not currently catered for.
|
||||
{
|
||||
tempReading = analogRead(pinMAP);
|
||||
tempReading = analogRead(pinMAP);
|
||||
#if defined(ANALOG_ISR)
|
||||
tempReading = AnChannel[pinMAP-A0];
|
||||
#else
|
||||
tempReading = analogRead(pinMAP);
|
||||
tempReading = analogRead(pinMAP);
|
||||
#endif
|
||||
|
||||
//Error check
|
||||
if(tempReading < VALID_MAP_MAX && tempReading > VALID_MAP_MIN)
|
||||
|
@ -62,8 +69,12 @@ void readMAP()
|
|||
|
||||
if( (MAPcurRev == startRevolutions) || (MAPcurRev == startRevolutions+1) ) //2 revolutions are looked at for 4 stroke. 2 stroke not currently catered for.
|
||||
{
|
||||
tempReading = analogRead(pinMAP);
|
||||
tempReading = analogRead(pinMAP);
|
||||
#if defined(ANALOG_ISR)
|
||||
tempReading = AnChannel[pinMAP-A0];
|
||||
#else
|
||||
tempReading = analogRead(pinMAP);
|
||||
tempReading = analogRead(pinMAP);
|
||||
#endif
|
||||
//Error check
|
||||
if(tempReading < VALID_MAP_MAX && tempReading > VALID_MAP_MIN)
|
||||
{
|
||||
|
@ -87,8 +98,12 @@ void readTPS()
|
|||
{
|
||||
currentStatus.TPSlast = currentStatus.TPS;
|
||||
currentStatus.TPSlast_time = currentStatus.TPS_time;
|
||||
analogRead(pinTPS);
|
||||
byte tempTPS = fastMap1023toX(analogRead(pinTPS), 255); //Get the current raw TPS ADC value and map it into a byte
|
||||
#if defined(ANALOG_ISR)
|
||||
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
|
||||
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).
|
||||
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
|
||||
|
@ -100,24 +115,36 @@ void readTPS()
|
|||
|
||||
void readCLT()
|
||||
{
|
||||
tempReading = analogRead(pinCLT);
|
||||
tempReading = fastMap1023toX(analogRead(pinCLT), 511); //Get the current raw CLT value
|
||||
#if defined(ANALOG_ISR)
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
void readIAT()
|
||||
{
|
||||
tempReading = analogRead(pinIAT);
|
||||
tempReading = fastMap1023toX(analogRead(pinIAT), 511); //Get the current raw IAT value
|
||||
#if defined(ANALOG_ISR)
|
||||
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
|
||||
currentStatus.iatADC = ADC_FILTER(tempReading, ADCFILTER_IAT, currentStatus.iatADC);
|
||||
currentStatus.IAT = iatCalibrationTable[currentStatus.iatADC] - CALIBRATION_TEMPERATURE_OFFSET;
|
||||
}
|
||||
|
||||
void readO2()
|
||||
{
|
||||
tempReading = analogRead(pinO2);
|
||||
tempReading = fastMap1023toX(analogRead(pinO2), 511); //Get the current O2 value.
|
||||
#if defined(ANALOG_ISR)
|
||||
tempReading = fastMap1023toX(AnChannel[pinO2-A0], 511); //Get the current O2 value.
|
||||
#else
|
||||
tempReading = analogRead(pinO2);
|
||||
tempReading = fastMap1023toX(analogRead(pinO2), 511); //Get the current O2 value.
|
||||
#endif
|
||||
currentStatus.O2ADC = ADC_FILTER(tempReading, ADCFILTER_O2, currentStatus.O2ADC);
|
||||
currentStatus.O2 = o2CalibrationTable[currentStatus.O2ADC];
|
||||
}
|
||||
|
@ -130,8 +157,12 @@ void readO2()
|
|||
|
||||
void readBat()
|
||||
{
|
||||
tempReading = analogRead(pinBat);
|
||||
tempReading = fastMap1023toX(analogRead(pinBat), 245); //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245)
|
||||
#if defined(ANALOG_ISR)
|
||||
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
|
||||
currentStatus.battery10 = ADC_FILTER(tempReading, ADCFILTER_BAT, currentStatus.battery10);
|
||||
}
|
||||
|
||||
|
|
|
@ -485,15 +485,24 @@ void setup()
|
|||
currentLoopTime = micros();
|
||||
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
|
||||
//This sets the ADC (Analog to Digitial Converter) to run at 1Mhz, greatly reducing analog read times (MAP/TPS)
|
||||
//1Mhz is the fastest speed permitted by the CPU without affecting accuracy
|
||||
//Please see chapter 11 of 'Practical Arduino' (http://books.google.com.au/books?id=HsTxON1L6D4C&printsec=frontcover#v=onepage&q&f=false) for more details
|
||||
//Can be disabled by removing the #include "fastAnalog.h" above
|
||||
#ifdef sbi
|
||||
sbi(ADCSRA,ADPS2);
|
||||
cbi(ADCSRA,ADPS1);
|
||||
cbi(ADCSRA,ADPS0);
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
|
||||
#if defined(ANALOG_ISR) //ADC interrupt routine
|
||||
//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.
|
||||
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
|
||||
ADCSRA = 0xEE; // ADC Interrupt Flag enabled and prescaler selected to 250KHz
|
||||
#else
|
||||
//This sets the ADC (Analog to Digitial Converter) to run at 1Mhz, greatly reducing analog read times (MAP/TPS)
|
||||
//1Mhz is the fastest speed permitted by the CPU without affecting accuracy
|
||||
//Please see chapter 11 of 'Practical Arduino' (http://books.google.com.au/books?id=HsTxON1L6D4C&printsec=frontcover#v=onepage&q&f=false) for more details
|
||||
//Can be disabled by removing the #include "fastAnalog.h" above
|
||||
#ifdef sbi
|
||||
sbi(ADCSRA,ADPS2);
|
||||
cbi(ADCSRA,ADPS1);
|
||||
cbi(ADCSRA,ADPS0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1450,6 +1459,37 @@ void loop()
|
|||
//************************************************************************************************
|
||||
//Interrupts
|
||||
|
||||
#if defined(ANALOG_H)
|
||||
//Analog ISR interrupt routine
|
||||
ISR(ADC_vect)
|
||||
{
|
||||
byte nChannel;
|
||||
int result = ADCL | (ADCH << 8);
|
||||
|
||||
ADCSRA = 0x6E; // ADC Auto Trigger disabled by clearing bit 7(ADEN)
|
||||
nChannel = ADMUX & 0x07;
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
if(ADCSRB & 0x08) { nChannel+=8; } //8 to 15
|
||||
if(nChannel==15)
|
||||
{
|
||||
ADMUX = 0x40; //channel 0
|
||||
ADCSRB = 0x00; //clear MUX5 bit
|
||||
}
|
||||
else if (nChannel==7) //channel 7
|
||||
{
|
||||
ADMUX = 0x40;
|
||||
ADCSRB = 0x08; //Set MUX5 bit
|
||||
}
|
||||
#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
||||
if (nChannel==7) { ADMUX = 0x40; }
|
||||
#endif
|
||||
else { ADMUX++; }
|
||||
AnChannel[nChannel] = result;
|
||||
|
||||
ADCSRA = 0xEE; // ADC Interrupt Flag enabled
|
||||
}
|
||||
#endif
|
||||
|
||||
//These functions simply trigger the injector/coil driver off or on.
|
||||
//NOTE: squirt status is changed as per http://www.msextra.com/doc/ms1extra/COM_RS232.htm#Acmd
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue