Adding functionality for Honda J series crank decoder. (#1202)

Changes have been tested and are running well on a J32.

Co-authored-by: Nick Amuchastegui <nick@watttime.org>
This commit is contained in:
nickamuch 2024-05-28 21:41:51 -07:00 committed by GitHub
parent 951f97f559
commit 40463c51d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 169 additions and 1 deletions

View File

@ -190,6 +190,7 @@
#define trigger_renix = 24
#define trigger_Rover = 25
#define trigger_K6A = 26
#define trigger_HondaJ32 = 27
[Constants]
@ -511,7 +512,7 @@ page = 4
TrigEdge = bits, U08, 5,[0:0], "RISING", "FALLING"
TrigSpeed = bits, U08, 5,[1:1], "Crank Speed", "Cam Speed"
IgInv = bits, U08, 5,[2:2], "Going Low", "Going High"
TrigPattern= bits, U08, 5,[3:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata / 3000GT", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "Subaru 6/7", "Daihatsu +1", "Harley EVO", "36-2-2-2", "36-2-1", "DSM 420a", "Weber-Marelli", "Ford ST170", "DRZ400", "Chrysler NGC", "Yamaha Vmax 1990+", "Renix", "Rover MEMS", "K6A", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
TrigPattern= bits, U08, 5,[3:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata / 3000GT", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "Subaru 6/7", "Daihatsu +1", "Harley EVO", "36-2-2-2", "36-2-1", "DSM 420a", "Weber-Marelli", "Ford ST170", "DRZ400", "Chrysler NGC", "Yamaha Vmax 1990+", "Renix", "Rover MEMS", "K6A", "Honda J32", "INVALID", "INVALID", "INVALID", "INVALID"
TrigEdgeSec= bits, U08, 6,[0:0], "RISING", "FALLING"
fuelPumpPin= bits , U08, 6,[1:6], "Board Default", "INVALID", "INVALID", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "INVALID", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "INVALID"
useResync = bits, U08, 6,[7:7], "No", "Yes"

View File

@ -2223,6 +2223,150 @@ void triggerSetEndTeeth_HondaD17(void)
{
}
/** @} */
/** Honda J 32 (3.2 liter 6 cyl SOHC).
* The Honda J32a4 (and all J series I'm aware of) has a crank trigger with nominal 24 teeth (22 teeth actually present).
* It has one missing tooth, then 7 teeth, then another missing tooth, then 15 teeth.
* The tooth rising edges all have uniform spacing between them, except for teeth 14 and 22, which measure about
* 18 degrees between rising edges, rather than 15 degrees as the other teeth do. These slightly larger
* teeth are immediately before a gap, and the extra 3 degrees is made up for in the gap, the gap being about
* 3 degrees smaller than might be nominally expected, such that the expected rotational angle is restored immediately after
* the gap (missing tooth) passes.
* Teeth are represented as 0V at the ECU, no teeth are represented as 5V.
* Top dead center of cylinder number 1 occurs as we lose sight of (just pass) the first tooth in the string of 15 teeth
* (this is a rising edge).
* The second tooth in the string of 15 teeth is designated as tooth 1 in this code. This means that
* when the interrupt for tooth 1 fires (as we just pass tooth 1), crank angle = 360/24 = 15 degrees.
* It follows that the first tooth in the string of 7 teeth is tooth 16.
* @defgroup dec_honda_j_32 Honda J 32
* @{
*/
void triggerSetup_HondaJ32(void)
{
triggerToothAngle = 360 / 24; //The number of degrees that passes from tooth to tooth
MAX_STALL_TIME = ((MICROS_PER_DEG_1_RPM/10U) * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
BIT_CLEAR(decoderState, BIT_DECODER_HAS_SECONDARY);
// Filter (ignore) triggers that are faster than this.
triggerFilterTime = (MICROS_PER_SEC / (MAX_RPM / 60 * 24));
toothLastToothTime = 0;
toothCurrentCount = 0;
toothOneTime = 0;
toothOneMinusOneTime = 0;
lastGap = 0;
revolutionOne = 0;
}
void triggerPri_HondaJ32(void)
{
// This function is called only on rising edges, which occur as we lose sight of a tooth.
// This function sets the following state variables for use in other functions:
// toothLastToothTime, toothOneTime, revolutionOne (just toggles - not correct)
curTime = micros();
curGap = curTime - toothLastToothTime;
toothLastToothTime = curTime;
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
if (currentStatus.hasSync == true) // We have sync
{
toothCurrentCount++;
if (toothCurrentCount == 25) { // handle rollover. Normal sized tooth here
toothCurrentCount = 1;
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
currentStatus.startRevolutions++;
SetRevolutionTime(toothOneTime - toothOneMinusOneTime);
}
else if (toothCurrentCount == 23 || toothCurrentCount == 15) // This is the first tooth after a missing tooth
{
toothCurrentCount++; // account for missing tooth
if (curGap < (lastGap >> 1) * 3) // This should be a big gap, if we find it's not actually big, we lost sync
{
currentStatus.hasSync = false;
toothCurrentCount=1;
}
}
else if (toothCurrentCount != 14 && toothCurrentCount != 22)
{
// Teeth 14 and 22 are about 18 rather than 15 degrees so don't update last_gap with this unusual spacing
lastGap = curGap;
}
// else toothCurrentCount == 14 or 22. Take no futher action.
}
else // we do not have sync yet. While syncing, treat tooth 14 and 22 as normal teeth
{
if (curGap < (lastGap >> 1) * 3 || lastGap == 0){ // Regular tooth, lastGap == 0 at startup
toothCurrentCount++; // Increment teeth between gaps
lastGap = curGap;
}
else { // First tooth after the missing tooth
if (toothCurrentCount == 15) { // 15 teeth since the gap before this, meaning we just passed the second gap and are synced
currentStatus.hasSync = true;
toothCurrentCount = 16; // This so happens to be the tooth number of the first tooth in the string of 7 (where we are now)
toothOneTime = curTime - (15 * lastGap); // Initialize tooth 1 times based on last gap width.
toothOneMinusOneTime = toothOneTime - (24 * lastGap);
}
else{ // Unclear which gap we just passed. reset counter
toothCurrentCount = 1;
}
}
}
}
// There's currently no compelling reason to implement cam timing on the J32. (Have to do semi-sequential injection, wasted spark, there is no VTC on this engine, just VTEC)
void triggerSec_HondaJ32(void)
{
return;
}
uint16_t getRPM_HondaJ32(void)
{
return RpmFromRevolutionTimeUs(revolutionTime); // revolutionTime set by SetRevolutionTime()
}
int getCrankAngle_HondaJ32(void)
{
// Returns values from 0 to 360.
// Tooth 1 time occurs 360/24 degrees after TDC.
// Teeth 14 and 22 are unusually sized (18 degrees), but the missing tooth is smaller (12 degrees), so this oddity only applies when toothCurrentCount = 14 || 22
int crankAngle;
uint16_t tempToothCurrentCount;
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
lastCrankAngleCalc = micros(); //micros() is no longer interrupt safe
elapsedTime = lastCrankAngleCalc - toothLastToothTime;
interrupts();
if (tempToothCurrentCount == 14)
{
crankAngle = 213; // 13 teeth * 15 degrees/tooth + 18 degrees
}
else if (tempToothCurrentCount == 22)
{
crankAngle = 333; // 21 teeth * 15 degrees/tooth + 18 degrees
}
else
{
crankAngle = triggerToothAngle * tempToothCurrentCount;
}
crankAngle += timeToAngleDegPerMicroSec(elapsedTime) + configPage4.triggerAngle;
if (crankAngle >= 720) { crankAngle -= 720; }
if (crankAngle > CRANK_ANGLE_MAX) { crankAngle -= CRANK_ANGLE_MAX; }
if (crankAngle < 0) { crankAngle += 360; }
return crankAngle;
}
void triggerSetEndTeeth_HondaJ32(void)
{
return;
}
/** @} */
/** Miata '99 to '05 with 4x 70 degree duration teeth running at cam speed.

View File

@ -40,6 +40,7 @@
#define DECODER_RENIX 24
#define DECODER_ROVERMEMS 25
#define DECODER_SUZUKI_K6A 26
#define DECODER_HONDA_J32 27
#define BIT_DECODER_2ND_DERIV 0 //The use of the 2nd derivative calculation is limited to certain decoders. This is set to either true or false in each decoders setup routine
#define BIT_DECODER_IS_SEQUENTIAL 1 //Whether or not the decoder supports sequential operation
@ -134,6 +135,13 @@ uint16_t getRPM_HondaD17(void);
int getCrankAngle_HondaD17(void);
void triggerSetEndTeeth_HondaD17(void);
void triggerSetup_HondaJ32(void);
void triggerPri_HondaJ32(void);
void triggerSec_HondaJ32(void);
uint16_t getRPM_HondaJ32(void);
int getCrankAngle_HondaJ32(void);
void triggerSetEndTeeth_HondaJ32(void);
void triggerSetup_Miata9905(void);
void triggerPri_Miata9905(void);
void triggerSec_Miata9905(void);

View File

@ -3396,6 +3396,21 @@ void initialiseTriggers(void)
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
break;
case DECODER_HONDA_J32:
triggerSetup_HondaJ32();
triggerHandler = triggerPri_HondaJ32;
triggerSecondaryHandler = triggerSec_HondaJ32;
getRPM = getRPM_HondaJ32;
getCrankAngle = getCrankAngle_HondaJ32;
triggerSetEndTeeth = triggerSetEndTeeth_HondaJ32;
primaryTriggerEdge = RISING; // Don't honor the config, always use rising edge
secondaryTriggerEdge = RISING; // Unused
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge); // Suspect this line is not needed
break;
case DECODER_MIATA_9905:
triggerSetup_Miata9905();
triggerHandler = triggerPri_Miata9905;