Conversion to Arduino MQTT

I have recently converted my Arduino Cayenne project over to Arduino MQTT as I understand that Arduino CAyenne will be closed down soon (Arduino Mega + W5100).
All went OK with conversion but I have some issues with the result:

The ap on the iphone almost always shows as offline for this MQTT project (project name in dull grey rather than bold) even though the icons/actuators etc work OK. Also when I rearrange the icons on the iphone ap dashboard - they do not stay that way next time I open the ap.
This makes the ap quite annoying to use and was working fine under Arduino Cayenne!

I found that I could not populate the dashboard myself with widgets that took their input from the Arduino. Actually I could do it but they did not work properly. When I deleted them and let the dashboard populate itself as data was published - then the icons produced worked fine and could be modified - however the presentation is not very good i.e. When a 2 state icon is OFF it is still coloured (it used to be dull grey) with a 0 beside it, when ON it is coloured with a 1 beside it. It was much better under Arduino Cayenne where it was more obvious when an icon was showing an ON or OFF state.

I have yet to try the triggers to send an SMS for a change of state but hopefully that will work as always. If anyone can help with the above issues it would be greatly appreciated!
Craig

Dear Gentlemen at Cayenne,

I have similar problems. My device is a WeMos D1 Mini, based on ESP8266. It was working 90% well via the Arduino option.
I have converted my code to be MQTT compatible according to your guide, but I have experienced the following issues:

  • After a power or connection fail the Cayenne does not remember and does not restore the previous status of the actuators, it starts every actuators from off ( not like the old Arduino option).
  • The new MQTT solution does nor remember the actuators status at all. If I switch on the motors/lamps and log off, than log on a bit later, it shows all actuators “off” or whatever status (sometimes on, even its real status is off).
  • I have observed, that the Cayenne dashboard does not reacts on / process the messages come from my device.
  • I have tried to remove my device and add again, but now I Cayenne can not see the connected device at all, it says “Waiting for board to connect…”, although the debug messages say “Connection ok”. It is really annoying, I do not / cannot understand what has happened, what did I wrong?

I look forward to your kind reply and help!

BR,
Zoltan

I think that when my code published digital ON/OFF to the dashboard the widget that was automatically set up is an analog sensor - I want it to be simply a 2 state display.
How would I change that? It does not seem possible in the settings of the widget and as I said earlier in my post - when I built the widget myself and let the Arduino code publish to it, it didn’t work properly (widget HIGH all the time regardless of the published value).
Craig

this line should add a 2 state display widget where x is the input value(1 or 0)

 Cayenne.virtualWrite(1, x, "digital_sensor", "d");

Ahhh I see - I was sending the data as analog! The issue with the 2 state display is fixed now thank you.
Still have an issue with the phone ap icons not staying where I put them. And the project appears as though it is offline on the phone ap (light grey) - but still works.
Cheers,
Craig

Ohh and also I don’t seem to be able to set up a trigger to SMS me when my project is offline. Other triggers relating to state of 2 state icons on the dashboard set up fine (yet to check that they work). The online/offline trigger will not save.
Craig

These issues should be fixed when the retain flag is enabled on the Cayenne MQTT server. Tagging @rsiegel

It’s interesting that the board says connected. Did you update the MQTT credentials on the board after re-adding it? Every time you generate a new MQTT device it makes new credentials for that device.

I think that’s just how it shows up, I don;t think it really changes colors based on online/offline. I agree it would be nice to have it like the other devices to easily tell which ones are connected.\

Online/offline triggers currently do not work for MQTT or LoRa devices. As far as I know this is on the road map to add.

1 Like

Dear adam,
It has not been offered new credentials to me, but it could be a problem on my browser’s side. Currently I am happy with Cayenne, I could been add a new device and it works well.
The only function I could not realize properly the “push button”. Here I quote the whole code I have made and I hope you may suggest some solution or workaround (or just suggests to open a new topic :slight_smile:) /Sorry for the weirdly formatted text!/
Zoltan

//Home IoT solution with Wemos D1 Mini ver 2.2 

//#define CAYENNE_DEBUG
//#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266.h>
#include <Adafruit_BME280.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <PCF8574.h>

//Port extender addresses
PCF8574 PCF_01(0x20); //For the outputs/relays
PCF8574 PCF_02(0x27); //For the inputs (0/1)

// My DS18B20's addresses
// 0x28, 0xA0, 0x63, 0x23, 0x07, 0x00, 0x00, 0x9F //1. temperature sensor
// 0x28, 0xFF, 0xD1, 0x5C, 0x52, 0x15, 0x01, 0x68
// 0x28, 0xDA, 0xED, 0x23, 0x07, 0x00, 0x00, 0xA1 //2. temperature sensor
// 0x28, 0x8B, 0xC6, 0x23, 0x07, 0x00, 0x00, 0x30
// 0x28, 0xFF, 0x92, 0xF5, 0x44, 0x16, 0x03, 0x87
// 0x28, 0x90, 0x97, 0x23, 0x07, 0x00, 0x00, 0xCB
// 0x28, 0xCD, 0x8D, 0x23, 0x07, 0x00, 0x00, 0x6E
// 0x28, 0xFF, 0x84, 0x28, 0x65, 0x15, 0x01, 0x2D
DeviceAddress gtemp1 = { 0x28, 0xA0, 0x63, 0x23, 0x07, 0x00, 0x00, 0x9F }; //1.
DeviceAddress gtemp2 = { 0x28, 0xDA, 0xED, 0x23, 0x07, 0x00, 0x00, 0xA1 }; //2.
OneWire oneWire(D5); //Ezeken a lábakon megy: 8, 9 - NEM MEGY 12-en, LEFAGY a 10,11 és 13 esetén
DallasTemperature sensors(&oneWire);

// WiFi and MQTT credentials
char ssid[] = "";
char wifiPassword[] = "";
char username[] = "";
char password[] = "";
char clientID[] = "";

unsigned long lastMillis = 0;
unsigned long lastMillis2 = 0;
unsigned long lastMillis3 = 0;

int S0 = 0;
int S0e = 0;
int S1 = 0;
int S1e = 0;
int S2 = 0;
int S2e = 0;
int S3 = 0;
int S3e = 0;
int S4 = 0;
int S4e = 0;
int S5 = 0;
int S5e = 0;
int S6 = 0;
int S6e = 0;
int S7 = 0;
int S7e = 0;

//BMP280 setup, create instance
Adafruit_BME280 bme;

void setup() {
//  pinMode(D4, OUTPUT);
  pinMode(D5,  INPUT_PULLUP); //One Wire bus pullup to avoid using any external resistor.
	Serial.begin(9600);
	Cayenne.begin(username, password, clientID, ssid, wifiPassword);
  bme.begin();
  sensors.begin();

//Set the DS18B20 resolution to 12 bit
  sensors.setResolution(gtemp1, 12);
  sensors.setResolution(gtemp2, 12);
  
//I2C portextender start
  PCF_01.begin(); // 8pcs output
  PCF_02.begin(); // 8pcs input

//Reset/clean up Cayenne dashboard after power failure or reset.
  Cayenne.loop();
       Cayenne.celsiusWrite(0, bme.readTemperature());
       Cayenne.virtualWrite(1, bme.readHumidity(), TYPE_RELATIVE_HUMIDITY, UNIT_PERCENT); //There is no predefined Write command.
       Cayenne.hectoPascalWrite(2, bme.readPressure()/100);
       sensors.requestTemperatures();
       Cayenne.celsiusWrite(3, sensors.getTempC(gtemp1));
       Cayenne.celsiusWrite(4, sensors.getTempC(gtemp2));
       Cayenne.digitalSensorWrite(9, PCF_02.readButton(0));
       Cayenne.digitalSensorWrite(10, PCF_02.readButton(1));
       Cayenne.digitalSensorWrite(11, PCF_02.readButton(2));
       Cayenne.digitalSensorWrite(12, PCF_02.readButton(3));
       Cayenne.digitalSensorWrite(13, PCF_02.readButton(4));
       Cayenne.digitalSensorWrite(14, PCF_02.readButton(5));
       Cayenne.digitalSensorWrite(15, PCF_02.readButton(6));
       Cayenne.digitalSensorWrite(16, PCF_02.readButton(7));
       Cayenne.virtualWrite(20,0);
       Cayenne.virtualWrite(21,0);
       Cayenne.virtualWrite(22,0);
       Cayenne.virtualWrite(23,0);
       Cayenne.virtualWrite(24,0);
       Cayenne.virtualWrite(25,0);
       Cayenne.virtualWrite(26,0);
       Cayenne.virtualWrite(27,0);
}

void loop() {
	Cayenne.loop();

// 8pcs input - PCF8574
// No status change, no message - try to avoid any unnecessary status update.

       S0 = PCF_02.readButton(0);
       if (S0 != S0e) {
       Cayenne.digitalSensorWrite(9, S0);
       S0e = S0;
       }

       S1 = PCF_02.readButton(1);
       if (S1 != S1e) {
       Cayenne.digitalSensorWrite(10, S1);
       S1e = S1;
       }

       S2 = PCF_02.readButton(2);
       if (S2 != S2e) {
       Cayenne.digitalSensorWrite(11, S2);
       S2e = S2;
       }

       S3 = PCF_02.readButton(3);
       if (S3 != S3e) {
       Cayenne.digitalSensorWrite(12, S3);
       S3e = S3;
       }

       S4 = PCF_02.readButton(4);
       if (S4 != S4e) {
       Cayenne.digitalSensorWrite(13, S4);
       S4e = S4;
       }

       S5 = PCF_02.readButton(5);
       if (S5 != S5e) {
       Cayenne.digitalSensorWrite(14, S5);
       S5e = S5;
       }

       S6 = PCF_02.readButton(6);
       if (S6 != S6e) {
       Cayenne.digitalSensorWrite(15, S6);
       S6e = S6;
       }

       S7 = PCF_02.readButton(7);
       if (S7 != S7e) {
       Cayenne.digitalSensorWrite(16, S7);
       S7e = S7;
       }

**//Reset the status of the three (3) "push buttons" on channel 22, 23 & 24.**
**//Unfortunately it should be updated frequently, since I cannot "reset" them from "CAYENNE_IN" directly**.
if(millis() - lastMillis3 > 3000) {
       lastMillis3 = millis();
       Cayenne.virtualWrite(22,0);
       Cayenne.virtualWrite(23,0);
       Cayenne.virtualWrite(24,0);
       }

//Data need just slow update.
   if(millis() - lastMillis2 > 120000) {
       lastMillis2 = millis();
     
       //BMP/BME280 szenzor
       Cayenne.celsiusWrite(0, bme.readTemperature());
       Cayenne.virtualWrite(1, bme.readHumidity(), TYPE_RELATIVE_HUMIDITY, UNIT_PERCENT); ////There is no predefined Write command.
       Cayenne.hectoPascalWrite(2, bme.readPressure()/100);
       
       //DS18B20 szenzorok
       sensors.requestTemperatures();  // Send the command to get temperatures.
       Cayenne.celsiusWrite(3, sensors.getTempC(gtemp1));
       Cayenne.celsiusWrite(4, sensors.getTempC(gtemp2));

       }
}


//Relay controls (8ch).

CAYENNE_IN(20) //GM
{
  PCF_01.write(0, !getValue.asInt());
}

CAYENNE_IN(21) //KM
{
  PCF_01.write(1, !getValue.asInt());
}

CAYENNE_IN(22) //GA - Should be a "push button", holding time 777ms, reset in the loop
{
  PCF_01.write(2, !getValue.asInt());
  delay(777);
  PCF_01.write(2, HIGH);
}

CAYENNE_IN(23) //GK - Should be a "push button", holding time 777ms, reset in the loop
{
  PCF_01.write(3, !getValue.asInt());
  delay(777);
  PCF_01.write(3, HIGH);
}

CAYENNE_IN(24) //BK - Should be a "push button", holding time 777ms, reset in the loop
{
  PCF_01.write(4, !getValue.asInt());
  delay(777);
  PCF_01.write(4, HIGH);
}

CAYENNE_IN(25) //Relé 6.
{
  PCF_01.write(5, !getValue.asInt());
}

CAYENNE_IN(26) //Relé 7.
{
  PCF_01.write(6, !getValue.asInt());
}

CAYENNE_IN(27) //Relé 8.
{
  PCF_01.write(7, !getValue.asInt());
}

//It might be useful for later.
/*
CAYENNE_IN(6)
{
  pinMode(2, OUTPUT);
  if (getValue.asInt() == 1)  //check the 0/1 value coming from the Cayenne widget
    {
    digitalWrite(2, HIGH);  
    }
  else
    {
    digitalWrite(2, LOW); 
    }
}
*/

//    tslfunc(VIRTUAL_PIN);
//    ds18b20func(VIRTUAL_PINT);
       //Some examples of other functions you can use to send data.
       //Cayenne.celsiusWrite(1, 22.0);
       //Cayenne.luxWrite(2, 700);
       //Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
1 Like

When you say push button are you talking about a button attached to a GPIO pin or a dashboard software button? Also you have an error in your comment here:

**//Reset the status of the three (3) "push buttons" on channel 22, 23 & 24.**
**//Unfortunately it should be updated frequently, since I cannot "reset" them from "CAYENNE_IN" directly**.

The // needs to come before the ** or just take the ** out as /* is a block comment.

Thanks for all that Adam. Actually the project does highlight into a bold colour after a few seconds - possibly when the server “talks” to my board? So all good there and thanks for the explanation of online/offline triggers not working on MQTT Cayene. I assume the other triggers work OK?
Also any idea on why I cannot move the icons on my phone ap (to make a more sensible arrangement) and have them stay there - currently the next time I log in the icons are back where they started from.
Thanks again,
Craig

Thank you for your fast reply!
Sorry, the stars **// are fault of formatting or fault of copy, there are no ** over there. (I have tried to format my code to make it more readable as I see in other’s nice reply, but I am too beginner yet :slight_smile: to do it on the right way)
The push button I have mentioned is a dashboard button/actuator. I have realized it by a relay, because I shall imitate a real momentary switch to interface my device to another one.
Unfortunately there is no momentary switch/push button actuator in Cayenne yet. This is why I created this not really elegant workaround.

Pls check the following rows, starts with CAYENNE_IN!
These short delays realize the push button function toward to another hardware I shall interface to (my relays react to active “L”).

CAYENNE_IN(22) //GA - Should be a “push button”, holding time 777ms, reset in the loop
{
PCF_01.write(2, !getValue.asInt());
delay(777);
PCF_01.write(2, HIGH);
}

CAYENNE_IN(23) //GK - Should be a “push button”, holding time 777ms, reset in the loop
{
PCF_01.write(3, !getValue.asInt());
delay(777);
PCF_01.write(3, HIGH);
}

CAYENNE_IN(24) //BK - Should be a “push button”, holding time 777ms, reset in the loop
{
PCF_01.write(4, !getValue.asInt());
delay(777);
PCF_01.write(4, HIGH);
}

The following part do the button/actuator status reset on the Cayenne dashboard, because I did not find any, better solution yet to avoid clicking on the actuator button twice.

if(millis() - lastMillis3 > 3000) {
lastMillis3 = millis();
Cayenne.virtualWrite(22,0);
Cayenne.virtualWrite(23,0);
Cayenne.virtualWrite(24,0);
}

can you give this a try : Switch button as pulse generator - #4 by shramik_salgaonkar

2 Likes

Thanks a lot, I will try it today evening!

2 Likes

Dear shramiksalgaonkar,

I have tested your solution on last weekend and it works well, thanks a lot again!
But I have limited program memory in my device, therefore I have modified the code to make it shorter.
Since I am not a professional, it may not work in every cases, pls check it!
(I did not copied all the code here below, just the point to save space.)

//Home IoT solution with Wemos D1 Mini ver 2.2
#include <DallasTemperature.h>
#include <PCF8574.h>
// WiFi and MQTT credentials


int GD = 0; //Garage Door
int GG = 0; //Garage Gate
int PG = 0; //Parking place Gate


void setup() {
Serial.begin(9600);
Cayenne.begin(username, password, clientID, ssid, wifiPassword);


void loop() {
Cayenne.loop();


//Reset the status of the three (3) “push buttons” on channel 22, 23 & 24 after it was pressed.
if (GD == 1)
{
Cayenne.digitalSensorWrite(22, 0);
GD = 0;
}
if (GG == 1)
{
Cayenne.digitalSensorWrite(23, 0);
GG = 0;
}
if (PG == 1)
{
Cayenne.digitalSensorWrite(24, 0);
PG = 0;
}


}


//Relay controls (8ch).


//ACTIVE LOW relay module!
CAYENNE_IN(22) //GD - Pushbutton, it holds for 1 sec.
{
GD = getValue.asInt();
PCF_01.write(2, !GD);
delay(1000);
PCF_01.write(2, HIGH);
}
CAYENNE_IN(23) //GG - Pushbutton, it holds for 1 sec.
{
GG = getValue.asInt();
PCF_01.write(3, !GG);
delay(1000);
PCF_01.write(3, HIGH);
}
CAYENNE_IN(24) //PG - Pushbutton, it holds for 1 sec.
{
BK = getValue.asInt();
PCF_01.write(4, !PG);
delay(1000);
PCF_01.write(4, HIGH);
}

1 Like

Having similar issues here with MQTT conversion

  • major space issues due to the size of the credentials!
  • cant get gauge widget to display for main “level” reading required for my app
  • cant get 2 state display for digital input - cant use [Cayenne.virtualWrite(1, x, “digital_sensor”, “d”);] because i have no space for the extra code!
  • my dashboard looks horrible as I cant get most of my widgets to load (code space!!)
  • slider widget is not holding last value set

The removal of the Arduino library support is going to cause me headaches!
I have a heap of 328 based industrial arduino devices and the move to MQTT only looks like it will make them all redundant where they worked just fine on Ardunio Cayenne Library :frowning:

I replied to another thread you posted in, but could you also share your code? We might be able to make some suggestions on cutting it down.

Hi Adam,
I have successfully converted my project from Arduino Cayenne over to MQTT and I have been running for a month or so now and I have to say that it IS much more stable! I have not had one instance of connection dropout etc so … all good there.
The only issue I have is with the iphone ap. All of the icons/widgets that I have populated the screen with, all work fine, its just that when I arrange them into a display that makes sense - they do not stay there when I next open the ap - they revert to their original position. Is this a known issue? Are there any solutions?
Thanks,
Craig

Oh and I still cant save a trigger to let me know if my device has gone offline. I can set it up but when I try to save it I get the red “not allowed” icon. Any advice there?
Thanks,
Craig

Last I heard re-ordering widgets is on the road map for mobile.

Unfortunately there are not yet triggers for offline with MQTT.