Hall effect sensor code critique wanted
turbosupra
Posts: 1,088
I'd like a second, third or tenth set of eyes to give these functions a quick glance over and see if there are any holes. I'm not the most efficient code writer by any means, but I would like to see if there are any holes in functionality.
This is for a 36-2 trigger wheel and hall effect sensor on an automobile.
Thanks for reading.
This is for a 36-2 trigger wheel and hall effect sensor on an automobile.
Thanks for reading.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 c_CrankSensorInputPin = 1 c_KeyOnInputPin = 2 c_CamSensorInputPin = 3 c_CrankSensorOutputPin = 5 c_CamSensorOutputPin = 7 c_ECUFeedbackPin = 8 OBJ Debug : "FullDuplexSerial" VAR ' ########### PUB Main Variables ########### ' ########### CalculateRPMs Variables ########### long RPMCalculator long c_WaitingforKeyOn long CrankToothSyncCount long SyncPulseLow long SyncPulseHigh long SyncPulseHighTime1 long SyncPulseHighTime2 long c_WaitingtoSyncPulses long SyncTimeBetweenPulses long c_WaitingtoSyncTDC long CrankToothCount long TDCSynced long CrankToothPulseTime long CrankToothTDC long cranksensorlow long CrankTDCTime long c_CountingCrankTeeth long cranksensorhigh long CrankTimeBetweenTriggerTeeth long CrankTDC long CrankTimeBetweenTDCs ' ########### RPMfromCrankTrigger Variables ########### long RPMfromCT ' ########### RPMfromTopDeadCenter Variables ########### long RPMfromTDC PUB CalculateRPMs dira[c_CrankSensorInputPin] := 0 dira[c_KeyOnInputPin] := 0 dira[c_CamSensorInputPin] := 0 repeat case RPMCalculator c_WaitingforKeyOn: If c_KeyOnInputPin == 1 ' If the key is on CrankToothSyncCount := 0 SyncPulseLow := true SyncPulseHighTime1 := 0 SyncPulseHighTime2 := 0 RPMCalculator := c_WaitingtoSyncPulses 'RPMCalculator := c_WaitingtoSyncTDC else RPMCalculator := c_WaitingforKeyOn Debug.Str(string("Key is off")) Debug.Tx(13) c_WaitingtoSyncPulses: If c_CrankSensorInputPin == 1 AND SyncPulseLow := true ' Initially set to low If SyncPulseHighTime1 <> 0 AND SyncPulseHighTime2 == 0 SyncPulseHighTime2 := cnt SyncPulseLow := false SyncTimeBetweenPulses := (SyncPulseHighTime2 - SyncPulseHighTime1) ' If rpms are at 200 and not TDC, variable is set to 0.00833333333333 . If at TDC variable is set to 0.0166666666667 RPMCalculator := c_WaitingtoSyncTDC Elseif SyncPulseHighTime1 == 0 ' First time entering the loop when pin sees a high SyncPulseHighTime1 := cnt SyncPulseHigh := true SyncPulseLow := false 'RPMCalculator := c_WaitingtoSyncPulses ' Jumps out of the if statement so the following elseif will not evaluate to true in this single loop Else Debug.Str(string("WaitingtoSyncPulses Error")) Debug.Tx(13) Elseif c_CrankSensorInputPin == 0 SyncPulseLow := true Else Debug.Str(string("Waiting to transistion")) Debug.Tx(13) ' 200rpms is a tooth pulse every 0.00833333333333 (* 1.75 = 0.0145833333333) c_WaitingtoSyncTDC: ' 400rpms is a tooth pulse every 0.00416666666667 (* 1.75 = 0.0072916666667) ' 500rpms is a tooth pulse every 0.00333333333333 (* 1.75 = 0.0058333333333) If c_CrankSensorInputPin == 1 AND SyncTimeBetweenPulses =< 0.0145833333333 ' aka 200rpms when car starts to turn over and pin goes high If CrankToothSyncCount =< 34 AND SyncPulseLow == true ' starts at 0 CrankToothSyncCount := CrankToothSyncCount + 1 SyncPulseLow := false Elseif CrankToothSyncCount > 34 AND SyncPulseLow == true SyncPulseLow := false CrankToothSyncCount := 1 ' when pin goes high a 35th time (which is also the first time during another revolution) CrankToothCount := 0 TDCSynced := true CrankToothPulseTime := cnt CrankToothTDC := cnt cranksensorlow := true CrankTDCTime := cnt Debug.Str(string("----- TDC Sync ----- TDC Sync ----- Count Higher than 34 -----")) Debug.Tx(13) RPMCalculator := c_CountingCrankTeeth Else Debug.Str(string("Error in c_WaitingtoSyncTDC")) Debug.Tx(13) Elseif c_CrankSensorInputPin == 1 AND SyncTimeBetweenPulses > 0.0145833333333 CrankToothTDC := cnt CrankToothCount := 0 TDCSynced := true CrankToothPulseTime := cnt cranksensorlow := true CrankTDCTime := cnt Debug.Str(string("----- TDC Sync ----- TDC Sync -----")) Debug.Tx(13) RPMCalculator := c_CountingCrankTeeth Elseif c_CrankSensorInputPin == 0 SyncPulseLow := true Else Debug.Str(string("Waiting to transition in c_WaitingtoSyncTDC")) Debug.Tx(13) c_CountingCrankTeeth: If c_CrankSensorInputPin == 1 AND cranksensorlow := true ' when pin goes high after a low cranksensorhigh := true cranksensorlow := false If CrankToothCount =< 34 CrankTimeBetweenTriggerTeeth := (cnt - CrankToothPulseTime) ' time between last crank sensor pulse and this one CrankToothCount := CrankToothCount + 1 CrankToothPulseTime := cnt Else CrankToothCount := 1 ' 1 or 35, they are both the same CrankTDC := true CrankTimeBetweenTDCs := (cnt - CrankTDCTime) ' when pin goes high a 35 time (which is also the first time during another revolution) CrankTDCTime := cnt Debug.Str(string("----- TDC ----- TDC -----")) Debug.Tx(13) elseif c_CrankSensorInputPin == 0 cranksensorlow := true cranksensorhigh := false else Debug.Str(string("Waiting for transition in CountingCrankTeeth")) Debug.Tx(13) PUB RPMfromCrankTrigger repeat If c_CrankSensorInputPin == 1 RPMfromCT := (((1/CrankTimeBetweenTriggerTeeth) * 36) * 60) If RPMfromCT =< 0 OR RPMfromCT => 10_000 RPMfromCT := 0 Debug.Str(string("Error in case RPMfromCrankTrigger")) Debug.Tx(13) Else RPMfromCT := RPMfromCT PUB RPMfromTopDeadCenter repeat If cranktdc == true RPMfromTDC := ((1/CrankTimeBetweenTDCs) * 60) If RPMfromTDC =< 0 OR RPMfromTDC => 10_000 RPMfromTDC := 0 Debug.Str(string("Error in case RPMfromTopDeadCenter")) Debug.Tx(13) Else RPMfromTDC := RPMfromTDC
Comments
Rich H
Thanks for the response, can you tell me why? How about the rest of it?
I could write (116666/clkfreq) but I don't think that buys me anything?
As of now, I believe the value has to be 1.75 times the length of time between each tooth's pulse at a cranking rpm of 200. If this 1.75(value) is seen, that means that TDC is reached during the minus 2 of the 36-2 portion of the trigger wheel.
I'm going to humbly ask for a laymens term explanation, because I feel like I'm missing something?
What I advise doing to keep it in integer is to multiply it by a factor of 10, so for example instead of 0.0145833333333, multiply it by 100,000 for 1,458. Then, if everything else follows through with a factor of 100,000 then instead of telling it to go the max speed of 200 rpm it would be multiplied by 100,000 to 200,000,000, but would be the equivalence of 200 rpm.
I think I have something working ... if I can test it and I get it working, I will send it to you in case you want to see what I've done.