Hey there!
I've been struggling on this topic for a while now, hence I decided to ask here. I browsed the forum for clear answers, unfortunately this topic is very confusing and answers usually only cover a specific part of it.
I would like to have an Arduino Nano that drives some sensors, collects all the values and can provide these values to a connected Arduino Mega2560 via SPI. I wired them like this:
Mega2560 Nano
MOSI 51 11
MISO 50 12
SCK 52 13
SS (Slave) 53 10
For the Nano (the slave) I use the following sketch:
#include <SPI.h>
volatile uint16_t sensorId;
volatile uint16_t distancePrimaryCM;
void setup() {
Serial.begin(115200);
pinMode(MISO, OUTPUT);
SPCR |= _BV(SPE);
SPCR |= _BV(SPIE);
}
ISR(SPI_STC_vect) {
sensorId = SPDR;
uint16_t value = distancePrimaryCM;
SPI.transfer(&value, 2);
}
void loop() {
distancePrimaryCM = 301;
Serial.println("Primary:");
Serial.println(distancePrimaryCM, DEC);
}
On the Mega2560 (the master) on the other hand, I have this running:
#include <SPI.h>
void setup(void) {
Serial.begin(115200);
digitalWrite(SS, HIGH);
SPI.begin ();
SPI.setClockDivider(SPI_CLOCK_DIV4);
}
uint16_t transferMeasure(const uint8_t id) {
uint16_t a = SPI.transfer(id);
a |= SPI.transfer(id) << 8;
return a;
}
void loop(void) {
uint16_t a;
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
digitalWrite(SS, LOW);
a = transferMeasure(0);
digitalWrite(SS, HIGH);
SPI.endTransaction();
Serial.println("Results:");
Serial.println(a);
delay(2000);
}
The setup seems to be working.. sort of. When I take a look at the master's serial output, it reads like this:
11:15:06.649 ->
11:15:06.649 -> Results:
11:15:06.649 -> 301
11:15:08.654 -> Results:
11:15:08.654 -> 0
11:15:10.669 -> Results:
11:15:10.669 -> 1
11:15:12.675 -> Results:
11:15:12.675 -> 301
11:15:14.648 -> Results:
11:15:14.648 -> 0
11:15:16.646 -> Results:
11:15:16.646 -> 301
11:15:18.655 -> Results:
11:15:18.655 -> 0
11:15:20.656 -> Results:
11:15:20.656 -> 1
11:15:22.658 -> Results:
11:15:22.658 -> 301
11:15:24.650 -> Results:
11:15:24.650 -> 0
11:15:26.650 -> Results:
11:15:26.650 -> 1
11:15:28.673 -> Results:
11:15:28.673 -> 301
11:15:30.662 -> Results:
11:15:30.662 -> 0
11:15:32.653 -> Results:
11:15:32.653 -> 301
11:15:34.678 -> Results:
11:15:34.678 -> 0
11:15:36.678 -> Results:
11:15:36.678 -> 301
11:15:38.674 -> Results:
11:15:38.674 -> 0
11:15:40.667 -> Results:
11:15:40.667 -> 1
11:15:42.643 -> Results:
11:15:42.643 -> 301
11:15:44.653 -> Results:
11:15:44.653 -> 0
11:15:46.654 -> Results:
11:15:46.654 -> 1
11:15:48.676 -> Results:
11:15:48.676 -> 301
11:15:50.647 -> Results:
11:15:50.647 -> 0
11:15:52.653 -> Results:
11:15:52.653 -> 1
11:15:54.642 -> Results:
11:15:54.642 -> 301
11:15:56.642 -> Results:
11:15:56.642 -> 0
11:15:58.648 -> Results:
11:15:58.648 -> 301
11:16:00.667 -> Results:
11:16:00.667 -> 0
...
Clearly there must be some timing issue while reading the values, as the sequence keeps repeating. I tried to fix this by adding delayMicroseconds(20); here and there, but that really didn't help.
Could anyone maybe tell, what's the issue and how this could be solved? I'd greatly appreciate help on this very unclear topic.
Thanks in advance!