PDA

View Full Version : Call Work from Pub Main but not in its own cog....



TJHJ
03-20-2012, 03:50 PM
Hi,
So I have been out of the game a bit, but what should work is running me up a wall....
I cant seem to get a value to update from one cog to another using a global var, in the peakknock value. Help please.

Ok simple knock sensor,
Wiring - GND ----- Piezo ----- 1 MOhm ----- LTC1298

I have checked the ADC and it is reading correctly.

this works


CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
' lcd connections
LED = 5
MOSI = 4
SCK = 3
DC = 2
SCE = 1
RST = 0

' ADC Connections
ADCcpin = 9
ADCdpin = 10
ADCspin = 11

OBJ
ADC : "LTC1298"
lcd : "jm_nokia_5110_fast"

VAR
Long PeakKnock, KnockYes, CurrentValue
Long Stack1[100]

Pub Main
lcd.start(RST, LED) 'Cog 1 ' start lcd
ADC.Start(ADCcpin) 'Cog 2 'Start ADC 1TC298
cognew(Sense, @Stack1)
repeat

lcd.clear
writeDec(0,0,Getknock) 'Get the current ADC Value and update the peakKnock value, and KnockYes
WriteDec(0,1,PeakKnock) 'print the peak knock value
if knockyes == true 'if a Knock has happened Print knock to the screen
LCD.Goto_XY(0,2)
LCD.STR(String("KNOCK"), lcd#NORMAL)
if ina[press] == 1 'if the button is pressed
waitpne(|<press, |<press,0) 'freeze the screen so it no longer flikers (I know I could have a delay im trying to make sure I dont miss a knock yet)
PeakKnock := 0 'Reset the peakKnock Value
KnockYes := false

Pub GetKnock | t
t := ADC.GetADC(1) ' Get the current ADC value
if t > 20 'If the value is greater than the threshold Set the knock happened flag to try
KnockYes := true
if t > PeakKnock 'if the current ADC value is greater than the old value in peakknock
PeakKnock := t 'replace the peak knock value with the current
return t 'return the current ADC Value


OK so this works as expected, a value quiet around 5, a knock gives a peak from 40-150.

Now if I move the get knock function to its own cog I get a constant 8192 in the peakKnock value. What is going on here???



Pub Main
lcd.start(RST, LED) 'Cog 1 ' start lcd
ADC.Start(ADCcpin) 'Cog 2 'Start ADC 1TC298
cognew(Sense, @Stack1)
repeat

lcd.clear
'Removed the update from the main function
WriteDec(0,1,PeakKnock) 'print the peak knock value
if knockyes == true 'if a Knock has happened Print knock to the screen
LCD.Goto_XY(0,2)
LCD.STR(String("KNOCK"), lcd#NORMAL)
if ina[press] == 1 'if the button is pressed
waitpne(|<press, |<press,0) 'freeze the screen so it no longer flikers (I know I could have a delay im trying to make sure I dont miss a knock yet)
PeakKnock := 0 'Reset the peakKnock Value
KnockYes := false

Pub Sense
repeat
GetKnock

Pub GetKnock | t
t := ADC.GetADC(1) ' Get the current ADC value
if t > 20 'If the value is greater than the threshold Set the knock happened flag to try
KnockYes := true
if t > PeakKnock 'if the current ADC value is greater than the old value in peakknock
PeakKnock := t 'replace the peak knock value with the current
return t 'return the current ADC Value


I dont understand why I am getting a junk value if I move the function into its own cog.
I have also tried this with the same results


Pub Sense
ADC.Start(ADCcPin)
repeat
GetKnock


Thank you for your help

Phil Pilgrim (PhiPi)
03-20-2012, 04:36 PM
When you added the ADC.Start to your new cog (which was the right thing to do), did you also remember to delete it from the main cog?

-Phil

turbosupra
03-20-2012, 06:40 PM
I can't really test this without the hardware, but I have had this strange nonsense happen to me too.

I believe it was because one method was trying to update a variable while the other was trying to read it.

Try adding this for PUB Sense, if you are monitoring knock on an ICE, then you don't need (80mHz/slowness of spin loop) for knock resolution. At absolute best let's say you have 10000rpm, you'll see 1 ignition event every 0.006 seconds or (4,800,000 clk cycles / num of cylinders). Knock will only occur during the compression stroke of a 4 stroke, so that means it only occurs every other rpm and even if you had an 8 cylinder 4 stroke, that's 1 event every (60000*2) clk cycles, or 1 event for every 120,000 clk cycles at 10k rpm, which is a worst case scenario. clkfreq/2000 will still give you 6 loops per ignition event, on an 8 cylinder 4 stroke ICE at 10k rpm.

As you probably already know, peak knock is most likely to occur at peak torque and not peak rpm if your tuning is correct, so it is not going to happen at redline.

8 cyl 4 stroke 10k rpm = 1336 events per second (worst case scenario that will never occur in reality)
clkfreq/2000 = 2000 events per second and should catch all 1336 events.




Pub Sense
repeat
GetKnock
waitcnt(clkfreq/2000)

TJHJ
03-21-2012, 06:41 PM
Phil
Yes I did remove the ADC.Start from the main code when running the second version, no change.

Turbo Supra,
As a car guy as well I would have gone with the same thought you went to as well, but it's not an engine knock it's a knock like on a door, there is no spacing or timing, just trying to pickup if someone hits the table/box.

side note
If anyone comes across this thinking of engine knock, I did once build a prop engine knock detector, you would need a higher resolution. I did the same thing, and had it sample around a few samples per stroke. Here is what I learned. 1 sample per stroke without syncing it to the fire sequence you may go a few cycles before you catch one. The problem is you need to catch both the voltage spike from the sensor and the knock at the right point in the stroke. The knock only occurs at the start of the ignition process and doesn't continue at its peak, through the whole ignition stroke. Well sort of it dissipates similar to an echo. If a pickup every few cycles is acceptable for your application, all is good, otherwise go higher sampling or a trigger system. I used a schmitt trigger and some caps to hold the voltage high if the sensor got peaked to detect it.
Side Note Over...

Its basically this on a prop not aurdino,
http://arduino.cc/en/Tutorial/Knock

Thank you for all the help so far,

turbosupra
03-21-2012, 07:26 PM
http://www.badhaven.com/wp-content/uploads/2012/02/doh-homer-simpson.jpg

Well thank you for the insight on the automotive knock sensor device. I don't know if I ever will build one, but I could see myself considering it at some time, although I would probably spend the couple hundred on a j&s knock sensor, before the couple of hundred hours it would take me to build one. That'd work out to about a dollar an hour :)

Your experience makes sense with what I was saying about it only occurring during the compression stroke and it would make sense that knock (preignition) would occur before the plug fired for that individual cylinder, just by definition. I don't know what frequency a piston rattling around in a cylinder would make, but I would imagine it varies based on the make up of the material used in the block ... iron, aluminum, alloys, etc.