Transferring an Integer under 100 us

Hello All,

I'm working on a project that has two Arduinos: one to drive a stepper motor and another to read a sdCard and figure out how many motor steps are required. Currently, I have the sd Arduino read the card, convert the file and fill an array with those steps. The sd card then sends the steps over to the motor controller arduino via I2C and the motor controller runs the array.

I want to make it so I don't require an array anymore. I want the sd Arduino to feed an integer of motor steps to the motor Arduino during the motor's downtime. I've calculated the downtime to being no less than ~120 microseconds.

Is there an easy way to do this?

Is there an easy way to do this?

Depends on what's easy for you.

With this description http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1241668644 you can increase the speed of the I2C to 400kHz. This way you should be able to transmit an integer in about 50us.

Although, from your description I don't get the reason to do so. Maybe you describe in a bit more detail to let us comprehend the reason.

Thanks pylon! I assumed the I2C bus was already confirmed to run in Fast mode. It lowers the time from ~330 us to ~130 us which still isn't enough. I also found that the Adafruit Touch screen shield does not like I2C set to Fast Mode.

The reason I need this done is to allow the motor to run without any interruption. I want to feed the motor controller arduino commands and values without interrupting the motor at its fastest speed. I also want to drop using an array so I'm no longer limited by the memory size on the controller.

How big are these values? Could they fit in a byte (0 to 255) instead?

You didn't mention that a touch shield is involved. How many integers do you need to transfer? 3?

The integers can go from -800 to +800.
I expect to send an integer every 100 ms. The integer is how many steps the motor must take for the next 100 ms period. I could break up the integer into a LSB and MSB and send only a byte per step (reassembling the bytes into an integer on the third step), but I am hoping there is a comm protocol fast enough to do it in one shot.

saiyanslayer:
The integers can go from -800 to +800.

Then that's a no go on my idea...

saiyanslayer:
I expect to send an integer every 100 ms. The integer is how many steps the motor must take for the next 100 ms period. I could break up the integer into a LSB and MSB and send only a byte per step (reassembling the bytes into an integer on the third step), but I am hoping there is a comm protocol fast enough to do it in one shot.

Well there is Serial Peripheral Interface, which can achieve faster communication between individual microcontrollers, and some other devices as well, than I2C. Unless your implementation somehow precludes using SPI, it could be a better communication option between the Arduinos at least.

With the steppers there is certainly SPI, but you are reliant on being able to read the SPI (and the data being present) between issuing steps to the stepper motor... which you have told us is 120us, which ain't a lot. Linking the two cards with an 8 bit bus as farseeker was alluding to is probably more reliable.. if the value is -800 to 800 you can do that with an 11 bit bus... i.e. 11 digital lines on one arduino linked to 11 digital lines on the other... but timing will be an issue I think.

This does demonstrate the inherent problem of stepper motors and microcontrollers... you have to keep telling the motor to keep going around, leaving little time for other tasks. Consider using a DC motor and an encoder with a PID controller algorithm... you'll have plenty of time (easily 5000-1000us) between the PID calculations to do all manner of things, like read the SD card thus eliminating an entire arduino.

The integers can go from -800 to +800.

This kind of integers does perfectly fit into two bytes. With a 400kHz I2C you need about 50us to transmit 2 bytes. How do you get to 130us?

pylon:

The integers can go from -800 to +800.

This kind of integers does perfectly fit into two bytes. With a 400kHz I2C you need about 50us to transmit 2 bytes. How do you get to 130us?

Recall that this project has to communicate between two Arduinos, then from the second Arduino to the stepper motors. With two transimissions of ~50 µs, plus the processing time on the second Arduino, I can see how the total time could exceed 130 µs.

Edit: Typo

For numbers of that magnitude, you only need eleven bits, not sixteen.

Far-seeker:

pylon:

The integers can go from -800 to +800.

This kind of integers does perfectly fit into two bytes. With a 400kHz I2C you need about 50us to transmit 2 bytes. How do you get to 130us?

Recall that this project has to communicate between two Arduinos, then from the second Arduino to the stepper motors. With two transimissions of ~50 µs, plus the processing time on the second Arduino, I can see how the total time could exceed 130 µs.

Edit: Typo

Correct. I also need to figure out which integer to send and to break the integer up, send the integer bytes, and then reassemble the integer.

Turns out SPI was the answer. I'm getting around ~52 us from start to finish. It's a bit more complicated to set up a Salve, but well worth the effort.

Thanks to everyone for the input.

I'm glad you found a solution that worked for you! :slight_smile:

Gee, I was going to suggest choose eleven pins and bit bang the heck out of them using the direct port manipulation method. You should be able to get at least that much speed out of it, maybe more like a few us per port (pair) update.

Why do you need 2 unos?. Can't you just read from the SD card and then output the value?

Mark

holmes4:
Why do you need 2 unos?. Can't you just read from the SD card and then output the value?

Mark

The second arduino is an Arduino Mega with the Adafruit Touchscreen shield. I don't want anything to interfere with the motor operation to ensure the motor's movements are as accurate as possible. I can't read from an SD card, decode the value into an integer, calculate a motor delay based on that integer, and then step a stepper motor while maintaining a touchscreen display without affecting the motor timing.

I had considered what you spoke of JoeN (11 line bus), but tomhow mentioned a timing issue and he was right. I tried setting up a 4 line bus and found it really hard to keep the two boards in sync. I also need the bus to be bi-directional so I know if the motor struck something, if it was rebooted on its own, if it's even on, or if it's receiving the sent info correctly. I found it really hard to program something like that in a reasonable amount of time. I was hoping something similar was out there, but SPI works great.