Ultrasonic Sensor Reading Fluctution

I have been building an obstacle colliding robot. I previously asked for help regarding this, but since it was on a different topic I opened a new thread. So my problem is that every now and then my range reading is dropping to 4 then back to the correct reading. (The number isn't always four it could be 7 or 8). From the video I have linked you could see that.

The PICAXE and the motors have different power supply to reduce the power fluctuation affecting the sensor.


Could you please help me

Code:
symbol trigPin = B.1 ;Assign pin B.1 to a variable called trigPin
symbol range = w1 ;Create a variable called range stored in w1
symbol currentsense = w0 ;Create a variable called currentsense stored in w1
symbol BuzzerPin = B.0 ;Assign pin B.0 to a variable called trigPin

;Motor Control Pin
symbol LForward = B.2 ;Assign pin B.2 to a variable called LForward
symbol RForward = B.4 ;Assign pin B.4 to a variable called RForward
symbol LBack = C.0 ;Assign pin C.0 to a variable called LBack
symbol RBack = C.2 ;Assign pin C.2 to a variable called RBack

;Limit Variable
symbol MotorLimit = 48 ;Stores the maximum safe current limit in a variable called MotorLimit
symbol targetrange= 30 ;Stores the maximum distance the robot will see an object and collide with.
symbol MotorPower = 797 ;Stores the duty (The power of the motor)
symbol SafeDistance = 15 ;Stores the minimum distance the robot will backaway when it is going backward due to currentsense

start0: ;Label, state the start of a parallel task, Initiliase the pwmout. (Only goes once).
    pwmout LForward,150,0 ;Initiate a pwm output on pin LForward with a period of 150 and a duty of 0.
    pwmout RForward,150,0 ;Initiate a pwm output on pin RForward with a period of 150 and a duty of 0.
    pwmout LBack,150,0 ;Initiate a pwm output on pin LBack with a period of 150 and a duty of 0.
    pwmout RBack,150,0 ;Initiate a pwm output on pin LBack with a period of 150 and a duty of 0.
start1: ;Label, state the start of a parallel task, (Constantly check the range using the ultrasonic and readadc pin B.3 for currentsense.
   
    readadc B.3,currentsense ;Reads the analogue value from pinB.3 and convert it to a digital value (Which the PICAXE understands) and stores it in a variable called currentsense.
    ultra trigPin,range ;Initiates the SRF005 Sensor, uses the trigPin to pulsin and pulsout, convert the raw distance into centimeters and then store in variable called range
    debug
goto start1 ;Goes back to the subsection "start1"

start2: ;Label, state the start of a parallel task, makes the robot move forward, while it is looking for object to collide with.
    pwmduty LForward, MotorPower ;Changes the duty on pin "LForward" by "MotorPower"
    pwmduty RForward, MotorPower ;Changes the duty on pin "RForward" by "MotorPower"
    pause 1000 ;Waits 200 ms
    pwmduty RForward, 0 ;Changes the duty on pin "RForward" to 0
    pause 500 ;Waits 100ms
goto start2 ;Goes back to the subsection "start2"

start3: ;Label, state the start of a parallel task, make the robot go forward and collide when it sees an object that is less than "targetrange" 30cm away from it.
do while range < targetrange AND range > 3 ;Code loop while range is less than targetrange AND while range is greater than 3
    suspend 2 ;Stops start2
    suspend 4 ;Stops start4
    pwmduty RForward, MotorPower ;Changes the duty on pin "LForward" by "MotorPower"
    pwmduty LForward, MotorPower ;Changes the duty on pin "RForward" by "MotorPower"
loop while range < targetrange AND range  > 3 ;Codes loop while range is less than targetrange AND while range is greater than 3
resume 2 ;Starts start2
resume 4 ;Starts start4
goto start3 ;Goes back to the subsection "start3"

start4: ;Label, state the start of a parallel task, make the robot go backwards and make sound when currentsense is above the current threshold.
if currentsense >= MotorLimit then
    pause 100
    if currentsense >= MotorLimit then
                suspend 2 ;Stops start2
                suspend 3 ;Stops start3
                pwmduty LForward,0 ;Changes the duty on pin "LForward" to 0
                pwmduty RForward,0 ;Changes the duty on pin "RForward" to 0
                        do while range <= SafeDistance  ;Code loop while range is less than or equal to SafeDistance
                        pwmduty LBack,MotorPower ;Changes the duty on pin "LBack" by "MotorPower"
                        pwmduty RBack,MotorPower ;Changes the duty on pin "RBack" by "MotorPower"
                        high BuzzerPin ;It give 5v to the BuzzerPin
                        loop while range <= SafeDistance 'Code loop while the range is less than or equal to SafeDistance
                pwmduty RBack,0 ;Changes the duty on pin "LBack" to 0
                pause 500 ;Waits 200ms
                pwmduty LBack,0 ;Changes the duty on pin "RBack" to 0
                low BuzzerPin ;Give 0v to the BuzzerPin
                resume 2 ;Starts start2
                resume 3 ;Starts start3
       
else goto start4
endif
else goto start4
endif

goto start4 ;Goes back to the subsection "start4"
 
Ok after some more testing, I have found that the fluctuation is happening because of the do while loop in start3 subsection. But more specifically its because of the line do while range < targetrange...

what ever value I put in targetrange it while fluctuate in the value to 0.

For example if I assign targetrange to 50, then from 0 to 50cm (range reading from the ultrasonic) the range reading will randomly drop to 7. But if I change the targetrange to 30 then the range reading will only drop to 7 when the range reading is below 30.

Does anyone know why?

Thanks
 
Last edited:

techElder

Well-known member
Remove debug from start1 and see if you get an improvement.

Variation could mean that the ultrasonic command is not getting enough time to adjust the variable that you are testing in another task. You'll have to find a way to be sure you are testing a completely updated variable.
 

hippy

Technical Support
Staff member
Code:
start0: ;Label, state the start of a parallel task, Initiliase the pwmout. (Only goes once).
    pwmout LForward,150,0 ;Initiate a pwm output on pin LForward with a period of 150 and a duty of 0.
    pwmout RForward,150,0 ;Initiate a pwm output on pin RForward with a period of 150 and a duty of 0.
    pwmout LBack,150,0 ;Initiate a pwm output on pin LBack with a period of 150 and a duty of 0.
    pwmout RBack,150,0 ;Initiate a pwm output on pin LBack with a period of 150 and a duty of 0.
start1: ;Label, state the start of a parallel task, (Constantly check the range using the ultrasonic and readadc pin B.3 for currentsense.
Your "Start0" code falls into "Start1" so you end up with two tasks doing the same thing, both executing the code in "Start1".

Using multi-tasking with SUSPEND and RESUME commands littered throughout is usually a good indication that the fundamental design approach is flawed. That multi-tasking is being used inappropriately. Not only that; it makes it virtually impossible to figure out what should be happening and determining if it is.

The code looks incredibly complicated for what should be a relatively simple task. If you can provide a written description of what you want your bot to do, how you'd like it to behave, then it should be possible to provide a simpler algorithm for doing that.
 
Code:
start0: ;Label, state the start of a parallel task, Initiliase the pwmout. (Only goes once).
    pwmout LForward,150,0 ;Initiate a pwm output on pin LForward with a period of 150 and a duty of 0.
    pwmout RForward,150,0 ;Initiate a pwm output on pin RForward with a period of 150 and a duty of 0.
    pwmout LBack,150,0 ;Initiate a pwm output on pin LBack with a period of 150 and a duty of 0.
    pwmout RBack,150,0 ;Initiate a pwm output on pin LBack with a period of 150 and a duty of 0.
start1: ;Label, state the start of a parallel task, (Constantly check the range using the ultrasonic and readadc pin B.3 for currentsense.
Your "Start0" code falls into "Start1" so you end up with two tasks doing the same thing, both executing the code in "Start1".

Using multi-tasking with SUSPEND and RESUME commands littered throughout is usually a good indication that the fundamental design approach is flawed. That multi-tasking is being used inappropriately. Not only that; it makes it virtually impossible to figure out what should be happening and determining if it is.

The code looks incredibly complicated for what should be a relatively simple task. If you can provide a written description of what you want your bot to do, how you'd like it to behave, then it should be possible to provide a simpler algorithm for doing that.


Description
This robot needs to find obstacles (coke cans) by using the ulltrasonic sensor. I written this code in parallel so that the bot can check the distance while it is moving around in circles. While the robot is moving in circles, if the ultrasonic reading goes below 30cm, it would mean that 30cm ahead there is a potential obstacle that the robot needs to collide when. So the robot will ram forward into the obstacle. After knocking the obstacle, the bot will go back to going around in circles until it finds another potential obstacle. To prevent the robot from hit a wall thinking it was a potential obstacle and then getting stuck, I wrote the subsection start4. I put a 1ohm resistor between the ground pin of the L293D H-Bridge and put a wire between the 1ohm resistor that goes to pin B.3 then through readadc it reads the value and stores in a variable called currentsense. I had measured the value of the pin B.3 when the motors were stalled, (it came out to 48). So when the motor get stalled in any way start4 will suspend all the other start subsection, except the one which controls the ultrasonic sensor. Then the robot should reverse until it has gone atleast 15cm away from the wall. Then turn left so that it doesn't crash into the wall again. Then start moving in circles until it finds another obstacle.
 
Last edited:
Remove debug from start1 and see if you get an improvement.

Variation could mean that the ultrasonic command is not getting enough time to adjust the variable that you are testing in another task. You'll have to find a way to be sure you are testing a completely updated variable.
Even without the debug, it would still drop to 7 or 4. While I do think that ultrasonic command isn't getting enough time to adjust the variable is true. But when I get rid of the do while loop the in start3, the code will work fine. Don't know why.

Code:
start3: ;Label, state the start of a parallel task, make the robot go forward and collide when it sees an object that is less than "targetrange" 30cm away from it.
do while range < targetrange AND range > 3 ;Code loop while range is less than targetrange AND while range is greater than 3
    suspend 2 ;Stops start2
    suspend 4 ;Stops start4
    pwmduty RForward, MotorPower ;Changes the duty on pin "LForward" by "MotorPower"
    pwmduty LForward, MotorPower ;Changes the duty on pin "RForward" by "MotorPower"
loop while range < targetrange AND range  > 3 ;Codes loop while range is less than targetrange AND while range is greater than 3
resume 2 ;Starts start2
resume 4 ;Starts start4
goto start3 ;Goes back to the subsection "start3"
 
Code:
symbol trigPin = B.1 ;Assign pin B.1 to a variable called trigPin
symbol range = w1 ;Create a variable called range stored in w1
symbol currentsense = w0 ;Create a variable called currentsense stored in w1
symbol BuzzerPin = B.0 ;Assign pin B.0 to a variable called trigPin

;Motor Control Pin
symbol LForward = B.2 ;Assign pin B.2 to a variable called LForward
symbol RForward = B.4 ;Assign pin B.4 to a variable called RForward
symbol LBack = C.0 ;Assign pin C.0 to a variable called LBack
symbol RBack = C.2 ;Assign pin C.2 to a variable called RBack

;Limit Variable
symbol MotorLimit = 48 ;Stores the maximum safe current limit in a variable called MotorLimit
symbol targetrange= 30 ;Stores the maximum distance the robot will see an object and collide with.
symbol MotorPower = 797 ;Stores the duty (The power of the motor)
symbol SafeDistance = 15 ;Stores the minimum distance the robot will backaway when it is going backward due to currentsense

start0: ;Label, state the start of a parallel task, Initiliase the pwmout. (Only goes once).
    pwmout LForward,150,0 
    pwmout RForward,150,0 
    pwmout LBack,150,0 
    pwmout RBack,150,0 

start1: 
    readadc B.3,currentsense 
    ultra trigPin,range 
    debug
goto start1 

start2: 
    pwmduty LForward, MotorPower
    pwmduty RForward, MotorPower 
    pause 1000 
    pwmduty RForward, 0 
    pause 500
goto start2 

start3: 
do while range < targetrange AND range > 3 
    suspend 2 
    suspend 4 
    pwmduty RForward, MotorPower 
    pwmduty LForward, MotorPower 
loop while range < targetrange AND range  > 3
resume 2 
resume 4 
goto start3 

start4: 
if currentsense 
    pause 100
    if currentsense >= MotorLimit then
                suspend 2 
                suspend 3 
                pwmduty LForward,0 
                pwmduty RForward,0 
                        do while range <= SafeDistance  
                        pwmduty LBack,MotorPower 
                        pwmduty RBack,MotorPower 
                        high BuzzerPin 
                        loop while range <= SafeDistance 
                pwmduty RBack,0 
                pause 500 
                pwmduty LBack,0 
                low BuzzerPin
                resume 2 
                resume 3 
       
else goto start4
endif
else goto start4
endif

goto start4
I am so sorry for adding a annotated code, since the forum doesn't color code like the PICAXE software, it would have made reading it very hard.
 
Top