Shop OBEX P1 Docs P2 Docs Learn Events
How to move Boe Boe (Arduino version) while sweeping a 3rd servo back and forth? — Parallax Forums

How to move Boe Boe (Arduino version) while sweeping a 3rd servo back and forth?

dwalls32dwalls32 Posts: 1
edited 2014-12-10 23:00 in General Discussion
First let me apologize if this has been asked or answered previously.

I'm building a robot with my son through a club and we have the Boe Bot with Arduino. We can move forward, reverse etc, but I'm not sure the best way to move forward with the 2 drive servos while also sweeping a 3rd servo from 0 to 180 degrees and back. I can do both individually, making the robot move or making the servo sweep back and forth, but I would like it to do both at the same time.

What's the best place to start?

Thank you!

Comments

  • Bill HenningBill Henning Posts: 6,445
    edited 2014-12-08 12:41
    You have to multiplex the tasks in the loop() section, either time based or turn based, basically it is a form of cooperative multi-threading.
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2014-12-08 16:55
    Using the Servo object, drive servos are "set and forget." They'll keep going until you turn them off. The turret is something different, though, in that you need to set up a procedure for sweeping the servo.

    Here's where Arduino programming gets challenging. Where your initial playtime might have used servos with delay statements, you can't use them if you expect to have real-time responses from your sensors. You will need to use background timers, interrupts, and other features of the Arduino to coordinate everything. The idea is to empty out your main loop so there's little there. Everything -- or as much as possible -- is done as interrupted tasks.

    1. For push button bumper switches, you can use the Arduino's external interrupt feature to run a routine if your robot runs into something. On a Uno, you only get two of these, though if you need tmore you can also make use of the pin change interrupt feature of the AVR. This is most easily done with an addon library; but note that adding such a library may alter the use, choice, and/or behavior of the pins.

    2. For reading sensors like Pings and IR, use a background timer like MsTimer2, which allows your code to temporarily branch off at set intervals to service those sensors. Since this library uses a specific physical timer in the Arduino's microcontroller, you can only run one of these at a time. There are some "software" timers that allow multiple instances of themselves. Check the libraries page on the Arduino.cc site, and play around with a couple until you find some you like. Metro is one of my favorites.

    With one or more background timers added, you use them to rotate your turret servo and take readings. Bear in mind that most ultrasonic and IR sensors aren't reliable when they are in motion. You should only take a reading from them after the turret has stopped.

    I've outlined some of these techniques in my various articles I've done for SERVO. If you have back issues, or access to them, check out the ArdBot and ArdBot II. The original ArdBot articles were in seven parts, and covered much of this. You might also check out the coding they use for the (overpriced but capable) Arduino Robot.

    After crafting a couple of more complex Arduino robots you will gain an appreciation of the Parallax Propeller, which does not use or need interrupts. Its 8 cores can run simultaneous tasks. This is not to dissuade you from using your Arduino and what you have, just to note that chips like the Propeller were made for robotics and cooperative multitasking.
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2014-12-09 07:48

    After crafting a couple of more complex Arduino robots you will gain an appreciation of the Parallax Propeller, which does not use or need interrupts. Its 8 cores can run simultaneous tasks. This is not to dissuade you from using your Arduino and what you have, just to note that chips like the Propeller were made for robotics and cooperative multitasking.

    Gordon's final point can't be emphasized enough. The Arduino requires multi-tasking via interrupts and threaded code; the Propeller just deploys the multi-tasking in parallel by starting another Cog (aka core) when required or even starting and stopping tasks independently (not threaded code).

    As you try to thread more tasks via interrupts, you find your response slows and becomes more sluggish. With the Propeller, the original speed is retained as additional CPUs take on the added tasks rather than one doing it all.

    If you have a lot of sensors to read (inputs), along with your three servos (outputs), the threaded code can get very tricky to manage.

    It is worth-while to learn both approaches.
  • ercoerco Posts: 20,256
    edited 2014-12-09 08:11
    Real men use a BS2 to drive 2 servos, oscillate 2 more servos at wildly different speeds, flash LEDs and sing Christmas carols, all while pondering the fate of humanity. :) All multiplexed in software, per Bill's comment. Well possible and a good challenge on an Arduino, which will (as others have said) make you appreciate the multitasking Propeller after you have paid your dues and learned on a lesser chip.

    https://www.youtube.com/watch?v=inM04mo9D8Q
  • xanaduxanadu Posts: 3,347
    edited 2014-12-09 09:04
    Using the advice above I'd start out blinking two or three LEDs at different speeds, then moving onto servos.

    Servo timing is not very forgiving and IMHO not a good starting point.

    Check out "state machine".

    Also here is a good article - https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2014-12-09 13:05
    While it's always a good idea to start simple, on the Arduino there is no requirement to manually refresh servos to keep them going, as there is on an MCU like the BASIC Stamp. So it's simple to drive a bot and do other things. In the Arduino servo timing comes from a hardware timer in the AVR, and it runs independently from the program loop.

    The issue with a servo turret is that it's a good idea to move it to its desired location, and only when stopped take a reading. The typical way of doing this is with delay statements, which could be half a second or longer to allow the servo to fully transit. The problem of combining a rolling robot with delays for a turret is that the robot is no longer as reactive as it should be. The standard Arduino delay statement is blocking; code execution in the main loop stops until the delay expires.

    Flashing LEDs at different rates is actually quite easy on the Arduino with the help of timer libraries, such as Metro. The timer produces a state machine, and is the same approach taken in the Adafruit article. The difference is that they code out the timer as a class in the sketch, whereas Metro (and others like it) are separate linked libraries. The problem is Metro and other process timers aren't included in the Arduino IDE. So many users don't know they exist, or what they're used for.
  • xanaduxanadu Posts: 3,347
    edited 2014-12-10 20:48
    Good to know, I always forget about dedicated PWM pins cause I'm spoiled with the Propeller.
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2014-12-10 23:00
    Early versions of the Arduino IDE required a refresh every 50ms or more, but for a while now they use an improved version of the library that doesn't require explicit refreshing. It relies on the Timer1 internal timer (on the Uno at least), and can service arbitrary pins. It's all interrupt based, and works in the background. The problem with the approach, of course, is that it uses up a valuable timer -- one of just three in the Uno. Add IR remote control and a few other features, and suddenly there are no more hardware timers left.
Sign In or Register to comment.