6

I am developing an application where an Arduino Pro Mini communicates with a 12-bit ADC over SPI. The communication is one-way, meaning that the ADC will only send data back to the Arduino, not receive any. The MOSI pin is therefore not required in my application, only SCK and MISO.

I wish to know if there is a way to have the Arduino SPI library ignore the MOSI pin, and controlling the clock pin directly. The ADC requires 16 clock cycles to perform one conversion, sending the data back on the last 12 clock cycles. The way I have implemented it is by using SPI.transfer16() to get 16 clock cycles, and storing the return value in a 16bit variable. The downside to this is that the MOSI pin is driven, and I can therefore not use it for other purposes. I would very much like to be able to generate 16 clock cycles without the need for driving MOSI. Any ideas?

Fulcrum
  • 61
  • 4
  • 1
    SPI devices communicate in full duplex mode. Cant you use other interfaces that use less wires in their standard? – Dat Han Bag Nov 05 '16 at 13:33
  • Switching it to an input should disconnect it from SPI. Otherwise, it will be MOSI. – Ignacio Vazquez-Abrams Nov 05 '16 at 13:37
  • 1
    You could always use bitbanging in the form of [shiftIn](https://www.arduino.cc/en/Reference/ShiftIn). – Gerben Nov 05 '16 at 14:35
  • @IgnacioVazquez-Abrams That would be a good solution if I wanted to use the MOSI pin as an input. However, I require it to be an output. – Fulcrum Nov 05 '16 at 14:39
  • @Gerben That looks viable. But I worry that it might not be as reliable as the hardware implementation. – Fulcrum Nov 05 '16 at 14:41
  • The SPI feature varies on different processors. The Arduino Pro Mini uses a ATmega328. Either you need to download the appropriate SPI (and other) libraries from github and alter them - or read the ATmega328 chip spec. It may be you can control the ATmega328 MOSI pin by simply using the pinmode() call and defining it as an output like you want. Or you may be stuck in a situation where the ATmega328 is either in SPI mode and controlling all SPI pins or not in SPI mode and letting you control all SPI pins. – st2000 Nov 05 '16 at 15:00
  • @st2000: I guess I'll just have to do some experimenting and see what works and what doesn't. – Fulcrum Nov 05 '16 at 15:29
  • @yabbadabba: Yes, as Gerben already recommended. Could possibly be a solution. – Fulcrum Nov 05 '16 at 15:29
  • The hardware features are so nice, because they're implemented in hardware. Theoretically, it would require changing the hardware itself. If you really need one extra pin, you could use an I/O expander (SPI or I2C) or a bigger chip. – Paul Dec 08 '16 at 13:54

2 Answers2

2

In microcontrollers, the GPIO pins have a multiplexer to select what the pin is used for. When you use the Arduino SPI library, the initialization function will set the multiplexer to MOSI for that pin. You should be able to run your own initialization for that pin and overwrite whatever the SPI initialization function did. Just make sure to call your initialization after SPI.begin(). This is the simplest solution.

If that doesn't work for some reason then you can dig into the source code for the Arduino SPI library. This isn't too hard either.

Bitbanging is the hardest solution and shouldn't be necessary for your application.

Joey M
  • 149
  • 1
  • 4
  • This solution worked for me. I wanted to use the MISO pin for DC on a SSD1331 display. I privately modified the AdaFruit library constructor to call pinMode after SPI.begin() and it worked. – Brian Erickson Jan 12 '18 at 16:59
0

You are using ADC which I suppose you have no way of changing firmware or anything to modify the protocol.
According to SPI protocol, when Slave receives a byte, it sends byte kind of a two shift registers in circular buffer. So even if your ADC finish the conversion it wont start communication protectively the protocol doesn't allow it.
In case if you have other ADC IC which is programmable you can implement your protocol but it wont be SPI it will be your own protocol, so be assure of it.

duck
  • 1,258
  • 10
  • 27
Devidas
  • 138
  • 3