Преобразование из ASCII uint8_t в строку

Я отправляю строку с Raspberry Pi на ESP32 через BT. Я получаю одно значение ASCII в строке. Как преобразовать его в одну целую строку? Я попробовал следующим образом, но я получаю сообщение об ошибке при запуске метода printReceivedMEssage(buffer):

недопустимое преобразование из 'uint8_t {он же unsigned char}' в 'uint8_t* {он же unsigned char*}' [-fpermissive]

uint8_t buffer; 

void printReceivedMessage(const uint8_t* buf) {
  char string_var[100];
  size_t bufflen = sizeof(buf);

  for (int i = 0; i < bufflen; ++i) {
    Serial.println(static_cast<char>(buf[i]));
  }

  memcpy( string_var, buf, bufflen );
  string_var[bufflen] = '\0'; // ' str' теперь является строкой
  Serial.print("string_var=");
  Serial.println(string_var);
}

void loop() {
  buffer = (char)SerialBT.read();  
  Serial.println(buffer); // ЗДЕСЬ ОТОБРАЖАЮТСЯ ЗНАЧЕНИЯ ASCII ПО ОДНОМУ НА СТРОКУ
  printReceivedMessage(buffer); // ОШИБКА
  delay(1000);
}

, 👍1

Обсуждение

https://majenko.co.uk/blog/our-blog-1/reading-serial-on-the-arduino-27, @Majenko

Ваш буфер состоит всего из одного байта, @SBF


1 ответ


2

С вашим кодом связано множество проблем. Они предполагают, что вы не знаете, что такое строки на самом деле.

В C / C ++ строки на самом деле представляют собой массивы символов (char). uint8_t имеет тот же размер, что и один символ, поэтому вы можете сохранить в нем только один символ. Для сохранения строки вам понадобится их массив. Таким образом, буфер должен быть объявлен следующим образом

uint8_t buffer[20] = "";

Теперь буфер может содержать строку из 19 символов. 20-й символ - это завершающий нулевой символ \0, который обозначает конец строки. Вы всегда должны оставлять достаточно места для нулевого символа, чтобы правильно завершать ваши строки.

Последовательное чтение: Есть много способов, как вы можете читать из Serial. Посмотрите на функцию Serial.readStringUntil(), которая будет считывать данные из Serial до тех пор, пока не достигнет указанного символа. Таким образом, вы можете легко разделить непрерывный поток байтов из Serial на отдельные сообщения. Обычно все сообщения в кодировке ASCII заканчиваются символом новой строки \n, чтобы отметить конец сообщения. С помощью Serial.readStringUntil('\n') (обратите внимание на одинарные кавычки для одного символа) вы будете читать, пока он не достигнет символа новой строки (или времени ожидания). Затем вы можете обработать прочитанную строку как полное сообщение.

Предоставление строки в качестве параметра функции: в C / C ++ вы не можете просто предоставить массив в качестве параметра функции в качестве других переменных. Это немного сложнее. Это связано с тем, что внутренний массив состоит всего из нескольких байтов в строке, а переменная просто указывает на первый его элемент. Это указатель (это специфический термин C / C ++). Указатели помечены знаком *, что вы уже сделали с вашим

void printReceivedMessage(const uint8_t* buf)

функция. Таким образом, параметр - это просто указатель на uint8_t. Это также объясняет сообщение об ошибке, потому что вы указали uint8_t, но вместо этого функция ожидает указатель на uint8_t. Хотя вы все еще можете получить доступ к данным массива с помощью этого параметра (учитывая, что вы реализовали то, что я написал выше о массиве), sizeof(buf) даст вам только размер указателя (2 байта на большинстве платформ Arduino). Таким образом, вам нужно добавить параметр, а также указать размер массива. Или вы можете использовать правильное завершение строк нулевым символом и получить длину строки с помощью strlen(). Эта функция перебирает указатель массива до тех пор, пока не найдет нулевой символ и не выдаст вам результирующую длину.

,