Преобразование byte* в int в Arduino
Я пытаюсь преобразовать значение byte*
в int
, вот как это у меня получилось.
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String topicStr = topic;
int* payload_value;
int updates_cal;
payload_value = (int*)payload;
//updates_cal = *payload_value;
Serial.print((int)payload_value);
delay(1);
Serial.println();
Serial.println("-----------------------");
}
Я получаю полезные данные MQTT в виде целочисленного значения. Который я хочу получить в своем NodeMCU (ESP8266).
Есть ли способ сделать это?
Спасибо!
@user3201500, 👍2
Обсуждение3 ответа
Лучший ответ:
Судя по комментариям, вы на самом деле получаете целочисленные данные в виде текста, в виде последовательности символов ASCII. Это то, что вы отправляете себе с помощью mosquitto_pub
. Буфер явно не завершается нулем.
Если эти символы представляют собой целочисленное значение, то способ получить его как целочисленное значение будет
char buffer[128];
// Убедитесь, что `length` меньше указанного выше размера буфера.
// В противном случае вам понадобится буфер большего размера
// Формируем C-строку из полезной нагрузки
memcpy(buffer, payload, length);
buffer[length] = '\0';
// Преобразуем его в целое число
char *end = nullptr;
long value = strtol(buffer, &end, 10);
// Проверяем ошибки конвертации
if (end == buffer || errno == ERANGE)
; // Произошла ошибка преобразования
else
Sterial.println(value);
Еще один подход, который позволяет избежать использования отдельного большого [своего] буфера только для нулевого завершения, заключается в
// Строим строку формата `scanf`, которая будет читаться не более `length`
// символов, не полагаясь на нулевое завершение полезной нагрузки
char format[16];
snprintf(format, sizeof format, "%%%ud", length);
// Конвертируем полезную нагрузку
int payload_value = 0;
if (sscanf((const char *) payload, format, &payload_value) == 1)
Serial.println(payload_value);
else
; // Произошла ошибка преобразования
Однако этот подход менее защищен от целочисленного переполнения, чем предыдущий.
Обратите внимание, что большая часть вышеперечисленных «прыжков через обручи» посвящена добавлению нулевого терминатора во входной буфер. Если вместо этого вы выберете обеспечение нулевого завершения на стороне отправителя, тогда все сведется к простому
// Преобразование C-строки в целое число
char *end = nullptr;
long value = strtol((const char *) payload, &end, 10);
// Проверяем ошибки конвертации
if (end == buffer || errno == ERANGE)
; // Произошла ошибка преобразования
else
Sterial.println(value);
Дополнительные буферы не требуются.
Комментарии не для расширенного обсуждения; этот разговор был [перемещен в чат](https://chat.stackexchange.com/rooms/93108/discussion-on-answer-by-ant-convert-byte-to-int-in-arduino)., @Majenko
byte*
означает "указатель на байт(ы). Обычно он используется для указания на байтовый буфер и обычно также имеет значение длины, чтобы вы знали, сколько байтов находится в буфере. . Похоже, ваша функция имеет значение длины.
Если вы уверены, что данные в параметре payload
представляют собой одиночное целое число, а длина верна для целого числа (я полагаю, 2 байта на Arduino), то вы сможете выполнить приведение введите указатель на int*
и затем извлеките значение из буфера:
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String topicStr = topic;
int payload_value;
int updates_cal;
if (length >= 2) {
// Приводим полезную нагрузку к указателю int и извлекаем значение
intValue = *((int*)payload);
}
}
Я пробовал это, но есть какая-то ошибка. Это сброс моего NodeMCU. Номер исключения – 9., @user3201500
Не знаю, нашли ли вы ответ, но у меня была точно такая же проблема, и в конце концов я пришел к следующему:
payload[length] = '\0'; // Добавьте NULL в конец char*, чтобы сделать его строкой.
int aNumber = atoi((char *)payload);
В конце концов, довольно просто!
Имейте в виду, что `
payload[length]`
не является частью памяти, выделенной для переменной полезной нагрузки. Последний элемент в пространстве памяти массива всегда имеет длину 1. Ваш подход может работать большую часть времени, но вы потенциально можете перезаписать другие переменные, расположенные в этом месте в памяти., @Steve2955
- Прошивать NodeMCU с помощью .ino-файла?
- Как определить размер Flash?
- Передача функции-члена класса в качестве аргумента
- В ESP-12E NodeMCU, какой выход PIN A0?
- esp32 Stack canary watchpoint срабатывает
- Каково использование зарезервированных контактов и контактов SDD2, SDD3 NodeMCU?
- NodeMCU (Arduino IDE) «DynamicJsonBuffer» не был объявлен в этой области
- NodeMCU поддерживает внедрение ключей?
Если вы хотите преобразовать
byte *
вint
, то он у вас уже есть, предполагая, чтоint
достаточно велик для хранения адреса на вашей платформе. Но какой в этом смысл? Вашеpayload_value
— это адрес., @AnT@AnT Мне просто нужно целое число (без указателя). Как я могу Serial.print его?, @user3201500
**Какое** конкретное целое число вам нужно? Взято откуда?, @AnT
@AnT целое число публикуется MQTT в виде сообщения., @user3201500
Описание формата сообщения MQQT предполагает, что вторая часть моего ответа (а также ответа Дункана С) является правильным способом сделать это., @AnT
Я пробовал это, но это ошибка. Вот как выглядит ошибка:, @user3201500
Исключение (9): epc1=0x40202430 epc2=0x00000000 epc3=0x00000000 excvaddr=0x3ffeeb79 depc=0x00000000 >>>стек>>>
8 января 2013 г., первая причина: 4, режим загрузки: (1,6)
, @user3201500Учитывая длинные комментарии в принятом ответе, рассмотрите возможность редактирования этих вопросов и / или заголовка, чтобы отразить более четкое изложение желаемого., @Kelly S. French