Toggling Button State

Hello People,
I recently discovered Cayenne and am loving it, but I have one question.

It is possible to change the state of a button widget from the Arduino.

Like If I press a button that is connected to my Arduino, it will change the state of a button widget in the app?

Thanks,
Ben

Welcome!

That is definitely possible! You want to treat it just like your writing data to the dashboard. But instead of writing to a new channel with your data, use the same channel that button/actuator is on and just write a 0 or 1. So the example below, writes a 0 or “off” to the button on channel 1. If you want it on just change the 0 to a 1. The button will update right away on the dashboard.

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

You can also do this with a analog slider too. Instead of writing a 0 or 1, write the value you want the slider to show as below. I have it writing to channel 4, and then the value of my variable txPwr.

Cayenne.virtualWrite(4, txPwr, "analog_actuator", "null");

One thing to note is I don’t believe this will call your CAYENNE_IN functions. Meaning, that is you have code under your CAYENNE_IN(channel#) that runs when you press the button, it won’t be run when you change the actuator state from your code. I think it only runs when you press the button on the dashboard. I could be wrong but if your code under CAYENNE_IN isn’t being run, thats why. Just move the code out of the CAYENNE_IN function if you need it to run on any change with a “if” statement.

i hope that wasn’t too confusing lol.

Hi @Benveghte, and welcome to the Cayenne Community.

You can track the state of a push button wired to your Arduino using a custom 2-State Widget (or a Generic Digital Input widget, which is ultimately a 2-State widget itself). We have a tutorial on how to set it up for Arduino here.

This is because the 0/1 state from the push button is a ‘sensor’ in the context of Cayenne – data flowing into the platform rather than out. The custom Button widget you found is intended for actuators, to control something like a relay or a light switch on your device from Cayenne.

You can of course base a trigger off of the 0/1 state of a 2-state widget which would then take some action in Cayenne, including controlling actuators on your device.

Hey @vapor83,
Thank you so much, that makes some sense, but could you break down the parts of
“Cayenne.virtualWrite(1, 0, “digital_sensor”, “d”);”
and would I still use virtualWrite when if the button widget is connected to a digital pin as opposed to a virtual one?

Thank you so much again,
Ben

Yes, @rsiegel yes that is my end goal, to control a relay from 2 input sources: a button and Cayenne. Right now I am just trying to toggle the state of an led.

Thanks,
Ben

are you using MQTT or regular Cayenne?

@vapor83 Regular

@Benveghte use this code for regular and add a two state widget with virtual pin V1.

CAYENNE_OUT(V1)
{
  x = digitalRead(INPUTPIN);
  Cayenne.virtualWrite(V1, x);
}

Could I use it if it was a digital pin?
For example:

bool buttonState = 0;
CAYENNE_OUT(D4) {
Cayenne.digitalWrite(D3, buttonState);
}

no. for using a digital pin you dont have to add code, you have to select the correct digital pin on dashboard.

?
Sorry, I don’t think I understand what you are saying.

My goal is to push the state of either a variable or a button from my Arduino to a widget on the cayenne app.

So from what I am assuming, I do need extra code to send a variable.

Thanks

@Benveghte to send a variable or sensor value to a cayenne dashboard from arduino you have call this code. Give this a try and let me know whether you are able to send the value of a digital switch connected to the arduino and see the change of state.

#define CAYENNE_DEBUG         // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"
int x,
int inputPin =2;
char token[] = "";
char ssid[] = "";
char password[] = "";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Cayenne.begin(token, ssid, password);
}
void loop() {
  // put your main code here, to run repeatedly:
  Cayenne.run();
}
CAYENNE_OUT(V1)
{
  x = digitalRead(inputPin);
  Cayenne.virtualWrite(V1, x);
}

and if I wanted to receive data from the cayenne app from the same pin, V1, I would use CAYENNE_IN(V1), how would I get it to toggle an led.

Also, do I have to put the commands outside of void loop (){}?

to receive data from cayenne app you have to add this code outside the void loop with a different virtual pin V2 and also on your dashboard you have to add a digital actuator widget.
go to: Add new > devices/widget > actuator > generic > digital output > fill all the details with virtual pin V2…

CAYENNE_IN(V2)
{
  int currentValue = getValue.asInt();
  if (currentValue == 1)
  {
    digtalWrite(ledPin, HIGH);
  }
  else
  {
    digtalWrite(ledPin, LOW);
  }
}

So I can’t have a single button that can toggle the state of an led but also be toggled by a physical button on my Arduino?

have a look at this post How to toggle light on and off , between Cayenne app and momentary switch, for home automation? - #10 by steaveultimate