Ошибка Cast from 'char*' to 'uint8_t {aka unsigned char}' loses precision [-fpermissive]
Я пытаюсь преобразовать строку, полученную из Websocket, в uint8_t, которую я могу скопировать в байты данных кадра протокола CAN. Я использую чип ESP32 и программирую его в Arduino IDE. Строка, которую он получает из веб-сокета, имеет вид "0322F12155555555".
#include <WiFi.h>
#include <SPIFFS.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <esp32_can.h>
#include <SPI.h>
#include <string.h>
uint8_t payload1;
char payload2[100];
...
AsyncWebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(1337);
...
// Обратный вызов: получение любого сообщения WebSocket
void onWebSocketEvent(uint8_t client_num,
WStype_t type,
uint8_t * payload,
size_t length) {
...
Serial.printf("[%u] Received text: %s\n", client_num, payload);
strcpy(payload2, (const char*)payload);
payload1 = (uint8_t)(payload2);
...
Ошибка:
error: cast from 'char*' to 'uint8_t {aka unsigned char}' loses precision [-fpermissive]
payload1 = (uint8_t)(payload2);
^
Позже я сегментирую данные в массив, но не уверен, что приведение правильное. Может ли кто-нибудь помочь с этим? Спасибо
-- Кит
1 ответ
Лучший ответ:
Вы не можете просто привести строку к числовому типу — C так не работает. На самом деле вы передаете адрес в памяти, по которому находится строка.
Вместо этого вам нужно взять содержимое строки и интерпретировать его.
Например, вы можете взять каждую пару символов и объединить их в шестнадцатеричное значение в строке, которую затем интерпретируете как число. Это можно сделать несколькими способами.
Например:
char temp[3]; // Временное место для строки преобразования
// Копируем два символа во временную строку
temp[0] = payload[0];
temp[1] = payload[1];
// и закончим строку правильно
temp[2] = 0;
// Преобразование строки с использованием базы 16
uint8_t val = strtol(temp, NULL, 16);
В строке примера у вас есть 16 символов, что соответствует 8 байтам данных. Таким образом, вы можете поместить его в цикл:
char temp[3]; // Временное место для строки преобразования
uint8_t vals[8]; // Массив для хранения ваших значений
// Перебираем значения
for (int i = 0; i < 8; i++) {
// Копируем два символа во временную строку
temp[0] = payload[i * 2];
temp[1] = payload[i * 2 + 1];
// и закончим строку правильно
temp[2] = 0;
// Преобразование строки с использованием базы 16
vals[i] = strtol(temp, NULL, 16);
}
Конечно, есть "более легкие" способы сделать это, которые не включают промежуточную строку или функцию strtol()
. Например, я часто использую эту маленькую функцию:
uint8_t h2d(char hex) {
if(hex > 0x39) hex -= 7; // настроить шестнадцатеричные буквы в верхнем или нижнем регистре
return(hex & 0xf);
}
Это берет один символ и преобразует его из шестнадцатеричного в десятичный. Таким образом, вы можете комбинировать это со сдвигом битов и ИЛИ, чтобы создать байт из двух символов:
val = h2d(payload[0]) << 4 | h2d(payload[1]);
В вашем цикле это будет выглядеть так:
for (int i = 0; i < 8; i++) {
// Преобразование строки с использованием базы 16
vals[i] = h2d(payload[i * 2]) << 4 | h2d(payload[i * 2 + 1]);
}
- Считывание данных нескольких датчиков из текстового файла, расположенного на SD-карте в Arduino/ESP32
- Не могу скомпилировать .ino с помощью библиотеки ArduinoJson
- устаревшее преобразование из строковой константы в 'char*'
- Количество элементов в массиве char
- ESP32 в Arduino-IDE с FS.h и SPIFFS
- Программаторы для этой платы отсутствуют - Программирование ESP32 Cam с помощью Ardunio IDE
- Установка значения float до двух знаков после запятой
- ESP32-CAM первый: 0x8 TG1WDT_SYS_RESET загрузочный цикл
Это должно быть uint8_t *, а не uint8_t., @Majenko
@Majenko, мне нужно, наконец, сегментировать данные и скопировать их в массив, который принимает
`
uint8_t`
. Как я могу это сделать?, @ObviousActivity936Я думаю, это звучит так, как будто вам нужно делать гораздо больше, чем просто кастинг. Вам нужно интерпретировать содержимое строки., @Majenko