I have doorbell that is controlled by an arduino. The problem is this: When I turn a ceiling fan on or off, the arduino is triggered causing the doorbell to chime. I am looking for the best way to eliminate this issue.
For the 'trigger', I am just using the doorbell button to make pin 13 read HIGH.
This occurs with two different ceiling fans in the house, any they are on separate circuits in the house.
How is the doorbell switch wired? Are you pulling the digital input (that the switch is connected to) low when the switch is not pressed? If a digital input is not actively tie either high or low it will float and pick all kinds of garbage.
Well, if you have long cables connected to inputs on the Arduino, you must expect problems like this.
Firstly, and in reference to groundfungus' comments, you would not be taking the Vcc line to the bell push, you would have it connected to ground and a pull-up at the Arduino. In this situation, you would likely want a "stiffer" pull-up than the internal one on the Arduino, perhaps 1k or so.
The wire to the bell push should be "figure 8"; standard "bell wire" where the two wires are together for the whole of the run. It should only be grounded at the Arduino.
It would be wise to have a resistor - say 22k - between the pull-up resistor where the switch line connects, and the actual Arduino, with a capacitor of perhaps 1µF between the Arduino input itself and ground.
Even so, you must use a "debounce" routine (with a time constant of about 1/10 of a second) on the switch input. If you are not employing this, it is no wonder that you get spurious triggering - until the push is pressed, you are essentially connecting a long wire antenna to the Arduino port.
These are excellent suggestions. As you suspected, I am connecting directly to door bell button with the pre-wired conductors. And I do realize it is going to act like a long antenna. I will need to give what you have suggested some thought. A quick read-through was not enough for me -I will have to spend a bit more time following what you are saying.
I was considering a simple relay that is activated by the door bell switch. It would be located adjacent to the arduino board so as to minimize induced current between the relay and board. Would this work as well or is your solution better and more elegant? I really am a novice when it comes to electronics.
I certainly would try wiring the switch between ground and the digital input with a 1K ohm resistor from the input to 5V before going to the trouble of wiring in a relay. If the input (no schematic leads to me guessing) was floating then the above has a good chance of fixing your problem.
Is this what you had in mind, GroundFungus? I re-wired it this way and as I expected, it read the pin as HIGH continuously and chimed as long as power was available.
Below is a sample of the code I am using. As you can see, I have not researched the 'Debounce' routine that was mentioned earlier. I will work on that soon.
/*-----( Import needed libraries )-----*/
/*-----( Declare Constants )-----*/
#define RELAY_ON 0
#define RELAY_OFF 1
const int doorbellbutton=13;
/*-----( Declare objects )-----*/
/*-----( Declare Variables )-----*/
#define Relay_2 2 // Arduino Digital I/O pin number
#define Relay_3 3
#define Relay_4 4
#define Relay_5 5
#define Relay_6 6
#define Relay_7 7
#define Relay_8 8
int buttonState=0; //used when determining the state of the doorbell switch
void setup() /****** SETUP: RUNS ONCE ******/
{
//-------( Initialize Pins so relays are inactive at reset)----
digitalWrite(Relay_2, RELAY_OFF);
digitalWrite(Relay_3, RELAY_OFF);
digitalWrite(Relay_4, RELAY_OFF);
digitalWrite(Relay_5, RELAY_OFF);
digitalWrite(Relay_6, RELAY_OFF);
digitalWrite(Relay_7, RELAY_OFF);
digitalWrite(Relay_8, RELAY_OFF);
//---( THEN set pins as inputs or outputs)----
pinMode(doorbellbutton,INPUT);
pinMode(Relay_2, OUTPUT);
pinMode(Relay_3, OUTPUT);
pinMode(Relay_4, OUTPUT);
pinMode(Relay_5, OUTPUT);
pinMode(Relay_6, OUTPUT);
pinMode(Relay_7, OUTPUT);
pinMode(Relay_8, OUTPUT);
}//--(end setup )---
void loop() {
// read the state of the switch
buttonState = digitalRead(doorbellbutton);
// check if the Door Bell Button is pressed
// if it is, the doorbellbutton is HIGH
if (buttonState==HIGH) {
// Enter each note and note length
delay(500);
PlayIt(2,300);
PlayIt(2,300);
PlayIt(2,300);
PlayIt(4,1000);
delay(300);
PlayIt(3,300);
PlayIt(3,300);
PlayIt(3,300);
PlayIt(5,1000);
}
}
void PlayIt(int Relay_N, unsigned int HowLong) {
digitalWrite(Relay_N, RELAY_ON); //activate solenoid
delay(10); // keep it hot long enough to strike
digitalWrite(Relay_N, RELAY_OFF); // turn off the solenoid
delay(HowLong); }
//--(end main loop )---
//*********( THE END )***********
I figured it may be helpful to see how it is currently wired. As Paul_B pointed out, at this time the doorbell switch wire is basically an antenna.
// check if the Door Bell Button is pressed
// if it is, the doorbellbutton is LOW
if (buttonState==LOW) {
Ok. I have re-coded the project using the Bounce routine and PIN 12 (as PIN 13 has the LED). And, now I am using the button to pull PIN 12 to ground, with a 1K pull up resistor between PIN 12 and 5v. It should be pointed out that the doorbell button wire that is wired in the house is not shielded. It actually looks like lamp wire. Two strand, un-shielded.
Below is a picture of the schematic, as well as a sample of the code I am currently using.
Even with the new wiring attempt, the arduino is still receiving a false signal when I turn ceiling fans or a box fan off.
Earlier it was suggested to use a 22K resistor, 1uF capacitor, and 1K resistor. But I could not decipher how this schematic might look. If that suggestion looks like it may help, could someone clarify it a bit for me.
#include <Bounce.h>
const int buttonPin = 12;
Bounce pushbutton = Bounce(buttonPin, 10); // 10 ms debounce
#define RELAY_ON LOW
#define RELAY_OFF HIGH
#define Relay_2 2 // Arduino Digital I/O pin number
#define Relay_3 3
#define Relay_4 4
#define Relay_5 5
#define Relay_6 6
#define Relay_7 7
#define Relay_8 8
void setup() /****** SETUP: RUNS ONCE ******/
{
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(57600);
//-------( Initialize Pins so relays are inactive at reset)----
digitalWrite(Relay_2, RELAY_OFF);
digitalWrite(Relay_3, RELAY_OFF);
digitalWrite(Relay_4, RELAY_OFF);
digitalWrite(Relay_5, RELAY_OFF);
digitalWrite(Relay_6, RELAY_OFF);
digitalWrite(Relay_7, RELAY_OFF);
digitalWrite(Relay_8, RELAY_OFF);
//---( THEN set pins as inputs or outputs )----
pinMode(Relay_2, OUTPUT);
pinMode(Relay_3, OUTPUT);
pinMode(Relay_4, OUTPUT);
pinMode(Relay_5, OUTPUT);
pinMode(Relay_6, OUTPUT);
pinMode(Relay_7, OUTPUT);
pinMode(Relay_8, OUTPUT);
}//--(end setup )---
void loop() {
if (pushbutton.update()) {
if (pushbutton.fallingEdge()) {
//PlayIt is a sub-routine that sends a signal to the respective solenoids with a note length
delay(500);
PlayIt(2,300);
PlayIt(2,300);
PlayIt(2,300);
PlayIt(4,1000);
delay(300);
PlayIt(3,300);
PlayIt(3,300);
PlayIt(3,300);
PlayIt(5,1000);
delay(300);
PlayIt(8,300);
PlayIt(8,300);
PlayIt(8,300);
delay(300);
PlayIt(7,300);
PlayIt(7,300);
PlayIt(7,300);
delay(300);
PlayIt(3,300);
PlayIt(3,300);
PlayIt(3,300);
delay(1300);
PlayIt(8,300);
PlayIt(8,300);
PlayIt(8,300);
delay(300);
PlayIt(7,300);
PlayIt(7,300);
PlayIt(7,300);
}
}
}
void PlayIt(int Relay_N, unsigned int HowLong)
{ digitalWrite(Relay_N, RELAY_ON); //activate solenoid
delay(10); // keep it hot long enough to strike
digitalWrite(Relay_N, RELAY_OFF); // turn off the solenoid
delay(HowLong); }
//--(end main loop )---
Paul__B:
Even so, you must use a "debounce" routine (with a time constant of about 1/10 of a second) on the switch input. If you are not employing this, it is no wonder that you get spurious triggering - until the push is pressed, you are essentially connecting a long wire antenna to the Arduino port.
Seconded, this is the simplest way to cure the problem. I would add a 100pF capacitor directly
across the doorbell wire as it reaches the Arduino to reduce radio interference, another possible issue that could bite.
I just reworked the code to use the Bounce routine. I have not tried the capacitor suggestion yet. I will get one at Radio Shack today and add it across the doorbell wires.
Does it matter what size capacitor? It was mentioned earlier to employ a 1uF, but you mention a 100pF.
100pF will short out radio frequency interference (mobile phone, WiFi, passing taxis),
a wise precaution for any incoming unshielded long signal cable.
The 1uF would be for hardware debouncing (so ignore it if you use software debouncing).
A series resistor for protection against over-voltage spikes is also a good idea anyway...
Excellent. I will give it a try later today. Thanks for the suggestion.
MarkT:
100pF will short out radio frequency interference (mobile phone, WiFi, passing taxis),
a wise precaution for any incoming unshielded long signal cable.The 1uF would be for hardware debouncing (so ignore it if you use software debouncing).
Actually, the 1µF is to suppress 60 (0r 50) Hz mains interference, the original problem.
MarkT:
A series resistor for protection against over-voltage spikes is also a good idea anyway...
Exactly.
Just an update on this...
I just returned from Radio Shack with both 1uF and 100pF capacitors. After installing each as shown in the drawing, it still picks up a signal from turning the ceiling fan off.
So, back to the drawing board.
Heiss:
Just an update on this...
I just returned from Radio Shack with both 1uF and 100pF capacitors. After installing each as shown in the drawing, it still picks up a signal from turning the ceiling fan off.
So, back to the drawing board.
Try both caps. The 100pF will get rid of any high frequency noise, while the 1uF will get rid of any low frequency noise. Due to caps not being the 'ideal' that theory tells us (especially cheap radioshack caps), they actually only have a relatively limited range that they will filter well. Also, if they aren't Ceramic, make sure they are oriented properly.
It wouldn't hurt to install the caps on both ends of the wire. Even better if you could replace the wire with twisted pair.