@reza:
I made some modifications to your sketch, trying to adhere to your style of programming. So it may be easier to adapt it to your needs.
#define MY_DEBUG
#define MY_RADIO_NRF24
#define MY_RF24_CHANNEL 0
#define MY_REPEATER_FEATURE
#define MY_NODE_ID 5
#include <SPI.h>
#include <MySensors.h>
#include <Bounce2.h>
#define RELAY_ON 0
#define RELAY_OFF 1
#define A_ID 1
#define B_ID 2
#define C_ID 3
#define D_ID 4
#define E_ID 5
#define F_ID 6
#define DISPLAY_INTERVALL 10000
const int buttonPinA = 14;
const int buttonPinB = 15;
const int buttonPinC = 16;
const int buttonPinD = 17;
const int buttonPinE = 18;
const int buttonPinF = 19;
const int relayPinA = 3;
const int relayPinB = 4;
const int relayPinC = 5;
const int relayPinD = 6;
const int relayPinE = 7;
const int relayPinF = 8;
int oldValueA = 0;
int oldValueB = 0;
int oldValueC = 0;
int oldValueD = 0;
int oldValueE = 0;
int oldValueF = 0;
unsigned long loop_count = 0; // counter for loop activity
unsigned long last_time;
bool toggleA = false, toggleB = false, toggleC = false, toggleD = false, toggleE = false, toggleF = false;
Bounce debouncerA = Bounce();
Bounce debouncerB = Bounce();
Bounce debouncerC = Bounce();
Bounce debouncerD = Bounce();
Bounce debouncerE = Bounce();
Bounce debouncerF = Bounce();
MyMessage msgA(A_ID, V_STATUS);
MyMessage msgB(B_ID, V_STATUS);
MyMessage msgC(C_ID, V_STATUS);
MyMessage msgD(D_ID, V_STATUS);
MyMessage msgE(E_ID, V_STATUS);
MyMessage msgF(F_ID, V_STATUS);
void setup()
{
pinMode(buttonPinA, INPUT_PULLUP);
pinMode(buttonPinB, INPUT_PULLUP);
pinMode(buttonPinC, INPUT_PULLUP);
pinMode(buttonPinD, INPUT_PULLUP);
pinMode(buttonPinE, INPUT_PULLUP);
pinMode(buttonPinF, INPUT_PULLUP);
// After setting up the buttons, setup debouncer
debouncerA.attach(buttonPinA);
debouncerA.interval(5);
debouncerB.attach(buttonPinB);
debouncerB.interval(5);
debouncerC.attach(buttonPinC);
debouncerC.interval(5);
debouncerD.attach(buttonPinD);
debouncerD.interval(5);
debouncerE.attach(buttonPinE);
debouncerE.interval(5);
debouncerF.attach(buttonPinF);
debouncerF.interval(5);
// Make sure relays are off when starting up
digitalWrite(relayPinA, RELAY_OFF);
digitalWrite(relayPinB, RELAY_OFF);
digitalWrite(relayPinC, RELAY_OFF);
digitalWrite(relayPinD, RELAY_OFF);
digitalWrite(relayPinE, RELAY_OFF);
digitalWrite(relayPinF, RELAY_OFF);
// Then set relay pins in output mode
pinMode(relayPinA, OUTPUT);
pinMode(relayPinB, OUTPUT);
pinMode(relayPinC, OUTPUT);
pinMode(relayPinD, OUTPUT);
pinMode(relayPinE, OUTPUT);
pinMode(relayPinF, OUTPUT);
wait(1000); // testing LEDs. should be omitted for Relais.
digitalWrite(relayPinA, RELAY_ON);
digitalWrite(relayPinB, RELAY_ON);
digitalWrite(relayPinC, RELAY_ON);
digitalWrite(relayPinD, RELAY_ON);
digitalWrite(relayPinE, RELAY_ON);
digitalWrite(relayPinF, RELAY_ON);
/*--------------------- Added these lines for toggle switch-------------------------*/
oldValueA = digitalRead(buttonPinA); // set oldValueA to the current status of the toggle switch
oldValueB = digitalRead(buttonPinB); // set oldValueB to the current status of the toggle switch
oldValueC = digitalRead(buttonPinC);
oldValueD = digitalRead(buttonPinD);
oldValueE = digitalRead(buttonPinE);
oldValueF = digitalRead(buttonPinF);
}
void presentation() {
// Send the sketch version information to the gateway and Controller
sendSketchInfo("RELAY6", "0.1");
// Register all sensors to gw (they will be created as child devices)
present(A_ID, S_LIGHT, "Relais A");
present(B_ID, S_LIGHT, "Relais B");
present(C_ID, S_LIGHT, "Relais C");
present(D_ID, S_LIGHT, "Relais D");
present(E_ID, S_LIGHT, "Relais E");
present(F_ID, S_LIGHT, "Relais F");
}
/*
Example on how to asynchronously check for new messages from gw
*/
void loop()
{
loop_count ++; // increment loop count
if ( millis() >= last_time + DISPLAY_INTERVALL ) { // Display Loop-cycles every DISPLAY_INTERVALL milliseconds
last_time = millis(); // reset and start over again
Serial.print("loop_count: ");
Serial.println(loop_count);
loop_count = 0;
}
debouncerA.update();
// Get the update value
int valueA = debouncerA.read();
if (valueA != oldValueA && valueA == 0) {
send(msgA.set(toggleA, true)); // Send new state and request ack back
digitalWrite(relayPinA, toggleA); // switch relais
Serial.println("Switch A pressed");
toggleA = !toggleA; // this is the actual toggle switch
}
oldValueA = valueA;
debouncerB.update();
// Get the update value
int valueB = debouncerB.read();
if (valueB != oldValueB) {
send(msgB.set(valueB ? false : true), true); // Send new state and request ack back
Serial.println("Switch B pressed");
oldValueB = valueB;
}
debouncerC.update();
// Get the update value
int valueC = debouncerC.read();
if (valueC != oldValueC) {
send(msgC.set(valueC ? false : true), true); // Send new state and request ack back
Serial.println("Switch C pressed");
oldValueC = valueC;
}
debouncerD.update();
// Get the update value
int valueD = debouncerD.read();
if (valueD != oldValueD) {
send(msgD.set(valueD ? false : true), true); // Send new state and request ack back
Serial.println("Switch D pressed");
oldValueD = valueD;
}
debouncerE.update();
// Get the update value
int valueE = debouncerE.read();
if (valueE != oldValueE) {
send(msgE.set(valueE ? false : true), true); // Send new state and request ack back
Serial.println("Switch E pressed");
oldValueE = valueE;
}
debouncerF.update();
// Get the update value
int valueF = debouncerF.read();
if (valueF != oldValueF) {
send(msgF.set(valueF ? false : true), true); // Send new state and request ack back
Serial.println("Switch F pressed");
oldValueF = valueF;
}
}
void receive(const MyMessage &message) {
// We only expect one type of message from controller. But we better check anyway.
if (message.type == V_STATUS) {
switch (message.sensor) {
case 1:
digitalWrite(message.sensor + 2, message.getBool() ? RELAY_ON : RELAY_OFF);
break;
case 2:
digitalWrite(message.sensor + 2, message.getBool() ? RELAY_ON : RELAY_OFF);
break;
case 3:
digitalWrite(message.sensor + 2, message.getBool() ? RELAY_ON : RELAY_OFF);
break;
case 4:
digitalWrite(message.sensor + 2, message.getBool() ? RELAY_ON : RELAY_OFF);
break;
case 5:
digitalWrite(message.sensor + 2, message.getBool() ? RELAY_ON : RELAY_OFF);
break;
case 6:
digitalWrite(message.sensor + 2, message.getBool() ? RELAY_ON : RELAY_OFF);
break;
default:
Serial.println("bad message (child_id >6)");
break;
}
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.sensor);
Serial.print(" from node:");
Serial.print(message.sender);
Serial.print(", New status: ");
Serial.println(message.getBool());
}
}
I haven`t copied the code for all push-buttons - I leave this to you if this sketch is functional for your needs.
Acting carefully, you may mingle some parts with blacey´s sketch successfully (by the way - impressing coding style).
Reenacting your sketch I found some strange behavior: no reaction to push-button-press - meaning the sketch didn´t even take notice of the push-button after it had been pressed once - or sometimes twice.
Adding an external pull-up resistor (4.7k) fixed this problem.
So maybe it has not been a sending problem but a hardware problem (internal pull-ups to weak?).
Please flood your sketch with print statements - like "button A pressed" "send command issued" etc. and watch your serial terminal carefully and/or post your logs.
Thinking about the modulo-driven time-statement - actually it is a cute idea. Something like
time_m = millis();
a = (time_m / 1000) % 3600;
should make it immune to uneven starting values an even loop-cycle duration. (loop-cycle-time of the above sketch: approximately 125 µs)
These are the lesser problems. I fear you have to do some boring English lecture.
Please read: https://en.wikipedia.org/wiki/Finite-state_machine
https://en.wikipedia.org/wiki/State_machine_replication
and first: https://en.wikipedia.org/wiki/Two_Generals'_Problem
https://en.wikipedia.org/wiki/Byzantine_fault_tolerance
as an excerpt :
The Two Generals Problem was the first computer communication problem to be proved to be unsolvable.
This is not "we don´t have a solution until now" but: "it is sure there can´t be a solution"
So you will have to live with a certain amount of uncertainty .....
Conclusion:
-
Check correct function of push-button with Serial.print(), with and without external pull-up resistor.
-
Please post your logs afterwards.
-
be prepared to make some decisions concerning tolerable fuzziness.
-
if necessary start learning about scripting capabilities of your controller.