Best Software Coding for Zumo Motor Setup?

Two questions about using the Zumo motors. I’ve been trying to build a function based set of movements I can use with my kids to simplify what is going on. (For example, go forward, turn left, backup, stop, etc)

  1. In the examples I see for-until loops where the speed is run up from 0 to some number to get the motors moving or stop them. In other arduino code examples for other motors I’ve seen single commands to set the motor speeds to 200 or so, then zero. Is the gradual increase required or better for some reason?
  2. I’ve had to add delays (delay (500) etc.) between function calls (stop, turn right, go) to get my code to work. I’m new to arduino, but assumed I was working in a synchronous execution environment. Am I not? If not, how do I best deal with that without sacrificing the speed of the processor when putting together a program for mini-sumo?

The ramping up of the motor power is just to provide smoother acceleration. The motors will turn at whatever voltage you set them to so you need to gradually increase or decrease the voltage if you want to avoid jerky movements or loss of traction.

As for why you need to place delays in your code, we’d need to see the code to better understand what it is you are doing. How do your “stop”, “turn” and “move” functions work? Are they state driven or do they do blocking delays? Or are you using encoders to measure movement?

[code]//Libraries used
//#include <QTRSensors.h>
//#include <ZumoReflectanceSensorArray.h>
#include <ZumoMotors.h>
#include <ZumoBuzzer.h>
//#include <Pushbutton.h>
/*
This sktech incorporates movement with ultrasonic ping to determin distance
*/
ZumoMotors motors;
ZumoBuzzer buzzer;
//setup sensor pins
const int pingPin = A4;
const int sensorPin = A5;
//Name other variables
long duration, inches;
const int MAX_SPEED = 200;
int SPEED_NOW,s;
void setup() {
// initialize pins
pinMode(pingPin, OUTPUT);
pinMode(sensorPin, INPUT);
//flip right motor
motors.flipRightMotor(true);
SPEED_NOW = Start(0);
}

void loop()
{
inches = Ping();

while (inches <= 12) {
buzzer.play(">g32>>c32>g32");
SPEED_NOW= Stop(SPEED_NOW);
delay(500);
SPEED_NOW= BackUp(SPEED_NOW);
delay(500);
SPEED_NOW= StopB(SPEED_NOW);
delay(500);
SPEED_NOW= SpinRight(SPEED_NOW);
delay(500);
SPEED_NOW = Start(0);
delay(500);
inches = Ping();
delay(500);
}
delay(2000);
SPEED_NOW = GoForward(SPEED_NOW);
buzzer.play(">g32>>c32");
}

long Ping()
{
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
// A different pin is used to read the signal from the PING))): a HIGH
long microseconds = pulseIn(sensorPin, HIGH);
// convert the time into a distance
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}

int Stop (int SPEED_NOW)
{
// This is where we stop the robot
for (s = SPEED_NOW; s >= 0; s–)
{
motors.setLeftSpeed(s);
motors.setRightSpeed(s);
delay(2);
}
return s;
}

int StopB (int SPEED_NOW)
{
// This is where we stop the robot
for (s = SPEED_NOW; s = 0; s++)
{
motors.setLeftSpeed(s);
motors.setRightSpeed(s);
delay(2);
}
return s;
}

int Start (int SPEED_NOW)
{
// run motors forward 0 - Max
for (s = SPEED_NOW; s <= MAX_SPEED; s++)
{
motors.setLeftSpeed(s);
motors.setRightSpeed(s);
delay(2);
}
return s;
}

int GoForward (int s)
{
// run both motors forward
if (s < MAX_SPEED){
s = s++;}
motors.setLeftSpeed(s);
motors.setRightSpeed(s);
return s;
}

int BackUp (int SPEED_NOW)
{
// run motors forward 0 - 100
for (s = SPEED_NOW; s >= -100; s–)
{
motors.setLeftSpeed(s);
motors.setRightSpeed(s);
delay(2);
}
return s;
}

int SpinRight (int SPEED_NOW)
{
//This spin right goes so far it is pretty much a left turn
// run motors forward 0 - Max
for (s = SPEED_NOW; s <= 24; s++)
{
motors.setRightSpeed(s);
delay(2);
}
delay (1000);
for (s = 24; s <= SPEED_NOW; s–)
{
motors.setRightSpeed(s);
delay(2);
}
return s;
}[/code]

Because you need to read the sensor and control the motors at the same time you’ll need to make the code “state” driven which means using variables to keep track of what state the motors are in and what they are meant to be doing. It’s a little more demanding if you are new to programming.

Here is an example of what I mean:

#include <ZumoMotors.h>

#define FORWARD     0
#define STOP        1
#define LEFT        2
#define RIGHT       3
#define BACK        4
#define END         5

// sequence of commands and how long to run each (in milliseconds)
int cmd_sequence[] = 
{
  // action, duration
  FORWARD, 2000,
  LEFT, 2000,
  FORWARD, 2000,
  LEFT, 2000,
  STOP, 1000,
  RIGHT, 4000,
  BACK, 3000,
  END
};

#define MAX_SPEED   100
ZumoMotors  motors;

void setup()
{

}


void loop()
{

  service_cmds();

}

// seqeuncer

int cmd_index = 0;
unsigned long cmd_end_time = 0;

void service_cmds( void )
{
  unsigned long now = millis();

  if ( now < cmd_end_time )
  {
    // we are waiting for the current
    // command to finish
    return;
  }

  if( cmd_sequence[cmd_index] == END )
  {
    // no more commands to run
    motors.setRightSpeed(0);
    motors.setLeftSpeed(0);
    return;
  }

  // handle the next command in the sequence
  int cmd = cmd_sequence[cmd_index++];
  cmd_end_time = now + (unsigned long) cmd_sequence[cmd_index++];

  switch(cmd)
  {
    case FORWARD: 
      motors.setRightSpeed(MAX_SPEED);
      motors.setLeftSpeed(MAX_SPEED);
      break;
    case BACK: 
      motors.setRightSpeed(-MAX_SPEED);
      motors.setLeftSpeed(-MAX_SPEED);
      break;
    case RIGHT: 
      motors.setRightSpeed(-MAX_SPEED);
      motors.setLeftSpeed(MAX_SPEED);
      break;
    case LEFT: 
      motors.setRightSpeed(MAX_SPEED);
      motors.setLeftSpeed(-MAX_SPEED);
      break;
    case STOP: 
      motors.setRightSpeed(0);
      motors.setLeftSpeed(0);
      break;
  }

}

This creates a list of commands and how long they need to run for and then has a function that executes the commands in sequence and manages the timing too.

You basically need something like this. There are lots of was to achieve this. The code above is the simplest example I could come up with but hopefully it helps you understand the problem you are facing.

Thanks for the code. I think it will take me a bit to understand it fully. I’m familiar with event driven programing, but this appears to be a little different animal.

And if I’m looking to do something like “If you’re less than 8 inches from an obstacle stop” Do I put that as an if statement in the void loop or in the sequencer? Any recommendations on good material for learning more about state based programing? I keep running into the QP framework and not much else. http://playground.arduino.cc/Code/QP#.Uwz99kjTlCo

I don’t personally have any recommendations on good books for software engineering. I started programming professionally a long time ago so I don’t have a good perspective anymore. Maybe others here can recommend something.

As for where to put the if statement… it’s your code. Try it one way, and if you don’t like it, try it the other. :slight_smile:

Fair enough. Thanks for all your help.