Seemingly working Nissan 360 decoder (4 and 6 cylinder)

This commit is contained in:
Josh Stewart 2017-03-01 16:17:30 +11:00
parent 4e3760057c
commit 22af95db32
5 changed files with 72 additions and 20 deletions

View File

@ -3,7 +3,8 @@
#include <limits.h>
#define READ_PRI_TRIGGER() (*triggerPri_pin_port & (1 << triggerPri_pin_mask) ? HIGH : LOW)
#define READ_PRI_TRIGGER() ((*triggerPri_pin_port & triggerPri_pin_mask) ? HIGH : LOW)
#define READ_SEC_TRIGGER() ((*triggerSec_pin_port & triggerSec_pin_mask) ? HIGH : LOW)
static inline void addToothLogEntry(unsigned long);
static inline int stdGetRPM();
@ -42,7 +43,7 @@ volatile unsigned int toothHistory[TOOTH_LOG_BUFFER];
volatile unsigned int toothHistoryIndex = 0;
volatile bool toothLogRead = false; //Flag to indicate whether the current tooth log values have been read out yet
volatile byte secondaryToothCount; //Used for identifying the current secondary (Usually cam) tooth for patterns with multiple secondary teeth
volatile unsigned int secondaryToothCount; //Used for identifying the current secondary (Usually cam) tooth for patterns with multiple secondary teeth
volatile unsigned long secondaryLastToothTime = 0; //The time (micros()) that the last tooth was registered (Cam input)
volatile int triggerActualTeeth;

View File

@ -1369,6 +1369,8 @@ void triggerSetup_Nissan360()
secondaryToothCount = 0; //Initially set to 0 prior to calculating the secondary window duration
secondDerivEnabled = false;
decoderIsSequential = true;
toothCurrentCount = 1;
triggerToothAngle = 2;
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
}
@ -1386,7 +1388,13 @@ void triggerPri_Nissan360()
if ( !currentStatus.hasSync ) { return; }
if ( toothCurrentCount == 360 )
if ( toothCurrentCount == 181) //1 complete crank revolution
{
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
currentStatus.startRevolutions++; //2 complete crank revolutions
}
else if ( toothCurrentCount == 361 )
{
toothCurrentCount = 1;
toothOneMinusOneTime = toothOneTime;
@ -1408,7 +1416,7 @@ void triggerSec_Nissan360()
//Calculate number of primary teeth that this window has been active for
if(secondaryToothCount == 0) { secondaryToothCount = toothCurrentCount; return; } //This occurs on the first rotation upon powerup
if(digitalRead(pinTrigger2) == HIGH) { secondaryToothCount = toothCurrentCount; return; } //This represents the start of a secondary window
if(READ_SEC_TRIGGER() == LOW) { secondaryToothCount = toothCurrentCount; return; } //This represents the start of a secondary window
//If we reach here, we are at the end of a secondary window
byte secondaryDuration = toothCurrentCount - secondaryToothCount; //How many primary teeth have passed during the duration of this secondary window
@ -1420,37 +1428,76 @@ void triggerSec_Nissan360()
if(secondaryDuration >= 15 || secondaryDuration <= 17) //Duration of window = 16 primary teeth
{
toothCurrentCount = 16; //End of first window (The longest) occurs 16 teeth after TDC
currentStatus.hasSync == true;
currentStatus.hasSync = true;
}
else if(secondaryDuration >= 11 || secondaryDuration <= 13) //Duration of window = 12 primary teeth
{
toothCurrentCount = 102; //End of second window is after 90+12 primary teeth
currentStatus.hasSync == true;
currentStatus.hasSync = true;
}
else if(secondaryDuration >= 7 || secondaryDuration <= 9) //Duration of window = 8 primary teeth
{
toothCurrentCount = 188; //End of third window is after 90+90+8 primary teeth
currentStatus.hasSync == true;
currentStatus.hasSync = true;
}
else if(secondaryDuration >= 3 || secondaryDuration <= 5) //Duration of window = 4 primary teeth
{
toothCurrentCount = 274; //End of fourth window is after 90+90+90+4 primary teeth
currentStatus.hasSync == true;
currentStatus.hasSync = true;
}
}
else if(configPage1.nCylinders == 6)
{
//I don't have this info yet :(
if(secondaryDuration >= 23 || secondaryDuration <= 25) //Duration of window = 16 primary teeth
{
toothCurrentCount = 24; //End of first window (The longest) occurs 24 teeth after TDC
currentStatus.hasSync = true;
}
else if(secondaryDuration >= 19 || secondaryDuration <= 21) //Duration of window = 12 primary teeth
{
toothCurrentCount = 84; //End of second window is after 60+20 primary teeth
currentStatus.hasSync = true;
}
else if(secondaryDuration >= 15 || secondaryDuration <= 17) //Duration of window = 16 primary teeth
{
toothCurrentCount = 136; //End of third window is after 60+60+16 primary teeth
currentStatus.hasSync = true;
}
else if(secondaryDuration >= 11 || secondaryDuration <= 13) //Duration of window = 12 primary teeth
{
toothCurrentCount = 192; //End of fourth window is after 60+60+60+12 primary teeth
currentStatus.hasSync = true;
}
else if(secondaryDuration >= 7 || secondaryDuration <= 9) //Duration of window = 8 primary teeth
{
toothCurrentCount = 248; //End of fifth window is after 60+60+60+60+8 primary teeth
currentStatus.hasSync = true;
}
else if(secondaryDuration >= 3 || secondaryDuration <= 5) //Duration of window = 4 primary teeth
{
toothCurrentCount = 304; //End of sixth window is after 60+60+60+60+60+4 primary teeth
currentStatus.hasSync = true;
}
}
else { currentStatus.hasSync == false; return ;} //This should really never happen
//else { currentStatus.hasSync = false; return ;} //This should really never happen
}
else
{
//Already have sync, but do a verify every 720 degrees.
//Not sure if this works for 6 cylinder???
if(secondaryDuration >= 15) //Duration of window = 16 primary teeth
if(configPage1.nCylinders == 4)
{
toothCurrentCount = 16; //End of first window (The longest) occurs 16 teeth after TDC
if(secondaryDuration >= 15) //Duration of window = 16 primary teeth
{
toothCurrentCount = 16; //End of first window (The longest) occurs 16 teeth after TDC
}
}
else if(configPage1.nCylinders == 6)
{
if(secondaryDuration >= 23) //Duration of window = 24 primary teeth
{
toothCurrentCount = 24; //End of first window (The longest) occurs 24 teeth after TDC
}
}
}
@ -1458,19 +1505,18 @@ void triggerSec_Nissan360()
int getRPM_Nissan360()
{
if( !currentStatus.hasSync) { return 0; }
//if(currentStatus.RPM < configPage2.crankRPM) { return crankingGetRPM(configPage2.triggerTeeth); }
return stdGetRPM();
}
int getCrankAngle_Nissan360(int timePerDegree)
{
//As each tooth represents 2 crank degrees, we only need to dtermine whether we're more or less than halfway between teeth to know whether to add another 1 degrees
//As each tooth represents 2 crank degrees, we only need to determine whether we're more or less than halfway between teeth to know whether to add another 1 degrees
unsigned long halfTooth = (toothLastToothTime - toothLastMinusOneToothTime) >> 1;
if ( (micros() - toothLastToothTime) > halfTooth)
{
//Means we're over halfway to the next tooth, so add on 1 degree
return (toothCurrentCount * 2) + 1;
return (toothCurrentCount * triggerToothAngle) + 1;
}
return (toothCurrentCount * 2);
return (toothCurrentCount * triggerToothAngle);
}

View File

@ -141,6 +141,8 @@ volatile byte tach_pin_mask;
volatile byte *triggerPri_pin_port;
volatile byte triggerPri_pin_mask;
volatile byte *triggerSec_pin_port;
volatile byte triggerSec_pin_mask;
//The status struct contains the current values for all 'live' variables
//In current version this is 64 bytes

View File

@ -453,7 +453,7 @@ void setup()
case 12:
triggerSetup_Nissan360();
trigger = triggerPri_Nissan360; //Is identical to the dual wheel decoder, so that is used. Same goes for the secondary below
trigger = triggerPri_Nissan360;
getRPM = getRPM_Nissan360;
getCrankAngle = getCrankAngle_Nissan360;

View File

@ -399,9 +399,6 @@ void setPinMapping(byte boardID)
tach_pin_port = portOutputRegister(digitalPinToPort(pinTachOut));
tach_pin_mask = digitalPinToBitMask(pinTachOut);
triggerPri_pin_port = portOutputRegister(digitalPinToPort(pinTrigger));
triggerPri_pin_mask = digitalPinToBitMask(pinTrigger);
//And for inputs
pinMode(pinMAP, INPUT);
pinMode(pinO2, INPUT);
@ -422,6 +419,12 @@ void setPinMapping(byte boardID)
pinMode(pinLaunch, INPUT); //If Launch Pull Resistor is not set make input float.
}
//These must come after the above pinMode statements
triggerPri_pin_port = portInputRegister(digitalPinToPort(pinTrigger));
triggerPri_pin_mask = digitalPinToBitMask(pinTrigger);
triggerSec_pin_port = portInputRegister(digitalPinToPort(pinTrigger2));
triggerSec_pin_mask = digitalPinToBitMask(pinTrigger2);
//Set default values
digitalWrite(pinMAP, HIGH);
//digitalWrite(pinO2, LOW);