Go Down

Topic: How fast can Arduino Uno switch ouput pins? (Read 2430 times) previous topic - next topic

jonek

Hi all,

I have only just discovered 'Arduino' and I am looking for some advice on whether an Arduino Uno will do what I need.

My project it to drive a very old robot arm that was known as a 'Minimover 5' 25 years ago!
It has 6 x 4-pin stepper motors and presents a TTL (5 volt) interface which used to connect directly to a Commodore computer (but I did make a Sinclair ZX Spectrum interface back then). Now I want to drive it via USB.

The interface is really simple using 8 TTL level outputs. 3 are used to 'address' each of the 6 motors, 4 used to 'set' the stepper motor pattern, and 1 to 'strobe' the data into the stepper motor coils.

My question is: how fast can a Arduino Uno change the output pattern? That is, what is the maximum frequency that a single output pin can be switched on/off? As you can see, to move all 6 motors 1 step requires 6 patterns to be output and for each the strobe to be toggled = pattern/strobe on/strobe off... so probably 18 changes (IOs) to make all 6 motors 'simultaneously' move 1 step.
(I have a simple Velleman K8055 card but that can only manage 125 IOs/second which moves the motor(s) very slowly - I need something like 10 to 20 times that speed.)

I am thinking that the Arduino could host a basic "Robot OS" and take movement commands from a host PC via USB so a PC application (Java) will handle the high level functions and the Arduino application will handle lower level hardware driving.

Does this sound feasible? If not, any thoughts on what else I should consider?

Many thanks,
- jon.


magagna

Short answer: yes, easily.

Slightly longer answer: 125 IOs / second * 20 = 2500 / second. A standard Arduino runs at 16 Mhz, which means it has 6400 clock cycles to do what you need. Even the (relatively) slow digitalWrite() command takes only about 17 clock cycles, leaving you lots of time to do other stuff.

Good luck!
http://en.wiktionary.org/wiki/magagna <-- My last name.  Pretty apt.

Techone

#2
Jan 07, 2012, 05:05 am Last Edit: Jan 07, 2012, 05:50 am by Techone Reason: 1
@jonek

That look like an impresssive project doing with Arduino.  My guess will be possibe using the Arduino.

Quote
It has 6 x 4-pin stepper motors and presents a TTL (5 volt) interface which used to connect directly to a Commodore computer (but I did make a Sinclair ZX Spectrum interface back then). Now I want to drive it via USB.


I am just curious...Did you use a PIA chip to connect with the Commodore ( assuming 64 ? ) or with the Sinclair ZX ? I wonder what kind ? ( 8000 series or 6800 series ) or others type of PIA.

Quote
My question is: how fast can a Arduino Uno change the output pattern?


I did a tread regarding the output speed. I measured it, I improve it using a mix of ATmega328P assembly and Arduino code to get the output as fast that I can. Too bad I can remember where in the forum it is... <-- I can't find it !!!  :~


Edit : I found it... It was in Electronics... Here the link : http://arduino.cc/forum/index.php/topic,72049.0.html

Here the code : The code was included in the tread. I got pictures and others codes. I just can find the tread !!!  :~  What give ???

Anyway, I am just trying to help.  The code is the latest and the fastest I can get the atmega / arduino output pin ( 12 ) . just put a scope at pin 12 and see for yourself. Place a 10 K resistor between pin 12 and GND.

Code: [Select]



void setup()
{
 pinMode(12, OUTPUT);
__asm__("LDI r16,0x10\n\t"); // set data to send to port B B00010000 = 16 = Ox10
__asm__("LDI r17,0x0\n\t"); // set data to send port B = 0
}

void loop()
{
   // The asm OUT instruction requires an ATmega port number for the target.
   // From iom328p, we see how it defines Port B in such a way that the
   // C compiler can access Port B.
   // #define PORTB _SFR_IO8(0x05)
   //
   // Bottom line: The ATmega328p port number for Arduino Port B is 0x05.
   //
   //
   // So: heres' the asm to affect output bits of Arduino Port B,
   // given that Artuino Port B is ATmega328p port 5
   __asm__
   (
       "startLoop:"
       "  out 0x05,r16\n"
       "  nop\n"
       "  out 0x05,r17\n"
       "  nop\n"
       "  # Use relative jump to get back to the start of the loop\n"
       "  # It's a 2-byte operation, whereas jmp takes three bytes\n"
       "  rjmp startLoop\n"
   );
}




It is possible to do this project. You will needs external circuit ( for the motors ) use a serial to parrallel like 74HS595 to save I/O pins, maybe use a secondary microcontroller acting like a slave or multislave...

just brainstorming here...

cr0sh

Whatever you do, try to keep the interface to that robot as -separate- from the base electronics as possible. What I mean by that, is use the interface as presented; don't go hacking at the internals of the base PCBs or anything. If there is an on-board port (like a DB25 or similar), use that. Pictures I have seen of similar vintage arm robots typically used such an interface, or have a ribbon cable terminated in an IDC connector or such (if yours has such a dual-row IDC connector - find or build a mating set of pins, perhaps mounted on a PCB with a standalone Arduino and FTDI interface or such).

Why do I say all of this? Because that arm is likely worth some money to a collector (if it isn't personally meaningful to you). While it likely isn't as collectible as the Armdroid (and sundry knock-offs), it is still considered a collectible on the vintage robotics market. Blow out the circuitry or otherwise hack it (unless you had no choice - and even then, it would be preferable to try to restore it), the value of it would probably plummet.

But - if you can make (and publish or sell - your choice) an interface system that could just be plugged in to a "standard" Minimover - you might have a small following (don't expect to get rich off this, though); I'm sure there are more than a few people out there who would love to hook their Minimover up to a more modern machine.

Your idea, as others have indicated, is very possible to implement; I don't think you'll have much if any of a problem doing do - good luck with it, and keep us posted on your progress (I've long wanted a Minimover, or an Armdroid, or some other early robot arm of that era, but I can't afford the collector's prices now; I have to settle for my small Armatron collection, and my OWI-535 Edge).
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

hardcore

owwww
I have a headache, some of these numbers do not look right.

16mhz = 1 second/16,000000 = 62ns
using the  assembler timings in the data sheet.
Code: [Select]

void setup(){
       DDRA  = B11111111;
        PORTA = B00000000; // sets digital pins low   
        DDRC  =  B11111100; //  technically the R/B lines are an input, but we have seen some datasheets writing to it!!
        PORTC = B11111111;
      LogicAnaliser();
      }
     
void loop(){
  // while (1 == 1){
// PINC= B00001000;
//unroll the loop to see just how fast we can go!!
__asm__(
      "LDI r16,0x80\n"
        "Loop:\n"
        "out 0x06,r16\n"
        "out 0x06,r16\n"
        "out 0x06,r16\n"
        "out 0x06,r16\n"
        "out 0x06,r16\n"
        "out 0x06,r16\n"
        "out 0x06,r16\n"               
        "rjmp Loop\n");
//  }
}


  void LogicAnaliser(){
        cli();
        PORTA = B10000001;    // sets digital pins of (port A) 7 & 1 HIGH
        // sei();
    }



From the above code we can see that we can toggle an I/O line about 3 times every 200ns, the loop timing can be seen after that.
Now obviously a program consists of more than just 'outs' , but it needs to be remembered that most physical hardware operates in the 'mS' time range nearly 100,000 times slower than we can write a port.

See the attachment for the physical analysis by the logic analyzer (when the administrator allows upload of a 41k file)


nmz787

Using the hardware Timers of the Atmega, you can easily do 4 or 8Mhz (I can't remember which, and I'm bad at math!) of GPIO toggling.

See the section on timers here, for some quick examples:
http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

dc42

If you're concerned about speed then I suggest driving the 8 inputs direct from Arduino pins, with all 8 of them on the same physical port (or possibly the 4 + 3 on the same port and the strobe line on a different port). Then you can write the motor selection and stepper pattern in one go instead of having to make 7 digitalWrite calls.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

jonek

Many thanks to you all for your fast responses, useful help and great encouragement!
I have ordered my first Arduino Uno and I'm looking forward to making that old arm go again after so many years! (And after 4 house moves, 4 new jobs and 4 children!)

For Techone:
Quote
I am just curious...Did you use a PIA chip to connect with the Commodore ( assuming 64 ? ) or with the Sinclair ZX ? I wonder what kind ? ( 8000 series or 6800 series ) or others type of PIA.


The Mini-Mover 5 had a 40-way ribbon cable with an IDC edge-connector.
If I remember correctly, the Commodore (I assume '64' too but was not that familiar with it.) had a rear edge-connector that the MiniMover was designed to plug into. I suppose it had a parallel interface which was driven by Basic 'peek' and 'poke' commands.

On the Sinclare(s), the rear edge connector exposed the Z80 bus lines so I built a board with an 8255 PIO with some simple TTL logic to map it into the IO address space.

For cr0sh:
Quote
Whatever you do, try to keep the interface to that robot as -separate- from the base electronics as possible. What I mean by that, is use the interface as presented; don't go hacking at the internals of the base PCBs or anything. If there is an on-board port (like a DB25 or similar), use that. Pictures I have seen of similar vintage arm robots typically used such an interface, or have a ribbon cable terminated in an IDC connector or such (if yours has such a dual-row IDC connector - find or build a mating set of pins, perhaps mounted on a PCB with a standalone Arduino and FTDI interface or such).


Yes, good points. I always intended to use the existing interface. I found a couple of other projects on the web where they had replaced the internals for 'educational reasons' but I don't want or need to do that. If an 4 Mhz Z80 can drive this then I don't think I'll need to change it!

I'll keep you updated but don't expect immediate results - my projects are often incredibly slow!


Techone

Quote
On the Sinclare(s), the rear edge connector exposed the Z80 bus lines so I built a board with an 8255 PIO with some simple TTL logic to map it into the IO address space.


In that case, a arduino will be fine. A arduino is already PIO buit-in , just use the same output of the PIO and connect the same way to the arduino. Let say for example you use 8 output going to the robot, than use 8 output pin of the ardiuno and program the arduino. ( do a test program to see it is working fine ).

I did a project like that using a Commodore 64 to control a RS arm robot using the parrallel interface using peek and poke ( I think ...? ), hey I did this in 1986.

Go Up