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

ir_wide_scan:
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
return


 

My (post-CtC advice) code:


symbol pos = b1
symbol ir_code = b2

main:
servo 7,150
pause 250

ir_wide_scan2:
  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
return

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

ir_sense:
  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
return

ir_timeout:
  let b3=6:debug:wait 3
return


 

(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.

**you have no loop **

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.

Hey, awesome!

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

main:
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

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

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

ircheck2:
return

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



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

clearscreen:
serout c.0,N2400,(254,1)
return

Fan-friggen-tastic

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!

Grrr…

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.

I don’t think it is "electrical noise"

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

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 

Hmm…

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.

And so it is

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

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.

From the picaxe tech guys:

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 :confused:

bahbots 1280… hmmm… I did get paid today…

Internal clock

I had not though of that and I didn’t know that the IR command used it. I guess it has to use some kinda timer in that it is measuring pulses. Hmmm.  I am using x2 units at 8mhz --might be the difference. Might be worth a shot to overclock your x1 to 8mhz and see what happens.

Oh, no, I have the 28X2 with

Oh, no, I have the 28X2 with its natural 8mhz as well. The IRIN command automatically drops it to 4mhz. I think that’s what messes things up.

I have an old version of the second PICAXE manual with only three appendices. There is a newer version with a fourth appendix that covers potential conficts with timers and interrupts that was an informative read. I’m still going to bang on this for awhile as it makes servos useless to me, at least as it stands.

I’ll try the LOW B.7 suggestion when I get home. Last night I tried using the PINSB command to make it an input just before the IRIN command in an attempt to take the servo offline with a subsequent SERVO command after the 4mhz processes were over. The whole thing went even more haywire so I nixed that idea. Maybe the LOW B.7 will work, I don’t know.

The problem has been

The problem has been resolved. The PICAXE guys suggested running a LOW B.7 command prior to the IRIN and then a subsequent SERVO 7,XXX to reinitialize the pin. It works flawlessly.

They don’t really know why there’s this conflict. Nobody knows exactly what the IR commands use to keep time either.