Используя ESP32 GPIO, Serial.printf(...) печатает странные символы, когда ввод превышает 12 символов.

Изучая C с помощью стартового комплекта Freenove WSP32-WROVER, я обнаружил проблему, на которую не могу найти ответ. Используя предоставленный код для ввода некоторых данных с помощью UART, может показаться странным поведение всякий раз, когда я ввожу строку, превышающую 12 символов. До 12 лет все в порядке.

/**********************************************************************
  Filename    : SerialRW
  Description : Use UART read and write data between ESP32 and PC.
  Auther      : www.freenove.com
  Modification: 2020/07/11
**********************************************************************/
String inputString = "";      //строка для хранения входящих данных
bool stringComplete = false;  // завершена ли строка

void setup() {
  Serial.begin(9600);
  Serial.println(String("\nESP32 initialization completed!\n")
                + String("Please input some characters,\n")
                + String("select \"Newline\" below and click send button. \n"));
}

void loop() {
  if (Serial.available()) {         // оцениваем, были ли получены данные
    char inChar = Serial.read();         // прочитать один символ
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
  if (stringComplete) {
    Serial.printf("inputString: %s \n", inputString);
    inputString = "";
    stringComplete = false;
  }
}

Вывод любой строки длиной более 12 символов иногда немного отличается, но всегда выглядит по одному и тому же шаблону. Для любой строки длиной 13 символов я получаю:

⸮⸮?

Выход меняется, если я добавляю символы, например, 20 символов:

Д⸮⸮?

Я предполагаю, что непечатаемый символ — это новая строка.

Скорость передачи установлена на одно и то же значение как в коде, так и в последовательном мониторе, и я получаю те же результаты, если изменяю скорость передачи.

Любые объяснения относительно такого поведения и способов его избежать будут приветствоваться.

, 👍1


1 ответ


Лучший ответ:

2

Изменить:

Serial.printf("inputString: %s \n", inputString);

к:

Serial.printf("inputString: %s \n", inputString.c_str());

%s ожидает const char *, который не соответствует тому, что дает inputString.

То, что вы видите в разнице между строками больше и меньше 12 символов, сводится к тому, оптимизация небольших строк и способ передачи структур в соглашении о вызовах ESP32.

,

Большое спасибо, это решило проблему <3, @UmbrellaCorpAgent

Как правило, лучше использовать массив символов, чем строку. Хотя строка может быть меньше, чем ваш максимальный размер массива, ее переменная природа затрудняет выбор правильного размера при распределении памяти. Хотя это не проблема в такой простой программе, как эта, когда вы переходите к более крупным проектам, где ваши функции используются в библиотеках, переменная природа строки делает выделение памяти в промежутках в фрагментации памяти слишком ненадежным. (Я решил много сбоев, просто заменив строки на массивы символов). Стоит привыкнуть к массивам символов, а не к строкам., @Tomas

Я попытался удалить "фрагментировано", к сожалению, 5-минутное правило редактирования для комментария слишком мало для дисграфического человека", @Tomas