Communicating between 2 arduinos with digital pins

Is it possible to communicate between two arduinos directly using digital pins, supposing that both of the boards have the grounds (and possibly +5v) tied together?

For example, if I wanted to implement a hardware stepper motor controller using an Arduino, and I wanted to drive that controller with another Arduino, could I just run the digital pins from the master Arduino to the digital pins of the slave Arduino and read the output with the slave Arduino?

For example, if I wanted to implement a hardware stepper motor controller using an Arduino, and I wanted to drive that controller with another Arduino, could I just run the digital pins from the master Arduino to the digital pins of the slave Arduino and read the output with the slave Arduino?

Yes, but...

A motor controller typically uses two pins per motor - one for direction control and one for stepping. If the Arduino sending the signals has two pins to spare to send data to the other Arduino with the motor shield, what's the benefit of a second Arduino. Just drive the motor controller directly.

A motor controller typically uses two pins per motor - one for direction control and one for stepping. If the Arduino sending the signals has two pins to spare to send data to the other Arduino with the motor shield, what's the benefit of a second Arduino. Just drive the motor controller directly.

What motor shield? I never said anything about a motor shield.

I was going to use the slave arduino's digital pins to directly switch transistors or H-bridges to drive a 5-phase stepper motor. Dedicated drivers for 5-phase stepper motors are apparently only legend, which is why I would contemplate dedicating an entire arduino to the task. Then, I could use my other (master) arduino to control the slave arduino with the "2-pins" method.

If youre goin to have an entire Arduino running the motor, you might offload more of the processing to slave and use a higher protocol like serial. Uses only 2 pins for interface and you could send direction, steps, speeds, accelerations, and let the slave take care of the detials..

Back to the OP: I had to do that once (Connect two Arduinos together. See http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1287843378 )

Very simple ('cause I had no time to be fancy) Pin 1TX from Master to pin 0 RX on Slave. (That is the wavy white wire between the two Arduinos) The 5Vin line and GND line connected between them, Master board received the 8V supply jack.

CommunicationProtocol ?! I used Serial.write/read. Remember the reciver buffers 64 bytes, so there is no critical timing. The slave just reads as if it was normal USB/Serial input. The Master sent 5 digits in ASCII and a terminator. There was no ACK back (that would require a wire back) as there was no need.

When downloading new programs I had to remove the serial wire, else the slave display went crazy trying to display all the code [smiley=cheesy.gif]
This was conceived in inspired panic, day before the opening. BTW, the system ran without fault for the whole 3 months!

When downloading new programs I had to remove the serial wire, else the slave display went crazy trying to display all the code

This IS a problem if your inter-Arduino comms is on the same pins as your Arduino to programming PC comms.

EASILY avoided with NewSoftSerial... lets you send and receive serial for the inter-Arduino comms on other pins.

All explained at....

.... All you need to do is read "2nd Arduino" everywhere you see "Some Serial Device"

Serial would work pretty well if timing wasn't absolutely critical. I would rather implement an instant "direction, pulses" interface, though.

While it's good to know that serial can work, has anyone successfully done it using digital pins, or the digital pins from the master directly to the interrupt pins of the slave?

A two-pin control should be easy. Run your pulse into an interrupt and direction into another pin.

The ISR in the slave simply reads the other pin and sets a global variable indicating the fact that a pulse had occured and the direction requested.

You either wait a short time before sending another command (which would be the normal case anyway) or have a third handshaking line.

That will be about 100x faster than serial although serial has more options re different commands etc.


Rob

The following did something like what you are speaking of... the hard way, though. I'd use NewSoftSerial today...

The above uses handshake to start transmission from a slave, but then uses timing to watch a serial stream arrive.

You could adapt it to handle a datastream in which each bit (in the narrow, binary numbers, sense) is sent on demand, only for as long as host needs it.

You either wait a short time before sending another command (which would be the normal case anyway) or have a third handshaking line.

I don't understand this bit about waiting and handshaking.

If I want to implement a CNC-like interface with one line being direction, and the other line being pulses (motor steps), why couldn't I just have the slave-board ISR set a boolean that a pulse had occurred, and then in my slave-board program loop I can check that boolean and step the motor one step if it's true, then set it back to false?

There is a risk that pulses could come quicker than my program loop could step the motor in which case I would 'lose steps', but the only solution for that would be to reduce the pulse frequency from the master arduino...is that what you meant by 'wait a short while before sending another command'?

The stepper motors I'm trying to drive are 50,000 steps per revolution, so speed is rather important.

is that what you meant by 'wait a short while before sending another command'?

Yep.

While I'm not a big fan of using magic numbers (ie the "wait" time to determine the pulse frequency) that's exactly what I'm doing at the moment with a protocol I'm writing.

50,000 steps per revolution,

That's a lot, what's the RPM? A lot depends on that.

I don't think I'd be using the library func (digitalWrite) for that, as the protocol is so simple it might even be worth dropping into some ASM.

if (direction == CCR)  // set direction pin high or low
   asm ("cbi  PORTx,PIN_DATA");
else
   asm ("sbi  PORTx,PIN_DATA");

asm ("sbi  PORTx,PIN_CLOCK");  // pulse interrupt pin
asm ("cbi  PORTx,PIN_CLOCK");

Just a thought. :slight_smile:


Rob

That's a lot, what's the RPM? A lot depends on that.

I'm not sure yet. Less than 60rpm, though. If I'm willing to give up some (probably unneeded) resolution, I could trim the interface down by an order of magnitude or so and have the slave arduino step 10 or 100 steps for each pulse from the master arduino.

So that's 50,000 pps or 20uS per pulse. I hope there isn't much else to do. :slight_smile:


Rob

Indeed. Even if I chop my communication protocol by a couple orders of magnitude, I hope the slave arduino is actually capable of stepping the motor that fast.