-
Device & model you are using
Arduino Uno with W5100 ethernet shield -
What dashboard are you using?
Web and Android -
Please describe the bug / issue as detailed as possible. Attaching the code and any relevant screenshots would be very helpful!
Upon migrating to MQTT, I discovered that if I have an Arduino reste, for example in case of a momentary power cut, when the Arduino goes back online, it does not read the state of the digital actuators and, therefore, it does not go back to the same state as prior to the reset due to blackout.
This is very bad if the system is set in a remote location and it has to be relyed upon for working in a determined manner. For example, in my case, I use to control a heather, a pump and a mixer, in a solar water heather system. In case of a momentary power cut, the system will go back to default state (be it on or off) regardless of the actual state of the actuators on the dashboard. This means that it is possible thet the actuator indicates a âONâ for (say for example) of the heather, but the heather is actually OFF (or viceversa); thus giving a totally incorrect information.
Moreover, if a system is turned ON and needs to stay ON, the power cut might put it in the OFF state and create a damage.
It would be better as it was in the old system, where upon Arduino reset after a power cut, the system would read the actuator state and go back to the same state.
Here is the code:
/*
Solarduino main
From "Cayenne DS18B20 Example"and other examples
"cayenne5MQTT_SolArduino1Main_camping"
This sketch shows how to send temperature data to a DS18B20 Sensor in the Cayenne Dashboard.
The CayenneMQTT Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.
Steps:
1. Install the OneWire library (http://www.pjrc.com/teensy/td_libs_OneWire.html) from the Arduino Library Manager.
2. Install the DallasTemperature library (http://milesburton.com/Main_Page?title=Dallas_Temperature_Control_Library#Code.2FLibrary) from the Arduino Library Manager.
3. In the Cayenne Dashboard add a new DS18B20 widget.
4. Set the widget to Value Display.
5. Select Virtual Pins and a virtual pin number.
6. Set VIRTUAL_CHANNEL to the pin number you selected.
7. Attach a DS18B20 to an digital pin on your Arduino.
Schematic:
[Ground] -- [DS18B20] -- [4.7k resistor] -- [5V]
|______________|
|
Digital Pin
8. Set the tmpPin variable to match the pin used to connect the DS18B20.
9. Set the token variable to match the Arduino token from the Dashboard.
10. Compile and upload this sketch.
11. Once the Arduino connects to the Dashboard it should automatically update the DS18B20 widget with data.
*/
// SETTING FOT THE SOLARDUINO MAIN FOR CAMPING VERNA SOLAR PANELS SYSTEM. V 1.0
// SAME AS SOLARDUINO AMBIENT, BUT WITH ALL 4 SENSORS AND 3 ACTUATORS USED IN THIS CASE, BUT THE SKETCH HAS BEEN KEPT
// THE SAME TO ENSURE IT IS CONSISTENT. THE ONLY CHANGES CONCERN THE "Resolution test", NOT PRSENT HERE.
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space
#include <OneWire.h>
#include <DallasTemperature.h>
#include <CayenneMQTTEthernet.h>//NEW MQTT library
// Virtual Pin of the DS18B20 widget.
#define VIRTUAL_CHANNEL1 1// sensor
#define VIRTUAL_CHANNEL2 2// sensor
#define VIRTUAL_CHANNEL3 3// sensor
#define VIRTUAL_CHANNEL4 4// sensor
#define VIRTUAL_CHANNEL5 5// sensor
#define VIRTUAL_CHANNEL7 7// relè
#define VIRTUAL_CHANNEL8 8// relè
#define VIRTUAL_CHANNEL9 9// relè
#define RELAY_DIGITAL_PIN1 7// relè pin
#define RELAY_DIGITAL_PIN2 8// relè pin
#define RELAY_DIGITAL_PIN3 9// relè pin
// Digital pin the DS18B20 is connected to. Do not use digital pins 0 or 1 since those conflict with the use of Serial.
const int tmpPin1 = 2;
const int tmpPin2 = 3;
const int tmpPin3 = 4;
const int tmpPin4 = 5;
const int tmpPin5 = 6;
unsigned long lastMillis = 0;
int x = 0;// set default for actuators; on (=1) or OFF (=0)
OneWire oneWire1(tmpPin1);
OneWire oneWire2(tmpPin2);
OneWire oneWire3(tmpPin3);
OneWire oneWire4(tmpPin4);
OneWire oneWire5(tmpPin5);
DallasTemperature sensors1(&oneWire1);
DallasTemperature sensors2(&oneWire2);
DallasTemperature sensors3(&oneWire3);
DallasTemperature sensors4(&oneWire4);
DallasTemperature sensors5(&oneWire5);
// NEW Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
// Solarduino Main - campeggio@gmail.com
char username[] = "5xxxxxxxxxxx";
char password[] = "5xxxxxxxxxxxxxxx";
char clientID[] = "9xxxxxxxxxxxxxxxxx";
// ---- static IP setting START ----
void setup()
{
// set digital pin to output
pinMode(RELAY_DIGITAL_PIN1, OUTPUT);// relè pin
pinMode(RELAY_DIGITAL_PIN2, OUTPUT);// relè pin
pinMode(RELAY_DIGITAL_PIN3, OUTPUT);// relè pin
/* digitalWrite(RELAY_DIGITAL_PIN1, HIGH);// set relay to off at startup
digitalWrite(RELAY_DIGITAL_PIN2, HIGH);// set relay to off at startup
digitalWrite(RELAY_DIGITAL_PIN3, HIGH);// set relay to off at startup
*/
Serial.begin(9600);
Cayenne.begin(username, password, clientID);
sensors1.begin();
sensors2.begin();
sensors3.begin();
sensors4.begin();
sensors5.begin();
}
void loop()
{
Cayenne.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 / 1000));// write seconds since on on channel 0
//NOTE: the following added lines is jut to try a workaorund (only on pin 7), just to test, but it did not work !
CAYENNE_IN(7);// this should read the actuator state and reset the relay to the same value
delay (10);
Cayenne.virtualWrite(7, x, "digital_actuator", "d");// and this, if the abbove did work, would set the actuator pin to the corret state
}
}
// This function is called when the Cayenne widget requests data for the Virtual Pin.
CAYENNE_OUT(VIRTUAL_CHANNEL1)
{
// Send the command to get temperatures.
sensors1.requestTemperatures();
// This command writes the temperature in Celsius to the Virtual Pin.
Cayenne.celsiusWrite(VIRTUAL_CHANNEL1, sensors1.getTempCByIndex(0));
// To send the temperature in Fahrenheit use the corresponding code below.
//Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
}
CAYENNE_OUT(VIRTUAL_CHANNEL2)
{
// Send the command to get temperatures.
sensors2.requestTemperatures();
// This command writes the temperature in Celsius to the Virtual Pin.
Cayenne.celsiusWrite(VIRTUAL_CHANNEL2, sensors2.getTempCByIndex(0));
// To send the temperature in Fahrenheit use the corresponding code below.
//Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
}
CAYENNE_OUT(VIRTUAL_CHANNEL3)
{
// Send the command to get temperatures.
sensors3.requestTemperatures();
// This command writes the temperature in Celsius to the Virtual Pin.
Cayenne.celsiusWrite(VIRTUAL_CHANNEL3, sensors3.getTempCByIndex(0));
// To send the temperature in Fahrenheit use the corresponding code below.
//Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
}
CAYENNE_OUT(VIRTUAL_CHANNEL4)
{
// Send the command to get temperatures.
sensors4.requestTemperatures();
// This command writes the temperature in Celsius to the Virtual Pin.
Cayenne.celsiusWrite(VIRTUAL_CHANNEL4, sensors4.getTempCByIndex(0));
// To send the temperature in Fahrenheit use the corresponding code below.
//Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
}
CAYENNE_OUT(VIRTUAL_CHANNEL5)
{
// Send the command to get temperatures.
sensors5.requestTemperatures();
// This command writes the temperature in Celsius to the Virtual Pin.
Cayenne.celsiusWrite(VIRTUAL_CHANNEL5, sensors5.getTempCByIndex(0));
// To send the temperature in Fahrenheit use the corresponding code below.
//Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
}
CAYENNE_IN(7)
{
CAYENNE_LOG("Channel %u, value %s", request.channel, getValue.asString());
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
{
x = getValue.asInt();// tried this as suggested, but no joy
digitalWrite(RELAY_DIGITAL_PIN1, !x);
}
/*// get value sent from dashboard
int currentValue7 = getValue.asInt(); // 7 to 9
// assuming you wire your relay as normally open
if (currentValue7 == 0) {
digitalWrite(RELAY_DIGITAL_PIN1, HIGH);
} else {
digitalWrite(RELAY_DIGITAL_PIN1, LOW);
}
*/
}
CAYENNE_IN(8)
{
CAYENNE_LOG("Channel %u, value %s", request.channel, getValue.asString());
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
// get value sent from dashboard
int currentValue8 = getValue.asInt(); // 7 to 9
// assuming you wire your relay as normally open
if (currentValue8 == 0) {
digitalWrite(RELAY_DIGITAL_PIN2, HIGH);
} else {
digitalWrite(RELAY_DIGITAL_PIN2, LOW);
}
}
CAYENNE_IN(VIRTUAL_CHANNEL9)
{
CAYENNE_LOG("Channel %u, value %s", request.channel, getValue.asString());
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
// get value sent from dashboard
int currentValue9 = getValue.asInt(); // 7 to 9
// assuming you wire your relay as normally open
if (currentValue9 == 0) {
digitalWrite(RELAY_DIGITAL_PIN3, HIGH);
} else {
digitalWrite(RELAY_DIGITAL_PIN3, LOW);
}
}