Я пытаюсь непрерывно отправить массив из 6 чисел с плавающей точкой по протоколу MQTT. Я отправлял их как символы ASCII, используя функцию sprintf. Я решил отправить их как необработанные байты. Я поместил эти поплавки в союз, чтобы представлять их как беззнаковый символ. Проблема в том, что когда любое из этих чисел с плавающей запятой имеет целочисленное значение, их байтовое представление становится нулевым после позиции целого числа.
union {
float array[6];
unsigned char bytes[6 * sizeof(float)];
} floatAsBytes;
Если все floatAsBytes.array состоят из значений с плавающей точкой, проблем вообще не возникает.
Если я скажу floatAsBytes.array[0] = 0
, floatAsBytes.bytes станет нулевым.
Если я скажу floatAsBytes.array[3] = 4
, я смогу увидеть первые 8 байтов, но на этот раз последние 16 байтов станут нулевыми.
Минимальный пример моего C-кода на стороне клиента
#define QOS 0
#define TIMEOUT 1000L
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include "MQTTClient.h"
union bitFloat{
float f[6];
unsigned char s[6*sizeof(float)];
};
void publish(MQTTClient client, char* topic, char* payload) {
MQTTClient_message pubmsg = MQTTClient_message_initializer;
pubmsg.payload = payload;
pubmsg.payloadlen = strlen(pubmsg.payload);
pubmsg.qos = QOS;
pubmsg.retained = 0;
MQTTClient_deliveryToken token;
MQTTClient_publishMessage(client, topic, &pubmsg, &token);
MQTTClient_waitForCompletion(client, token, TIMEOUT);
}
int main(){
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;
MQTTClient_create(&client, "MQTTADDRESS:MQTTPORT", "TestClient",
MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(-1);
}
int i;
while(1){
union bitFloat payload;
payload.f[0] = 4.53; payload.f[1] = 2.39; payload.f[2] = 28.96; payload.f[3] = -1.83; payload.f[4] = -27.0; payload.f[5] = 9.32;
publish(client, "MyTestTopic", payload.s);
sleep(1);
}
return 0;
}
Python-скрипт для получения и отображения сообщений
# !/usr/bin/env python
import struct
import numpy as np
import paho.mqtt.client as mqtt
def on_message(client, userdata, message):
test1 = struct.unpack('<f', message.payload[0:4])[0]
test2 = struct.unpack('<f', message.payload[4:8])[0]
test3 = struct.unpack('<f', message.payload[8:12])[0]
test4 = struct.unpack('<f', message.payload[12:16])[0]
test5 = struct.unpack('<f', message.payload[16:20])[0]
test6 = struct.unpack('<f', message.payload[20:24])[0]
print(test1, test2, test3, test4, test5, test6)
client = mqtt.Client()
client.on_message = on_message
client.connect("MQTTADDRESS", MQTTPORT)
client.subscribe("MyTestTopic")
client.loop_forever()