From 9c557ecffef1dae2c870267966514f1dd49f8fd4 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Mon, 13 Jul 2015 14:22:05 +1000 Subject: [PATCH] GM 24X decoder added --- decoders.h | 2 + decoders.ino | 96 +++++++++++++++++++++++++++++++++++++++++ reference/speeduino.ini | 2 +- speeduino.ino | 11 +++++ 4 files changed, 110 insertions(+), 1 deletion(-) diff --git a/decoders.h b/decoders.h index 3dc94fd9..20c98d12 100644 --- a/decoders.h +++ b/decoders.h @@ -19,6 +19,8 @@ unsigned int triggerFilterTime; // The shortest time (in uS) that pulses will be unsigned int triggerToothAngle; //The number of crank degrees that elapse per tooth unsigned long revolutionTime; //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that) +unsigned int toothAngles[24]; //An array for storing fixed tooth angles. Currently sized at 24 for the GM 24X decoder, but may grow later if there are other decoders that use this style + //Used for identifying long and short pulses on the 4G63 (And possibly other) trigger patterns #define LONG 0; #define SHORT 1; diff --git a/decoders.ino b/decoders.ino index ecb6b32a..d083925f 100644 --- a/decoders.ino +++ b/decoders.ino @@ -320,3 +320,99 @@ int getCrankAngle_4G63(int timePerDegree) return crankAngle; } +/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Name: GM 24X +Desc: TBA +Note: Useful references: +http://www.vems.hu/wiki/index.php?page=MembersPage%2FJorgenKarlsson%2FTwentyFourX +*/ +void triggerSetup_24X() +{ + triggerToothAngle = 180; //The number of degrees that passes from tooth to tooth (primary) + toothAngles[0] = 12; + toothAngles[1] = 18; + toothAngles[2] = 33; + toothAngles[3] = 48; + toothAngles[4] = 63; + toothAngles[5] = 78; + toothAngles[6] = 102; + toothAngles[7] = 108; + toothAngles[8] = 123; + toothAngles[9] = 138; + toothAngles[10] = 162; + toothAngles[11] = 177; + toothAngles[12] = 183; + toothAngles[13] = 198; + toothAngles[14] = 222; + toothAngles[15] = 237; + toothAngles[16] = 252; + toothAngles[17] = 258; + toothAngles[18] = 282; + toothAngles[19] = 288; + toothAngles[20] = 312; + toothAngles[21] = 327; + toothAngles[22] = 342; + toothAngles[23] = 357; + + toothCurrentCount = 25; //We set the initial tooth value to be something that should never be reached. This indicates no sync +} + +void triggerPri_24X() +{ + if(toothCurrentCount == 25) { currentStatus.hasSync = false; return; } //Indicates sync has not been achieved (Still waiting for 1 revolution of the crank to take place) + curTime = micros(); + curGap = curTime - toothLastToothTime; + + if(toothCurrentCount == 0) + { + toothCurrentCount = 1; //Reset the counter + toothOneMinusOneTime = toothOneTime; + toothOneTime = curTime; + currentStatus.hasSync = true; + startRevolutions++; //Counter + } + else + { + toothCurrentCount++; //Increment the tooth counter + } + + //High speed tooth logging history + toothHistory[toothHistoryIndex] = curGap; + if(toothHistoryIndex == 511) + { toothHistoryIndex = 0; } + else + { toothHistoryIndex++; } + + toothLastToothTime = curTime; +} +void triggerSec_24X() +{ + toothCurrentCount = 0; //All we need to do is reset the tooth count back to zero, indicating that we're at the beginning of a new revolution + return; +} + +int getRPM_24X() +{ + noInterrupts(); + revolutionTime = (toothOneTime - toothOneMinusOneTime); //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that) + interrupts(); + return ldiv(US_IN_MINUTE, revolutionTime).quot; //Calc RPM based on last full revolution time (uses ldiv rather than div as US_IN_MINUTE is a long) +} +int getCrankAngle_24X(int timePerDegree) +{ + //This is the current angle ATDC the engine is at. This is the last known position based on what tooth was last 'seen'. It is only accurate to the resolution of the trigger wheel (Eg 36-1 is 10 degrees) + unsigned long tempToothLastToothTime; + int tempToothCurrentCount; + //Grab some variables that are used in the trigger code and assign them to temp variables. + noInterrupts(); + tempToothCurrentCount = toothCurrentCount; + tempToothLastToothTime = toothLastToothTime; + interrupts(); + + int crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage2.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was. + crankAngle += ldiv( (micros() - tempToothLastToothTime), timePerDegree).quot; //Estimate the number of degrees travelled since the last tooth + if (crankAngle > 360) { crankAngle -= 360; } + + return crankAngle; +} + diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 699f91d4..74dc39fb 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -202,7 +202,7 @@ page = 4 TrigSpeed = bits, U08, 5[1:1], "Crank Speed", "Cam Speed" IgInv = bits, U08, 5[2:2], "No", "Yes" oddfire = bits, U08, 5[3:3], "No", "Yes" - TrigPattern= bits, U08, 5[4:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" + TrigPattern= bits, U08, 5[4:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata", "GM 24X", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" IdleAdv = scalar, U08, 6, "Deg", 0.352,-28.4, -10, 80, 0 IdleAdvTPS = scalar, U08, 7, "ADC", 1, 0, 0, 255, 0 IdleAdvRPM = scalar, U08, 8, "RPM", 100, 0, 0, 1200, 0 diff --git a/speeduino.ino b/speeduino.ino index 98e9c0e9..93ef8c51 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -266,6 +266,17 @@ void setup() attachInterrupt(triggerInterrupt2, triggerSec_4G63, CHANGE); break; + case 5: + triggerSetup_24X(); + trigger = triggerPri_24X; + getRPM = getRPM_24X; + getCrankAngle = getCrankAngle_24X; + + if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering) + else { attachInterrupt(triggerInterrupt, trigger, FALLING); } // Primary trigger connects to + attachInterrupt(triggerInterrupt2, triggerSec_24X, CHANGE); + break; + default: trigger = triggerPri_missingTooth; getRPM = getRPM_missingTooth;