# [Help] Converted doorbell lights an LED lamp but switch code relies on Delays

#### FranciscoB

Joined Feb 8, 2014
35
Doorbell receiver module had it's speaker removed, does not produce sound. Instead, the signal generated is read through A0 and is used to turn a LED block ON for a few minutes.

It´s working as a wireless lamp, so I can light my way to the bathroom at night.

When the powerbank is turned on, the arduino runs at 5V, the LED block is connected to 5V and the doorbell receiver is running at 3.3V. The output of the audio chip is being listened through A0 and, when I press the transmitter, the audio chip output goes higher, which turns the LED block on through D3 by PWM. I would like to:

- Press one time, LEDs turn on for OnTime=2min
- Press again immediately and OnTime becomes Ontime=4min
- Press again, etc...

- I go to the bathroom, come back and it's still on? I decide to press again and D3 goes LOW.

I wrote this simple code using delays to test the overall setup. I guess I have to use milis() or a Timer library but for that I need your help.

Code:
/* Wireless doorbell modified to turn ON a block of LEDs instead of playing a melody.
When the switch is pressed on the transmitter, a voltage change occurs in the audio
chip output of the receiver, which corresponds to the playing of the melody. This voltage
change is read through and analog pin. When the voltage rises over a defined threshold,
pin D3 outputs a PWM signal for a certain interval of time. The base of a 3904 transistor
is connected to D3 through a 1K Ohm resistor; the collector is connected to the load and the emitter do GND.*/

const int analogPin = A0;    // A0 connected to audio chip output
const int ledPin = 3;       // D3 to resistor to transistor base to trigger LED block
const int threshold = 650;   // an arbitrary threshold level that's in the range of the analog input

unsigned long interval = 2 * 60 * 1000UL; //2 minutes ON time

void setup() {

pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:

// Serial.begin(9600); // initialize serial communications:

}

void loop() {

//Serial.println(analogValue); // print the analog value:
//delay(10);        // delay in between reads for stability

/*When the switch in pressed, analogValue rises over threshold, it's time to turn LED ON for interval */

if (analogValue > threshold) {

// sets the value (range from 0 to 255):
// wait for 30 milliseconds to see the dimming effect
delay(10);
}

delay(interval);

// sets the value (range from 0 to 255):
// wait for 30 milliseconds to see the dimming effect
delay(10);
}

}
}

#### djsfantasi

Joined Apr 11, 2010
7,619
Your code for what you desire would be best implemented as a state machine. To do this you can use the Arduino SELECT CASE construct.

First, I would check to see if the wireless receiver had detected a button press. You can still delay after reading the pin.

If so, execute the following block of code.

For each press, I would increment a variable, let's call it pressState. If the variable was greater than the maximum number of states, set it to 0. This variable would be used in the case statement.

Case 1 would save the start time. I'd use a long integer variable. It would also calculate an end time (another long integer variable) by adding 120,000 to the start time (two minutes, 120 seconds or 120,000 ms). And finally, it would turn the light on.

Case 2 would simply calculate the end time by adding 240,000 to the start time.

Case 3 would calculate the end time by adding whatever...

Case 4 would set the end time to the start time.

This would be the end of the code block I mentioned.

Then, if the current time in milliseconds, i.e. millis(), is greater than the end time - turn the light off.

Then, lather, rinse and repeat. That is, loop around and do the whole thing over again.