Multitasking multiple motors

Hello,

I’m trying to control multiple motor + h-bridges at once. I would like the two control up to 4 motors (using two h-bridges, SN754410) simultaneously. is this possible? Right now I have set up the code to control two motor (one h-bridge) which works fine, but to test multitasking, I’m trying to make an LED blink on/off while the two motors do there thing (delays, etc.)

as of now, the LED only blinks as the loop cycles, not constantly while the motors run. If the blinking LED isn’t working correctly, I imagine the other motors won’t either.

Is there away to create multiple loops/cycles? so that the motors can be control simultaneously?

here is the code:

/* Controlling Two DC Motors Using H-Bridge + PhotoCell
* ------------
*
* Uses an H-Bridge (L293E or SN754410) to control the direction of two DC motors.
* Additional DC motor added.  Photocells used to control direction of each motor. 
* Modification to Physical Computing tutorial: 
* http://itp.nyu.edu/physcomp/Labs/DCMotorControl
*
* Modified 23 February 2007
* By Kyle Janzen
* http://kylejanzen.blogspot.com/
*
* based on an original by Physical Computing @ ITP
*/

  int photo1Pin = 1;     // select analog input pin for photocell1
  int photo2Pin = 2;     // select analog input pin for photocell2
  int val1 = 0;          // variable to store the value coming from photocell1
  int val2 = 0;          // variable to store the value coming from photocell2
  int motor1Pin = 3;     // H-bridge leg 1 
  int motor2Pin = 4;     // H-bridge leg 2
  int motor3Pin = 5;     // H-bridge leg 3 
  int motor4Pin = 6;     // H-bridge leg 4 
  int speed1Pin = 9;     // H-bridge enable pin 1-2
  int speed2Pin = 10;    // H-bridge enable pin 3-4 
  int ledPin = 13;
  
void setup() 
{

  // set all the other pins you're using as outputs:
  pinMode(motor1Pin, OUTPUT); 
  pinMode(motor2Pin, OUTPUT);
  pinMode(motor3Pin, OUTPUT); 
  pinMode(motor4Pin, OUTPUT); 
  pinMode(speed1Pin, OUTPUT);
  pinMode(speed2Pin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  
  // set speedPin high so that motor can turn on:
  digitalWrite(speed1Pin, HIGH);
  digitalWrite(speed2Pin, HIGH); 

}

void ledLoop() 
{
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(1000);                  // waits for a second
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(1000);                  // waits for a second
}

void mirrorLoop()
{   
    val1 = analogRead(photo1Pin);    // set val1 to equal reading of photo1Pin
    val2 = analogRead(photo2Pin);    // set val2 to equal reading of photo2Pin
    digitalWrite(ledPin, HIGH);   // sets the LED on
    if (val1 < 280) {        
    digitalWrite(motor1Pin, LOW);    // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, HIGH);   // set leg 2 of the H-bridge high 
    delay(val2*5);
    digitalWrite(motor3Pin, HIGH);
    digitalWrite(motor4Pin, LOW);
    delay(val2*6);
    digitalWrite(motor1Pin, HIGH);    // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge high 
    delay(val2*5);
    digitalWrite(motor3Pin, LOW);
    digitalWrite(motor4Pin, HIGH);
    delay(val2*6);      
    }else if (val1 > 350){   
    digitalWrite(motor1Pin, HIGH);   // set leg 1 of the H-bridge high
    digitalWrite(motor2Pin, LOW);    // set leg 2 of the H-bridge low
    delay(val2*2);
    digitalWrite(motor3Pin, HIGH);
    digitalWrite(motor4Pin, LOW);
    delay(val2*2);
    digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge high
    digitalWrite(motor2Pin, HIGH);    // set leg 2 of the H-bridge low
    delay(val2*2);
    digitalWrite(motor3Pin, LOW);
    digitalWrite(motor4Pin, HIGH);
    delay(val2*2);
    }else{
    digitalWrite(motor1Pin, LOW);
    digitalWrite(motor2Pin, LOW);
    digitalWrite(motor3Pin, LOW);
    digitalWrite(motor4Pin, LOW); 
    delay(val2*5);
    digitalWrite(motor1Pin, LOW);
    digitalWrite(motor2Pin, LOW);
    digitalWrite(motor3Pin, LOW);
    digitalWrite(motor4Pin, LOW);
    delay(val2*6); 
    }
}

void loop() {
   
   ledLoop();
   mirrorLoop();

}

let me know of any suggestions.
Thank you.
Kyle

Basically, you need to trigger events based on the current time (i.e. the value returned by millis()) rather than using delay(). For a basic example that might help you get started, see: http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay. It demonstrates how to blink an LED without using the delay() function.

I was playing around with "multi-tasking" the arduino just the other night to be able to execute specific code in different timeslots. Maybe that solution could be of use for you. It was actually a student who asked me and I answered quickly that multi-tasking was not doable, but curiosity drove me to test some things and I have a sketch where I can attach up to ten (just a limit in the code) callback methods and set the timeout individually for each one of them. Minimum timeout is 1 ms but there is no guarantee that the code will execute at the exact set time (depends on what you place in your callback methods).

Reply if you want a link to the files. I havn't had the time to put them somewhere yet, but they'll be up soon...

/Markus

Sounds useful, send 'em over.

I would like the link as well :)

Hi.

I uploaded a rough draft of the code to the lab site at k3. Here is a direct link to the zip:
http://webzone.k3.mah.se/projects/lab/Folder/index.aspx?page=6&tab=12&file=81&function=folder&id=9

There are some things worth telling you though:

  1. I havn’t considered the “overflow” in the millis() method, so it will probably stop working after about 9 hours
  2. You can’t have your own loop() method, see tab 2 (Taskmanager) for more on that!!! Just use the attachTask(int, void, long), detachTask(int) and changeTimeout(int) to control the different callbacks.
    …probably some other issues…

How to use:

  1. Write your variables and methods
  2. use attachTask(index, callback method, timeout) in the setup
  3. use detachTask(index) and changeTimeout(timeout) to alter your callbacks
    (I have tried changing and detaching tasks from other tasks and it works fine, you can start a callback and have another callback ending it after a certain amount of time…)

Good luck! Hope it will be useful!

/Markus

Here you can donload DuinOS, with preemptive multitasking, based on the robust FreeRTOS (www.freertos.org):

http://robotgroup.com.ar/noticias/20091102/duinos-sistema-operativo-multitarea-para-arduino

There is an example scketch with the package.

Regards, Julián

Even though this thread is old, I have to post a link to my TimedAction library. It offers virtually the same functionality described in the thread, but is not a multitasking scheme. It is a protothreading framework, and not a competitor of the DuinOS.

A TimedAction will always complete its actions before the next action gets called.

Happy Coding!

Hi, the link to download DuinOS had changed to this:

http://robotgroup.com.ar/duinos/wiki

There you will find (in the downloads section) the v0.1 and the v0.2 versions.

Regards, Julián http://robotgroup.com.ar