diff --git a/comms.ino b/comms.ino index ee28c399..23a7d2e5 100644 --- a/comms.ino +++ b/comms.ino @@ -218,7 +218,7 @@ This function returns the current values of a fixed group of variables */ void sendValues(int length) { - byte packetSize = 33; + byte packetSize = 34; byte response[packetSize]; response[0] = currentStatus.secl; //secl is simply a counter that increments each second. Used to track unexpected resets (Which will reset this count to 0) @@ -262,6 +262,7 @@ void sendValues(int length) response[31] = lowByte(currentStatus.rpmDOT); response[32] = highByte(currentStatus.rpmDOT); + response[33] = currentStatus.flex; cli(); Serial.write(response, (size_t)packetSize); sei(); diff --git a/globals.h b/globals.h index a4ba2d07..f1e6f722 100644 --- a/globals.h +++ b/globals.h @@ -125,6 +125,7 @@ struct statuses { byte launchCorrection; //The amount of correction being applied if launch control is active byte afrTarget; byte idleDuty; + byte flex; //Ethanol reading (if enabled). 0 = No ethanol, 100 = pure ethanol. Eg E85 = 85. unsigned long TAEEndTime; //The target end time used whenever TAE is turned on volatile byte squirt; volatile byte spark; @@ -191,7 +192,8 @@ struct config1 { byte mapSample : 2; byte strokes : 1; byte injType : 1; - byte nCylinders : 4; //Number of cylinders + byte nCylinders : 3; //Number of cylinders + byte flexEnabled : 1; //config2 in ini byte cltType1 : 2; @@ -430,6 +432,7 @@ byte pinStepperDir; //Direction pin for the stepper motor driver byte pinStepperStep; //Step pin for the stepper motor driver byte pinLaunch; byte pinIgnBypass; //The pin used for an ignition bypass (Optional) +byte pinFlex; //Pin with the flex sensor attached // global variables // from speeduino.ino extern struct statuses currentStatus; // from speeduino.ino diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 97503b92..fde69ba0 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -158,7 +158,8 @@ page = 2 mapSample = bits, U08, 36, [0:1], "Instantaneous", "Cycle Average", "Cycle Minimum", "INVALID" twoStroke = bits, U08, 36, [2:2], "Four-stroke", "Two-stroke" injType = bits, U08, 36, [3:3], "Port", "Throttle Body" - nCylinders = bits, U08, 36, [4:8], "INVALID","1","2","3","4","INVALID","6","INVALID","8","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID" + nCylinders = bits, U08, 36, [4:6], "INVALID","1","2","3","4","INVALID","6","INVALID","8" + flexEnabled= bits, U08, 36, [7:7], "Off", "On" ; Config2 cltType = bits, U08, 37, [0:1], "GM", "Unknown1", "Unknown2", "Unknown3" @@ -464,6 +465,7 @@ page = 8 requiresPowerCycle = launchPin requiresPowerCycle = launchEnable requiresPowerCycle = launchHiLo +; requiresPowerCycle = flexEnabled defaultValue = pinLayout, 1 defaultValue = TrigPattern, 0 @@ -482,6 +484,7 @@ page = 8 defaultValue = multiplyMAP, 0 defaultValue = includeAFR, 0 defaultValue = stoich, 14.7 + defaultValue = flexEnabled, 0 [Menu] @@ -523,6 +526,7 @@ page = 8 subMenu = accelEnrichments, "&Acceleration Enrichment" subMenu = egoControl, "AFR/O2", 3 subMenu = RevLimiterS, "Rev Limits", 2 + subMenu = flexFueling, "Flex Fuel", 2 subMenu = veTableDialog, "&VE Table", 0 subMenu = sparkTbl, "&Spark Table", 2 subMenu = afrTable1Tbl, "A&FR Table", 5 @@ -661,6 +665,8 @@ page = 8 panel = std_injection, North panel = engine_constants_south, South + dialog = flexFueling, "Flex Fuel" + field = "Flex sensor", flexEnabled dialog = accelEnrichments_center, "" field = "TPSdot Threshold", tpsThresh @@ -1230,7 +1236,7 @@ page = 8 ochGetCommand = "A" - ochBlockSize = 33 + ochBlockSize = 34 secl = scalar, U08, 0, "sec", 1.000, 0.000 squirt = scalar, U08, 1, "bits", 1.000, 0.000 @@ -1285,6 +1291,7 @@ page = 8 sparkUnusedh = bits, U08, 29, [7:7] afr2 = scalar, U08, 30, "O2", 0.100, 0.000 rpmDOT = scalar, S16, 31, "rpm/s", 1.000, 0.000 + flex = scalar, U08, 33, "%", 1.000, 0.000 ; Computed output channels. See "megatuneExamples.ini" for all the ; pre-defined variables, search for "???" and you'll see them. diff --git a/sensors.h b/sensors.h index d8a94cab..5d874152 100644 --- a/sensors.h +++ b/sensors.h @@ -1,3 +1,6 @@ +#ifndef SENSORS_H +#define SENSORS_H + // 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 @@ -6,6 +9,8 @@ #define ADCFILTER_O2 128 #define ADCFILTER_BAT 128 +volatile byte flexCounter = 0; + /* * Simple low pass IIR filter macro for the analog inputs * This is effectively implementing the smooth filter from http://playground.arduino.cc/Main/Smooth @@ -15,3 +20,5 @@ void instanteneousMAPReading(); void readMAP(); + +#endif // SENSORS_H diff --git a/sensors.ino b/sensors.ino index 37c9cb7f..3f784d5d 100644 --- a/sensors.ino +++ b/sensors.ino @@ -137,3 +137,12 @@ void readBat() currentStatus.battery10 = ADC_FILTER(tempReading, ADCFILTER_BAT, currentStatus.battery10); } +/* + * The interrupt function for reading the flex sensor frequency + * This value is incremented with every pulse and reset back to 0 once per second + */ + void flexPulse() + { + ++flexCounter; + } + diff --git a/speeduino.ino b/speeduino.ino index 97fdbbab..3ecbd140 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -87,7 +87,6 @@ byte mapErrorCount = 0; byte iatErrorCount = 0; byte cltErrorCount = 0; - unsigned long counter; unsigned long currentLoopTime; //The time the current loop started (uS) unsigned long previousLoopTime; //The time the previous loop started (uS) @@ -223,6 +222,13 @@ void setup() initialiseFan(); initialiseAuxPWM(); initialiseCorrections(); + + //Check whether the flex sensor is enabled and if so, attach an interupt for it + if(configPage1.flexEnabled) + { + attachInterrupt(digitalPinToInterrupt(pinFlex), flexPulse, RISING); + currentStatus.flex = 0; + } //Once the configs have been loaded, a number of one time calculations can be completed req_fuel_uS = configPage1.reqFuel * 100; //Convert to uS and an int. This is the only variable to be used in calculations diff --git a/timers.ino b/timers.ino index 95cb10af..00fa8dd2 100644 --- a/timers.ino +++ b/timers.ino @@ -12,9 +12,11 @@ Timers are typically low resolution (Compared to Schedulers), with maximum frequ */ #include "timers.h" #include "globals.h" +#include "sensors.h" void initialiseTimers() { +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this //Configure Timer2 for our low-freq interrupt code. TCCR2B = 0x00; //Disbale Timer2 while we set it up TCNT2 = 131; //Preload timer2 with 131 cycles, leaving 125 till overflow. As the timer runs at 125Khz, this causes overflow to occur at 1Khz = 1ms @@ -24,12 +26,17 @@ void initialiseTimers() /* Now configure the prescaler to CPU clock divided by 128 = 125Khz */ TCCR2B |= (1< 150 || flexCounter < 50) + { + //This indicated an error condition. Spec of the sensor is that errors are above 170Hz) + } + else + { + currentStatus.flex = flexCounter - 50; //Standard GM Continental sensor reads from 50Hz (0 ethanol) to 150Hz (Pure ethanol). Subtracting 50 from the frequency therefore gives the ethanol percentage. + flexCounter = 0; + } + + } } - //Reset Timer2 to trigger in another ~1ms +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this + //Reset Timer2 to trigger in another ~1ms TCNT2 = 131; //Preload timer2 with 100 cycles, leaving 156 till overflow. TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag - +#endif } diff --git a/utils.ino b/utils.ino index 31762f53..15f5a56d 100644 --- a/utils.ino +++ b/utils.ino @@ -32,6 +32,7 @@ void setPinMapping(byte boardID) pinCoil3 = 12; //Pin for coil 3 pinCoil4 = 13; //Pin for coil 4 pinTrigger = 2; //The CAS pin + pinTrigger2 = 3; //The CAS pin pinTPS = A0; //TPS input pin pinMAP = A1; //MAP sensor pin pinIAT = A2; //IAT sensor pin @@ -44,6 +45,7 @@ void setPinMapping(byte boardID) pinFan = 47; //Pin for the fan output pinFuelPump = 4; //Fuel pump output pinTachOut = 49; //Tacho output pin + pinFlex = 19; // Flex sensor (Must be external interrupt enabled) break; case 1: //Pin mappings as per the v0.2 shield @@ -71,6 +73,7 @@ void setPinMapping(byte boardID) pinStepperStep = 17; //Step pin for DRV8825 driver pinFan = 47; //Pin for the fan output pinFuelPump = 4; //Fuel pump output + pinFlex = 2; // Flex sensor (Must be external interrupt enabled) break; case 2: //Pin mappings as per the v0.3 shield @@ -99,6 +102,7 @@ void setPinMapping(byte boardID) pinStepperStep = 17; //Step pin for DRV8825 driver pinFan = A13; //Pin for the fan output pinLaunch = 12; //Can be overwritten below + pinFlex = 2; // Flex sensor (Must be external interrupt enabled) break; case 3: @@ -128,6 +132,7 @@ void setPinMapping(byte boardID) pinStepperStep = 17; //Step pin for DRV8825 driver pinFan = 47; //Pin for the fan output (Goes to ULN2803) pinLaunch = 12; //Can be overwritten below + pinFlex = 2; // Flex sensor (Must be external interrupt enabled) break; case 10: @@ -160,6 +165,7 @@ void setPinMapping(byte boardID) pinFuelPump = 42; //Fuel pump output 2n2222 pinFan = 47; //Pin for the fan output pinTachOut = 49; //Tacho output pin + pinFlex = 2; // Flex sensor (Must be external interrupt enabled) break; case 20: @@ -273,8 +279,6 @@ void setPinMapping(byte boardID) pinMode(pinIdle2, OUTPUT); pinMode(pinFuelPump, OUTPUT); pinMode(pinIgnBypass, OUTPUT); - if (configPage3.launchHiLo) { pinMode(pinLaunch, INPUT); } - else { pinMode(pinLaunch, INPUT_PULLUP); } //If launch triggers on LOW signal, then set a pull up as the default inj1_pin_port = portOutputRegister(digitalPinToPort(pinInjector1)); inj1_pin_mask = digitalPinToBitMask(pinInjector1); @@ -305,7 +309,11 @@ void setPinMapping(byte boardID) pinMode(pinTrigger, INPUT); pinMode(pinTrigger2, INPUT); pinMode(pinTrigger3, INPUT); - // + pinMode(pinFlex, INPUT_PULLUP); //Standard GM / Continental flex sensor requires pullup + if (configPage3.launchHiLo) { pinMode(pinLaunch, INPUT); } + else { pinMode(pinLaunch, INPUT_PULLUP); } //If launch triggers on LOW signal, then set a pull up as the default + + //Set default values digitalWrite(pinMAP, HIGH); //digitalWrite(pinO2, LOW); digitalWrite(pinTPS, LOW);