Virtual switches that never go off and controllers
-
For a project i'm working on i have converted a old 1950's phone into a doorbell/multiple switches.
If i dail 3, for example it does a "send(msgDail_1.set(1));" This message is set up as S_BINARY and V_STATUS.
In my experience some home automation software like Domotics doesnt like this very much as the switch never switches off. A simple solution can be to send a off command directly after the on command. This seems to be working most of the time, but sometime it seems a bit random. Maybe because the status is only high for a very low time.
A normal switch would always have 2 states, or be pressed for several 100ms.
A solution can be to add a "wait" for maybe 500ms. However i found that the "wait" function actually stops the Arduino from receiving input. Most of the time that wont be a problem, but i would like to get it working the right way. Both the send and wait function are in a "switch case" if it makes ant difference.
Do you guys recognize this problem? How have you solved this?
-
For a project i'm working on i have converted a old 1950's phone into a doorbell/multiple switches.
If i dail 3, for example it does a "send(msgDail_1.set(1));" This message is set up as S_BINARY and V_STATUS.
In my experience some home automation software like Domotics doesnt like this very much as the switch never switches off. A simple solution can be to send a off command directly after the on command. This seems to be working most of the time, but sometime it seems a bit random. Maybe because the status is only high for a very low time.
A normal switch would always have 2 states, or be pressed for several 100ms.
A solution can be to add a "wait" for maybe 500ms. However i found that the "wait" function actually stops the Arduino from receiving input. Most of the time that wont be a problem, but i would like to get it working the right way. Both the send and wait function are in a "switch case" if it makes ant difference.
Do you guys recognize this problem? How have you solved this?
The code so far....
Another problem i have is in the "ringtone" in the last part of the code. It stops the whole code of the arduino while running. Is wait not a suitable function for this? or does this happen because its in a while loop?
Are there better ways to solve this?/** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * ******************************* * * DESCRIPTION * * Simple binary switch example * Connect button or door/window reed switch between * digitial I/O pin 3 (button below) and GND. * http://www.mysensors.org/build/binary */ /// ##### mysensors setup ###### #define ProjectName "OldPhone" // Name that is vissible in controller #define ProjectVersion "0,1" // Version that is vissible in controller #define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define childIdDoor 1 // child ID number used by mysensors foor doorbell button #define chuildIdDail_1 101 // child ID number used by mysensors when the number 1 is dailed #define chuildIdDail_2 102 // child ID number used by mysensors when the number 2 is dailed #define chuildIdDail_3 103 // child ID number used by mysensors when the number 3 is dailed #define chuildIdDail_4 104 // child ID number used by mysensors when the number 4 is dailed #define chuildIdDail_5 105 // child ID number used by mysensors when the number 5 is dailed #define chuildIdDail_6 106 // child ID number used by mysensors when the number 6 is dailed #define chuildIdDail_7 107 // child ID number used by mysensors when the number 7 is dailed #define chuildIdDail_8 108 // child ID number used by mysensors when the number 8 is dailed #define chuildIdDail_9 109 // child ID number used by mysensors when the number 9 is dailed #define chuildIdDail_10 110 // child ID number used by mysensors when the number 0 is dailed // ###### Include libraries ##### #include <SPI.h> // needed for NRF24 #include <MySensors.h> // mysensors library #include <Bounce2.h> // for debouncing buttons and dail // ###### I/O pin number setup ###### #define button 3 // input pin activated when doorbell button is pressed #define edail 8 // input pin activated when dail is used (Enable Dail) #define pdail 7 // input pin activated with each tick of the dail (Pulse Dial) #define lbell 4 // output pin to swing bellh hamer left #define rbell 5 // output Pin to swing bellh hamer right // ##### Debouncer variables ##### Bounce debouncerButton = Bounce(); // Create button debouncer for doorbell button Bounce debouncerEdail = Bounce(); // Create button debouncer for Enable Dail Bounce debouncerPdail = Bounce(); // Create button debouncer for Pulse Dial int valueButton = 0; // Value int oldValueButton = 0; int valueEdail = 0; int oldValueEdail = 0; int valuePdail = 0; int oldValuePdail = 0; int dailCount = 0; int newDailCount = 0; int ring = 0; int ringX = 15; int onPulse = 20; int offPulse = 10; int repeat = 0; int repeatX = 4; int ringPause = 2000; // ##### setup MySensors message containers ##### MyMessage msgDoor(childIdDoor,V_STATUS); // message container used for doorbell button MyMessage msgDail_1(chuildIdDail_1,V_STATUS); // message container used when the number 1 is dailed MyMessage msgDail_2(chuildIdDail_2,V_STATUS); // message container used when the number 2 is dailed MyMessage msgDail_3(chuildIdDail_3,V_STATUS); // message container used when the number 3 is dailed MyMessage msgDail_4(chuildIdDail_4,V_STATUS); // message container used when the number 4 is dailed MyMessage msgDail_5(chuildIdDail_5,V_STATUS); // message container used when the number 5 is dailed MyMessage msgDail_6(chuildIdDail_6,V_STATUS); // message container used when the number 6 is dailed MyMessage msgDail_7(chuildIdDail_7,V_STATUS); // message container used when the number 7 is dailed MyMessage msgDail_8(chuildIdDail_8,V_STATUS); // message container used when the number 8 is dailed MyMessage msgDail_9(chuildIdDail_9,V_STATUS); // message container used when the number 9 is dailed MyMessage msgDail_10(chuildIdDail_10,V_STATUS); // message container used when the number 0 is dailed void setup() { //##### I/O pin function setup ##### pinMode(button,INPUT); //set the already defined I/O pin as input pinMode(edail, INPUT); //set the already defined I/O pin as input pinMode(pdail, INPUT); //set the already defined I/O pin as input pinMode(lbell, OUTPUT); //set the already defined I/O pin as output pinMode(rbell, OUTPUT); //set the already defined I/O pin as output // ##### Debouncer setup ##### debouncerButton.attach(button); debouncerButton.interval(5); debouncerEdail.attach(edail); debouncerEdail.interval(5); debouncerPdail.attach(pdail); debouncerPdail.interval(5); } // ##### Function of MySensors that presents all attached sensors to the controller ##### void presentation() { sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller present(childIdDoor, S_BINARY); // Present doorbell button as binary switch present(chuildIdDail_1, S_BINARY); // Present the dailing of number 1 as binary switch present(chuildIdDail_2, S_BINARY); // Present the dailing of number 2 as binary switch present(chuildIdDail_3, S_BINARY); // Present the dailing of number 3 as binary switch present(chuildIdDail_4, S_BINARY); // Present the dailing of number 4 as binary switch present(chuildIdDail_5, S_BINARY); // Present the dailing of number 5 as binary switch present(chuildIdDail_6, S_BINARY); // Present the dailing of number 6 as binary switch present(chuildIdDail_7, S_BINARY); // Present the dailing of number 7 as binary switch present(chuildIdDail_8, S_BINARY); // Present the dailing of number 8 as binary switch present(chuildIdDail_9, S_BINARY); // Present the dailing of number 9 as binary switch present(chuildIdDail_10, S_BINARY); // Present the dailing of number 0 as binary switch } void loop() { // ##### debouncer updater ##### debouncerButton.update(); // Update debouncer for doorbell button valueButton = debouncerButton.read(); // Set current value of doorbell button debouncerEdail.update(); // Update debouncer for enable dail valueEdail = debouncerEdail.read(); // Set current value of enable dail debouncerPdail.update(); // Update debouncer for pulse dail valuePdail = debouncerPdail.read(); // Set current value of pulse dail // ##### Mysensors code to check doorbell button and sent message ##### if (valueButton != oldValueButton) { // Check if the value of the button has changed send(msgDoor.set(valueButton==HIGH ? 1 : 0)); // Transmit the new value oldValueButton = valueButton; // Change old value so this doenst loop } // ##### Mysensors code to read dail counter and sent message as one individual sensor ##### switch (newDailCount) { // Check the current vallue of the completed counter case 1: // if value is equal to 1 send(msgDail_1.set(1)); // Transmit ON message for dail switch 1 send(msgDail_1.set(0)); // Transmit OFF message for dail switch 1. Some home automation software prefers this. break; // end of case case 2: // if value is equal to 2 send(msgDail_2.set(1)); // Transmit ON message for dail switch 2 send(msgDail_2.set(0)); // Transmit OFF message for dail switch 2. Some home automation software prefers this. break; // end of case case 3: // if value is equal to 3 send(msgDail_3.set(1)); // Transmit ON message for dail switch 3 send(msgDail_3.set(0)); // Transmit OFF message for dail switch 3. Some home automation software prefers this. break; // end of case case 4: // if value is equal to 4 send(msgDail_4.set(1)); // Transmit ON message for dail switch 4 send(msgDail_4.set(0)); // Transmit OFF message for dail switch 4. Some home automation software prefers this. break; // end of case case 5: // if value is equal to 5 send(msgDail_5.set(1)); // Transmit ON message for dail switch 5 send(msgDail_5.set(0)); // Transmit OFF message for dail switch 5. Some home automation software prefers this. break; // end of case case 6: // if value is equal to 6 send(msgDail_6.set(1)); // Transmit ON message for dail switch 6 send(msgDail_6.set(0)); // Transmit OFF message for dail switch 6. Some home automation software prefers this. break; // end of case case 7: // if value is equal to 7 send(msgDail_7.set(1)); // Transmit ON message for dail switch 7 send(msgDail_7.set(0)); // Transmit OFF message for dail switch 7. Some home automation software prefers this. break; // end of case case 8: // if value is equal to 8 send(msgDail_8.set(1)); // Transmit ON message for dail switch 8 send(msgDail_8.set(0)); // Transmit OFF message for dail switch 8. Some home automation software prefers this. break; // end of case case 9: // if value is equal to 9 send(msgDail_9.set(1)); // Transmit ON message for dail switch 9 send(msgDail_9.set(0)); // Transmit OFF message for dail switch 9. Some home automation software prefers this. break; // end of case case 10: // if value is equal to 10 send(msgDail_10.set(1)); // Transmit ON message for dail switch 10 send(msgDail_10.set(0)); // Transmit OFF message for dail switch 10. Some home automation software prefers this. break; // end of case } newDailCount = 0; // Reset the completed counter so this doesnt loop // ###### Code for checking enable dail and sending state trough serial ###### if (valueEdail != oldValueEdail && valueEdail == HIGH) { // Check if enable dail has changed AND if its currently its currently activated Serial.println("dail is activated..."); // If so sent message oldValueEdail = valueEdail;} // And change old value so this doenst loop else if (valueEdail != oldValueEdail && valueEdail == LOW) { // Check if enable dail has changed AND if its currently its currently deactivated Serial.println("dail is deactivated..."); // If so sent message newDailCount = dailCount; // Write the counted pulses to the New Dail Count dailCount = 0; // Reset the dail count for next dail oldValueEdail = valueEdail; // And change old value so this doenst loop } // ###### Code for checking pusle dail and sending state trough serial ###### if (valuePdail != oldValuePdail && valueEdail == HIGH) { // Check if dail pulse has changed AND if currently its currently activated if (valuePdail == LOW) { // Only take action when the signal goes from high to low to prevent double count dailCount++; // If the conditions are met increase counter by 1 Serial.print("Tick! Total ammout of pulses: "); // Serial print a messagge saying a pulse was detected Serial.println (dailCount); // Serial print a the current value of the counter } oldValuePdail = valuePdail; // Change old value so this doenst loop } if (valueButton == HIGH) { // If the boorbell button was pressed (read from debouncer) while (repeat < repeatX){ // start a loop if the number of repeats isnt reached yet (a repeat is the time a bell is ringed pauesed) repeat++; // add 1 count to the "repeat" counter while (ring < ringX){ // start a loop if the number of rings isnt reached yet (a ring is the hammer hitting each bell once) ring++; // add 1 count to the "ring" counter digitalWrite(lbell, HIGH); // power the bell coil so that the hammer hits the left bell !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! wait(onPulse); // hold for the amount of ms set for "onPulse" !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! digitalWrite(lbell, LOW); // power down the bell coil !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! wait(offPulse); // wait for the amount of ms set for "offpulse" !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! digitalWrite(rbell, HIGH); // power the bell coil so that the hammer hits the right bell !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! wait(onPulse); // hold for the amount of ms set for "onPulse" !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! digitalWrite(rbell, LOW); // power down the bell coil !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! wait(offPulse); // wait for the amount of ms set for "offpulse" !!! VERY IMPORTANT: "LBELL" AND "RBELL" CAN NEVER BE HIGH AT THE SAME TIME !!! } // go back to start if loop till "ring" has the same value as "ringX" wait (ringPause); // wait for the amount of ms set for "ringPause" if (ring == ringX){ // if the amount of "ring" is the same as the amount set in "ringX".... ring = 0; // reset the "ring" counter } } } if (repeat == repeatX){ // if the amount of "repeat" is the same as the amount set in "repeatX".... repeat = 0; // reset the "repeat" counter } } -
wait() will not mess with ability to receive radio - in fact, handling the radio is exactly what is done inside wait(). However, if a radio message needs to be handled, wait() can take more time than the specified number of milliseconds. Therefore, wait() won't be suitable for generating a precise 5ms square wave.
As you probably already guessed, button presses will be ignored during wait(), unless you use interrupts.
For a more flexible solution, you'll need to modify all code to work without wait. See https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay for a simple starting point, but be aware that it gets more and more complex with multiple different things happening at the same time.
-
@mfalkvidd said in Virtual switches that never go off and controllers:
wait() will not mess with ability to receive radio - in fact, handling the radio is exactly what is done inside wait(). However, if a radio message needs to be handled, wait() can take more time than the specified number of milliseconds. Therefore, wait() won't be suitable for generating a precise 5ms square wave.
As you probably already guessed, button presses will be ignored during wait(), unless you use interrupts.
For a more flexible solution, you'll need to modify all code to work without wait. See https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay for a simple starting point, but be aware that it gets more and more complex with multiple different things happening at the same time.
Thanks for the info! i was afraid that was what wait was doing. The question is how bad i want to fix this... I know about millis. I dont have to rewrite that much code for it. Maybe there is some library i can use.
Also it doesnt really matter how good the square wave is, as long as the 2 "bell" pins are never high at the same time.
I guess millis can be the solution for sending a off signal to, or are there better ways to handle this?
-
@mfalkvidd said in Virtual switches that never go off and controllers:
wait() will not mess with ability to receive radio - in fact, handling the radio is exactly what is done inside wait(). However, if a radio message needs to be handled, wait() can take more time than the specified number of milliseconds. Therefore, wait() won't be suitable for generating a precise 5ms square wave.
As you probably already guessed, button presses will be ignored during wait(), unless you use interrupts.
For a more flexible solution, you'll need to modify all code to work without wait. See https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay for a simple starting point, but be aware that it gets more and more complex with multiple different things happening at the same time.
Thanks for the info! i was afraid that was what wait was doing. The question is how bad i want to fix this... I know about millis. I dont have to rewrite that much code for it. Maybe there is some library i can use.
Also it doesnt really matter how good the square wave is, as long as the 2 "bell" pins are never high at the same time.
I guess millis can be the solution for sending a off signal to, or are there better ways to handle this?
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login