Software.serial crash when i use Serial.write inside while

Is there someone who can give an explanation why software.serial crash when i used inside a while loop and not inside a for loop. I post my original sketch with where software.serial crashes and a copy of the for loop which does not cause software.serial to crash. I am also attaching a picture of my logic analyzer where it works and crashes. It's my last function in my sketch void _tx_packet()


const int rxPin = 2;    // rx  pin

int _1_bit_delay = 80;      // 1 bit dealy
int _1h_bit_delay = 115;    // 1.5 bit delay to center


bool flag_ok = false;
bool flag_error = false;
byte buffer[64];
int cnt = 0;

void _delay_bit(int);
int  _rx_byte();
void _test_syn();
void _test_idle();
void _rx_packet();
void _tx_packet();

int main()
{
  setup();

  while (1){
    myLoop();
    
    }
}


void setup() {
 
  Serial.begin(115200);                      // for debug
  DDRD = B00001000;                          // pin 3 output
  bitSet(PORTD, 3);                          // debug pin
  pinMode(rxPin, INPUT);
  digitalWrite(rxPin, HIGH);                 // pullups

  // Timer 0 setup
  TCCR0A = 0;
  TCCR0B = 0;
  TCCR0B = 0 <<WGM02 | 0<<CS02 | 1<<CS01 | 1<<CS00;  // clkI/O/64 (from prescaler) Normale mode
  TCNT0 = 0;          // reset Timer 1 counter

  // Timer 1 setup
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1B = 0 <<WGM12 | 0<<CS12 | 1<<CS11 | 0<<CS10; // clkI/O/8 (from prescaler) Normale mode
  TCNT1 = 0;          // reset Timer 1 counter

  
}
//****************************************************************************************
//
//
//****************************************************************************************

void myLoop() {

_test_syn();

if(flag_ok == true)
_test_idle();

if(flag_ok == true)
_rx_packet();

if(flag_ok == true)
_tx_packet();

}

//****************************************************************************************
//
//
//****************************************************************************************

int _rx_byte() {

  flag_error = false;                           // reset flag error     
  TCNT0 = 153;                                  // timeout 400 uS timer 0
  bitSet(TIFR0, TOV0);                          //clear TOV0 flag by set, timer 0

  while(bitRead(PIND,rxPin) == 1)               // wait for rx line go low for start bit of byte
  {   
  if(bitRead(TIFR0, TOV0) == HIGH){             // 
     flag_error = true;                         // timeout reached 400 uS flag error set, no new byte received
     break;                                     // break the while for exit funktion
      }
  }

      _delay_bit(_1h_bit_delay);                   // wait 1.5 bit time to center
      
      int d = 0;

      for (int j=8; j > 0; --j)                    // recive 8 bit
      {                 
      bitSet(PORTD, 3);                            // debug pin
      d >>= 1;
    
      if(bitRead(PIND,rxPin) == 1)
      d |= 0x80;
        
      bitClear(PORTD, 3);                         // debug pin
      _delay_bit(_1_bit_delay);                   // wait 1 bit time
      }

     return d;
     
}

//****************************************************************************************
//
//
//****************************************************************************************

void _delay_bit(int d_bit){

 int i = 0;

 while(i < d_bit ){
 asm volatile("nop");
 i++;
 }
}

//****************************************************************************************
//
//
//****************************************************************************************

void _test_syn(){
  
flag_ok = false;
int i = 0;
int d = 0;

TCNT1 = 60000;                                    // timeout 2.7 ms timer 1
bitSet(TIFR1, TOV1);                              //clear TOV1 flag by bitset


while(bitRead(TIFR1, TOV1) != HIGH)
{ 
    bitClear(PORTD, 3);                         // debug pin

    while(bitRead(PIND,rxPin) == 0)            // wait for rx line go high
    {
    if(bitRead(TIFR1, TOV1) == HIGH)
     break;
    }
  
    if(bitRead(TIFR1, TOV1) == HIGH)
     break;                                       // timeout exit while
    
    d = _rx_byte();

    
    if((flag_error) || (bitRead(TIFR1, TOV1) == 1))  //test for timeout or error
    break;    
    
    if(d == 0x55)                   // if 0x55 count up need 3 x 0x55
        i++;      
    else
        i = 0;                       // reset syn word counter
            
    
    if (i == 3){                     // Test if 3 syn word in row are recive 
    flag_ok = true;
    break;
    }
    
 }
 bitSet(PORTD, 3);                  // debug pin
}

//****************************************************************************************
//
//
//****************************************************************************************

void _test_idle(){

flag_ok = false;
int i = 0;

TCNT1 = 0;                           // timeout 32 ms
bitSet(TIFR1, TOV1);                     //clear TOV1 flag by bitset

while(bitRead(TIFR1, TOV1) != HIGH)
{

  i = 0;
  while(bitRead(PIND,rxPin) == 1){
    
    i++;
    bitClear(PORTD, 3);
    if(i > 200){
    flag_ok = true;                       // ilde for 100 uS ok
    break;
    }       
  
    
    if(bitRead(TIFR1, TOV1) == HIGH)
    break;
  }
   bitSet(PORTD, 3);
   if(flag_ok == true )
   break;
}

}
//****************************************************************************************
//
//
//****************************************************************************************

 void _rx_packet(){

  flag_ok = false;
  flag_error = false;

  cnt = 0;
  
  TCNT1 = 0;                                    // timeout 32 ms timer 1
  bitSet(TIFR1, TOV1);                          //clear TOV1 flag by bitset

  while(bitRead(TIFR1, TOV1) != HIGH)
{
  int d = 0; 
  

  d = _rx_byte();                               // recieve 1 start byte "0x33"
  Serial.write(d);                              // debug
  if(flag_error == true)                         // timeout exit while
  break;

  
  buffer[0] = d;                                // save byte
  
  if(!d == 0x33){
    flag_error = true;
    break;
  }

  d = _rx_byte();                               // recieve 1 byte how many byte to recieved next
  Serial.write(d);                             // debug
  if(flag_error == true)                         // timeout exit while
  break;

  buffer[1] = d;                                // save byte
  
  cnt = 0;
  cnt = d & 0x1F;                               // how many byte to recieved need 5 first bit 000X XXXX

  cnt = cnt + 4;                                // save how many byte more to recieved  2 + data + 2 crc byte 

  int i = 2;                                     // use for pointer for buffer
  

  while((i < cnt ) &&  (bitRead(TIFR1, TOV1) == 0)){
  
     d = _rx_byte();                               // recieve 1 byte 
      Serial.write(d);                             // debug
     if(flag_error == true)                         // timeout exit while
     break;
    
     buffer[i] = d;                                // save byte
    
     i++;
     }

    if(flag_error == false)                         // check for erorr
     flag_ok = true;

    break;                                         // exit while before timeout parket recieved
                                          
}
   
}
//****************************************************************************************
//
//
//****************************************************************************************

 void _tx_packet(){
   int i = 0;
   int x = 12;



     while(i < x){
     Serial.print(buffer[i]);
    i++;
    delayMicroseconds(100); 
   }


 //for(int i = 0; i < 10; i++){
 //   delayMicroseconds(100);
 //   Serial.write(buffer[i]);   
 //}

 }

Work when i use for loop

for(int i = 0; i < 10; i++){
    delayMicroseconds(100);
    Serial.write(buffer[i]);   
 }

your code is hard to follow but I notice that you don't check for overflow here

Can't understand what it has to do with software.serial crash in the while loop I don't check for overflow. I receive 12 bytes each time and buffer[64] I send them with software.serial inside the while loop where it crashes but not in the for loop. if it was due to overflow, then it would not work in both the while loop and the for loop or ?

I don't know what you receive or how things are wired up

I'm just saying that a buffer overflow will lead to weird behavior and that you don't have any safeguard there. If you think it's not overflowing, so be it.

it's unclear to me where the while loop and for loop are in your code.

why don't you use SoftwareSerial that has been tested rather than this complicated code?

This code also crash software serial.

void _tx_packet(){
   int i = 0;
   int x = 12;

    byte buffer1[64] = {0x33, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x55, 0x66 };

     while(i < x){
     Serial.print(buffer1[i]);
    i++;
    delayMicroseconds(100); 
   }

1. Can you summarize the purpose of your sketch of post #1?

2. If you are using Arduino IDE, then why have you used the main() function and TC0 instead of TC2?

3. Are setup()/loop() functions not suffice?

4. What is software.serial?

Sry, could you please post justo the two loops? All I can see through the small window here turns up no strictly equivalent loops, one while, the other for.

a7

there is no software serial in that code... not sure what you are saying

Assuming you missed the closing brace, there is nothing crashing in this code

void _tx_packet() {
  int i = 0;
  int x = 12;
  byte buffer1[64] = {0x33, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x55, 0x66 };
  while (i < x) {
    Serial.print(buffer1[i]);
    i++;
    delayMicroseconds(100);
  }
}

void setup() {
  Serial.begin(115200);
  _tx_packet();
}

void loop() {}

the Serial monitor will just show

518495051525354555685102

Reasons.

Which is why @2000nico2000 might shouldn't have launch a new thread, or ar the very least provide a link to the other thread on what seems to be the same matter.

a7

I'm the one mixing things up, thought software.serial lib was the same as serial.write. But then it is serial.write that crashes

I use main because I have some problems with my function delay. which sometimes gave a longer delay. I will be recommended. to use main that way.

I know. From your other thread, hello!

I was trying to answer @GolamMostafa… and make point about creating a new thread where you probably should not have.

a7

1 Like

I don't use serial monitor i use my logic analyzer that show crash. one picture when it work an not


the crash is likely somewhere else. Serial is asynchronous
there is nothing crashing in

void _tx_packet() {
  int i = 0;
  int x = 12;
  byte buffer1[64] = {0x33, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x55, 0x66 };
  while (i < x) {
    Serial.print(buffer1[i]);
    i++;
    delayMicroseconds(100);
  }
}

unless there is not enough RAM on the stack to allocate buffer1 and the two integers (i and x) when you call the function.

Made it work. Had used Serial.print instead of Serial.write. :upside_down_face:

Can you please explain, with simple example, the difference between Serial.print() and Serial.write()? What does appear on the OutputBox of Serial Monitor when the following codes are executed.

Serial.print(0x32);
Serial.write(0x32);

that's does not explain anything... it just changes the way things get written out. It does not crash

But Serial.write send 1 byte, serial.print converte to 2 byte and if i use to small delay between then it will crash.

this work

void _tx_packet(){


   int i = 0;
   
     while(i < cnt){
      
      Serial.print(buffer[i],HEX);
      delayMicroseconds(200);     
      i++; 
     }


 }

smaller delay don't work

void _tx_packet(){


   int i = 0;
   
     while(i < cnt){
      
      Serial.print(buffer[i],HEX);
      delayMicroseconds(100);     
      i++; 
     }

my logic analyzer show

Serial.print(0x32); = 0x35 0x30
Serial.write(0x32); = 0x32