stm32duino / Arduino_Core_STM32

STM32 core support for Arduino

Home Page:https://github.com/stm32duino/Arduino_Core_STM32/wiki

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

When the readStringUntil function is used, the system may freeze

ShiPC123 opened this issue · comments

Hello everyone I am using system version 2.7.1, MCU is STM32G070CBT6,The burning mode is STLINK, when I use the readStringUntil() function, the system gets stuck. This is a screenshot of my code
1
When I run setMath3 () in setup, the system freezes,
2
This situation only occurs during the burning code or power-on process, about once in 10 times, I tried to modify the serial buffer to 256, but the fault was not solved

Also, I set setTimeout to 20
However, the situation was not resolved, and sometimes the program stopped executing after the first few lines, which bothered me for a long time

Also, I set setTimeout to 20
However, the situation was not resolved, and sometimes the program stopped executing after the first few lines, which bothered me for a long time

Hi @ShiPC123
could you share full code. Screenshot does not really help.
Better a simpler test code would be helpful to reproduce.
Did you try to debug to see where/why you stuck.

#define ld1125_occ_txt "occ,"
#define ld1125_mov_txt "mov,"
#define ld1125_null_txt "null"

#define ld1125_get_all_str "get_all"
#define ld1125_get_all_suc_str "received message: get_all\r"

#define ld1125_save_str "save"
#define ld1125_save_suc_str "received message: save\r"
#define ld1125_save_suc2_str "all vars have been saved\r"


#define sensor_out_type_mov   1  
#define sensor_out_type_occ   2  
#define sensor_out_type_null   3  

float sensor_distance;
int  sensor_type;
int sensor_str;

bool test_mode = 1;



#include <multi_button.h>
#include <My_RS485.h>
#include <String.h>

#include<HardwareSerial.h>
HardwareSerial my485_1(PA3, PA2);
HardwareSerial sensor_uart(PA1, PA0);

#define my485_en1  PA4

RS485 rs485_1(&my485_1, my485_en1);


struct Button btn1;


#define led_run PB13

#define led_1_r PD3
#define led_1_g PB3
#define led_1_b PB4

#define led_2_r PA15
#define led_2_g PD0
#define led_2_b PD1

uint32_t led_rgb_group[6] = {led_1_r, led_1_g, led_1_b, led_2_r, led_2_g, led_2_b};

#define key PD2



uint8_t read_button1_GPIO() {
  return digitalRead(key);
}





void setup() {
  delay(1000);
  my485_1.begin(115200);
  rs485_1.setMicrosPerByte(115200);

  pinMode(led_run, OUTPUT);
  pinMode(led_1_r, OUTPUT);
  pinMode(led_1_g, OUTPUT);
  pinMode(led_1_b, OUTPUT);
  pinMode(led_2_r, OUTPUT);
  pinMode(led_2_g, OUTPUT);
  pinMode(led_2_b, OUTPUT);

  digitalWrite(led_1_r, HIGH);
  digitalWrite(led_1_g, HIGH);
  digitalWrite(led_1_b, HIGH);
  digitalWrite(led_2_r, HIGH);
  digitalWrite(led_2_g, HIGH);
  digitalWrite(led_2_b, HIGH);




  pinMode(key, INPUT);


  button_init(&btn1, read_button1_GPIO, 0);

  button_attach(&btn1, SINGLE_CLICK,     BTN1_SINGLE_Click_Handler);
  button_attach(&btn1, LONG_PRESS_HOLD,  BTN1_LONG_PRESS_HOLD_Handler);
  button_attach(&btn1, LONG_PRESS_START,  BTN1_LONG_PRESS_START_Handler);

  button_start(&btn1);
  sensor_uart.begin(115200);
  sensor_uart.setTimeout(20);
  String data_str = sensor_uart.readStringUntil('\n');
  rs485_1.println("1111");
  int a = setTestMode(1);
  delay(100);
  rs485_1.println("2222");
  int b = setUartDelay(1000);
  delay(100);
  rs485_1.println("3333");
  int c = setMath1(150);
  delay(100);
  rs485_1.println("4444");
  int d = setMath2(100);
  delay(100);
  rs485_1.println("5555");
  int e = setMath3(80);
  delay(100);
  rs485_1.println("6666");
  int f = setRmax(3);
  delay(100);

  rs485_1.print(a);
  rs485_1.print(",");
  rs485_1.print(b);
  rs485_1.print(",");
  rs485_1.print(c);
  rs485_1.print(",");
  rs485_1.print(d);
  rs485_1.print(",");
  rs485_1.print(e);
  rs485_1.print(",");
  rs485_1.println(f);


}

void led_show_addr(int addr) {
  for (int i = 0; i < 6; i++) {
    digitalWrite(led_rgb_group[i], HIGH);
  }
  if (addr <= 5) {
    digitalWrite(led_rgb_group[addr], LOW);
  }
  else if (addr > 5 && addr <= 14 ) {
    int tmp = addr % 3;
    digitalWrite(led_rgb_group[3 + tmp], LOW);
    if (addr <= 8) {
      digitalWrite(led_rgb_group[0], LOW);
    }
    else if (addr <= 11) {
      digitalWrite(led_rgb_group[1], LOW);
    }
    else if (addr <= 14) {
      digitalWrite(led_rgb_group[2], LOW);
    }
  }
}



void BTN1_SINGLE_Click_Handler(void* btn) {
  static int index = 0;

  led_show_addr(index);
  index++;
  if (index >= 15) {
    index = 0;
  }
}

void BTN1_LONG_PRESS_HOLD_Handler(void* btn) {


}


void BTN1_LONG_PRESS_START_Handler(void* btn) {


}

void loop() {

  //  static long last_key_time;
  //  if (millis() - last_key_time > 5) {
  //    last_key_time = millis();
  //    button_ticks();
  //  }

  //    rs485_1.write(0xAA);
  //    rs485_1.write(0x55);
  //    rs485_1.write(0x00);
  //    rs485_1.write(0x00);
  //    delay(1000);

  //  sensor_read();
  //
  //  static long last_key_time;
  //  if (millis() - last_key_time > 500) {
  //    last_key_time = millis();
  //    rs485_1.print(sensor_type);
  //    rs485_1.print(",");
  //    rs485_1.print(sensor_distance);
  //    rs485_1.print(",");
  //    rs485_1.println(sensor_str);
  //  }

  debug_uart();
  run_led();

}



void sensor_read() {
  if (sensor_uart.available() > 0) {
    delay(2);
    String data_str = sensor_uart.readStringUntil('\n');
    String data_type = data_str.substring(0, data_str.indexOf(' '));
    if (data_str == "null\r") {
      sensor_type = sensor_out_type_null;
      sensor_distance = 0;
      sensor_str = 0;
    }
    else {
      if (data_type == ld1125_mov_txt) {

        sensor_type = sensor_out_type_mov;

        String data_vals = data_str.substring(data_str.indexOf(' ') + 1, data_str.length());

        String data_vals_txt = data_vals.substring(0, data_vals.indexOf('='));

        if (data_vals_txt == "dis") {
          String data_vals_str = data_vals.substring(data_vals.indexOf('=') + 1, data_vals.length());
          sensor_distance = data_vals_str.toFloat();
        }

        if (test_mode) {

          String str_vals = data_vals.substring(data_vals.indexOf(' ') + 1, data_vals.length());

          String str_vals_txt = str_vals.substring(0, str_vals.indexOf('='));

          if (str_vals_txt == "str") {
            String str_vals_str = str_vals.substring(str_vals.indexOf('=') + 1, str_vals.length());
            sensor_str = str_vals_str.toFloat();
          }
        }
      }
      else if (data_type == ld1125_occ_txt) {

        sensor_type = sensor_out_type_occ;

        String data_vals = data_str.substring(data_str.indexOf(' ') + 1, data_str.length());

        String data_vals_txt = data_vals.substring(0, data_vals.indexOf('='));

        if (data_vals_txt == "dis") {
          String data_vals_str = data_vals.substring(data_vals.indexOf('=') + 1, data_vals.length());
          sensor_distance = data_vals_str.toFloat();
        }

        if (test_mode) {

          String str_vals = data_vals.substring(data_vals.indexOf(' ') + 1, data_vals.length());

          String str_vals_txt = str_vals.substring(0, str_vals.indexOf('='));

          if (str_vals_txt == "str") {
            String str_vals_str = str_vals.substring(str_vals.indexOf('=') + 1, str_vals.length());
            sensor_str = str_vals_str.toFloat();
          }
        }
      }
    }
  }
}



bool setTestMode(bool test_mode) {
  String set_test_mode_suc_str = "received message: test_mode=" + String(test_mode) + "\r";
  String set_test_mode_suc2_str = "test_mode is " + String(test_mode) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("test_mode=" + String(test_mode));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');
    String set_test_mode_3 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
        || set_test_mode_3 == set_test_mode_suc_str || set_test_mode_3 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setUartDelay(int time_set) {
  String set_test_mode_suc_str = "received message: utons=" + String(time_set) + "\r";
  String set_test_mode_suc2_str = "utons is " + String(time_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("utons=" + String(time_set));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setMath1(int val_set) {
  String set_test_mode_suc_str = "received message: mth1=" + String(val_set) + "\r";
  String set_test_mode_suc2_str = "mth1 is " + String(val_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("mth1=" + String(val_set));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setMath2(int val_set) {
  String set_test_mode_suc_str = "received message: mth2=" + String(val_set) + "\r";
  String set_test_mode_suc2_str = "mth2 is " + String(val_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("mth2=" + String(val_set));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setMath3(int val_set) {
  String set_test_mode_suc_str = "received message: mth3=" + String(val_set) + "\r";
  String set_test_mode_suc2_str = "mth3 is " + String(val_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  rs485_1.println("1234567");
  sensor_uart.flush();
  sensor_uart.println("mth3=" + String(val_set));
  delay(27);
  rs485_1.println("7654321");
  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setRmax(int val_set) {
  String set_test_mode_suc_str = "received message: rmax=" + String(val_set) + "\r";
  String set_test_mode_suc2_str = "rmax is " + String(val_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("rmax=" + String(val_set));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}




void debug_uart() {
  //
  if (sensor_uart.available() > 0) {
    delay(2);
    while (sensor_uart.available()) {
      rs485_1.write(sensor_uart.read());
    }
  }

  if (rs485_1.available() > 0) {
    delay(2);
    while (rs485_1.available()) {
      sensor_uart.write(rs485_1.read());
    }
  }
}

void run_led() {
  static long last_updata;
  if (millis() / 500 - last_updata > 1) {
    last_updata =  millis() / 500;
    static bool led_state;
    led_state = !led_state;
    digitalWrite(led_run, led_state);
  }
}

This is my source code, and the code is stuck when running readuntil () function

This code is to set the relevant parameters of the mmwave radar, when the setting is successful, the mmwave radar will return instructions, so I used the readStringUntil () function, I suspected that the radar module was abnormal, but I used the USB-to-TTL module to read the radar module directly, and found that it was still working normally.

I also used an oscilloscope to observe the power supply voltage and RST reset pin voltage waveform of the single chip microcomputer, which were normal, basically ruling out the crash of the single chip microcomputer caused by hardware problems

Well, your code seems doing lot of thing mainly with your class My_RS485 under the hood.
Which target you used ? The generic?
I will try to reproduce using a simplified code anyway your best bet is to debug on your side.

I changed my code to look like this

#define ld1125_occ_txt "occ,"
#define ld1125_mov_txt "mov,"
#define ld1125_null_txt "null"

#define ld1125_get_all_str "get_all"
#define ld1125_get_all_suc_str "received message: get_all\r"

#define ld1125_save_str "save"
#define ld1125_save_suc_str "received message: save\r"
#define ld1125_save_suc2_str "all vars have been saved\r"


#define sensor_out_type_mov   1
#define sensor_out_type_occ   2
#define sensor_out_type_null   3

float sensor_distance;
int  sensor_type;
int sensor_str;

bool test_mode = 1;

#include<HardwareSerial.h>
HardwareSerial my485_1(PA3, PA2);
HardwareSerial sensor_uart(PA1, PA0);

#define my485_en1  PA4

#define led_run PB13

void setup() {
  my485_1.begin(115200);
  pinMode(my485_en1, OUTPUT);
  digitalWrite(my485_en1, HIGH);
  pinMode(led_run, OUTPUT);
  sensor_uart.begin(115200);
  sensor_uart.setTimeout(20);
  String data_str = sensor_uart.readStringUntil('\n');
  my485_1.println("1111");
  int a = setTestMode(1);
  delay(100);
  my485_1.println("2222");
  int b = setUartDelay(1000);
  delay(100);
  my485_1.println("3333");
  int c = setMath1(150);
  delay(100);
  my485_1.println("4444");
  int d = setMath2(100);
  delay(100);
  my485_1.println("5555");
  int e = setMath3(80);
  delay(100);
  my485_1.println("6666");
  int f = setRmax(3);
  delay(100);

  my485_1.print(a);
  my485_1.print(",");
  my485_1.print(b);
  my485_1.print(",");
  my485_1.print(c);
  my485_1.print(",");
  my485_1.print(d);
  my485_1.print(",");
  my485_1.print(e);
  my485_1.print(",");
  my485_1.println(f);

}

void loop() {
  run_led();
}

bool setTestMode(bool test_mode) {
  String set_test_mode_suc_str = "received message: test_mode=" + String(test_mode) + "\r";
  String set_test_mode_suc2_str = "test_mode is " + String(test_mode) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("test_mode=" + String(test_mode));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');
    String set_test_mode_3 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
        || set_test_mode_3 == set_test_mode_suc_str || set_test_mode_3 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setUartDelay(int time_set) {
  String set_test_mode_suc_str = "received message: utons=" + String(time_set) + "\r";
  String set_test_mode_suc2_str = "utons is " + String(time_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("utons=" + String(time_set));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setMath1(int val_set) {
  String set_test_mode_suc_str = "received message: mth1=" + String(val_set) + "\r";
  String set_test_mode_suc2_str = "mth1 is " + String(val_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("mth1=" + String(val_set));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setMath2(int val_set) {
  String set_test_mode_suc_str = "received message: mth2=" + String(val_set) + "\r";
  String set_test_mode_suc2_str = "mth2 is " + String(val_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("mth2=" + String(val_set));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setMath3(int val_set) {
  String set_test_mode_suc_str = "received message: mth3=" + String(val_set) + "\r";
  String set_test_mode_suc2_str = "mth3 is " + String(val_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("mth3=" + String(val_set));
  delay(27);
  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}

bool setRmax(int val_set) {
  String set_test_mode_suc_str = "received message: rmax=" + String(val_set) + "\r";
  String set_test_mode_suc2_str = "rmax is " + String(val_set) + "\r";
  while (sensor_uart.available() > 0) {
    sensor_uart.read();
    delayMicroseconds(100);
  }
  sensor_uart.flush();
  sensor_uart.println("rmax=" + String(val_set));
  delay(27);

  if (sensor_uart.available() > 0) {

    String set_test_mode_1 = sensor_uart.readStringUntil('\n');
    String set_test_mode_2 = sensor_uart.readStringUntil('\n');

    if (set_test_mode_1 == set_test_mode_suc_str || set_test_mode_1 == set_test_mode_suc2_str
        || set_test_mode_2 == set_test_mode_suc_str || set_test_mode_2 == set_test_mode_suc2_str
       ) {
      return true;
    }
    else {
      return false;
    }
  }
}



void run_led() {
  static long last_updata;
  if (millis() / 500 - last_updata > 1) {
    last_updata =  millis() / 500;
    static bool led_state;
    led_state = !led_state;
    digitalWrite(led_run, led_state);
  }
}

However, there is still a chance that a jam will occur when running readStringUntil () after power-on

now i remove if (sensor_uart.available() > 0) and change from sensor_uart.setTimeout(20) to sensor_uart.setTimeout(500);
Seems to be working properly now But I'm still not sure why

I've tested and has no issue with ReadStringUntil. The timeout works as expected.
Maybe your issue is you set a too small timeout, then the API exit before getting the delimiter.
You should debug to see where you seems to freeze.
I close this issue as it seems related to your implementation.