What is wrong here ?

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

What is wrong here ?

Post by FFMan »

I'm altering my race car lap timing program to use a magnetic pickup present in most circuits rather than the IR beacon and detector I used previously. The IR is prone to interference from other beacons, people knocking it out of alignment, range issues and last but not least me forgetting to take it home !

I have a sensor that i tested at a circuit last weekend and have wired this to pin 4 on a 328n which is defined as zxinputpullup, which the switch takes low when a magnet is detected.

The detection part works fine. The task below correctly detects the change of state but never prints 'cont'. The aim of the routine is to provide half a second of hysterysis to the global trigger variable. BCN_INT is defined as zero for a 328n and the task has a 170 byte stack.

apart from the frowned upon use of a goto - what is going wrong ?

Code: Select all

Sub BeaconDetectTask()

	
IR:	'Loop looking for beacon

	debug.print "wait trig"
	Call WaitForInterrupt(zxPinFallingEdge,BCN_INT)
	debug.print "Trig"
	
	by_BeaconDetected=0

	Sleep (0.5)

	debug.print "cont"
	by_BeaconDetected=1
	
	goto IR
	
End Sub
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

Boy, I don't see anything wrong between printing "trig" and printing "cont".

I take it you ARE getting the "trig" printed?

Replace the goto with a do or while(true) loop. It might be nice to have a way to exit the loop so you might use a while(global boolean variable) loop. This or another process can then change the boolean to break the loop.

Then remove the sleep() function. It ought to print "trig" and "cont" back to back. Does that happen?

-Tony
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

ok - so i've tidied the code to look like:-

Code: Select all

Sub BeaconDetectTask()
	
	'Loop looking for beacon
	do 
		debug.print "wait trig"
		Call WaitForInterrupt(zxPinFallingEdge,BCN_INT)
		debug.print "Trig"
	
		'by_BeaconDetected=0

		'Sleep (0.5)

		debug.print "cont"
		'by_BeaconDetected=1
	
	loop
	
End Sub
and i get debug output of :-

Trig
cont
wait tri

yes there is a missing g, and if i leave in the variable setting then more letters are missing, suggesting its a timing issue. then i also fail to get any more triggers - the main program is still running but i get no more triggers.

as an experiment i wrote a stand alone test prog to mimic this code and it worked perfectly so there is an interaction going on with other parts of my code but at the moment not sure what this could be. there is a lot of pin io going on to drive the lcd but other than that its all fairly normal.

i'll dig some more but any pointers much appreciated.

bed time here for now.
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

Post by pjc30943 »

EDIT: I see now that you mentioned it was a task.

What else is running? Is another task also using debug.print without a semaphore?
Paul
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

pjc30943 wrote:EDIT: I see now that you mentioned it was a task.

What else is running? Is another task also using debug.print without a semaphore?
Good question. I always look to Don to tell me about the vagaries of debug.print and how it will block tasks (or not) and so on.

One thing you might try is to increase the task stack just to prove that the problem is not a stack overrun. If you have the space, try doubling it and see if it still misbehaves.

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

FFMan wrote:yes there is a missing g, and if i leave in the variable setting then more letters are missing, suggesting its a timing issue.
This symptom could be the result of stack corruption or a bug (in your code or ours) that inadvertently leaves interrupts disabled.

This type of problem is difficult to diagnose. It is usually difficult to create a simplified test case that exhibits the problem but worth the effort. If you can create a simplified test case that requires no external input (or some easy-to-reproduce external input sequence) that will go a long way toward determining the root cause of the problem.
- Don Kinzer
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

i'll see if i can create a test case.

although the program is quite large, the actual code running when the problem is evident is quite very simple. i suspect some interaction with the io writing to the lcd and i'll start by commenting out this code and go from there. the lcd code does lock the task momentarily.

i'll have a play this evening and post results back.
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

looking at the lcd code i see it has a block that locks the task, toggles some pins and then has a Pause(0.002), toggles some pins and unlocks the task.

The documentation states that pause prevents other tasks running. This didn't seem to be an issue when using IR and InputCapture, but that has now been replaced with WaitforInterrupt, perhaps there is some interaction there.

I'll concerntrate on this area later.
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

ok - a few checks and changes made and it doesn't get any clearer but here is what I have found:-

I have the 2 functions shown below. If the line

Call LCD_Plot(Cstr(by_Ret) & Cstr(timer),0,0)

is left in its original form:-

Call LCD_Plot(Cstr(by_Ret) ,0,0)

the process fails to complete the 'cont' debug and fails to retrigger. If i have the display line with the timer it works fine and retriggers etc as expected. I tried adding 50 bytes to the stack but this didn't help.

Code: Select all

function Read_Beacon() as byte

	if bo_TestMode=true then
		Read_Beacon= GetPin(TRG_Pin)
		'debug.print "~";
	else
		Read_Beacon=by_BeaconDetected
	end if
	
end function


'Display beacon state to user
Sub Beacon_Test()

	dim by_Ret as byte

	Call LCD_Clear
	Call LCD_Plot("Beacon:",0,0)
	Call LCD_Plot("Exit>",1,255)

	Do while UserInput(false)=0
		by_Ret=Read_Beacon
		Call LCD_Plot(Cstr(by_Ret) & Cstr(timer),0,0)	'0,12
	loop
	

end sub

FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

interestingly if i replace the cstr(timer) addition with a constant such as:-

Call LCD_Plot(Cstr(by_Ret) & "a",0,0)

i still see the issue. From programming way back would it be true to say the compiler creates a new variable if a non-constant is concatenated, whereas by adding nothing, or another constant the compiler is passing by reference and this is causing the issue and perhaps this is because this variable is a return from a previous function call and passed by reference itself ? a wild guess really....

I can work round it using this 'fix', and in the main operational code (as opposed to this routine which is for the user to test the beacon), there isn't an issue anyhow.
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

FFMan wrote:i[W]ould it be true to say the compiler creates a new variable if a non-constant is concatenated, whereas by adding nothing, or another constant the compiler is passing by reference
No. Both the CStr(by_Ret) and the CStr(timer) calls return allocated strings (assuming that the parameter is not a compile-time constant). With the string concatenation operator (&), the two strings are combined into a single allocated string which is then passed to the called subroutine (where it is ultimately deallocated). Even if you concatenate a constant string to the result of CStr(by_Ret), the result is still an allocated string (again, assuming that by_Ret is not a compile-time constant.

The problem could be related to the concatenation operation or to the freeing of the concatenated string. We haven't seen any issues recently with operations like this but there still could be something unusual going. Tracking down the problem will be difficult (perhaps impossible) without a working example that manifests the issue.
- Don Kinzer
Post Reply