My original answer agreed with the one by @Bmoore in its diagnosis, but I now believe that your algorithm in loop()
is essentially correct. Here's what happens:
- We're in the first iteration,
first==0
. You enter thewhile(distance > minimumRange)
, which you stay in until the condition breaks.distance
is now<= minimumRange
andfirst == 0
. - You enter
while(distance <= minimumRange && first == 0)
. You stay there, constantly stopping the drive engines and taking measurements, until the object has clearance from the ultrasound sensor.distance
is now> minimumRange
andfirst == 0
. - You enter
while(distance > minimumRange)
. You stay in it until the condition breaks.distance
is now<= minimumRange
andfirst == 0
. - You don't enter
while(distance <= minimumRange && first == 1)
becausefirst == 0
. - You set
first = 1
and end the iteration. - You're now in the second iteration. Again,
distance
is now<= minimumRange
andfirst == 1
. You don't enter the first threewhile
s because of that. - You enter
while(distance <= minimumRange && first == 1)
and stay in thatwhile
until the heat death of the Universe (or until your Arduino's power runs out, whichever first).
So, the algorithm is solid. Therefore, there must be something wrong elsewhere. Here's what I see is suspect:
pickObject()
andputObject()
are reversed. You stay in the secondwhile
. This can combine with an invalid starting position: if your robot can move its arm upwards and downwards from the starting state, then maybe something's wrong with your assumptions.- for whatever reason,
distance
is always less thanminimumRange
after it encounters the first object (sensor fault, to short of a wait between trig pulse and echo, etc.) . You then stay in the first iteration, in the secondwhile
. Note that this requires the previous error condition to be consistent with observation.
There are also several things that are not exactly correct in your code:
digitalWrite()
latches, i.e. if you set in onLOW
orHIGH
on a pin, the value will stay set until you change it. You keep writing those values unnecessarily.- as the other answers point out,
loop()
is a... loop. It repeats itself. You should rewrite yourwhile
s intoif
s (updating the conditions of course). - you're also making your algorithm dependent on a busy-waiting approach by keeping measuring distance constantly until the arm moves, sending pulses over and over again. Electrical energy is not free, especially not on an embedded platform. You should add a
delay()
in those cases.
There may be also other malfunctions as well (I certainly hope you're not stalling your arm-driving engine, since you never actually stop it!).
Therefore, in general, you should solve such problems like so:
- Add
Serial.Write()
statements to your code, make them informative, describe which steps has occurred and with what values of crucial parameters. - Connect your Arduino to the IDE via USB, or use a logging shield that e.g works with an SD card.
- Based on those logs, determine where the fault in the algorithm is.
Using logging in that manner will save you many headaches.