Data format to use on a micro controller and MQTT

3.9k Views Asked by At

I'm using MQTT on an Arduino to send sensors data to a Javascript page.

Until now I've sent only simple data format: int or floats.

What format can I use to send more complex, structured data? for example:

{ "temperature": 32, "humidity": 67 }

I'd like to send it on a single MQTT message.

I could use Json, but I fear it's a bit heavy for an Arduino.


Update

Ok, seems to be a general consensus on JSON, however I'm a bit concerned about the memory requirement.

I've found two libraries for json encoding/decoding on an Arduino:

ArduinoJson claims to be less memory consuming, however doesn't support:

  • reading from Stream (latest versions of the Arduino MQTT library supports receiving messages in streams)
  • filtering of incoming json (to selectively parse only required Json fields)
2

There are 2 best solutions below

0
On

The way I do it is just publish the temp in Celsius (or Faranheit) from the Arduino to the broker for example

/raw/sensorid temp

Then on the broker I transform it all into JSON including adding a timestamp and republish to another topic. I find it easier this way as I don't need to change the arduino code if I move the sensor or have replace it. Here is the code I use if you are interested, it's using Onewire sensors.

For example;

Arduino Publishes:
/raw/DE24532156 10


On my broker I Transforms the data to:
/house/temps {"location":"outside","tempC":10,"tempF":50,"average":14,"max":16,"min":8,"timestamp":12234234}

I do all my transformation in python using mqttwarn.

3
On

Use the topics themselves to structure the data:

/home/sensors/count 2
/home/sensors/sensor1/name Kitchen
/home/sensors/sensor1/temperature 21
/home/sensors/sensor1/humidity 47
/home/sensors/sensor2/name Upstairs
/home/sensors/sensor2/temperature 23
/home/sensors/sensor2/humidity 48

Publishing many simple messages is easier for a resource constrained Arduino. The alternative is constructing some large JSON string like you are thinking:

/home/sensors = {{"name":"Kitchen", "temperature": 21, "humidity": 47 },
                 {"name":"Upstairs", "temperature": 23, "humidity": 48 }}

Also, I think the topics is the more useful design (API) for the both publisher and client. For the Arduino side, consider how the topic approach does not force every location to have both temperature and humidity sensors? For the client side, the topic approach allows a use case that shows just the humidity.