5
\$\begingroup\$

I have an Arduino (duemilanove) connected to a floppy disk drive and I can happily control the stepper motor using three pins on the ribbon cable to three digital pins of my Arduino (well 2 + the ground!).

I would like to control multiple motors at once, but using one Arduino per motor is going to be costly. I have read a bit about 555 timers. If I wanted to control two motors simultaneously stepping the motors independently of each other from my single Arduino, could this be done with a 555 timer IC for each motor?

The Arduino is "single threaded" so I want a way, I guess, to push the "commands" (signals) for driving the step motors onto another chip. This way the single thread of the Arduino can loop round each chip handing out commands for their attached motor (or maybe a method of queueing?).

I have read a little about interrupts on the Arduino also, but I don't think these will be any use will they?

\$\endgroup\$
  • 8
    \$\begingroup\$ I object to this question on the grounds of redundancy - the answer to "do I need a 555 timer" is always yes. It doesn't necessarily have to be connected, but without one you will experience symptoms of sadness, ennui and a worrying nagging feeling that you've forgotten something. \$\endgroup\$ – Optimal Cynic Nov 4 '11 at 5:58
  • 5
    \$\begingroup\$ Wrong! The answer to Do I need a 555 timer is always "NO". 555 timers are ancient crufty analog parts that take a lot of space, power, and require analog parts to do sloppy timing at best. There is really no excuse for them in new designs since the late pleistocene. There only remaining niche is clueless hobbyists and other amateurs. \$\endgroup\$ – Olin Lathrop Feb 29 '12 at 20:18
9
\$\begingroup\$

It can be done with interrupts. Attach an interrupt to a timer, so that it fires regularly (say once a milisecond), and use that interrupt to pop the next command off the top of a queue (could just be an array).

Your main loop then just adds commands to this array.

A single Arduino has 14 IO lines, so the number of motors you can control depends solely on the number of wires needed for each motor.

There are dedicated stepper motor driver ICs that are much better and simpler than using a 555 timer. The floppy drive will be using one (maybe embedded inside another chip). They usually accept simple up/down step signals and convert them into the proper sequence of pulses.

Edit

Example code, using the Timer1 library:

#include <TimerOne.h>

void test()
{
  digitalWrite(5,HIGH);
  delayMicroseconds(100);
  digitalWrite(5,LOW);
}

void setup()
{
  Timer1.attachInterrupt(&test,100000);
}

void loop()
{
}

This will cause digital pin 5 to go high then low once every 100,000µS - you see there is nothing in the main loop at all. Just replace the two digitalWrite() calls with the code to step your motors once. You do not need to specify any inter-step delay in that part of the code - that delay is set by the value of 100000 in the Timer1.attachInterrupt() function. To change the speed of the steps, change that value.

\$\endgroup\$
  • \$\begingroup\$ Hi Majenko, thanks for your answer! If I want to drive two motors separately though I can't see how this would work? Driving one motor uses the main loop of the Arduino. To step every 1ms for motor 1, the main loop is doing "step, delay 1, step, delay 1" so its "busy". Even with interrupts, how can I be stepping another motor independantly with a 2ms delay, like "step, delay 2, step, delay 2" etc.... \$\endgroup\$ – jwbensley Oct 22 '11 at 9:12
  • \$\begingroup\$ Would I have to be running interrupts even faster and being doing something like "step motor 1, step motor 2, delay $in_microseconds" so that I am flicking my main loop between the two motors? \$\endgroup\$ – jwbensley Oct 22 '11 at 9:14
  • \$\begingroup\$ You wouldn't have the delay in the interrupt. The delay is caused by the timer. You would just have "step1; step2" in the interrupt. That would then get called ever 1ms so both motors would step once per millisecond. \$\endgroup\$ – Majenko Oct 22 '11 at 9:25
  • \$\begingroup\$ Take a look at arduino.cc/playground/Code/Timer1 \$\endgroup\$ – Majenko Oct 22 '11 at 9:27
  • 1
    \$\begingroup\$ Just to explain a bit more, you can run the service routine for a timer interrupt every millisecond, in the service routine step each motor which it is desired to have step. A millisecond later you step them again. You could do this by having a "desired position' variable for each motor, and the service routine would compare that against a "current position" one to do decide if it needs to step, if so it issues an up or down step and increments/decrements the position variable. Make sure to declare any variables used by both the ISR and main thread as 'volatile'. Eventually, ramp the speed. \$\endgroup\$ – Chris Stratton Oct 23 '11 at 1:24
2
\$\begingroup\$

Provided that you will use 2 out pins per motor, you can control up to ( (GPIO pins) / 2 ) using a simple software mechanism called a scheduler.

If you are a beginner I suggest trying to implement a cooperative scheduler, it's probably the easiest to take on. If you have problems with that you should look for help In this book. It's a very nice, very complete free book called "Patterns for Time-Triggered Embedded Systems". It's well written and it contains great info from the basics over to pretty advanced stuff.

A good knowledge of the C language if recommended, but if you have problems with the likes of "function pointers" or such, don't give in - look up a few tutorials, once you catch the drift it's really really easy :)

Also, in my opinion, it would be much more towards your advantage learning theses software patterns than using 555 or multiplexers in order to achieve your purpose. These software tools are much more versatile and flexible.

\$\endgroup\$
1
\$\begingroup\$

You can control about 6 low voltage motors under 5v using this code and you adjust the timing for each of them by changing the code, or you can use the led as an output to signal 6 other relay for whatever timing you want. For higher power you might want another power source beside that, pretty simple to do it this way, hope it works for you.

/*
  Switch statement  with serial input

 Demonstrates the use of a switch statement.  The switch
 statement allows you to choose from among a set of discrete values
 of a variable.  It's like a series of if statements.

 To see this sketch in action, open the Serial monitor and send any character.
 The characters a, b, c, d, and e, will turn on LEDs.  Any other character will turn
 the LEDs off.

 The circuit:
 * 5 LEDs attached to digital pins 2 through 6 through 220-ohm resistors

 created 1 Jul 2009
 by Tom Igoe 

This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SwitchCase2
 */

void setup() {
  // initialize serial communication:
  Serial.begin(9600); 
   // initialize the LED pins:
      for (int thisPin = 2; thisPin < 7; thisPin++) {
        pinMode(thisPin, OUTPUT);
      } 
}

void loop() {
  // read the sensor:
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    // do something different depending on the character received.  
    // The switch statement expects single number values for each case;
    // in this exmaple, though, you're using single quotes to tell
    // the controller to get the ASCII value for the character.  For 
    // example 'a' = 97, 'b' = 98, and so forth:

    switch (inByte) {
    case 'a':    
      digitalWrite(2, HIGH);
      break;
    case 'b':    
      digitalWrite(3, HIGH);
      break;
    case 'c':    
      digitalWrite(4, HIGH);
      break;
    case 'd':    
      digitalWrite(5, HIGH);
      break;
    case 'e':    
      digitalWrite(6, HIGH);
      break;
    default:
      // turn all the LEDs off:
      for (int thisPin = 2; thisPin < 7; thisPin++) {
        digitalWrite(thisPin, LOW);
      }
    } 
  }
}
\$\endgroup\$
0
\$\begingroup\$

Depending on what else you plan to do with the microcontroller, one alternative might be to replace the Arduino with multiple ATTiny85 chips. They cost about $2.50 each and can be programmed via the Arduino using its IDE. See the following URLs for instructions.
http://hlt.media.mit.edu/?p=1229
http://www.youtube.com/watch?v=30rPt802n1k

\$\endgroup\$
  • \$\begingroup\$ Good out of the box suggestion. Full Arduinos are overkill on many projects once the concept is tested, and are easily replaced with a suitable smaller MCU with the bare minimum support circuitry. \$\endgroup\$ – Anindo Ghosh Nov 2 '12 at 21:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.