Is there a 'Software SPI'?

In one of my applications the SPI pins are occupied by a motor shield but I want to use the SPI bus too. Is there any possibility of using a soft SPI bus on other pins? Given that people have created a software UART it doesn't seem completely out of the question, but I can't find any mention of this being done/tried.

I think this is what you want:

Good luck!

you are talking about bit banging SPI

shiftOut() is bit banging, pretty much exactly what you are looking for, see official Arduino reference for details

but please consider that SPI is designed to be used for multiple devices, so you shouldn't need to have a separate SPI bus for separate devices, unless you absolutely need parallel data transfer rates

Hook up your second device to SCK, MOSI, MISO, and give it its own SlaveSelect pin - that's the way SPI is designed to operate.

I do understand that multiple SPI devices could be connected to the same SPI bus; that's not the problem.

I only have one device that needs SPI, but the SPI pins are already being used for other purposes. I'll have a go at replacing the stock SPI API with one that implements the 'bit banging' approach that described here. Thanks for the suggestions, and especially thanks to magagna for the link to an example.

if you read datashet of atmegaxxx, you'll see that is possible to use USART as SPI..you can search via google if there are libraries for this purpose,or you must implement this..

frank26080115:
shiftOut() is bit banging, pretty much exactly what you are looking for, see official Arduino reference for details

I'm pleased to see that the SPI API uses a class and a static instance, so it should be possible for me to derive a 'Software SPI' subclass from it and use instances of that anywhere that the hardware SPI could be used. But I'm still not quite clear what is the best way to implement the software SPI. At first I thought that shiftIn() and shiftOut() were the answer, but I don't see how to achieve the bidirectional concurrent transfer with those - is 'bit banging' the only option here, or am I missing a trick?

...At first I thought that shiftIn() and shiftOut() were the answer, but I don't see how to achieve the bidirectional concurrent transfer with those - is 'bit banging' the only option here, or am I missing a trick?

That's correct, shiftIn()/Out() aren't for bidirectional communication at the bit level. If you can program both communication endpoints you could use shiftin/out to communicate full bytes at a time by alternating calls...it would be slower, but you may not need to send massive amounts of data back and forth so that may not matter. If you only have control over the Arduino side and the other component only speaks hardware SPI, obviously this won't work....

As I was typing this an idea comes to mind -- what about using one of those remap-any-pin shields to swap some lines so your hardware SPI pins are freed up?

[edit] - This is what I'm talking about Go-Between Shield - DEV-11002 - SparkFun Electronics?

I'm in the UK which reduces my supply options a bit - I only found one in stock in the UK and it's in the post now. But it still goes against the grain to throw hardware at a problem which seems relatively feasible to fix in software so I'm going to keep pushing on with the idea of a software SPI.

ArduinoSoftSpi

We are releasing Arduino code that enables the use of an SD-card and an APA102/spi led strip on the Teensy 3.1 (and other arduino) platforms.

This one-header library specifies a highly optimized software implementation of SPI. This ArduionSoftSpi is estimated to be able to drive two thousand APA102 pixels @ ~30 fps, based on a test of 435 pixels running at 4ms refresh rate on a Teensy 3.1.

Using a software implementation of spi eliminates the SPI conflict when attempting to drive the APA102 leds and also reading from an SdCard.

This code was pulled from a beta implementation of another library.

Git it here:

Zackees

PS: We forgot which library we pulled this code from. It definitely wasn't us who wrote it originally. If anyone recognizes the original code please send us a link so that we can amend the attribution!

1 Like