Hello guys.
I connected three arduino uno board using protocol SPI(1 master and 2 slave).
The slave arduino uno receive data when start circle and then the data not change.
If you press the reset button on the slave, the data is updated, but if you do not press the reset button and try to change the data transferred in the master, the data is not overwritten in the slave.
Once I reset the cycle, the data is successfully received by the slave.
Why is this happening?
#include <AccelStepper.h>
#include <SPI.h>
byte buf [2];
volatile byte pos;
volatile bool process_it;
AccelStepper stepperr(1,3,4); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
int spMotor1;
void setup()
{
stepperr.setPinsInverted(-1, -1, -1);
// Serial.begin(115200); // устанавливаем последовательное соединение
stepperr.setMaxSpeed(10000);
// turn on SPI in slave mode
SPCR |= bit (SPE);
// have to send on master in, *slave out*
pinMode (MISO, OUTPUT);
// get ready for an interrupt
pos = 0; // buffer empty
process_it = false;
// now turn on interrupts
SPI.attachInterrupt();
}
ISR (SPI_STC_vect)
{
byte c = SPDR; // grab byte from SPI Data Register
// add to buffer if room
if (pos < sizeof buf)
{
buf [pos++] = c;
// example: newline means time to process buffer
if (c == '\n')
process_it = true;
} // end of room available
spMotor1 = (buf[0] << 8) | (buf[1]);
}
void loop()
{
if (process_it)
{
buf [pos] = 0;
// Serial.println (buf);
pos = 0;
process_it = false;
} // end of flag set
// Serial.println( spMotor1,DEC);
stepperr.setSpeed(spMotor1);
//Serial.println(spMotor1);
stepperr.runSpeed();
}
But at that point, how do you know how many characters are in the buffer? You never check if you’re received 2 bytes, so it could be putting anything into your motor speed.
Is the master really sending ‘\n’ line-endings? If not, then you never reset pos back to zero, so you will just write off the end of the array and damage other variables in the program. Additionally, you only set the length of the buffer to 2, so the ‘\n’ (if sent) will also be outside the array, causing damage.
Now SPI is a little different to regular Serial, because you do get the CS signal to tell you when data starts or ends. So you can reset pos when the main loop detects that CS is high. You should still have some checks inside the ISR to make sure you don’t write past the end of the array.
You might want to check if you accidentally fall into slave mode on the master. If you’re not using the slave select pin (digital pin 10) as an output, and it’s not tied to a specific value, it can force the SPI master to go into slave mode. It’s normally best to set the spi select pin as an output if you’re not using it on the master. Otherwise, to set the pullup on it so it won’t accidentally go low as an input and throw you into slave mode.
But at that point, how do you know how many characters are in the buffer? You never check if you’re received 2 bytes, so it could be putting anything into your motor speed.
Is the master really sending ‘\n’ line-endings? If not, then you never reset pos back to zero, so you will just write off the end of the array and damage other variables in the program. Additionally, you only set the length of the buffer to 2, so the ‘\n’ (if sent) will also be outside the array, causing damage.
Now SPI is a little different to regular Serial, because you do get the CS signal to tell you when data starts or ends. So you can reset pos when the main loop detects that CS is high. You should still have some checks inside the ISR to make sure you don’t write past the end of the array.