4

when I try the following code the SPI works correctly (see oscilloscope plot)

#include <SPI.h>

void setup() {
  SPI.begin();
}

void loop() {
  SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE3));
  byte a[] = {0xC,0xFF,0xFF,0xFF};
  SPI.transfer(a, 4);
  SPI.endTransaction();
  delay(10);
}

enter image description here

However when I move the array declaration to the a global it doesn't work any more. (see next oscilloscope plot) Why is this?

#include <SPI.h>

byte a[] = {0xC,0xFF,0xFF,0xFF};

void setup() {
  SPI.begin();
}

void loop() {
  SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE3));
  SPI.transfer(a, 4);
  SPI.endTransaction();
  delay(10);
}

enter image description here

2
  • it is not necessarily anything related to SPI ... use byte a[] = {'a', 'b', 'c', 'd'}; and do serial.write(a[0]) to print a value to serial monitor ... see if the result is the same
    – jsotola
    Jan 21, 2022 at 5:05
  • 2
    From the code you show I don't see any problem. It should work. Hm... Jan 21, 2022 at 11:52

1 Answer 1

5

When you call SPI.transfer(a, 4);, any "received data" is stored in your byte array, a[]. The original data is overwritten.

If you print out the contents of the array before and after the function call to SPI.transfer(), you will see in the serial monitor what is happening to your array contents.

Here are 2 test sketches to illustrate the difference between the array with a global scope, VS the one with a static scope.

Global Scope

// Sketch uses 2344 bytes (7%) of program storage space.
// Global variables use 193 bytes (9%) of dynamic memory. 
#include <SPI.h>

byte a[] = {0xC,0xFF,0xFF,0xFF};

void setup() {
  SPI.begin();
  Serial.begin(9600);
}

void loop() {
  SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE3));
  for(int i = 0; i < 4; i++){
    Serial.print(a[i]);
  }
  Serial.println();
  SPI.transfer(a, 4);
  SPI.endTransaction();
  for(int i = 0; i < 4; i++){
    Serial.print(a[i]);
  }
  Serial.println('\n');
  delay(1000);
}

Static Scope

// Sketch uses 2410 bytes (7%) of program storage space.
// Global variables use 193 bytes (9%) of dynamic memory. 
#include <SPI.h>

void setup() {
  SPI.begin();
  Serial.begin(9600);
}

void loop() {
  SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE3));
  byte a[] = {0xC,0xFF,0xFF,0xFF};
  for(int i = 0; i < 4; i++){
    Serial.print(a[i]);
  }
  Serial.println();
  SPI.transfer(a, 4);
  SPI.endTransaction();
  for(int i = 0; i < 4; i++){
    Serial.print(a[i]);
  }
  Serial.println('\n');
  delay(1000);
}

The following sketch should solve the problem. Using the const keword before the declaration of the b[] array is optional.

// Sketch uses 2436 bytes (7%) of program storage space.
// Global variables use 197 bytes (9%) of dynamic memory. 
#include <SPI.h>
const byte b[] = {0xC,0xFF,0xFF,0xFF};

void setup() {
  SPI.begin();
  Serial.begin(9600);
}

void loop() {
  SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE3));
  byte a[] = {0xC,0xFF,0xFF,0xFF};
  for(int i = 0; i < 4; i++){
    Serial.print(a[i]);
  }
  Serial.println();
  SPI.transfer(a, 4);
  SPI.endTransaction();
  memcpy(a, b, sizeof(b));
  for(int i = 0; i < 4; i++){
    Serial.print(a[i]);
  }
  Serial.println('\n');
  delay(1000);
}

One last edit. The compile size can be reduced by 66 bytes thanks to the static keyword.

// Sketch uses 2370 bytes (7%) of program storage space.
// Global variables use 197 bytes (9%) of dynamic memory. 
#include <SPI.h>
const byte b[] = {0xC,0xFF,0xFF,0xFF};

void setup() {
  SPI.begin();
  Serial.begin(9600);
}

void loop() {
  SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE3));
  static byte a[] = {0xC,0xFF,0xFF,0xFF};
  for(int i = 0; i < 4; i++){
    Serial.print(a[i]);
  }
  Serial.println();
  SPI.transfer(a, 4);
  SPI.endTransaction();
  memcpy(a, b, sizeof(b));
  for(int i = 0; i < 4; i++){
    Serial.print(a[i]);
  }
  Serial.println('\n');
  delay(1000);
}

For more information, see: Arduino.cc

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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