Interfacing new driver board with Arduino

I'm wrapping up the design of a driver board that I started building for the homebrew pinball community. The idea is that a user can create a serial chain of these boards (RS-485) to drive as many things as they have on their machines. The original intent was to be driven by a P-ROC board, but it occurs to me it would be silly not to make it work with an Arduino, assuming the specs line up.

As the design stands today, the P-ROC board masters the bus by sending commands out serially on a standard CMOS output pin. This goes directly into a "Master Driver Board" that converts it to RS-485 to send down the rest of the chain. I suppose this Master board is similar to an Arduino RS-485 shield (form-factor aside).

The commands are currently sent out at 12 Mbps, since the P-ROC runs on a 12 MHz clock. Each transaction is approximately 32 bits long. I made up a very simple protocol.

I've never used an Arduino, but I know some people who would like to drive a chain of these boards with one. My questions:

Is the Arduino capable of interfacing to my Master board at 12 Mbps?
Can it supply 4 bytes per transaction fast enough not to starve the receiver?
Would you recommend I drop down to 8 Mbps so we can use the Arduino's SPI (MOSI pin?) at clock/2?
Any other suggestions?

Thank you.

  • Gerry

Would one of you with a 16 MHz arduino and an oscilloscope be willing to see if you can get 32-bit words to clock out of the SPI (MOSI pin) at 8 MHz contiguously (without getting starved for data)? I'd really appreciate it.

Each driver board transaction is 4 bytes long, with a minimum of a 10 clock gap between transactions. So if we can get 32-bit words to clock out contiguously, these driver boards will work with arduinos.

Many thanks.

  • Gerry

Unfortunately I don't know much about SPI yet, I want to and was just testing it on speed for my 5x5x5 cube-project.
I don't have an oscilloscope unfortunately, but adapted my sketch a little to send/read 1 Megabyte, which takes a little less as 2.11 seconds (2109524uS) using the code below.

More then fast enough for me, but I'm afraid it may be too slow for you.
Tested on a duemilanove-board with atmega 328 and 16 Mhz crystal.

#include "SPI.h"                 // necessary library
int ss=10;                       // using digital pin 10 for SPI slave select
unsigned long ti;                // stores processing time per cube
unsigned long ln= 0;             // longest time it took
unsigned long sh= 3000000000;    // shortest time it took
byte value = 110;                // standard byte to send by SPI
byte In;                         // Byte retrieved from SPI

void setup()
{
  pinMode(ss, OUTPUT);           // we use this for SS pin
  digitalWrite(ss, HIGH);
  SPI.begin();                   // wake up the SPI bus.
  SPI.setClockDivider(SPI_CLOCK_DIV2); // fastest rate
  SPI.setBitOrder(MSBFIRST);
  Serial.begin(115200);
  
}

void loop(){
  ti = micros(); // store time
  digitalWrite(ss,LOW);
  for (int layer=0; layer< 1024;layer++){ 
     for (int i = 0;i< 1024; i++){
          In = SPI.transfer(value); // send value (0~255)
     }
  }
  digitalWrite(ss, HIGH);
  ti = micros() - ti;
  if (ti < sh){sh = ti;}
  if (ti > ln){ln = ti;}
  Serial.print( "1 cube took : ");
  Serial.print(ti);
  Serial.print(" uS, shortest : ");
  Serial.print(sh);
  Serial.print(", longest : ");
  Serial.println(ln);

}

Interesting. Thanks for the reply. For my application, total bandwidth isn't nearly as important as being able to handle a single 4-byte send. I suppose if the execution of your code is completely consistent (why wouldn't it be?), then perhaps data can't be fed to the SPI fast enough for a contiguous burst at 8 MHz.

Hmm, so 8 MHz is only good for single byte transactions or transactions that can except idle time between bytes?

EDIT: It occurs to me that in your code the microcontroller will be spending cycles processing your loop iterations. So I still have hope that it could work if you had 4 SPI.transfer() commands back to back.

  • Gerry

I bought an arduino uno to get this working, but I'm having a couple of issues with the SPI interface.

First, the MOSI pin idles high, and I need it to idle low. I can probably change my protocol to change this requirement, but it would be nice if I could just change the idle polarity. I see the option to change the idle polarity of the SCLK but not MOSI.

Second, at 2 MHz, back-to-back SPI.transfer() commands have 1 clock (500ns) of idle time between them. At 8 MHz, the speed I need it to run, there are 3 clocks (384ns) of idle time between the transfers. Is there any way to speed this up, or am I stuck with it?

I really don't want to have to change my protocol to accept idle time between bytes if I don't have to.

  • Gerry

OK - I have reworked my driver board protocol to accept high idle cycles and to accept idle cycles between bytes within a transaction, and it's now working perfectly. The arduino is fully capable of controlling my driver boards at 8 MHz now.

In a few weeks time, I will be making the driver boards available. There are two main types of boards: Sink-16 and Source-Sink-8.

Sink-16 boards have 16 low-side circuits capable of activating high current devices operating on anything from 5V-80V DC.

Source-Sink-8 boards have 8 high side circuits to source up to 20V DC and 8 5V-80V low side circuits.

These were initially designed for the homebrew pinball crowd (to drive coils, motors, flashlamps, lamp/leds, lamp/led matrixes, etc), but they'll work well for a number of other applications.

There's more info at PinballControllers.com.

  • Gerry

The new driver boards are now available at PinballControllers.com. Current offerings include boards with 16 individual driver circuits (up to 80V DC) and boards that can control 8x8 matrixes with up to 20V DC using 8 source circuits and 8 sink circuits. Up to 16 boards can be chained together and individually addressed.

I've included an arduino sample driver board control sketch.

We put together a demo fixture for these new driver boards and made a demonstration video.

Here's the original demo video: - YouTube

Here's the fixture being driver by an Arduino Uno: PinballControllers.com Driver Board Demo with Arduino - YouTube