Page 1 of 1
multi-tasking ping sonars
Posted: 25 February 2008, 10:55 AM
by LtDan80
The current problem I am having is that after about 3 minutes of running the code, it begins to malfunction. The chip randomly gives a high reading and a low reading to either sensor. It works perfect before this. i am trying to figure out if it is an RC time constant problem, a problem with the RAM getting filled, or a problem with the code. Hese is what I have.
Code: Select all
Option Explicit
Dim Stack1(1 To 48) As Byte
Dim Stack2(1 To 48) As Byte
Dim Width1 as Single, Feet1 as Single, Inches1 as Single
Dim Width2 as Single, Feet2 as Single, Inches2 as Single
'---------------------------------------------------
Public Sub Main()
CallTask "SonarTask1", Stack1
Call Sleep(0.2)
CallTask "SonarTask2", Stack2
Call Sleep(0.2)
Do
Call Sleep(120.0)
Loop
End Sub
'-------------------------------------------------------------------------------------
Private Sub SonarTask1()
Do
Call PulseOut(17, 3.0, 1)
Call PulseIn(17, 1, Width1)
Feet1 = Width1 * 550.0 'assuming 1100 feet per sec
Inches1 = Feet1 * 12.0
Debug.Print CStr(Inches1)
Call Delay(0.3)
If Inches1 <5.0 then
Call Putpin (25,0) 'turns on LED pin 25, ZX-24a
Else
Call Putpin (25,1) 'turns off LED pin 25, ZX-24a
End If
Call PutPin(17, 1)
Loop
End Sub
'-------------------------------------------------------------------------------------
Private Sub SonarTask2()
Do
Call PulseOut(18, 3.0, 1)
Call PulseIn(18, 1, Width2)
Feet2 = Width2 * 550.0 'assuming 1100 feet per sec
Inches2 = Feet2 * 12.0
Debug.Print CStr(Inches2)
Call Delay(0.3)
If Inches2 <5.0 then
Call Putpin (26,0) 'turns on LED pin 26, ZX-24a
Else
Call Putpin (26,1) 'turns off LED pin 26, ZX-24a
End If
Call PutPin(18, 1)
Loop
End Sub
Thanks for your help, The paper I have decided to do will cover multi-tasking IR and Sonar with the ZX-24a. I hope the paper will be able to help you all later.
Dan
Re: multi-tasking ping sonars
Posted: 25 February 2008, 12:08 PM
by dkinzer
LtDan80 wrote:after about 3 minutes of running the code, it begins to malfunction.
Some of the problems that were brought to your attention still have not been rectified. For example, you're still calling PulseOut() with a delay parameter of 3.0 seconds. It's not clear why you're trying to generate a pulse of 3 seconds but the Ping Sonar definitely doesn't need it. The data sheet (which I recommend that you read thoroughly) indicates a minimum trigger pulse width of 2 uS with a typical trigger pulse width of 5 uS.
Secondly, there is still a problem with the output state at the beginning of the loop. The following code may address these problems.
Code: Select all
Private Sub SonarTask1()
Const pingPin as Byte = 17
Const ledPin as Byte = 25
Const triggerPulse as Single = 5.0e-6
Do
Call PutPin(pingPin, 0)
Call PulseOut(pingPin, triggerPulse, 1)
Call PulseIn(pingPin, 1, Width1)
Feet1 = Width1 * 550.0 'assuming 1100 feet per sec
Inches1 = Feet1 * 12.0
Debug.Print CStr(Inches1)
Call Delay(0.3)
If Inches1 <5.0 then
Call Putpin (ledPin,0) 'turns on LED pin 0, MMC_BS2
Else
Call Putpin (ledPin,1) 'turns off LED pin 0, MMC_BS2
End If
Loop
End Sub
Note, also, that I introduced constants for the pins. This not only improves the readability of the code, it will facilitate simple conversion later to using a single parameterized task routine to handle both sonar tranducers.
Posted: 27 February 2008, 10:59 AM
by LtDan80
Don, I restructured the code. It now reads:
Code: Select all
Dim Stack1(1 To 36) As Byte
Dim Stack2(1 To 36) As Byte
Dim Width1 as Single, Feet1 as Single, Inches1 as Single
Dim Width2 as Single, Feet2 as Single, Inches2 as Single
'---------------------------------------------------
Public Sub Main()
CallTask "SonarTask1", Stack1
Call Sleep(0.1)
CallTask "SonarTask2", Stack2
Call Sleep(0.1)
Do
Call Sleep(60.0)
Loop
End Sub
'-------------------------------------------------------------------------------------
Private Sub SonarTask1()
Const pingPin as Byte = 17
Const ledPin as Byte = 25
Const triggerPulse as Single = 5.0e-6
Do
Call PutPin(pingPin, 0)
Call PulseOut(pingPin, triggerPulse, 1)
Call PulseIn(pingPin, 1, Width1)
Feet1 = Width1 * 550.0 'assuming 1100 feet per sec
Inches1 = Feet1 * 12.0
Debug.Print CStr(Inches1)
Call Delay(0.3)
If Inches1 <5.0 then
Call Putpin (ledPin,0) 'turns on Red LED pin 25, ZX-24a
Else
Call Putpin (ledPin,1) 'turns off Red LED pin 25, ZX-24a
End If
Loop
End Sub
'-------------------------------------------------------------------------------------
Private Sub SonarTask2()
Const pingPin as Byte = 18
Const ledPin as Byte = 26
Const triggerPulse as Single = 5.0e-6
Do
Call PutPin(pingPin, 0)
Call PulseOut(pingPin, triggerPulse, 1)
Call PulseIn(pingPin, 1, Width2)
Feet2 = Width2 * 550.0 'assuming 1100 feet per sec
Inches2 = Feet2 * 12.0
Debug.Print CStr(Inches2)
Call Delay(0.3)
If Inches2 <5.0 then
Call Putpin (ledPin,0) 'turns on Green LED pin 26, ZX-24a
Else
Call Putpin (ledPin,1) 'turns off Green LED pin 26, ZX-24a
End If
Loop
End Sub
I am still getting the same error however. It is very random with when it fails, after 10 trials, I have had everything from it failing at 46 seconds, up to running over 10 minutes perfectly fine and then freezing. I have not touched anything in that time and have just been letting the Sonar's read off of a wall. Any other suggestions would be great.
Posted: 27 February 2008, 11:45 AM
by dkinzer
LtDan80 wrote:I restructured the code
When you post code, please wrap it in code /code tags. The easiest way to do this is to select all of the text that is code and click the 'Code' button above the message body edit control. You can also just type 'code' and '/code' each enclosed in square brackets.
You might try increasing the task stack size but I suspect that this will have no effect.
How are you powering the ZX and the Ping sonar? What else is connected, if anything, and how is it powered? Which ZX device are you using?
Posted: 27 February 2008, 13:37 PM
by LtDan80
I am using a ZX-24a. The board I am using is a motor mind carrier board. I am using 2 ping sonar's, and it is powered through a 12 volt ac to dc converter. When it enters the MMC it gets regulated down to 5 volts.
Re: multi-tasking ping sonars
Posted: 27 February 2008, 14:37 PM
by mikep
LtDan80 wrote:The current problem I am having is that after about 3 minutes of running the code, it begins to malfunction. The chip randomly gives a high reading and a low reading to either sensor. It works perfect before this.
I'm not quite sure what "before this" means. If something previously worked then you should be able to see what changed.
My guess is that now and again the two sonars are interfering with each other and PulseIn() is getting confused. You could verify this by only starting one task or the other. It might be better to fire both sonars in one task, one after the other rather than have separate tasks for each one.
There are some other code improvements that could be made but we will save that for later. ZBasic is quite different to Stamp Basic and I think you will find it has several advantages. BTW Don't worry too much about RAM - you have a huge amount on the ZX-24a compared the Basic Stamps.
Posted: 27 February 2008, 15:19 PM
by dkinzer
LtDan80 wrote:I restructured the code.
After thinking about it some more, I'm sure that you're going to need a mechanism to ensure atomic execution of the PulseOut/PulseIn sequence. Otherwise, you run the risk of a task being suspended between the two calls.
There are two mechanisms available for serializing this sequence - using a semaphore or locking the task. Note, however, that neither of these methods will help if you eventually add WaitForInterval() or WaitForInterrupt() calls. Here's how the code would look using task locking:
Code: Select all
Call LockTask()
Call PulseOut(pingPin, triggerPulse, 1)
Call PulseIn(pingPin, 1, Width2)
Call UnlockTask()
Posted: 01 March 2008, 19:13 PM
by dkinzer
For the last 24 hours I've had a variation of your program running here. I have only one of the Ping devices so it's not quite the same setup that you have. The code below is what I'm using. It has two tasks that use the same Ping device.
Code: Select all
Dim Stack1(1 To 48) As Byte
Dim Stack2(1 To 48) As Byte
Dim Width1 as Single, Feet1 as Single, Inches1 as Single
Dim Width2 as Single, Feet2 as Single, Inches2 as Single
'---------------------------------------------------
Public Sub Main()
CallTask SonarTask(1), Stack1
Call Sleep(0.2)
CallTask SonarTask(2), Stack2
Call Sleep(0.2)
Do
Call Sleep(0)
Loop
End Sub
'-------------------------------------------------------------------------------------
Private Sub SonarTask(ByVal id as UnsignedInteger)
Const trigPin as Byte = 5
Const trigPulse as Single = 5.0e-6
Dim LED as Byte
LED = IIF(id = 1, 25, 26)
Do
Dim width as Single
Call PutPin(trigPin, 1)
Call LockTask()
Call PulseOut(trigPin, trigPulse, 1)
Call PulseIn(trigPin, 1, width)
If (id = 1) Then
Width1 = width
Feet1 = Width1 * 550.0 'assuming 1100 feet per sec
Inches1 = Feet1 * 12.0
Else
Width2 = width
Feet2 = Width2 * 550.0 'assuming 1100 feet per sec
Inches2 = Feet2 * 12.0
End If
Debug.Print CStr(id); " : "; Fmt(Inches2, 1)
If Inches2 < 5.0 then
Call Putpin (LED,0) 'turns on LED pin 26, ZX-24a
Else
Call Putpin (LED,1) 'turns off LED pin 26, ZX-24a
End If
Call UnlockTask()
Call Delay(0.3)
Loop
End Sub