NodeMCU and Digital Motion Sensor


So, i’m trying to add a Digital Motion Sensor to a ESP8266/NodeMCU but am having a problem:

I can get Example -> Cayenne-MQTT-ESP8266 -> ESP8266 sketch to load and return Millis
If I go to add a Widget -> Digital Motion Sensor, I cannot select a device from the drop down

ok so the sketch needs the digital motion sensor code, so I

Load up Example -> Cayenne -> Sensors -> DigitalMotionSensor sketch,
However there is no char token[] = “AuthenticationToken”; to be found in the Dashboard.

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
Where is it?

or do i just need to copy the sensor code over from
Example -> Cayenne -> Sensors -> DigitalMotionSensor sketch,
Example -> Cayenne-MQTT-ESP8266 -> ESP8266



I copied the DigitalSensorCode pieces from
Example -> Cayenne -> Sensors -> DigitalMotionSensor sketch,
Example -> Cayenne-MQTT-ESP8266 -> ESP8266

but all i get is a second channel, and still cannot add a DigitalMotionSensor Widget.

Any ideas?

// 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_PRINT Serial
#include <CayenneMQTTESP8266.h>
//#include <CayenneEthernet.h>

// WiFi network info.
char wifiPassword[] = “mitmhoneypotattack”;

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = “ed1794a0-6bf3-11e7-8c3a-xxxxxx”;
char password[] = “934a207798ce1080cafb92cxxxxxxxxxxx”;
char clientID[] = “b9b8b850-7107-11e7-844a-xxxxxxxxx”;

unsigned long lastMillis = 0;

// Virtual Pin of the Digital Motion Sensor widget.
#define VIRTUAL_PIN V1

// Digital pin the motion sensor is connected to. Do not use digital pins 0 or 1 since those conflict with the use of Serial.
const int motionSensorPin = 4;

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

void loop() {

//Publish data every 10 seconds (10000 milliseconds). Change this value to publish at a different interval.
if (millis() - lastMillis > 10000) {
lastMillis = millis();
//Write data to Cayenne here. This example just sends the current uptime in milliseconds.
Cayenne.virtualWrite(0, lastMillis);
//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);

int previousState = -1;
int currentState = -1;
unsigned long previousMillis = 0;

void checkSensor()
unsigned long currentMillis = millis();
// Check sensor data every 250 milliseconds
if (currentMillis - previousMillis >= 250) {
// Check the sensor state and send data when it changes.
currentState = digitalRead(motionSensorPin);
if (currentState != previousState) {
Cayenne.virtualWrite(VIRTUAL_PIN, currentState);
previousState = currentState;
previousMillis = currentMillis;

//Default function for processing actuator commands from the Cayenne Dashboard.
//You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_LOG(“CAYENNE_IN_DEFAULT(%u) - %s, %s”,, getValue.getId(), getValue.asString());
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError(“Error message”);



Channel 1 IS your motion indicator. You can rename it by pressing the gear icon in the upper right corner of the widget.

The only thing I see is you may need to add this to setup:

pinMode(motionSensorPin, INPUT);




To add a bit – when connecting a sensor to Cayenne via MQTT, you don’t need to pick from a list like in your first screenshot. That add sensor process is for non-MQTT connected Raspberry Pi and Arduino devices only.

When you’re using MQTT, you just publish the sensor data to a channel on Cayenne using statements in your code (like virutalWrite() or celsiusWrite() ) and then the widget will be automatically created on your Cayenne dashboard upon receipt of the first data. You can then customize the widget as you like (for example, you could make your motion sensor there into a 2-state widget instead of a raw numeric value, etc).

Also, I like your wifi credentials there. I’d still try to connect to it :stuck_out_tongue:


thank you very much for the replies and information, I knew I was missing something fundamental.

Question, how do I change the ‘channel’ into a 2 state? I don’t see that option in the gear icon settings for the widget in the dashboard. Does it have to be done in code?

"You can then customize the widget as you like (for example, you could make your motion sensor there into a 2-state widget instead of a raw numeric value, "


Ok, I think I see what the issue might be here. That example digital motion sensor sketch was written for the Arduino connectivity rather than the MQTT connectivity. However, 95% of it should still be good. We just need to change the virtualWrite() statement so it’s not trying to write to a virtual pin (a concept that doesn’t exist with the MQTT connectivity) and instead to an MQTT channel with appropriate tagging for the data type.

Assuming you still want to write to channel 1, I would switch out the Arduino write statement:

Cayenne.virtualWrite(VIRTUAL_PIN, currentState);

for this MQTT write statement:

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

Delete the existing channel 1 widget before uploading this code change. Once it connects, it should auto-create a new widget on your dashboard (which should actually default to a 2-state type). You then should see settings on this widget to set it to other widget types, one of which is literally a motion sensor widget we have that looks like this:

[RESOLVED] No change "2 state" widget esp8266

thanks that worked perfect! now I just need to figure out why this hc-sr501 isn’t switching on and off, but thats on my end.

Thanks so much!