Here I'm trying to Send the SPI command from the master (Arduino Nano) to the slave(ATMEGA324PB). First Master receives a command from the serial monitor. When the serial message receives completely, the Master passes the message to the Slave. Whenever the slave has a message to send, it will interrupt the Arduino nano using pin 3. However, in the first round slave send messages to master, and master can read it successfully. But in the second round It couldn't happen. I was unable to find the issue. I will attach the codes below.
User message is like in this manner XF01600#.
- Send X (or Y)
- Send F (or B)
- Send 01600
- Send #
This is my Master Code :
` #include <SPI.h>`
char Direction;
char Axis;
char TxCommand;
char TxEnd;
bool stringComplete = false; // Is receive complete ?
bool TxComplete=false;
int k=0;
int j=0;
String StepCount;
SPISettings setting(200000,MSBFIRST,SPI_MODE0);
void setup() {
Serial.begin(9600);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(2,OUTPUT);
attachInterrupt(digitalPinToInterrupt(3),SlaveReceive,RISING);
SPI.begin();
}
void SlaveReceive(){
SPI.begin();
SPI.beginTransaction(setting);
digitalWrite(10,LOW);
TxCommand=SPI.transfer(0xFF);//dummy
TxEnd=SPI.transfer(0xFF);//dummy
digitalWrite(10,HIGH);
SPI.endTransaction();
Serial.print("Received Command-");
Serial.println(TxCommand );
Serial.print("Received End-");
Serial.println(TxEnd);
if(TxEnd=='~'){
TxComplete=true;
}
}
void SPI_Transfer(){
SPI.transfer(Direction);//transfer direction
delay(5);
SPI.transfer(StepCount.length());//transfer incoming step length
delay(5);
for(int i=0;i<StepCount.length();i++){//transfer step count;
SPI.transfer(StepCount[i]);
Serial.println(StepCount[i]);
delay(5);
}
SPI.transfer('#');
delay(5);
}
void loop() {
if (stringComplete) {
if(Direction=='F'){
digitalWrite(2,HIGH);
}
else if(Direction=='B'){
digitalWrite(2,LOW);
}
Serial.print("Direction-");
Serial.println(Direction);
Serial.println(StepCount);
Serial.println(StepCount.length());
SPI.beginTransaction(setting);
if(Axis=='X'){ // Chip Select line for X axis driver is pin 10;
digitalWrite(10,LOW);
SPI_Transfer();
digitalWrite(10,HIGH);
}
else if(Axis=='Y'){ /// Chip select line for Y axis driver is pin 9;
digitalWrite(9,LOW);
SPI_Transfer();
digitalWrite(9,HIGH);
}
SPI.endTransaction();
stringComplete = false;
k=0;
}
if(TxComplete){
if(TxCommand=='S'){
digitalWrite(2,LOW);
TxComplete=false;
}
}
}
void serialEvent() {
while (Serial.available()>0) {
if(k==0){
Axis = Serial.read();
k++;
}
else if(k==1){
Direction=Serial.read();
k++;
}
else if(Serial.read()!='#'){
//StepCount[k-1]=Serial.readString();
StepCount=Serial.parseInt();
k++;
}
else{
stringComplete = true;
}
}
}
Slave Main Command :
while(1){
if(SPI_RECEIVE_COMPLETE){
SPI_RECEIVE_COMPLETE=false;
PORTA |=(1<<4);
Decode_SPI_Command();
switch (SPI_Command)
{
case 'F':
_Run_Motor(SPI_Data, true, 1, 0.3);//10 CYCLE
SlaveSendData(0x53);//S
break;
case 'B':
_Run_Motor(SPI_Data, false, 1, 0.3);
SlaveSendData(0x53);//S
break;
}
for(uint8_t i=0;i<15;i++){
SPI_Received_Data[i]=0;
}
SPI_Data=0;
SPI_BYTES_Transfer=0;
}
PORTA &=~(1<<4);
}
The Slave data send function:
void SlaveSendData(uint8_t SlaveCommand){
SPI_BYTES_Transfer=0;
SPI_Data_TX=true;
SPDR1=SlaveCommand;
SPI_Transmit_Data[0]=0x7E;//~
PORTA |=(1<<3);
_delay_ms(10);
PORTA &=~(1<<3);
}
Slave SPI interrupt function:
ISR(SPI1_STC_vect){
if(SPI_Data_TX){//slave is transmitting data
SPDR1 = SPI_Transmit_Data[SPI_BYTES_Transfer];
SPI_BYTES_Transfer++;
if(SPI_Received_Data[SPI_BYTES_Transfer-1]=='~'){
SPI_Data_TX=false;
//SPDR1=0x00;
SPI_BYTES_Transfer=0;
}
}
else{
SPI_Received_Data[SPI_BYTES_Transfer] = SPDR1;
SPI_BYTES_Transfer++;
if(SPI_Received_Data[SPI_BYTES_Transfer-1]=='#'){
SPI_RECEIVE_COMPLETE=true;
SPDR1=0x00;
}
}
}
Here I have found that in the else part SPI_RECEIVE_COMPLETE=true; never occurs on the second try. But I couldn't find where the issue is..?
serial monitor Arduino Serial Monitor
Could you please take a look, Thank you.