0

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#.

  1. Send X (or Y)
  2. Send F (or B)
  3. Send 01600
  4. 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.

sgsi
  • 1

0 Answers0