Button widget error

I am using a RP2040 COnnect Arduino with Cayenne and I am able connect and send data from my controller to the dashboard but when I try to put a button widget and send data to the controller and the message is received but the button keeps loading forever.


My code is below :slight_smile:

#include <SPI.h>
#include <WiFiNINA.h>
#include <PubSubClient.h>
#include <Arduino_LSM6DSOX.h>

int hydrogen;
int temperature_deg;
float x, y, z;
//#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = "TELUSWiFi0280";        // your network SSID (name)
char pass[] = "8m4c8DbzKz";    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the WiFi radio's status


#define MQTT_SERVER     "mqtt.mydevices.com"
#define MQTT_SERVERPORT 1883
#define MQTT_USERNAME   "973c1410-f0b0-11ec-9f5b-45181495093e"
#define MQTT_PASSWORD   "ba071053e33cabd2a7fe0149e2b52c34c01323b1"
#define CLIENT_ID       "402c18d0-f314-11ec-a681-73c9540e1265"


#define MQTT_TOPIC_HYDROGEN  "v1/" MQTT_USERNAME "/things/" CLIENT_ID "/data/1"
#define MQTT_TOPIC_X   "v1/" MQTT_USERNAME "/things/" CLIENT_ID "/data/2"
#define MQTT_TOPIC_Y   "v1/" MQTT_USERNAME "/things/" CLIENT_ID "/data/3"
#define MQTT_TOPIC_Z   "v1/" MQTT_USERNAME "/things/" CLIENT_ID "/data/4"
#define MQTT_TOPIC_BOARD_TEMP   "v1/" MQTT_USERNAME "/things/" CLIENT_ID "/data/5"
#define MQTT_TOPIC_LED   "v1/" MQTT_USERNAME "/things/" CLIENT_ID "/cmd/6"

WiFiClient espClient;
PubSubClient client(MQTT_SERVER, MQTT_SERVERPORT, espClient);

//Defineining a datatype to store the mqtt message, up to 50 bytes
char  msg[50];


long    timeStampNow;
long    timeStampLastMsg = 0;

void setup() {
  // Initialize serial monitor for debugging purposes.
  Serial.begin(9600);
  Serial.println("DEBUG: Entering setup ");

  // Attempt to connect to WiFi.
  WiFi.begin(ssid, pass);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

 // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

 // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
   // delay(2000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");

//Accelerometer setup
  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }

  Serial.print("Accelerometer sample rate = ");
  Serial.print(IMU.accelerationSampleRate());
  Serial.println(" Hz");
  Serial.println();
  Serial.println("Acceleration in g's");
  Serial.println("X\tY\tZ");

//Onboard temperature sensor setup
if (IMU.temperatureAvailable()){
    int temperature_deg = 0;
    }

  // Initialize MQTT PubSub Library
  client.setServer(MQTT_SERVER, MQTT_SERVERPORT);
  // Function called in case of an incomming mqtt message from Cayenne Dashboard
  // (In this case is the dashboard button to turn on/off the heater)
  client.setCallback(mqttCallback);

  Serial.println("DEBUG: Setup Done! ");

}

// -------------------- LOOOP -------------------

void loop() {
  // Check if the esp8266 is connected to the mqtt server.
  if (!client.connected()) {
    reconnect();
  }

  // If connected, perform PubSubClient housekeeping function.
  client.loop();

  // Publish temperature readings every 2 seconds (2000ms)
  timeStampNow = millis();
  if (timeStampNow - timeStampLastMsg > 5000) {    // Publish interval in milliseconds
    // Reset the counter
    timeStampLastMsg = timeStampNow;
    // Jump to the actual function to read and publish temperatures.
    hydrogendata();
    accelerometer();
    board_temp();
  }

  delay(1000);
  //Serial.println("DEBUG: Reached MAIN LOOP END --> Looping ");
}


// ------------------------------ OTHER FUNCTIONS

// Function that attempts to reconnect to the mqtt server.

void reconnect() {
  // If esp8266 is disconnected from the mqtt server, try to reconnect.
  // (*** I still need to think what wil happen to the boiler if connection is lost ***)
  while (!client.connected()) {
    Serial.print("DEBUG: Attempting MQTT connection...");

    // Attempt to connect
    if (client.connect(CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
      Serial.println("connected");

      // Once connected, resubscribe to the Dashboard on/off button topic.
      // client.subscribe(MQTT_TOPIC_BTN_ONOFF);
      client.subscribe(MQTT_TOPIC_LED);

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
  //Serial.println("DEBUG: Quiting reconnect loop ");
}


// Function that handles temperature adquisition from sensors, and publishing to Cayenne Dashboard.
void hydrogendata(){
  hydrogen = analogRead(A0);
  // Construct the mqtt message following Cayenne's rules, according to the Docs..
  // Send Sensor data -> Topic: v1/username/things/clientID/data/channel

  //using a float rounded to 2 decimal places.
  String hydrogen_message = String(hydrogen);
  Serial.println(hydrogen_message);
  mqtt_message(hydrogen_message);
  
  // Finally! Publish the temperature to Cayenne Dashboard, Channel 1.
  client.publish(MQTT_TOPIC_HYDROGEN,msg);
  }

void mqtt_message(String message){
  // Convert the string into a Char Array
  message.toCharArray(msg, 50);
  Serial.print("Publish message: ");
  Serial.println(msg);  
  }

void accelerometer(){
  if (IMU.accelerationAvailable()) {
    IMU.readAcceleration(x, y, z);
    Serial.print(x);
    Serial.print('\t');
    Serial.print(y);
    Serial.print('\t');
    Serial.println(z);
  }
  String acc_x_message = String(x);
  String acc_y_message = String(y);
  String acc_z_message = String(z);

//Publishing accelerometer values to Cayenne Dashboard, Channel 2-4
  mqtt_message(acc_x_message);
  client.publish(MQTT_TOPIC_X,msg);
  mqtt_message(acc_y_message);
  client.publish(MQTT_TOPIC_Y,msg);
  mqtt_message(acc_z_message);
  client.publish(MQTT_TOPIC_Z,msg);
}

void board_temp(){
    IMU.readTemperature(temperature_deg);
    String onboard_temp = String(temperature_deg);
    mqtt_message(onboard_temp);
    client.publish(MQTT_TOPIC_BOARD_TEMP,msg);
}

// Function to intercept MQTT messages
void mqttCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
 
  Serial.print("Message:");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
 
  Serial.println();
  Serial.println("-----------------------");
}

you need send a ack back to show the updated state. You can check the docs for more info Cayenne Docs

or you can use GitHub - myDevicesIoT/Cayenne-MQTT-Arduino: Cayenne MQTT Arduino Library
which handles it.

1 Like