Switch button as pulse generator

Hi,
I need a switch functionality of a push button, so the signal should just go to ON (1) for e.g. 200ms (defined time) and than automatically OFF (0) after pressing the button on cayenne. So far I just found the possibility to toggel the state.
I have not found a solution so far …
THANKS a lot for hints

Welcome!

Are you using MQTT or regular Cayenne to connect? I use a virtualWrite back to the button just pushed that makes it act as a momentary push button. As soon as the button is pressed, it makes the button go back to (0). This example is for restarting a ESP on MQTT connection. If you need to to only be 200ms or something similar that could be harder to do.

CAYENNE_IN(1)
{
	restartChip = getValue.asInt();
	delay(500);

	if (restartChip == 1)  // if button is pressed "on"
	  {
		  Cayenne.virtualWrite(1, 0, "digital_sensor", "d");  // writes channel 1(the button) back to off or 0
		  Cayenne.loop();  // needed so it transmits the off state back to the dashboard
		  delay(1500);   // give it time to update

		  ESP.restart();
	  }
}

Thanks, so far I‘m using regular as it is my first programm with Cayenne

@klaus.313 @vapor83 @bestes @rsiegel @ognqn.chikov @adam @kreggly what about this approcah for a push button on cayenne dashboard (MQTT).
Add a custom button widget with virtual pin 1.

// This example shows how to connect to Cayenne using an ESP8266 and send/receive sample data.
// Make sure you install the ESP8266 Board Package via the Arduino IDE Board Manager and select the correct ESP8266 board before compiling.

//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266.h>
int x;
// WiFi network info.
char ssid[] = "";
char wifiPassword[] = "";

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "";
char password[] = "";
char clientID[] = "";

unsigned long lastMillis = 0;

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

void loop() {
  Cayenne.loop();

  //Publish data every 10 seconds (10000 milliseconds). Change this value to publish at a different interval.
  if (millis() - lastMillis > 20000) {
    lastMillis = millis();
    if (x == 1)
    {
      Cayenne.virtualWrite(2, 1, "digital_sensor", "d");
      Serial.println("digital_sensor is 1");
    }
    else
    {
      Cayenne.virtualWrite(2, 0, "digital_sensor", "d");
      Serial.println("digital_sensor is 0");
    }
  }
}
CAYENNE_IN(1)
{
  int currentValue = getValue.asInt();
  if (currentValue == 1)
  {
    x = 1;
    Serial.println("x is 1");
  }
  else
  {
    x = 0;
    Serial.println("x is 0");
  }
}

next this will add a two state widget on dashboard.
add a trigger when the two state widget becomes 1 make digital output 0.
let me know about this approach as it works fine for me.

1 Like

Thanks :grinning:, so far I have not worked with MQTT.
I will try it later the day

Hello @shramik_salgaonkar,
I will test it also!

1 Like

This slighly modified code does what I like to have BUT one question remains :
Is the output pin 6 here (I need to toggel a physical pin) directly linked to the Cayenne widget channel 6 ?
In regular Cayenne I have virtual channels to widgets - how does it work with MQTT ?

void setup() {
Serial.begin(9600);
Cayenne.begin(username, password, clientID);
pinMode(5, INPUT);
// pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
}

void loop() {
Cayenne.loop();

//Publish data every 10 seconds (10000 milliseconds). Change this value to publish at a different interval.
if (millis() - lastMillis > 500) {
lastMillis = millis();
if (x == 1)
{
delay(300);
Cayenne.virtualWrite(6, 0, “digital_sensor”, “d”);
Serial.println(“digital_sensor is 0 again”);
digitalWrite(7,LOW);
x = 0;
}
}
}
CAYENNE_IN(6)
{
int currentValue = getValue.asInt();
if (currentValue == 1)
{
x = 1;
Serial.println(“x is 1”);
digitalWrite(7,HIGH);
}
else
{
x = 0;
Serial.println(“x is 0”);
}
}

Here you define the type of operation with “pinMode” and then again we have Virtual Channels!

I’m still struggling: How do I define virtual channels with MQTT ?
what I like to have is access to pyhsical PINs 5 to 8 by digitalWrite and digitalRead and I need the Virtual channels to the widgets …

  1. In the Cayenne Dashboard add a new Value Custom Widget.
  2. Select Virtual I/O and a virtual pin number.
  3. Set VIRTUAL_PIN to the pin number you selected.

You can define virtual pin like this: #define VIRTUAL_PIN V1

This is example from the documentation:

// This function is called when the Cayenne widget requests data for the Virtual Pin.
CAYENNE_OUT(VIRTUAL_PIN)
{
	// Read data from the sensor and send it to the virtual channel here.
	// You can write data using virtualWrite or other Cayenne write functions.
	// For example, to send a temperature in Celsius you can use the following:
	// Cayenne.virtualWrite(VIRTUAL_PIN, 25.5, TEMPERATURE, CELSIUS);
}

I can’t select Virtual I/O …

@klaus.313 are you using MQTT or regular cayenne???

I use MQTT based on your advice.
It seems I have not fully understood the Cayenne functionality/approach
for my first trial I used regular and I was able to select virtual channels (Vx) to the dashboard to exchange date from and to my Arduino. So I can use the PIN (GPIO) assignmens like I need.
With my MQTT version now I don’t have the posibility to select virtual channels in the button widget for example…

Is it right that with MQTT the channels e.g. 5…8 are directly assigned to the physical GPIOs ?

@klaus.313 follow this step by step.
Step 1: go to add new > bring your own thing > take note of MQTT username password and client id.
Step 2: Open arduino ide and copy this code, select correct board and port and upload.

// This example shows how to connect to Cayenne using an ESP8266 and send/receive sample data.
// Make sure you install the ESP8266 Board Package via the Arduino IDE Board Manager and select the correct ESP8266 board before compiling.

//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266.h>
int x;
// WiFi network info.
char ssid[] = "";
char wifiPassword[] = "";

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "";
char password[] = "";
char clientID[] = "";

unsigned long lastMillis = 0;

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

void loop() {
  Cayenne.loop();

  //Publish data every 10 seconds (10000 milliseconds). Change this value to publish at a different interval.
  if (millis() - lastMillis > 20000) {
    lastMillis = millis();
    if (x == 1)
    {
      Cayenne.virtualWrite(2, 1, "digital_sensor", "d");
      Serial.println("digital_sensor is 1");
    }
    else
    {
      Cayenne.virtualWrite(2, 0, "digital_sensor", "d");
      Serial.println("digital_sensor is 0");
    }
  }
}
CAYENNE_IN(1)
{
  int currentValue = getValue.asInt();
  if (currentValue == 1)
  {
    x = 1;
    Serial.println("x is 1");
    digitalWrite(LED_BUILTIN, LOW);
  }
  else
  {
    x = 0;
    Serial.println("x is 0");
   digitalWrite(LED_BUILTIN, HIGH);
  }
}

this will bring your device online on your cayenne dashboard.
Step 3: On your cayenne dashboard you will see a two state widget with name channel 2. add it.
Step 4: go to add new > custom widget > button > fill all the details with virtual pin 1 and add it to your dashboard.
Step 5: add a trigger. when the two state widget becomes 1 make button widget 0
this is complete step required to make a push button on your dashboard to turn on the onboard led on and off.
please follow step by step and try it out. if you are stuck somewhere let me know.

in MQTT you have to select button from custom widget, then only you can select virtual pin.

NO. as simple as i can explain what are virtual pins. virtual pins are basically imaginary pins which are not digital nor analog connectivity. this are pins that can be used to transfer any value you want from cayenne to your arduino and then depending on this virtual pin values you can program the arduino to do whatever you want.
example you assign virtual pin 1 to a button widget . then you use this code to get value of the value button(1 or 0).

CAYENNE_IN(1)
{
  int currentValue = getValue.asInt();
  if (currentValue == 1)
{
//do whatever you want if button is pressed on cayenne dashboard.
   digitalWrite(LED_BUILTIN, LOW);
 }
else
{
  //do whatever you want when button is released on the cayenne dashboard.
   digitalWrite(LED_BUILTIN, HIGH);
 }

here my Botton widget, I just can select a channel … is channel 0 hear ment as virtual channel

when I assign e.g. GPIO 5 as digital output by pinmode and use “virtual” channel 5 for communication it will not work
I had to use different GPIO numbers … thats the reason why I do not understand that these numbers should have nothing in common …

sorry my bad. in MQTT we use channel. so you are right when you select channel 0 it is meant as virtual pin 0. so now change channel 0 to 1. and use the code i gave.

thanks, I really appreciate your help
just to be sure: this channel 0 (in the example) has nothing to do with PHYSICAL GPIO 0 (or any other number)
At least I observed issues assigning same numbers to channels and GPIOs and it does work anymore in the application I need.
2. How many of thes channels I can use ?

the channel and GPIO are not related
till now there is no limit on the amount of channels inn MQTT.
what are planning to do?