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
*/
2021-06-21 22:30:52 -07:00
/** @file
* Read sensors with appropriate timing / scheduling .
*/
2017-01-17 22:37:55 -08:00
# include "sensors.h"
2018-08-13 19:47:15 -07:00
# include "crankMaths.h"
2018-07-19 00:35:35 -07:00
# include "globals.h"
# include "maths.h"
2018-12-29 09:26:30 -08:00
# include "storage.h"
2019-02-14 00:53:16 -08:00
# include "comms.h"
2019-02-28 11:09:11 -08:00
# include "idle.h"
2020-05-21 22:26:20 -07:00
# include "errors.h"
2020-04-21 18:02:35 -07:00
# include "corrections.h"
2021-04-20 21:36:27 -07:00
# include "pages.h"
2021-11-14 20:47:55 -08:00
# include "decoders.h"
2023-04-23 17:30:51 -07:00
# include "auxiliaries.h"
# include "utilities.h"
2023-12-04 22:35:45 -08:00
# include BOARD_H
2016-06-10 05:38:05 -07:00
2023-10-06 00:10:20 -07:00
uint32_t MAPcurRev ; //Tracks which revolution we're sampling on
unsigned int MAPcount ; //Number of samples taken in the current MAP cycle
unsigned long MAPrunningValue ; //Used for tracking either the total of all MAP readings in this cycle (Event average) or the lowest value detected in this cycle (event minimum)
unsigned long EMAPrunningValue ; //As above but for EMAP
bool auxIsEnabled ;
uint16_t MAPlast ; /**< The previous MAP reading */
unsigned long MAP_time ; //The time the MAP sample was taken
unsigned long MAPlast_time ; //The time the previous MAP sample was taken
volatile unsigned long vssTimes [ VSS_SAMPLES ] = { 0 } ;
volatile byte vssIndex ;
volatile byte flexCounter = 0 ;
volatile unsigned long flexStartTime ;
volatile unsigned long flexPulseWidth ;
volatile byte knockCounter = 0 ;
volatile uint16_t knockAngle ;
//These variables are used for tracking the number of running sensors values that appear to be errors. Once a threshold is reached, the sensor reading will go to default value and assume the sensor is faulty
byte mapErrorCount = 0 ;
//byte iatErrorCount = 0; Not used
//byte cltErrorCount = 0; Not used
static inline void validateMAP ( void ) ;
2023-11-30 19:56:14 -08:00
# if defined(ANALOG_ISR)
2023-12-04 22:35:45 -08:00
static volatile uint16_t AnChannel [ 16 ] ;
2023-11-30 19:56:14 -08:00
ISR ( ADC_vect )
{
2023-12-04 22:35:45 -08:00
byte nChannel = ( ADMUX & 0x07 ) ;
2023-11-30 19:56:14 -08:00
2023-12-04 22:35:45 -08:00
byte result_low = ADCL ;
byte result_high = ADCH ;
2023-11-30 19:56:14 -08:00
# if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
2023-12-04 22:35:45 -08:00
if ( nChannel = = 7 ) { ADMUX = 0x40 ; }
2023-11-30 19:56:14 -08:00
# elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
2023-12-04 22:35:45 -08:00
if ( BIT_CHECK ( ADCSRB , MUX5 ) ) { nChannel + = 8 ; } //8 to 15
2023-11-30 19:56:14 -08:00
if ( nChannel = = 15 )
{
2023-12-04 22:35:45 -08:00
ADMUX = ADMUX_DEFAULT_CONFIG ; //channel 0
2023-11-30 19:56:14 -08:00
ADCSRB = 0x00 ; //clear MUX5 bit
2023-12-05 18:39:32 -08:00
BIT_CLEAR ( ADCSRA , ADIE ) ; //Disable interrupt as we're at the end of a full ADC cycle. This will be re-enabled in the main loop
2023-11-30 19:56:14 -08:00
}
else if ( nChannel = = 7 ) //channel 7
{
2023-12-04 22:35:45 -08:00
ADMUX = ADMUX_DEFAULT_CONFIG ;
2023-11-30 19:56:14 -08:00
ADCSRB = 0x08 ; //Set MUX5 bit
}
# endif
else { ADMUX + + ; }
2023-12-04 22:35:45 -08:00
//ADMUX always appears to be one ahead of the actual channel value that is in ADCL/ADCH. Subtract 1 from it to get the correct channel number
if ( nChannel = = 0 ) { nChannel = 16 ; }
AnChannel [ nChannel - 1 ] = ( result_high < < 8 ) | result_low ;
2023-11-30 19:56:14 -08:00
}
# endif
2021-06-21 22:30:52 -07:00
/** Init all ADC conversions by setting resolutions, etc.
*/
2022-11-05 15:43:29 -07:00
void initialiseADC ( void )
2016-11-17 17:57:11 -08:00
{
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
# if defined(ANALOG_ISR)
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
2023-12-04 22:35:45 -08:00
ADMUX = ADMUX_DEFAULT_CONFIG ; //Select AVCC as reference, ADC Right Adjust Result, Starting at channel 0
2016-11-17 17:57:11 -08:00
//All of the below is the longhand version of: ADCSRA = 0xEE;
2023-11-30 19:56:14 -08:00
# ifndef ADFR
# define ADFR 5 //Looks like this is now defined. Retain this for compatibility with earlier versions of Arduino IDE that did not have this.
# endif
2016-11-17 17:57:11 -08:00
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
2022-04-10 17:49:58 -07:00
//This sets the ADC (Analog to Digital 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
2019-07-08 00:51:08 -07:00
//Please see chapter 11 of 'Practical Arduino' (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
2019-02-20 13:46:10 -08:00
# elif defined(ARDUINO_ARCH_STM32) //STM32GENERIC core and ST STM32duino core, change analog read to 12 bit
2020-08-09 15:54:36 -07:00
analogReadResolution ( 10 ) ; //use 10bits for analog reading on STM32 boards
2016-11-17 17:57:11 -08:00
# endif
2017-10-10 06:12:07 -07:00
MAPcurRev = 0 ;
MAPcount = 0 ;
MAPrunningValue = 0 ;
2018-07-26 00:07:31 -07:00
//The following checks the aux inputs and initialises pins if required
auxIsEnabled = false ;
for ( byte AuxinChan = 0 ; AuxinChan < 16 ; AuxinChan + + )
{
2018-09-23 14:50:15 -07:00
currentStatus . current_caninchannel = AuxinChan ;
if ( ( ( configPage9 . caninput_sel [ currentStatus . current_caninchannel ] & 12 ) = = 4 )
& & ( ( configPage9 . enable_secondarySerial = = 1 ) | | ( ( configPage9 . enable_intcan = = 1 ) & & ( configPage9 . intcan_available = = 1 ) ) ) )
{ //if current input channel is enabled as external input in caninput_selxb(bits 2:3) and secondary serial or internal canbus is enabled(and is mcu supported)
//currentStatus.canin[14] = 22; Dev test use only!
auxIsEnabled = true ;
2018-07-26 00:07:31 -07:00
}
2018-09-23 14:50:15 -07:00
else if ( ( ( ( configPage9 . enable_secondarySerial = = 1 ) | | ( ( configPage9 . enable_intcan = = 1 ) & & ( configPage9 . intcan_available = = 1 ) ) ) & & ( configPage9 . caninput_sel [ currentStatus . current_caninchannel ] & 12 ) = = 8 )
2018-12-29 09:26:30 -08:00
| | ( ( ( configPage9 . enable_secondarySerial = = 0 ) & & ( ( configPage9 . enable_intcan = = 1 ) & & ( configPage9 . intcan_available = = 0 ) ) ) & & ( configPage9 . caninput_sel [ currentStatus . current_caninchannel ] & 3 ) = = 2 )
2018-09-23 14:50:15 -07:00
| | ( ( ( configPage9 . enable_secondarySerial = = 0 ) & & ( configPage9 . enable_intcan = = 0 ) ) & & ( ( configPage9 . caninput_sel [ currentStatus . current_caninchannel ] & 3 ) = = 2 ) ) )
{ //if current input channel is enabled as analog local pin check caninput_selxb(bits 2:3) with &12 and caninput_selxa(bits 0:1) with &3
2022-07-10 05:38:42 -07:00
byte pinNumber = pinTranslateAnalog ( configPage9 . Auxinpina [ currentStatus . current_caninchannel ] & 63 ) ;
2018-09-23 15:14:53 -07:00
if ( pinIsUsed ( pinNumber ) )
{
//Do nothing here as the pin is already in use.
2020-08-17 21:51:32 -07:00
BIT_SET ( currentStatus . engineProtectStatus , PROTECT_IO_ERROR ) ; //Tell user that there is problem by lighting up the I/O error indicator
2018-09-23 15:14:53 -07:00
}
else
{
//Channel is active and analog
pinMode ( pinNumber , INPUT ) ;
//currentStatus.canin[14] = 33; Dev test use only!
auxIsEnabled = true ;
}
2018-07-26 00:07:31 -07:00
}
2018-09-23 14:50:15 -07:00
else if ( ( ( ( configPage9 . enable_secondarySerial = = 1 ) | | ( ( configPage9 . enable_intcan = = 1 ) & & ( configPage9 . intcan_available = = 1 ) ) ) & & ( configPage9 . caninput_sel [ currentStatus . current_caninchannel ] & 12 ) = = 12 )
2018-12-29 09:26:30 -08:00
| | ( ( ( configPage9 . enable_secondarySerial = = 0 ) & & ( ( configPage9 . enable_intcan = = 1 ) & & ( configPage9 . intcan_available = = 0 ) ) ) & & ( configPage9 . caninput_sel [ currentStatus . current_caninchannel ] & 3 ) = = 3 )
2018-09-23 14:50:15 -07:00
| | ( ( ( configPage9 . enable_secondarySerial = = 0 ) & & ( configPage9 . enable_intcan = = 0 ) ) & & ( ( configPage9 . caninput_sel [ currentStatus . current_caninchannel ] & 3 ) = = 3 ) ) )
2022-06-26 17:39:14 -07:00
{ //if current input channel is enabled as digital local pin check caninput_selxb(bits 2:3) with &12 and caninput_selxa(bits 0:1) with &3
2022-02-13 16:16:21 -08:00
byte pinNumber = ( configPage9 . Auxinpinb [ currentStatus . current_caninchannel ] & 63 ) + 1 ;
2018-12-29 09:26:30 -08:00
if ( pinIsUsed ( pinNumber ) )
{
//Do nothing here as the pin is already in use.
2020-08-17 21:51:32 -07:00
BIT_SET ( currentStatus . engineProtectStatus , PROTECT_IO_ERROR ) ; //Tell user that there is problem by lighting up the I/O error indicator
2018-12-29 09:26:30 -08:00
}
else
{
//Channel is active and digital
pinMode ( pinNumber , INPUT ) ;
//currentStatus.canin[14] = 44; Dev test use only!
auxIsEnabled = true ;
}
2018-07-26 00:07:31 -07:00
}
2018-12-29 09:26:30 -08:00
} //For loop iterating through aux in lines
2023-12-04 22:35:45 -08:00
2018-12-29 09:26:30 -08:00
//Sanity checks to ensure none of the filter values are set above 240 (Which would include the 255 value which is the default on a new arduino)
//If an invalid value is detected, it's reset to the default the value and burned to EEPROM.
//Each sensor has it's own default value
2021-12-21 12:56:55 -08:00
if ( configPage4 . ADCFILTER_TPS > 240 ) { configPage4 . ADCFILTER_TPS = ADCFILTER_TPS_DEFAULT ; writeConfig ( ignSetPage ) ; }
if ( configPage4 . ADCFILTER_CLT > 240 ) { configPage4 . ADCFILTER_CLT = ADCFILTER_CLT_DEFAULT ; writeConfig ( ignSetPage ) ; }
if ( configPage4 . ADCFILTER_IAT > 240 ) { configPage4 . ADCFILTER_IAT = ADCFILTER_IAT_DEFAULT ; writeConfig ( ignSetPage ) ; }
if ( configPage4 . ADCFILTER_O2 > 240 ) { configPage4 . ADCFILTER_O2 = ADCFILTER_O2_DEFAULT ; writeConfig ( ignSetPage ) ; }
if ( configPage4 . ADCFILTER_BAT > 240 ) { configPage4 . ADCFILTER_BAT = ADCFILTER_BAT_DEFAULT ; writeConfig ( ignSetPage ) ; }
if ( configPage4 . ADCFILTER_MAP > 240 ) { configPage4 . ADCFILTER_MAP = ADCFILTER_MAP_DEFAULT ; writeConfig ( ignSetPage ) ; }
if ( configPage4 . ADCFILTER_BARO > 240 ) { configPage4 . ADCFILTER_BARO = ADCFILTER_BARO_DEFAULT ; writeConfig ( ignSetPage ) ; }
if ( configPage4 . FILTER_FLEX > 240 ) { configPage4 . FILTER_FLEX = FILTER_FLEX_DEFAULT ; writeConfig ( ignSetPage ) ; }
2021-07-16 16:42:58 -07:00
flexStartTime = micros ( ) ;
2018-12-29 09:26:30 -08:00
2021-09-14 04:45:44 -07:00
vssIndex = 0 ;
2016-11-17 17:57:11 -08:00
}
2022-11-05 15:43:29 -07:00
static inline void validateMAP ( void )
2020-05-21 22:26:20 -07:00
{
//Error checks
if ( currentStatus . MAP < VALID_MAP_MIN )
{
currentStatus . MAP = ERR_DEFAULT_MAP_LOW ;
mapErrorCount + = 1 ;
setError ( ERR_MAP_LOW ) ;
}
else if ( currentStatus . MAP > VALID_MAP_MAX )
{
currentStatus . MAP = ERR_DEFAULT_MAP_HIGH ;
mapErrorCount + = 1 ;
setError ( ERR_MAP_HIGH ) ;
}
else
{
if ( errorCount > 0 )
{
clearError ( ERR_MAP_HIGH ) ;
clearError ( ERR_MAP_LOW ) ;
}
mapErrorCount = 0 ;
}
}
2023-10-06 00:10:20 -07:00
void instanteneousMAPReading ( void )
2016-03-08 21:40:11 -08:00
{
2019-05-21 14:47:09 -07:00
//Update the calculation times and last value. These are used by the MAP based Accel enrich
MAPlast = currentStatus . MAP ;
MAPlast_time = MAP_time ;
MAP_time = micros ( ) ;
2017-07-02 18:52:27 -07:00
unsigned int tempReading ;
2016-03-08 21:40:11 -08:00
//Instantaneous MAP readings
2017-06-28 21:34:47 -07:00
# if defined(ANALOG_ISR_MAP)
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
2017-06-28 21:34:47 -07:00
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-07-29 21:25:07 -07:00
//During startup a call is made here to get the baro reading. In this case, we can't apply the ADC filter
2023-12-05 19:47:13 -08:00
if ( currentStatus . initialisationComplete = = true ) { currentStatus . mapADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_MAP , currentStatus . mapADC ) ; } //Very weak filter
2017-07-29 21:25:07 -07:00
else { currentStatus . mapADC = tempReading ; } //Baro reading (No filter)
2017-04-20 23:33:24 -07:00
2018-01-23 17:05:50 -08:00
currentStatus . MAP = fastMap10Bit ( currentStatus . mapADC , configPage2 . mapMin , configPage2 . mapMax ) ; //Get the current MAP value
2017-07-26 19:47:59 -07:00
if ( currentStatus . MAP < 0 ) { currentStatus . MAP = 0 ; } //Sanity check
2021-07-03 18:26:57 -07:00
//Repeat for EMAP if it's enabled
if ( configPage6 . useEMAP = = true )
{
2023-12-04 22:35:45 -08:00
# if defined(ANALOG_ISR_MAP)
tempReading = AnChannel [ pinEMAP - A0 ] ;
# else
tempReading = analogRead ( pinEMAP ) ;
tempReading = analogRead ( pinEMAP ) ;
# endif
2021-07-03 18:26:57 -07:00
//Error check
if ( ( tempReading < VALID_MAP_MAX ) & & ( tempReading > VALID_MAP_MIN ) )
{
currentStatus . EMAPADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_MAP , currentStatus . EMAPADC ) ;
}
else { mapErrorCount + = 1 ; }
currentStatus . EMAP = fastMap10Bit ( currentStatus . EMAPADC , configPage2 . EMAPMin , configPage2 . EMAPMax ) ;
if ( currentStatus . EMAP < 0 ) { currentStatus . EMAP = 0 ; } //Sanity check
}
2017-04-20 23:33:24 -07:00
2016-03-08 21:40:11 -08:00
}
2023-10-06 00:10:20 -07:00
void readMAP ( void )
2016-03-08 21:40:11 -08:00
{
2017-07-02 18:52:27 -07:00
unsigned int tempReading ;
2016-06-10 05:38:05 -07:00
//MAP Sampling system
2018-01-23 17:05:50 -08:00
switch ( configPage2 . mapSample )
2016-06-10 05:38:05 -07:00
{
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
2022-04-17 21:12:57 -07:00
if ( ( currentStatus . RPMdiv100 > configPage2 . mapSwitchPoint ) & & ( ( currentStatus . hasSync = = true ) | | BIT_CHECK ( currentStatus . status3 , BIT_STATUS3_HALFSYNC ) ) & & ( currentStatus . startRevolutions > 1 ) ) //If the engine isn't running and RPM below switch point, fall back to instantaneous reads
2016-06-10 05:38:05 -07:00
{
2019-08-20 22:20:29 -07:00
if ( ( MAPcurRev = = currentStatus . startRevolutions ) | | ( ( MAPcurRev + 1 ) = = currentStatus . startRevolutions ) ) //2 revolutions are looked at for 4 stroke. 2 stroke not currently catered for.
2016-03-08 21:40:11 -08:00
{
2017-06-28 21:34:47 -07:00
# if defined(ANALOG_ISR_MAP)
tempReading = AnChannel [ pinMAP - A0 ] ;
# else
tempReading = analogRead ( pinMAP ) ;
tempReading = analogRead ( pinMAP ) ;
# endif
//Error check
if ( ( tempReading < VALID_MAP_MAX ) & & ( tempReading > VALID_MAP_MIN ) )
{
2018-12-29 09:26:30 -08:00
currentStatus . mapADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_MAP , currentStatus . mapADC ) ;
2017-08-20 18:50:50 -07:00
MAPrunningValue + = currentStatus . mapADC ; //Add the current reading onto the total
2017-06-28 21:34:47 -07:00
MAPcount + + ;
}
else { mapErrorCount + = 1 ; }
2018-04-24 04:31:52 -07:00
//Repeat for EMAP if it's enabled
if ( configPage6 . useEMAP = = true )
{
2023-11-30 19:56:14 -08:00
# if defined(ANALOG_ISR_MAP)
tempReading = AnChannel [ pinEMAP - A0 ] ;
# else
tempReading = analogRead ( pinEMAP ) ;
tempReading = analogRead ( pinEMAP ) ;
# endif
2018-04-24 04:31:52 -07:00
//Error check
if ( ( tempReading < VALID_MAP_MAX ) & & ( tempReading > VALID_MAP_MIN ) )
{
2018-12-29 09:26:30 -08:00
currentStatus . EMAPADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_MAP , currentStatus . EMAPADC ) ;
2018-04-24 04:31:52 -07:00
EMAPrunningValue + = currentStatus . EMAPADC ; //Add the current reading onto the total
}
else { mapErrorCount + = 1 ; }
}
2017-06-28 21:34:47 -07:00
}
else
{
2022-04-10 17:49:58 -07:00
//Reaching here means that the last cycle has completed and the MAP value should be calculated
2017-06-28 21:34:47 -07:00
//Sanity check
if ( ( MAPrunningValue ! = 0 ) & & ( MAPcount ! = 0 ) )
{
2019-05-21 14:47:09 -07:00
//Update the calculation times and last value. These are used by the MAP based Accel enrich
MAPlast = currentStatus . MAP ;
MAPlast_time = MAP_time ;
MAP_time = micros ( ) ;
2023-11-05 14:10:08 -08:00
currentStatus . mapADC = udiv_32_16 ( MAPrunningValue , MAPcount ) ;
2018-01-23 17:05:50 -08:00
currentStatus . MAP = fastMap10Bit ( currentStatus . mapADC , configPage2 . mapMin , configPage2 . mapMax ) ; //Get the current MAP value
2020-05-21 22:26:20 -07:00
validateMAP ( ) ;
2018-04-24 04:31:52 -07:00
//If EMAP is enabled, the process is identical to the above
if ( configPage6 . useEMAP = = true )
{
2023-11-05 14:10:08 -08:00
currentStatus . EMAPADC = udiv_32_16 ( EMAPrunningValue , MAPcount ) ; //Note that the MAP count can be reused here as it will always be the same count.
2018-04-24 04:31:52 -07:00
currentStatus . EMAP = fastMap10Bit ( currentStatus . EMAPADC , configPage2 . EMAPMin , configPage2 . EMAPMax ) ;
if ( currentStatus . EMAP < 0 ) { currentStatus . EMAP = 0 ; } //Sanity check
}
2017-06-28 21:34:47 -07:00
}
else { instanteneousMAPReading ( ) ; }
2019-12-21 01:06:54 -08:00
2017-10-11 00:54:42 -07:00
MAPcurRev = currentStatus . startRevolutions ; //Reset the current rev count
MAPrunningValue = 0 ;
2018-04-24 04:31:52 -07:00
EMAPrunningValue = 0 ; //Can reset this even if EMAP not used
2017-10-11 00:54:42 -07:00
MAPcount = 0 ;
2016-03-08 21:40:11 -08:00
}
2016-06-10 05:38:05 -07:00
}
2021-07-18 16:07:44 -07:00
else
{
instanteneousMAPReading ( ) ;
MAPrunningValue = currentStatus . mapADC ; //Keep updating the MAPrunningValue to give it head start when switching to cycle average.
2021-08-09 05:57:55 -07:00
if ( configPage6 . useEMAP = = true )
{
EMAPrunningValue = currentStatus . EMAPADC ;
}
2021-07-18 16:07:44 -07:00
MAPcount = 1 ;
}
2016-06-10 05:38:05 -07:00
break ;
2017-02-08 19:17:20 -08:00
2016-06-10 05:38:05 -07:00
case 2 :
//Minimum reading in a cycle
2021-07-18 16:07:44 -07:00
if ( currentStatus . RPMdiv100 > configPage2 . mapSwitchPoint ) //If the engine isn't running and RPM below switch point, fall back to instantaneous reads
2016-06-10 05:38:05 -07:00
{
2019-08-19 19:02:53 -07:00
if ( ( MAPcurRev = = currentStatus . startRevolutions ) | | ( ( MAPcurRev + 1 ) = = currentStatus . startRevolutions ) ) //2 revolutions are looked at for 4 stroke. 2 stroke not currently catered for.
2016-03-08 21:40:11 -08:00
{
2017-06-28 21:34:47 -07:00
# if defined(ANALOG_ISR_MAP)
tempReading = AnChannel [ pinMAP - A0 ] ;
# else
tempReading = analogRead ( pinMAP ) ;
tempReading = analogRead ( pinMAP ) ;
# endif
//Error check
if ( ( tempReading < VALID_MAP_MAX ) & & ( tempReading > VALID_MAP_MIN ) )
{
if ( ( unsigned long ) tempReading < MAPrunningValue ) { MAPrunningValue = ( unsigned long ) tempReading ; } //Check whether the current reading is lower than the running minimum
}
else { mapErrorCount + = 1 ; }
}
else
{
2022-04-10 17:49:58 -07:00
//Reaching here means that the last cycle has completed and the MAP value should be calculated
2019-05-21 14:47:09 -07:00
//Update the calculation times and last value. These are used by the MAP based Accel enrich
MAPlast = currentStatus . MAP ;
MAPlast_time = MAP_time ;
MAP_time = micros ( ) ;
2017-06-28 21:34:47 -07:00
currentStatus . mapADC = MAPrunningValue ;
2018-01-23 17:05:50 -08:00
currentStatus . MAP = fastMap10Bit ( currentStatus . mapADC , configPage2 . mapMin , configPage2 . mapMax ) ; //Get the current MAP value
2017-06-28 21:34:47 -07:00
MAPcurRev = currentStatus . startRevolutions ; //Reset the current rev count
MAPrunningValue = 1023 ; //Reset the latest value so the next reading will always be lower
2020-05-21 22:26:20 -07:00
validateMAP ( ) ;
2016-03-08 21:40:11 -08:00
}
2016-06-10 05:38:05 -07:00
}
2021-07-18 16:07:44 -07:00
else
{
instanteneousMAPReading ( ) ;
MAPrunningValue = currentStatus . mapADC ; //Keep updating the MAPrunningValue to give it head start when switching to cycle minimum.
}
2016-06-10 05:38:05 -07:00
break ;
2017-06-28 21:34:47 -07:00
2019-11-13 22:40:25 -08:00
case 3 :
//Average of an ignition event
2022-04-17 21:12:57 -07:00
if ( ( currentStatus . RPMdiv100 > configPage2 . mapSwitchPoint ) & & ( ( currentStatus . hasSync = = true ) | | BIT_CHECK ( currentStatus . status3 , BIT_STATUS3_HALFSYNC ) ) & & ( currentStatus . startRevolutions > 1 ) & & ( ! currentStatus . engineProtectStatus ) ) //If the engine isn't running, fall back to instantaneous reads
2019-11-13 22:40:25 -08:00
{
if ( ( MAPcurRev = = ignitionCount ) ) //Watch for a change in the ignition counter to determine whether we're still on the same event
{
# if defined(ANALOG_ISR_MAP)
tempReading = AnChannel [ pinMAP - A0 ] ;
# else
tempReading = analogRead ( pinMAP ) ;
tempReading = analogRead ( pinMAP ) ;
# endif
//Error check
if ( ( tempReading < VALID_MAP_MAX ) & & ( tempReading > VALID_MAP_MIN ) )
{
currentStatus . mapADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_MAP , currentStatus . mapADC ) ;
MAPrunningValue + = currentStatus . mapADC ; //Add the current reading onto the total
MAPcount + + ;
}
else { mapErrorCount + = 1 ; }
}
else
{
2022-04-10 17:49:58 -07:00
//Reaching here means that the next ignition event has occurred and the MAP value should be calculated
2019-11-13 22:40:25 -08:00
//Sanity check
if ( ( MAPrunningValue ! = 0 ) & & ( MAPcount ! = 0 ) & & ( MAPcurRev < ignitionCount ) )
{
//Update the calculation times and last value. These are used by the MAP based Accel enrich
MAPlast = currentStatus . MAP ;
MAPlast_time = MAP_time ;
MAP_time = micros ( ) ;
2023-11-05 14:10:08 -08:00
currentStatus . mapADC = udiv_32_16 ( MAPrunningValue , MAPcount ) ;
2019-11-13 22:40:25 -08:00
currentStatus . MAP = fastMap10Bit ( currentStatus . mapADC , configPage2 . mapMin , configPage2 . mapMax ) ; //Get the current MAP value
2020-05-21 22:26:20 -07:00
validateMAP ( ) ;
2019-11-13 22:40:25 -08:00
}
else { instanteneousMAPReading ( ) ; }
2019-12-21 01:06:54 -08:00
2019-11-13 22:40:25 -08:00
MAPcurRev = ignitionCount ; //Reset the current event count
MAPrunningValue = 0 ;
MAPcount = 0 ;
}
}
2021-07-18 16:07:44 -07:00
else
{
instanteneousMAPReading ( ) ;
MAPrunningValue = currentStatus . mapADC ; //Keep updating the MAPrunningValue to give it head start when switching to ignition event average.
MAPcount = 1 ;
}
2019-12-14 14:57:22 -08:00
break ;
2019-11-13 22:40:25 -08:00
2017-06-28 21:34:47 -07:00
default :
//Instantaneous MAP readings (Just in case)
instanteneousMAPReading ( ) ;
break ;
2016-06-10 05:38:05 -07:00
}
2016-03-08 21:40:11 -08:00
}
2020-04-01 16:42:26 -07:00
void readTPS ( bool useFilter )
2016-03-23 04:09:04 -07:00
{
2022-05-24 18:02:55 -07:00
currentStatus . TPSlast = currentStatus . TPS ;
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
2020-04-01 16:42:26 -07:00
//The use of the filter can be overridden if required. This is used on startup to disable priming pulse if flood clear is wanted
if ( useFilter = = true ) { currentStatus . tpsADC = ADC_FILTER ( tempTPS , configPage4 . ADCFILTER_TPS , currentStatus . tpsADC ) ; }
else { currentStatus . tpsADC = tempTPS ; }
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
2018-06-16 19:20:09 -07:00
if ( configPage2 . tpsMax > configPage2 . tpsMin )
{
//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 < configPage2 . tpsMin ) { tempADC = configPage2 . tpsMin ; }
else if ( currentStatus . tpsADC > configPage2 . tpsMax ) { tempADC = configPage2 . tpsMax ; }
2022-01-01 00:30:21 -08:00
currentStatus . TPS = map ( tempADC , configPage2 . tpsMin , configPage2 . tpsMax , 0 , 200 ) ; //Take the raw TPS ADC value and convert it into a TPS% based on the calibrated values
2018-06-16 19:20:09 -07:00
}
else
{
//This case occurs when the TPS +5v and gnd are wired backwards, but the user wishes to retain this configuration.
//In such a case, tpsMin will be greater then tpsMax and hence checks and mapping needs to be reversed
tempADC = 255 - currentStatus . tpsADC ; //Reverse the ADC values
2020-06-25 21:55:45 -07:00
uint16_t tempTPSMax = 255 - configPage2 . tpsMax ;
uint16_t tempTPSMin = 255 - configPage2 . tpsMin ;
2018-06-16 19:20:09 -07:00
//All checks below are reversed from the standard case above
2020-06-25 21:55:45 -07:00
if ( tempADC > tempTPSMax ) { tempADC = tempTPSMax ; }
else if ( tempADC < tempTPSMin ) { tempADC = tempTPSMin ; }
2022-01-01 00:30:21 -08:00
currentStatus . TPS = map ( tempADC , tempTPSMin , tempTPSMax , 0 , 200 ) ;
2018-06-16 19:20:09 -07:00
}
2019-11-07 21:40:53 -08:00
//Check whether the closed throttle position sensor is active
if ( configPage2 . CTPSEnabled = = true )
{
if ( configPage2 . CTPSPolarity = = 0 ) { currentStatus . CTPSActive = ! digitalRead ( pinCTPS ) ; } //Normal mode (ground switched)
else { currentStatus . CTPSActive = digitalRead ( pinCTPS ) ; } //Inverted mode (5v activates closed throttle position sensor)
}
else { currentStatus . CTPSActive = 0 ; }
2016-03-23 04:09:04 -07:00
}
2019-04-16 00:33:56 -07:00
void readCLT ( bool useFilter )
2016-03-23 04:09:04 -07:00
{
2017-07-02 18:52:27 -07:00
unsigned int tempReading ;
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2023-11-30 19:56:14 -08:00
tempReading = AnChannel [ pinCLT - A0 ] ; //Get the current raw CLT value
2016-11-06 05:31:18 -08:00
# else
tempReading = analogRead ( pinCLT ) ;
2020-08-07 02:32:31 -07:00
tempReading = analogRead ( pinCLT ) ;
//tempReading = fastMap1023toX(analogRead(pinCLT), 511); //Get the current raw CLT value
2016-11-06 05:31:18 -08:00
# endif
2019-04-16 00:33:56 -07:00
//The use of the filter can be overridden if required. This is used on startup so there can be an immediately accurate coolant value for priming
if ( useFilter = = true ) { currentStatus . cltADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_CLT , currentStatus . cltADC ) ; }
else { currentStatus . cltADC = tempReading ; }
2020-08-10 19:07:12 -07:00
currentStatus . coolant = table2D_getValue ( & 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
}
2022-11-05 15:43:29 -07:00
void readIAT ( void )
2016-03-23 04:09:04 -07:00
{
2017-07-02 18:52:27 -07:00
unsigned int tempReading ;
2017-02-08 19:17:20 -08:00
# if defined(ANALOG_ISR)
2023-11-30 19:56:14 -08:00
tempReading = AnChannel [ pinIAT - A0 ] ; //Get the current raw IAT value
2016-11-06 05:31:18 -08:00
# else
tempReading = analogRead ( pinIAT ) ;
2020-08-07 02:32:31 -07:00
tempReading = analogRead ( pinIAT ) ;
2016-11-06 05:31:18 -08:00
# endif
2018-12-29 09:26:30 -08:00
currentStatus . iatADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_IAT , currentStatus . iatADC ) ;
2020-08-10 19:07:12 -07:00
currentStatus . IAT = table2D_getValue ( & iatCalibrationTable , currentStatus . iatADC ) - CALIBRATION_TEMPERATURE_OFFSET ;
2016-03-23 04:09:04 -07:00
}
2022-11-05 15:43:29 -07:00
void readBaro ( void )
2017-07-17 00:06:14 -07:00
{
2018-01-23 17:05:50 -08:00
if ( configPage6 . useExtBaro ! = 0 )
2017-07-17 00:06:14 -07:00
{
int tempReading ;
// readings
# if defined(ANALOG_ISR_MAP)
tempReading = AnChannel [ pinBaro - A0 ] ;
# else
tempReading = analogRead ( pinBaro ) ;
tempReading = analogRead ( pinBaro ) ;
# endif
2023-12-05 19:47:13 -08:00
if ( currentStatus . initialisationComplete = = true ) { currentStatus . baroADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_BARO , currentStatus . baroADC ) ; } //Very weak filter
2021-11-14 20:47:55 -08:00
else { currentStatus . baroADC = tempReading ; } //Baro reading (No filter)
2017-07-17 00:06:14 -07:00
2018-01-23 17:05:50 -08:00
currentStatus . baro = fastMap10Bit ( currentStatus . baroADC , configPage2 . baroMin , configPage2 . baroMax ) ; //Get the current MAP value
2017-07-17 00:06:14 -07:00
}
2021-11-14 20:47:55 -08:00
else
{
/*
* If no dedicated baro sensor is available , attempt to get a reading from the MAP sensor . This can only be done if the engine is not running .
* 1. Verify that the engine is not running
* 2. Verify that the reading from the MAP sensor is within the possible physical limits
*/
//Attempt to use the last known good baro reading from EEPROM as a starting point
byte lastBaro = readLastBaro ( ) ;
if ( ( lastBaro > = BARO_MIN ) & & ( lastBaro < = BARO_MAX ) ) //Make sure it's not invalid (Possible on first run etc)
{ currentStatus . baro = lastBaro ; } //last baro correction
else { currentStatus . baro = 100 ; } //Fall back position.
//Verify the engine isn't running by confirming RPM is 0 and it has been at least 1 second since the last tooth was detected
unsigned long timeToLastTooth = ( micros ( ) - toothLastToothTime ) ;
2023-11-05 14:10:08 -08:00
if ( ( currentStatus . RPM = = 0 ) & & ( timeToLastTooth > MICROS_PER_SEC ) )
2021-11-14 20:47:55 -08:00
{
instanteneousMAPReading ( ) ; //Get the current MAP value
/*
* The highest sea - level pressure on Earth occurs in Siberia , where the Siberian High often attains a sea - level pressure above 105 kPa ;
* with record highs close to 108.5 kPa .
2021-11-18 16:07:38 -08:00
* The lowest possible baro reading is based on an altitude of 3500 m above sea level .
2021-11-14 20:47:55 -08:00
*/
2021-11-18 16:07:38 -08:00
if ( ( currentStatus . MAP > = BARO_MIN ) & & ( currentStatus . MAP < = BARO_MAX ) ) //Safety check to ensure the baro reading is within the physical limits
2021-11-14 20:47:55 -08:00
{
currentStatus . baro = currentStatus . MAP ;
storeLastBaro ( currentStatus . baro ) ;
}
}
}
2017-07-17 00:06:14 -07:00
}
2022-11-05 15:43:29 -07:00
void readO2 ( void )
2016-03-23 04:09:04 -07:00
{
2019-06-05 01:22:19 -07:00
//An O2 read is only performed if an O2 sensor type is selected. This is to prevent potentially dangerous use of the O2 readings prior to proper setup/calibration
if ( configPage6 . egoType > 0 )
{
unsigned int tempReading ;
# if defined(ANALOG_ISR)
2023-11-30 19:56:14 -08:00
tempReading = AnChannel [ pinO2 - A0 ] ; //Get the current O2 value.
2019-06-05 01:22:19 -07:00
# else
tempReading = analogRead ( pinO2 ) ;
2020-08-10 19:07:12 -07:00
tempReading = analogRead ( pinO2 ) ;
//tempReading = fastMap1023toX(analogRead(pinO2), 511); //Get the current O2 value.
2019-06-05 01:22:19 -07:00
# endif
currentStatus . O2ADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_O2 , currentStatus . O2ADC ) ;
2020-08-10 19:07:12 -07:00
//currentStatus.O2 = o2CalibrationTable[currentStatus.O2ADC];
currentStatus . O2 = table2D_getValue ( & o2CalibrationTable , currentStatus . O2ADC ) ;
2019-06-05 01:22:19 -07:00
}
else
{
currentStatus . O2ADC = 0 ;
currentStatus . O2 = 0 ;
}
2016-03-23 04:09:04 -07:00
}
2017-02-08 19:17:20 -08:00
2022-11-05 15:43:29 -07:00
void readO2_2 ( void )
2018-04-05 14:11:58 -07:00
{
2017-06-28 21:34:47 -07:00
//Second O2 currently disabled as its not being used
//Get the current O2 value.
2018-04-05 14:11:58 -07:00
unsigned int tempReading ;
# if defined(ANALOG_ISR)
2023-11-30 19:56:14 -08:00
tempReading = AnChannel [ pinO2_2 - A0 ] ; //Get the current O2 value.
2018-04-05 14:11:58 -07:00
# else
tempReading = analogRead ( pinO2_2 ) ;
2020-08-10 19:07:12 -07:00
tempReading = analogRead ( pinO2_2 ) ;
//tempReading = fastMap1023toX(analogRead(pinO2_2), 511); //Get the current O2 value.
2018-04-05 14:11:58 -07:00
# endif
2018-12-29 09:26:30 -08:00
currentStatus . O2_2ADC = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_O2 , currentStatus . O2_2ADC ) ;
2020-08-10 19:07:12 -07:00
currentStatus . O2_2 = table2D_getValue ( & o2CalibrationTable , currentStatus . O2_2ADC ) ;
2018-04-05 14:11:58 -07:00
}
2016-03-23 04:09:04 -07:00
2022-11-05 15:43:29 -07:00
void readBat ( void )
2016-03-23 04:09:04 -07:00
{
2020-07-07 22:29:56 -07:00
int tempReading ;
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
2019-02-28 11:09:11 -08:00
2019-07-08 00:56:02 -07:00
//Apply the offset calibration value to the reading
tempReading + = configPage4 . batVoltCorrect ;
2020-07-07 22:29:56 -07:00
if ( tempReading < 0 ) {
tempReading = 0 ;
} //with negative overflow prevention
2019-07-08 00:56:02 -07:00
2019-02-28 11:09:11 -08:00
//The following is a check for if the voltage has jumped up from under 5.5v to over 7v.
//If this occurs, it's very likely that the system has gone from being powered by USB to being powered from the 12v power source.
2022-04-10 17:49:58 -07:00
//Should that happen, we re-trigger the fuel pump priming and idle homing (If using a stepper)
2019-02-28 11:09:11 -08:00
if ( ( currentStatus . battery10 < 55 ) & & ( tempReading > 70 ) & & ( currentStatus . RPM = = 0 ) )
{
2022-04-10 17:49:58 -07:00
//Re-prime the fuel pump
2019-02-28 11:09:11 -08:00
fpPrimeTime = currentStatus . secl ;
2023-12-05 19:47:13 -08:00
currentStatus . fpPrimed = false ;
2019-02-28 11:09:11 -08:00
FUEL_PUMP_ON ( ) ;
//Redo the stepper homing
if ( ( configPage6 . iacAlgorithm = = IAC_ALGORITHM_STEP_CL ) | | ( configPage6 . iacAlgorithm = = IAC_ALGORITHM_STEP_OL ) )
{
2022-09-13 06:16:31 -07:00
initialiseIdle ( true ) ;
2019-02-28 11:09:11 -08:00
}
}
2018-12-29 09:26:30 -08:00
currentStatus . battery10 = ADC_FILTER ( tempReading , configPage4 . ADCFILTER_BAT , currentStatus . battery10 ) ;
2016-03-23 04:09:04 -07:00
}
2021-09-14 04:45:44 -07:00
/**
* @ brief Returns the VSS pulse gap for a given history point
*
* @ param historyIndex The gap number that is wanted . EG :
* historyIndex = 0 = Latest entry
* historyIndex = 1 = 2 nd entry entry
*/
uint32_t vssGetPulseGap ( byte historyIndex )
2020-04-20 05:57:00 -07:00
{
2021-09-14 04:45:44 -07:00
uint32_t tempGap = 0 ;
2020-05-18 21:44:28 -07:00
noInterrupts ( ) ;
2021-09-14 04:45:44 -07:00
int8_t tempIndex = vssIndex - historyIndex ;
if ( tempIndex < 0 ) { tempIndex + = VSS_SAMPLES ; }
if ( tempIndex > 0 ) { tempGap = vssTimes [ tempIndex ] - vssTimes [ tempIndex - 1 ] ; }
else { tempGap = vssTimes [ 0 ] - vssTimes [ ( VSS_SAMPLES - 1 ) ] ; }
2020-05-18 21:44:28 -07:00
interrupts ( ) ;
2021-09-14 04:45:44 -07:00
return tempGap ;
}
2022-11-05 15:43:29 -07:00
uint16_t getSpeed ( void )
2021-09-14 04:45:44 -07:00
{
uint16_t tempSpeed = 0 ;
2023-05-02 22:23:49 -07:00
// Get VSS from CAN, Serial or Analog by using Aux input channels.
2020-04-23 03:34:31 -07:00
if ( configPage2 . vssMode = = 1 )
{
2023-05-02 22:23:49 -07:00
// Direct reading from Aux channel
if ( configPage2 . vssPulsesPerKm = = 0 )
{
tempSpeed = currentStatus . canin [ configPage2 . vssAuxCh ] ;
}
// Adjust the reading by dividing it by set amount.
else
{
tempSpeed = ( currentStatus . canin [ configPage2 . vssAuxCh ] / configPage2 . vssPulsesPerKm ) ;
}
tempSpeed = ADC_FILTER ( tempSpeed , configPage2 . vssSmoothing , currentStatus . vss ) ; //Apply speed smoothing factor
2020-04-23 03:34:31 -07:00
}
2021-06-21 22:30:52 -07:00
// Interrupt driven mode
2020-04-23 03:34:31 -07:00
else if ( configPage2 . vssMode > 1 )
2020-04-20 05:57:00 -07:00
{
2021-09-14 04:45:44 -07:00
uint32_t pulseTime = 0 ;
uint32_t vssTotalTime = 0 ;
2020-08-07 02:32:31 -07:00
2021-09-14 04:45:44 -07:00
//Add up the time between the teeth. Note that the total number of gaps is equal to the number of samples minus 1
for ( byte x = 0 ; x < ( VSS_SAMPLES - 1 ) ; x + + )
2020-08-09 15:54:53 -07:00
{
2021-09-14 04:45:44 -07:00
vssTotalTime + = vssGetPulseGap ( x ) ;
2020-08-09 15:54:53 -07:00
}
2021-09-14 04:45:44 -07:00
pulseTime = vssTotalTime / ( VSS_SAMPLES - 1 ) ;
2023-11-05 14:10:08 -08:00
if ( ( micros ( ) - vssTimes [ vssIndex ] ) > MICROS_PER_SEC ) { tempSpeed = 0 ; } // Check that the car hasn't come to a stop. Is true if last pulse was more than 1 second ago
2022-02-04 14:26:40 -08:00
else
2023-05-17 18:02:06 -07:00
{
2023-11-05 14:10:08 -08:00
tempSpeed = MICROS_PER_HOUR / ( pulseTime * configPage2 . vssPulsesPerKm ) ; //Convert the pulse gap into km/h
2023-05-17 18:02:06 -07:00
tempSpeed = ADC_FILTER ( tempSpeed , configPage2 . vssSmoothing , currentStatus . vss ) ; //Apply speed smoothing factor
}
2021-09-14 04:45:44 -07:00
if ( tempSpeed > 1000 ) { tempSpeed = currentStatus . vss ; } //Safety check. This usually occurs when there is a hardware issue
2020-04-20 05:57:00 -07:00
}
return tempSpeed ;
}
2022-11-05 15:43:29 -07:00
byte getGear ( void )
2020-04-20 05:57:00 -07:00
{
byte tempGear = 0 ; //Unknown gear
if ( currentStatus . vss > 0 )
{
2020-05-18 21:44:28 -07:00
//If the speed is non-zero, default to the last calculated gear
tempGear = currentStatus . gear ;
2023-11-05 14:10:08 -08:00
uint16_t pulsesPer1000rpm = udiv_32_16 ( currentStatus . vss * 10000UL , currentStatus . RPM ) ; //Gives the current pulses per 1000RPM, multiplied by 10 (10x is the multiplication factor for the ratios in TS)
2020-04-20 05:57:00 -07:00
//Begin gear detection
if ( ( pulsesPer1000rpm > ( configPage2 . vssRatio1 - VSS_GEAR_HYSTERESIS ) ) & & ( pulsesPer1000rpm < ( configPage2 . vssRatio1 + VSS_GEAR_HYSTERESIS ) ) ) { tempGear = 1 ; }
else if ( ( pulsesPer1000rpm > ( configPage2 . vssRatio2 - VSS_GEAR_HYSTERESIS ) ) & & ( pulsesPer1000rpm < ( configPage2 . vssRatio2 + VSS_GEAR_HYSTERESIS ) ) ) { tempGear = 2 ; }
else if ( ( pulsesPer1000rpm > ( configPage2 . vssRatio3 - VSS_GEAR_HYSTERESIS ) ) & & ( pulsesPer1000rpm < ( configPage2 . vssRatio3 + VSS_GEAR_HYSTERESIS ) ) ) { tempGear = 3 ; }
else if ( ( pulsesPer1000rpm > ( configPage2 . vssRatio4 - VSS_GEAR_HYSTERESIS ) ) & & ( pulsesPer1000rpm < ( configPage2 . vssRatio4 + VSS_GEAR_HYSTERESIS ) ) ) { tempGear = 4 ; }
else if ( ( pulsesPer1000rpm > ( configPage2 . vssRatio5 - VSS_GEAR_HYSTERESIS ) ) & & ( pulsesPer1000rpm < ( configPage2 . vssRatio5 + VSS_GEAR_HYSTERESIS ) ) ) { tempGear = 5 ; }
else if ( ( pulsesPer1000rpm > ( configPage2 . vssRatio6 - VSS_GEAR_HYSTERESIS ) ) & & ( pulsesPer1000rpm < ( configPage2 . vssRatio6 + VSS_GEAR_HYSTERESIS ) ) ) { tempGear = 6 ; }
}
return tempGear ;
}
2022-11-05 15:43:29 -07:00
byte getFuelPressure ( void )
2020-05-28 19:21:28 -07:00
{
2020-08-17 15:54:21 -07:00
int16_t tempFuelPressure = 0 ;
2020-05-28 19:21:28 -07:00
uint16_t tempReading ;
2020-08-07 02:32:31 -07:00
if ( configPage10 . fuelPressureEnable > 0 )
2020-06-05 21:27:46 -07:00
{
//Perform ADC read
2023-11-30 19:56:14 -08:00
# if defined(ANALOG_ISR)
tempReading = AnChannel [ pinFuelPressure - A0 ] ;
# else
tempReading = analogRead ( pinFuelPressure ) ;
tempReading = analogRead ( pinFuelPressure ) ;
# endif
2020-06-05 21:27:46 -07:00
tempFuelPressure = fastMap10Bit ( tempReading , configPage10 . fuelPressureMin , configPage10 . fuelPressureMax ) ;
2021-12-21 12:56:55 -08:00
tempFuelPressure = ADC_FILTER ( tempFuelPressure , ADCFILTER_PSI_DEFAULT , currentStatus . fuelPressure ) ; //Apply smoothing factor
2020-06-05 21:27:46 -07:00
//Sanity checks
if ( tempFuelPressure > configPage10 . fuelPressureMax ) { tempFuelPressure = configPage10 . fuelPressureMax ; }
2020-08-17 15:54:21 -07:00
if ( tempFuelPressure < 0 ) { tempFuelPressure = 0 ; } //prevent negative values, which will cause problems later when the values aren't signed.
2020-06-05 21:27:46 -07:00
}
2020-05-28 19:21:28 -07:00
return ( byte ) tempFuelPressure ;
}
2022-11-05 15:43:29 -07:00
byte getOilPressure ( void )
2020-06-05 17:55:34 -07:00
{
2020-08-17 15:54:21 -07:00
int16_t tempOilPressure = 0 ;
2020-06-05 17:55:34 -07:00
uint16_t tempReading ;
2020-08-07 02:32:31 -07:00
if ( configPage10 . oilPressureEnable > 0 )
2020-06-05 21:27:46 -07:00
{
//Perform ADC read
2023-11-30 19:56:14 -08:00
# if defined(ANALOG_ISR)
tempReading = AnChannel [ pinOilPressure - A0 ] ;
# else
tempReading = analogRead ( pinOilPressure ) ;
tempReading = analogRead ( pinOilPressure ) ;
# endif
2020-06-05 17:55:34 -07:00
2020-06-05 21:27:46 -07:00
tempOilPressure = fastMap10Bit ( tempReading , configPage10 . oilPressureMin , configPage10 . oilPressureMax ) ;
2021-12-21 12:56:55 -08:00
tempOilPressure = ADC_FILTER ( tempOilPressure , ADCFILTER_PSI_DEFAULT , currentStatus . oilPressure ) ; //Apply smoothing factor
2020-08-07 02:32:31 -07:00
//Sanity check
2020-06-05 21:27:46 -07:00
if ( tempOilPressure > configPage10 . oilPressureMax ) { tempOilPressure = configPage10 . oilPressureMax ; }
2020-08-17 15:54:21 -07:00
if ( tempOilPressure < 0 ) { tempOilPressure = 0 ; } //prevent negative values, which will cause problems later when the values aren't signed.
2020-06-05 21:27:46 -07:00
}
2020-06-05 17:55:34 -07:00
return ( byte ) tempOilPressure ;
}
2016-06-24 01:02:53 -07:00
/*
2020-08-17 19:34:56 -07:00
* The interrupt function for reading the flex sensor frequency and pulse width
* flexCounter value is incremented with every pulse and reset back to 0 once per second
2016-06-24 01:02:53 -07:00
*/
2022-11-05 15:43:29 -07:00
void flexPulse ( void )
2018-07-26 00:07:31 -07:00
{
2020-08-17 19:34:56 -07:00
if ( READ_FLEX ( ) = = true )
{
2021-07-16 16:42:58 -07:00
unsigned long tempPW = ( micros ( ) - flexStartTime ) ; //Calculate the pulse width
flexPulseWidth = ADC_FILTER ( tempPW , configPage4 . FILTER_FLEX , flexPulseWidth ) ;
2020-08-17 19:34:56 -07:00
+ + flexCounter ;
}
else
{
flexStartTime = micros ( ) ; //Start pulse width measurement.
}
2018-07-26 00:07:31 -07:00
}
2018-06-29 15:03:56 -07:00
2018-08-13 19:47:15 -07:00
/*
* The interrupt function for pulses from a knock conditioner / controller
*
*/
2022-11-05 15:43:29 -07:00
void knockPulse ( void )
2018-08-13 19:47:15 -07:00
{
2018-12-29 09:26:30 -08:00
//Check if this the start of a knock.
2018-08-13 19:47:15 -07:00
if ( knockCounter = = 0 )
{
2023-11-05 14:10:08 -08:00
//knockAngle = crankAngle + timeToAngleDegPerMicroSec( (micros() - lastCrankAngleCalc) );
2018-12-29 09:26:30 -08:00
knockStartTime = micros ( ) ;
2018-08-13 19:47:15 -07:00
knockCounter = 1 ;
}
else { + + knockCounter ; } //Knock has already started, so just increment the counter for this
}
2020-04-20 05:57:00 -07:00
/**
* @ brief The ISR function for VSS pulses
*
*/
2022-11-05 15:43:29 -07:00
void vssPulse ( void )
2020-04-20 05:57:00 -07:00
{
//TODO: Add basic filtering here
2021-09-14 04:45:44 -07:00
vssIndex + + ;
if ( vssIndex = = VSS_SAMPLES ) { vssIndex = 0 ; }
2020-08-07 02:32:31 -07:00
2021-09-14 04:45:44 -07:00
vssTimes [ vssIndex ] = micros ( ) ;
2020-04-20 05:57:00 -07:00
}
2018-06-29 15:03:56 -07:00
uint16_t readAuxanalog ( uint8_t analogPin )
2018-07-26 00:07:31 -07:00
{
2018-06-29 15:03:56 -07:00
//read the Aux analog value for pin set by analogPin
unsigned int tempReading ;
# if defined(ANALOG_ISR)
2023-12-04 22:35:45 -08:00
tempReading = AnChannel [ analogPin - A0 ] ; //Get the current raw Auxanalog value
2018-06-29 15:03:56 -07:00
# else
tempReading = analogRead ( analogPin ) ;
2018-12-29 14:45:05 -08:00
tempReading = analogRead ( analogPin ) ;
2018-06-29 15:03:56 -07:00
# endif
return tempReading ;
2018-07-26 00:07:31 -07:00
}
2018-06-29 15:03:56 -07:00
uint16_t readAuxdigital ( uint8_t digitalPin )
2018-07-26 00:07:31 -07:00
{
2018-06-29 15:03:56 -07:00
//read the Aux digital value for pin set by digitalPin
unsigned int tempReading ;
tempReading = digitalRead ( digitalPin ) ;
return tempReading ;
2018-07-26 00:07:31 -07:00
}