I would like help with coming up with some logic for making a method more dynamic
turbosupra
Posts: 1,088
I have these two objects that start when their respective cogs start, and after that they are static. I have a third object that monitors the 2 frequencies generated by each one and compares them to each other. Right now they run and do not change once they are started (as far as how far one is offset from the other), staying at a constant frequency. I would like a way to vary the second method in reference to the first method, which will simulate real world conditions much more accurately. I do not need to vary the frequency, but I do need to shift the start time of each loop in the second code block back and forth, in reference to the the loop (tooth) count of the first code block.
Does anyone have any ideas on how to go about this? These methods work perfect as static spin methods, but I will try and rewrite them in PASM if I need to. I can't seem to envision a way to do this very well, so any help with that would be very appreciated. Thanks for reading.
Does anyone have any ideas on how to go about this? These methods work perfect as static spin methods, but I will try and rewrite them in PASM if I need to. I can't seem to envision a way to do this very well, so any help with that would be very appreciated. Thanks for reading.
PUB simulateCrankWheel(simCrankWheelPinNum, crankTeethSimToothCnt, crankTeethSimMissingToothCnt, crankTeethSimRPM, autoRangeRPM) | localIndex, waitTime, logicHighWaitTime, logicLowWaitTime, logicHighGapWaitTime, logicLowGapWaitTime, startCnt, existingTeeth ' Initialize variables here dira[simCrankWheelPinNum]~~ outa[simCrankWheelPinNum]~ localIndex := 0 waitTime := (clkfreq/((crankTeethSimRPM*(crankTeethSimToothCnt*2))/60)) ' for 1500rpm = 44444, for 600rpm = 111111, 5555 for 12000rpm logicHighWaitTime := ((waitTime/50)*45) logicLowWaitTime := ((waitTime/50)*55) logicHighGapWaitTime := ((((waitTime*6)/100)*43)-logicHighWaitTime) ' this percentage can be measured by a prop scope and a signal capture logicLowGapWaitTime := ((((waitTime*6)/100)*57)-logicLowWaitTime) existingTeeth := (crankTeethSimToothCnt - crankTeethSimMissingToothCnt) startCnt := cnt {ctra := (%00100 << 26) | simCrankWheelPinNum ' setup counter for pin frqa := 1 ' this makes the cnt screw up every 26 seconds phsa := 0} { This is for a Hall effect signal/sensor simulation For 1000rpms on a 36-2 crank trigger wheel, it'd be (1000(36*2)) = 72000, then 72000/60 = 1200 teeth on/teeth off per clkfreq. 80000000(clkfreq)/1200 = a tooth on or tooth off every 133333.3 clk cycles. It would be on for 66666.67 clk cycles and then was off for every 66666.67 clk cycles So you'd loop on for 66666.67 cycles and then off for 66666.67 cycles and after 34 times, you'd wait for 66666.67 cycles * 4, to simulate the 2 missing teeth on and accompanying 2 "missing" teeth off (or gaps in between each tooth) . It should account for 2 missing teeth and 3 missing toothgaps An example to start the method would be simulateCamWheel(7, 3, 105, 100) } repeat repeat localIndex from 1 to (existingTeeth) ' loop number of physical teeth on and off outa[simCrankWheelPinNum]~~ ' high waitcnt(startCnt += logicHighWaitTime) ' on for 1 tooth outa[simCrankWheelPinNum]~ 'low waitcnt(startCnt += logicLowWaitTime) ' off for 1 tooth outa[simCrankWheelPinNum]~ ' low waitcnt(startCnt += logicLowGapWaitTime) ' off for 57% of 2 teeth outa[simCrankWheelPinNum]~~ ' high waitcnt(startCnt += logicHighGapWaitTime) ' on for 43% of 2 teeth
PUB simulateCamWheel(simCamWheelPinNum, engineRPM, crankRotsToCamRots, degreeOfTrigger1, degreeOfTrigger2, degreeOfTrigger3, camTriggerDegreeWidth, autoRangeVVTI, degreeChangesPerSecond) | localIndex, crankRpmPerSecond, camRpmPerSecond, localCnt, trigger1Wait, trigger2Wait, trigger3Wait, emtpySpace1Wait, emtpySpace2Wait, emtpySpace3Wait, cyclesPerDegOfRot, toothWaitDelay, startTooth, autoRangeChangesPerSecond, advancing, retarding, degreesShifted, updateCnt dira[simCamWheelPinNum]~~ outa[simCamWheelPinNum]~ localIndex := 0 crankRpmPerSecond := (engineRPM/60) ' 166.667 crank rots per second at 10k rpm camRpmPerSecond := (((engineRPM*10)/60)/2) ' 83.333 cam rots per second at 10k rpm cyclesPerDegOfRot := (((clkfreq/camRpmPerSecond)/360)*10) ' 960000/360 at 10k or 2660 toothWaitDelay := (clkfreq/(crankRpmPerSecond*36)) autoRangeChangesPerSecond := (clkfreq/degreeChangesPerSecond) trigger1Wait := (camTriggerDegreeWidth*cyclesPerDegOfRot) ' 19 degrees trigger2Wait := (camTriggerDegreeWidth*cyclesPerDegOfRot) ' 19 degrees trigger3Wait := (camTriggerDegreeWidth*cyclesPerDegOfRot) ' 19 degrees emtpySpace1Wait := (degreeOfTrigger1*cyclesPerDegOfRot) ' 72 degrees emtpySpace2Wait := (degreeOfTrigger2*cyclesPerDegOfRot) ' 72 degrees emtpySpace3Wait := (degreeOfTrigger3*cyclesPerDegOfRot) ' 159 degrees startTooth := 26 localCnt := cnt repeat outa[simCamWheelPinNum]~~ ' pin high waitcnt(localCnt += trigger1Wait) ' wait cnt time stamp plus trigger degree width in cycles outa[simCamWheelPinNum]~ ' pin low waitcnt(localCnt += emtpySpace1Wait) ' wait cnt time stamp plus first empty space degree width in cycles outa[simCamWheelPinNum]~~ ' pin high waitcnt(localCnt += trigger2Wait) ' wait cnt time stamp plus trigger degree width in cycles outa[simCamWheelPinNum]~ ' pin low waitcnt(localCnt += emtpySpace2Wait) ' wait cnt time stamp plus second empty space degree width in cycles outa[simCamWheelPinNum]~~ ' pin high waitcnt(localCnt += trigger3Wait) ' wait cnt time stamp plus trigger degree width in cycles outa[simCamWheelPinNum]~ ' pin low waitcnt(localCnt += emtpySpace3Wait) ' wait cnt time stamp plus third empty space degree width in cycles
Comments
You may not want this adjustment to be added to all the WAITCNTs, maybe just to a few of them depending on where you want to adjust the simulation. There'll always be a discontinuity somewhere that will take a few cycles to smooth out.
I've noticed at the slower frequencies (less than 3600hz for crank object/150hz for cam object) , the 2 objects don't clock exactly synced. What would you suggest to set this, or is this probably a code error, since they do clock exactly at higher speeds?
You're right, it is the values in waitcnt, at a certain speed the one loop (x2) takes 13709184, and the other 13791600 and they should both match. I did however get the values to jump back and forth as I want them to dynamically. I just now how to figure out a correction algorithm, it doesn't look like there is a rhyme or reason to the differences
Can you tell me what you mean by base 2 or explain the concept a little better? I thought that I was already using base 2 with the prop
We could say 1 degree equals 1024 (0x400)
0.5 degrees = 512 (0x200)
0.25 degrees = 256 (0x100)
0.125 degrees = 128 (0x80)
0.1 degree ~ 102 = (0x66)
Therefore, 2.2 degrees = 2*1024 + 2*102 = 2252 or 0x8CC. That's pretty good resolution.
Basically, remove decimal math from the calculations. The only time you have to worry about the number is when displaying the results.
I think I'm going to have to rewrite the object in PASM, so that I can sync it properly. I don't think spin is fast enough unfortunately