I2C Slave Arduino, does it block while reading and writing data?

I have not located an answer to this while searching but I have a project to create a motor driver board from the arduino to run a couple of geared down steppers. The gearing means the step rate will be pretty fast and I need to service the next step quit frequently. Perhaps as much as every 250 microseconds. I wanted to be able to add this to an I2C network to allow for a bigger brain to just tell it to drive forward, turn, move backwards, ect. I figured that to move even 16 bytes over a 400khz bus is going to be slow compared to the step rate at speed.

My question is though, does the I2C routine consume all the time as it reads in bytes? Looking at it it appears it's an interrupt handler but i didn't know if its a buffered deal or if you have to wait as it reads in each bit?

If It uses a buffer then I can issue new commands as the steppers are still running. If it blocks until all the data is read in then I will have to sit tight and execute commands one at a time and wait till the drive is done moving. Would need a HALT signal to tell it it has to stop right now because of a sensed condition.

1 Like

Its a hardware-hardware transfer, so bytes are being moved.
Have you considered SPI? Would be faster I think.

I didn't find too much in the way of any example of SPI slave for the arduino. I've had pretty decent luck with I2C but I just didn't see any mention of a buffer in the data sheet so I wasn't sure if it's got to grab each byte or if there is space for a few bytes until the master stops it.

Otherwise I can do it a byte at a time and allow time for the controller to service steps in between. SPI would be cool, I'm just not real familiar with it and I had planned for an I2C bus but plans can change.

Try this
http://arduino.cc/forum/index.php/topic,69734.0.html

also search for "spi slave", "Nick Gammon"

Thanks. I had not come across that one yet. Very helpful. I think there is an object for the Propeller that can reach 2Mhz for SPI communication so that would be a big boost from 400KHz.

Ok so I found a reference here:
http://arduino.cc/playground/Main/WireLibraryDetailedReference

It seems the hardware would be perfectly able to pull in the bytes and then notify me of the fact that data is waiting but the wire library at present ties up into waiting for transmission to end before releasing the processor so your interrupt is still called to signal available data but the MCU was tied up prior to that inside the library too. That's a bummer. The communication isn't really critical that it get there at a 2MHz clock rate but tying the processor up staring at the TWI hardware even at 400KHz seems wasteful.

Anyway, if I2C turns out to be better for me to go with then I could always send the data a couple bytes at a time with pauses in between. Even if the data took a milli-sec or two to get there it's not a big deal. I'll study up on the SPI routines shown in the other link too. Maybe even see if I can alter the wire library to not block.

1 Like

SPI should do it for you.

In there I have an SPI slave that generates an interrupt after the byte is received (one at a time). That should suit you. SPI is somewhat faster than I2C, and getting a byte at a time, inside an ISR, sounds like what you are looking for.

Yeah, saw your post when I looked up the search terms suggested above. Really good write-up. Just will come down to how important a couple pins are vs the other concerns. I'll have to give it a try here shortly.