Cayenne MQTT messages are currently rate limited to 60 messages each minute. If your client code sends messages at a higher rate it will have messages dropped and if it continues to send messages above the limit can run the risk of being disconnected or blocked.
In order to keep your client sending messages below the limits make sure you only send data at intervals. For embedded devices like Arduino this means you should not send data by just using a virtualWrite()
call within the main loop()
. Doing this will result in the function being called to send data every time through the loop()
which can cause thousands of messages being sent each minute. In order to send messages at intervals there a few methods you can use:
-
The built-in
CAYENNE_OUT_DEFAULT()
andCAYENNE_OUT()
functions.
This method is probably the simplest since these functions are designed to automatically run at intervals (currently every 15 seconds). To use them just declare them in your program and include a write function to send data to Cayenne:CAYENNE_OUT_DEFAULT() { Cayenne.virtualWrite(0, millis()); }
CAYENNE_OUT_DEFAULT()
can be used for most situations but if you want to use specific functions for different channels you can useCAYENNE_OUT(channel)
functions instead. -
Manually calculating the interval to send data.
This method allows you to determine the intervals yourself rather than using the set interval theCAYENNE_OUT
functions use. To do this with Arduino you can just use the built-inmillis()
function to check the elapsed time and send data at the required interval:unsigned long lastMillis = 0; void setup() { Serial.begin(9600); Cayenne.begin(username, password, clientID); } void loop() { Cayenne.loop(); //Publish data every 10 seconds (10000 milliseconds). Change this value to publish at a different interval. if(millis() - lastMillis > 10000) { lastMillis = millis(); Cayenne.virtualWrite(0, lastMillis); } }
-
A timer function.
This method requires including a timer class in your code to run a function at the specified interval. For an example showing how to use a timer class see theSendDataOnTimer
example sketch: Cayenne-MQTT-Arduino/SendDataOnTimer.ino at master · myDevicesIoT/Cayenne-MQTT-Arduino · GitHub. -
Only send data when it changes.
This method can be used for sensors that have values that do not change very often. In that case you can just send the data when it changes and prevent a lot of unnecessary messages. Though that may affect the graph display so if you plan to use graphing for the sensor you may want to use one of the other methods to send data at regular intervals. If you don’t care about regular data points though you can just keep track of the previous state of the sensor and update it when it changes:int previousState = -1; int currentState = -1; void setup() { Serial.begin(9600); Cayenne.begin(username, password, clientID); } void loop() { Cayenne.loop(); // Check the sensor state and send data when it changes. currentState = digitalRead(4); if (currentState != previousState) { Cayenne.virtualWrite(0, currentState); previousState = currentState; } }
When sending data make sure you keep it within the current limit of 60 messages per minute if you don’t want data dropped or your client disconnected. This means that if, for instance, you wanted to send data for 10 different sensors you should either send each sensor’s data separately at most each second or if you want to send them all at once make sure you only do it at most every 10 seconds.
The examples above are based on the Cayenne MQTT Arduino library but the same rate limits apply for any other clients, like the Cayenne MQTT Python library or any third party MQTT libraries used to connect to Cayenne. So if using those you should also make sure that data is sent at appropriate intervals.