Hello All, and thank you in advance!
I am currently working on a prototype project for a data logger that intends to receive a byte message of 200 bytes over SPI (later on messages up to 400 bytes as well). Then send them to another Arduino board (preferrably UART) that has an Ethernet Shield to Send UDP data packets to a laptop. Right now I would like to focus on this issue described below since I have confirmed the Ethernet Arduino code to work when receiving UART messages from the code below.
Where I am at currently:
I have a custom board I developed that reliably takes a serial message from an RS422 interface and translates it to an SPI interface (arduino compatible 5V). I do not suspect my custom board anymore because when using an oscilloscope I can verify that the Clock, Data (MO(customboard) SI(arduino) in my case), and, Chip Select are being sent to the arduino. My custom board acts as the master since it generates the clock for the arduino to receive at.
Custom Board Specifications:
Clock speed : 1,228,800Hz - forced to work with this since its the speed of the data I need to receive.
Data that I send : Can be configurable on my end with a simulator-esque communications card. I can send any size or data value I want for the most part.
CS : Active Low
Boards I have tested this code on : Arduino Nano, Arduino Mega (Issue persists for both).
All messages have 100ms between each new message. During this time I send the UART message to the other arduino.
Problem:
When utilizing the code below I am getting sporadic results where it skips a byte and writes the next byte twice. For instance:
I am sending hex bytes {0x61 , 0x62, 0x63, 0x64} which correlates to the "abcd" writes to the Serial monitor.
I am at a complete loss here and would like to see if someone with a deeper knowledge base on SPI interrupts and byte indexing could help.
Furthermore, I have also done print statements where I print the byte, and then the byte index next to it like so, proving that the byte is written into the previous index. (or so i believe)
(All code is written to receive 4 bytes currently because the behavior is similar and easier to demonstrate.)
Thank you for your time!
#include <SPI.h>
volatile byte receivedBuffer[4];
volatile byte byteIndex = 0;
volatile boolean arrayReceived = false;
volatile int voltage1 = 0;
void setup() {
pinMode(MISO, OUTPUT); // MISO as output
pinMode(SS,INPUT);
SPCR |= _BV(SPE); // Enable SPI
SPCR |= _BV(SPIE); // Enable SPI interrupt
SPI.setDataMode(SPI_MODE0);
//pinMode(LED_BUILTIN, OUTPUT); // For debug activity
Serial.begin(1000000);
Serial.println("SPI Slave Ready for 8-byte packets");
Serial.println(sizeof(receivedBuffer));
//digitalWrite(2,LOW);
}
ISR(SPI_STC_vect) {
//byte data = SPDR; // Read the incoming byte
//digitalWrite(2, HIGH);
if (byteIndex < sizeof(receivedBuffer)) {
receivedBuffer[byteIndex] = lowByte(SPDR);
byteIndex++;
if (byteIndex == sizeof(receivedBuffer)) {
arrayReceived = true;
//Serial.println('xyz');
//Serial.print(byteIndex);
}
}
//digitalWrite(2,LOW);
}
void loop() {
// while (!arrayReceived){
// Serial.println(byteIndex);
// }
while (arrayReceived) {
delayMicroseconds(20);
//Serial.print("Received byte packet: ");
for (int i = 0; i < sizeof(receivedBuffer); i++) {
Serial.write(receivedBuffer[i]);
//Serial.print(receivedBuffer[i]);
//if(i == sizeof(receivedBuffer)){
//Serial.write(receivedBuffer[i]);
//}
//Serial.print("-");
}
//Serial.print("\n");
Serial.println();
//digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Toggle LED
byteIndex = 0;
arrayReceived = false;
}
//voltage1 = analogRead(A0);
}

