The task I need to accomplish is as follows:

I have an analog/digital converter that sends out a 10-bit signal. This signal needs to be transferred to an Arduino Uno using the SPI protocol. Because the SPI protocol works with a 16 bit pattern I need to expand the incoming signal. The slave Arduino then needs to put out the transferred number in decimal.

I imitated the ADC with another Arduino Uno, setting it as master, but unfortunately at the time I only had one Arduino so I couldn't test my code. Furthermore, I don't really have a clue how to "expand" a 10-bit signal to a 16-bit one. Can someone please explain it to me and have a look at my code?

Code for the master Arduino:

#include <SPI.h>
#define SS 10
#define MOSI 11

void setup() {
  pinMode(SS, OUTPUT);
  pinMode(MOSI, OUTPUT);
  SPI.beginTransaction(SPISettings(62500, LSBFIRST, SPI_MODE0));

void loop() {
  byte x=0000001101;
  byte y=0011111111;

Code for the slave Arduino:

#include <SPI.h>
#define SS 10
#define MOSI 11

void setup() {
  pinMode(SS, INPUT);
  pinMode(MOSI, INPUT);

void loop() {
  byte x=SPDR;
  byte y=SPDR;

A byte is only 8 bits, so your code:

  byte x=0000001101;
  byte y=0011111111;

won't do what you think it does.

A 10 bit value will be stored as an int (which is 16 bits) or 2 bytes.

Assuming it is an int then this will convert it to two bytes.

 const int adcData = 0x03FF;  // From ADC
 byte dataToSend[2] = {0, 0}; // Initialise it to zeros
 dataToSend[0] = (adcData & 0xFF00) >> 8;  // didn't really need the bit mask just to make it clearer.
 dataToSend[1] = (adcData & 0x00FF);
 // Now send dataToSend via the SPI bus.

To reassemble the data on the otherside:

 byte dataReadFromSPI[2];  // Filled with the data read from the SPI
 int adcData = 0;
 adcData = (dataReadFromSPI[0] << 8) | (dataReadFromSPI[1]);
  • Please note that 0000001101 is not a binary number in C/C++. It is actually octal (577). GCC allow an extension of number literal syntax for binary numbers. 0b0000001101 or the Arduino style B0000001101. May 3 '17 at 9:12
  • Could you please also explain how to transfer a whole array over the SPI protocol. I struggle a bit with that one...
    – Xenox
    May 3 '17 at 12:30
  • I haven't used SPI, but you should be able to find some example code. There will be a function that writes some data to the SPI bus, it will probably accept a single byte, so it may well be as simple as calling it twice. There is usually some start transmission and end transmission functions, make sure you call this write function between these two calls. May 3 '17 at 14:45

Can someone please explain it to me

the answer depends on the transfer protocol: whether the data needs to be left or right aligned.

after that, you just need to break down the transfer into two 8-bit spi calls, like the one below:

//transfer 10-bit spi, right aligned, msb first
void spi_write10(uint16_t dat) {
  dat = dat & 0x3ff;  //bound data to lowest 10 bits
  spi_write(dat >> 8); //send msb first
  spi_write(dat); //send lsb last

in your main code, you should then activate the cs line accordingly:

  spi_select(SPI_CS); //lower device cs line
  spi_write10(dat); //send data, lowest 10-bits
  spi_deselect(SPI_CS); //end transmission

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.