SPI communication using two arduinos

I am noob and i have just started ide using for project. I have facing difficulty in transfering data of 2048 byte from two arduinos uno by master to slave using Serial Peripheral Interface protocol. As my arduino limited memory is 2048 but i want to transfer them in packets of 2 byte. Please help..

As your question has nothing to do with the operation of the IDE your topic has been moved to the Project Guidance category of the forum

What are you going to to do with each of the packet of bytes that you receive and what code have you written so far ?

1 Like

what arduinos are you using?
SPI is tricky to use for interprocessor communication
why not use serial?

1 Like

Arduino uno

By using packetd of 2 byte it will easily transfer data i guess packest means the chunk size.

Master
#include <SPI.h>

const int ssPin = 10;   // Choose any digital pin for SS
const int arraySize = 2048;
byte dataToSend[arraySize];

void setup() {
  Serial.begin(9600);
  SPI.begin();
  pinMode(ssPin, OUTPUT);
  digitalWrite(ssPin, HIGH); // Deselect slave initially

  // Generate a triangular-like wave
  for (int i = 0; i < arraySize; ++i) {
    dataToSend[i] = map(i, 0, arraySize - 1, 0, 255);
  }
}

void loop() {
  digitalWrite(ssPin, LOW); // Select the slave

  int chunkSize = 2; // Adjust as needed, depending on your communication requirements

  for (int i = 0; i < arraySize; i += chunkSize) {
    for (int j = 0; j < chunkSize; ++j) {
      SPI.transfer(dataToSend[i + j]);
    }
  }

  digitalWrite(ssPin, HIGH); // Deselect the slave

  Serial.println("Data sent to slave.");
  delay(1000); // Wait before next transmission

  // Your other non-blocking tasks can go here
}


Slave

#include <SPI.h>

const int ssPin = 10;   // Match with the SS pin on the master
const int arraySize = 2048;
byte receivedData[arraySize];

void setup() {
  Serial.begin(9600);
  SPI.begin();
  pinMode(ssPin, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(ssPin) == LOW) { // Check if slave is selected
    int chunkSize = 2; // Match the chunkSize used by the master

    for (int i = 0; i < arraySize; i += chunkSize) {
      for (int j = 0; j < chunkSize; ++j) {
        receivedData[i + j] = SPI.transfer(0);
      }
    }

    // Visualize receivedData on Serial Plotter
    for (int i = 0; i < arraySize; ++i) {
      Serial.println(receivedData[i]);
    }

    Serial.println("Data received from master.");

    // Process receivedData array as needed
  }
  // Your other non-blocking tasks can go here
}


Can someone help me out it's very urgent....

Do either of those sketches compile on a Uno ?

1 Like

How far apart are the two Arduinos, less then 25cm/10" I hope. There are many other protocols that will send a lot more then two bytes and validate the message when received.

Yes we can change the packet byte means the chunk size

Yes they compile both of them but the output in select monitor it is blank

Can anyone give the corect code for master and slave.
In hardware connection i have connect all the four conection of spi i.e slave select mosi miso and serial clock and ground of both arduinos

Forum is not a free give away shop fixing what ever there is. You already got the tip that SPI is not favourable...

Find useful guides on SPI communication with Arduino and other micorocontroller here
SPI Communication between Two Arduino Boards

When I compile the master sketch with a Uno as its target board I get this

Sketch uses 2286 bytes (7%) of program storage space. Maximum is 32256 bytes.
Global variables use 2257 bytes (110%) of dynamic memory, leaving -209 bytes for local variables. Maximum is 2048 bytes.
data section exceeds available space in board

Compilation error: data section exceeds available space in board

I would like to request you for reading the following points carefully about the working principle of SPI Protocol and then prepare your Master and Slave sketches to send/receive 1-byte data. After that you store your 2048 bytes data in Program Memory (as UNO has limited RAM memory) for onward transfer to Slave.

  1. At Master side, you can create SPI Port by executing SPI.begin() code.

  2. At Slave side, you create SPI Port by manipulating the values of SPCR Register. Do not execute SPI.begin() code, but you include SPI.h Library for the meanings of SS, MOSI, MISO, SCK names.

  3. SPI always sends data 1 byte at a time for which you can execute SPI.transfer(dataByte) code.

  4. When a data arrives at the Slave, the SPIF flag becomes HIGH which can be utilized (by including SPI.attachInterrupt() code in the Slave Sketch) to interrupt the MCU. The MCU jumps to the ISR routine, reads the data byte from SPDR register (by executing byte y = SPDR code) (and saves in Program Memory).

  5. Sample Sketches:
    In the attached file of post #2 of this thread: https://forum.arduino.cc/t/problem-about-spi-transferring-byte-data-with-nano/1007995.

There are two more SPI.transfers that send two or more bytes at the time.
Leo..

Nick Gammon's SPI Tutorial includes both modes and codes.

1 Like

I have wanted to mean that SPI (being a byte oriented protocol) always sends 1-byte data over a bus cycle even we execute SPI.transfer(buffer, sizeof buffer). SPI.transfer16(0x1234) requires two bus cycles for sending the bytes of the 16-bit data item.

SPI.transfe16(0x1234) is broken down to:

SPI.transfer(highByte(0x1234));
SPI.transfer(lowByte(0x1234));

SPI moves 1 bit per SPICLK cycle, default divider is 4.

16M/4 spiclk * 8 bits = 512KB/s single-direction transfer rate.
SPI is bi-directional but most apps don't use that.

You can get DIP SPI chips for many uses.
.
If you need longer wires, slow SPI down by selecting a bigger divider. Note that default /4 would go to 8, 16, 32, 64 or 128 depending on how long those lines have to be and, I'd use shielded cable.
Arduino doc says how-to set the SPICLK divider but says new projects should use a different function.

There is only 1 data line to transmit per bus clock cycle. 1 wire, 1 bit.