SPI transfer (read and write) and Transfer Data over TCP

The SPI device requires user to send 8 bytes of command before it will send an acknowledgement back to the core. After sending 8 bytes to the slave device, the core will have to wait for 50ms before sending command to read the acknowledgement data from slave in 8 bytes length.

SPI.transfer function has both data transfer and receive perform on the same time. Any suggestions, thanks.

How it works:
Transmit from Core to Slave Device: 0xFF 0xFF 0xFF 0x0D 0x00 0x00 0x00 0x00
Receive from Slave Device to Core: 0xFF 0xFF 0xFF 0x0E 0x0D 0x00 0x00 0x00

leeway, the SPI protocol calls for a single master clock to the slave so while it writes, it also reads. In your case, when you send the 8 bytes to the slave simply ignore the read data, wait the 50ms then do your reads. Typically, a “dummy” byte value (eg. 0xFF or 0x00) is sent to the slave for the reads to work. So logically, it looks like this:

for (8 bytes of data TO slave)
  SPI.transfer(data);

wait 50ms

for (8 bytes of data FROM slavve)
  data[] = SPI.transfer(0x00);

If there is a specific message structure from the slave, you would test for that in the receive portion of the code. :smile:

1 Like

Another question, how can I initialised multiple Slave Select pins (i.e. A2 and other available pins)?
By using SPI.begin() class function, it only initialise A2 pin as slave select pin.

You may use any other pin as a slave select for another device. Just make it an output pin in setup() with pinMode(thePin, OUTPUT) and then set it low/high as needed with digitalWrite(thePin, LOW) or digitalWrite(thePin, HIGH). Simple! :sunflower: :thumbsup:

1 Like

leeway, SPI.transfer() doesn’t control the A2 (SS) line. Instead, libraries will control the SS line by default by doing what zachary was saying:

digitalWrite(SS, LOW);
SPI.transfer()
digitalWrite(SS,HIGH);

This is done because there may be more than one peripheral on the SPI bus and each of their libraries needs to control their respective chip select lines. As zachary mentioned, you control the chip select for a specific device before and after the SPI.transfer. :slight_smile:

I am surprised of the output signal. I do not understand why slave (MISO) has signal first before MOSI. Furthermore the clock signal is irregular.

Any explanation for these? Thanks once again.

leeway, MOSI coming up first just shows the slave is fast at responding to its CS. What’s important is the clock, and it comes up after the CS is low and data is stable. As for the fluctuations in the SCK (clock) they do seem odd but all the data/clock edges look fine. Data on MISO & MOSI is captured on the rising edge of SCK and all the data is stable on those edges. Each group of bytes has 8 clock “cycles” (low-high-low) with some delay (clock = low) between bytes due to code delays most likely. So really, it all looks good!

HOWEVER, can I ask what your SPI device is? There are several things affecting how an SPI master communicates with an SPI slave based on the SPI modes required by the slave. Knowing which device you are trying to use would help. :smile:

my SPI device is C329 Camera module.

Reading that datasheet, that looks like an SPI mode 0 device with clock defaulting to low and the rising edge clocking into the slave (MOSI) and the falling edge clocking out of the slave (MISO).

SPI.setDataMode(SPI_MODE0);
1 Like

leeway, you may want to check out this article. It seems the C329 is tricky in SPI mode Do you have a library for this device? If so, I can take a look to see if I see anything that might need tweaking :smile:

It seems to work now. However, I have problem sending the JPEG image of 320 by 240 px through http to a PC or smartphone. How am I suppose to code such that the buffer can send to the client otherwise the buffer will be replaced by the next chunk of JPEG data using TCPServer and TCPClient functions. Furthermore, I do not know how to merge the JPEG packets over at the client side. Any advise?

Looks silly here, I tried to send all the image data through the TCP connection but it does not work (it hangs) which I think is probably due to limited amount of space in spark core.

Really confused here.