Let's Make Robots!

FIXED: irin resets servo?

I've attached an IR receiver to a servo to use as an IR beacon detector. I'm trying to have the servo sweep through its travel to look for an infrared signal using the "irin" command on a 28X2. I want it to start the servo all the way to the right and pause for an IR signal check. If no signal then increment to the left a little bit, look for IR signal, if no signal, blah blah blah...

My (original) code snippet:

let servo_pos = 70

let servo_pos = servo_pos + 5            'increments servopos value
if servo_pos > 225 then goto main       'if servo is full left then stop IR search
servopos 7, servo_pos                        'starts servo full left
irin [550,ir_wide_scan], A.1, ir_code    'look for IR signal
if ir_code > 0 then goto lock_on          'start maneuvers to home in on signal


My (post-CtC advice) code:

symbol pos = b1
symbol ir_code = b2

servo 7,150
pause 250

  let b3=1:debug:wait 3
for pos = 75 to 255 step 5 'increments servopos value
  let b3=2:debug:wait 3
servopos 7, pos 'starts servo full right
  let b3=3:debug:wait 3
let ir_code = 0
  let b3=4:debug:wait 3
gosub ir_sense
  let b3=7:debug:wait 3
next pos

  let b3=100:debug:wait 3
low c.0
pause 2000
high C.0
goto main

  let b3=5:debug:wait 3
irin [2000,ir_timeout],A.0,ir_code 'look for IR signal
  let b3=99:debug:wait 3
if ir_code = 5 then goto lock_on

  let b3=6:debug:wait 3


(The following is in regards to the original code. See the comments section for details on the modified code)

So what happens is the servo will go to position 75 and wait for .55 seconds while looking for the IR signal. After that, the servo backs up 75 "clicks" (to center/position 150 the first time through the loop) and then goes back down to 80. Then it waits for IR, it times out, the servo backs up 75 clicks (this time to 145), then goes to 85, and on and on it goes. When it eventually gets incremented to around 150, when it backs up its 75 clicks, it reaches the end of the servo's travel and it makes angry servo sounds as well. Very disconcerting.

If I leave out the irin command everything works as I expect.

Is this just the way it is or am I missing something? This thing is making me feel retarded.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

There is no loop in the subroutine you are showing. It is simply going through once and returning back to whatever routine it came from. --Little for/next I would think.

Mmm, I thought when irin timed out it would return to the beginning of the specified address like a goto command, hence my "loop." Nice trick with the ircheck2 sub.

A+, thanks m8!

I had this! I was able to find it! Woo Hoo.

Wherever you see writei2c, just substitute your servo command (I use a i2c servo driver) --You can get rid of the i2cslave thing too. Other than that, it should work straight away.Oh yeah --this one sweeps both directions so you can find the "edges" on either side of the beacon.


i2cslave $C2, i2cslow, i2cbyte
goto waitforbutton

writei2c 6,(1)
pause 250
for b21=1 to 255 step 5
writei2c 6,(b21)
pause 50
let b10=0
gosub ircheck
if b10=111 then main2
next b21
goto main2

writei2c 6,(250)
pause 250
for b20=250 to 1 step -5
writei2c 6,(b20)
pause 50
let b10=0
gosub ircheck3
if b10=111 then waitforbutton
next b20
goto waitforbutton

irin [30, ircheck2], d.3,b10
if b10=111 then
sertxd ("Right to Left ",#b21,LF,CR)


irin [30, ircheck2], d.3,b10
if b10=111 then
sertxd ("Left to Right ",#b20,LF,CR)

readadc 5,b9
if b9>200 then
gosub clearscreen
goto main
goto waitforbutton

serout c.0,N2400,(254,1)

Unfortunately the results are almost the same. I modified my code per your advice and added it to the original post.

Using the debug I found that when irin is called the servo moves back some 75 units and then takes a reading. When irin timesout and jumps to the ir_timeout subroutine, the servo magically turns back to where it was supposed to be during the irin command.

I even tried the servo command vs servopos. Perhaps the I2C interface with the servo gets around this crap somehow. I'm wondering if I should just turn off the servo pin before the irin command and turn it back on after irin.

You were right the first time --you are missing something really simple here...

Are you reusing a variable somewhere? Somehow the servo position variable is getting changed somewhere. I would put this:

sertxd ("I am at this point in the code and the var is: ", #variable_you_are_watching,LF,CR)

... in a ton of places within the code and keep an eye on the what your servo pos var is doing. This way, you can debug on-the-fly and figure out exactly where this is going wrong.

The modified code is the entirety of it. The debugs and pauses let me see what's happening almost realtime.

To get to even gorier details, as soon as the debug #5 and the three second pause clicks by (when the servo starts backing up), it can read the IR signal right then. So if the tx's pulse and the rx's servo timing is just right it almost looks like it's working perfectly. There's just this little servo twitch...

I'm at a loss. I will try the sertxd command just in case. Thanks Chris for beating on this with me. It's like a Live Show Help Segment lol 

Do you think the servo timer might be affected by the irin command? Maybe the timer gets commandeered for counting IR pulses, I don't know. Getting ready to forego using a servo in a standard way for this project. This might be an opportune time to free up pins and troubleshoot this problem with an I2C servo driver hehe.

I2C controllers are too expensive. I don't want to up-size to a standard servo for bigger onboard I2C brains either. Thanks again for the help, CtC. I'm just going to have the robot turn itself on its wheels instead of looking around with a servo.

Starting to get weary of picaxe limitations...

Perhaps it's time to switch to Arduino? You don't necessarily have to buy an original Arduino, a compatible board that can be programmed in the Arduino IDE and is designed for robots will be much better. I have used I2C and servos at the same time in Arduino with no problems. Take a look at the uBotino microcontroller and the Robot Builder's Shield for Arduino. I will make an example of using I2C with the uBotino board this weekend.

They think it has something to do with the clock dropping to 4mhz for the IR reading. Also if the bot is moving forward it will stop in its tracks when I run the IRIN command. Very annoying. There's a suggestion to make b.7 low previous to the IRIN command and then a SERVO 7,x command afterwards to get things back on track. That doesn't stop it from interrupting the motors however :/

bahbots 1280.... hmmm.. I did get paid today...