Hello
I 've been doing a project and I have to control 3 different loads using a button. I tried using this code:
int led1 = 2;
int led2 = 3;
int led3 = 4;
int controle1 = 9;
int controle2 = 10;
int controle3 = 11;
void setup()
{
pinMode (led1, OUTPUT);
pinMode (controle1 , INPUT);
pinMode (led2, OUTPUT);
pinMode (controle2 , INPUT);
pinMode (led3, OUTPUT);
pinMode (controle3 , INPUT);
}
void loop()
{
delay(10); // Delay a little bit to improve simulation performance
digitalWrite(led1 , LOW);
digitalWrite(led2 , LOW);
digitalWrite(led3 , LOW);
while( digitalRead(led1) == 0 ) {
if (digitalRead(controle1) == 0) {
digitalWrite(led1, HIGH);
delay (3000);
}
}
while ( digitalRead(led1) == 1 ) {
if (digitalRead(controle1) == 0) {
digitalWrite(led1, LOW);
delay (3000);
}
}
while ( digitalRead(led2) == 0) {
if (digitalRead(controle2) == 0) {
digitalWrite(led2, HIGH);
delay (3000);
}
}
while ( digitalRead(led2) == 1) {
if (digitalRead(controle2) == 0) {
digitalWrite(led2, LOW);
delay (3000);
}
}
while ( digitalRead(led3) == 0) {
if (digitalRead(controle3) == 0) {
digitalWrite(led3, HIGH);
delay (3000);
}
}
while ( digitalRead(led3) == 1) {
if (digitalRead(controle3) == 0) {
digitalWrite(led3, LOW);
delay (3000);
}
}
}
But when I tested it I got one problem, the output would only work in the order led1 turn on , led 1 turn off, led2 turn on and this goes on, I couldn't use the second load first and I also couldn't turn two leds on at the same time.
Thanks in advance.
Your while loops and delays are blocking everything else. Take a look at the Blink Without Delay example and the following guides:
http://forum.arduino.cc/index.php?topic=503368.0
http://forum.arduino.cc/index.php?topic=223286.0
Once you understand that, you can make abstraction of the concept and put it inside a class. This is especially useful if you need the same code multiple times (e.g. for your three loads).
class TimerOutput {
public:
TimerOutput(uint8_t pin)
: pin(pin) {
pinMode(pin, OUTPUT); // Set the pin as a digital output
}
void turnOff() {
digitalWrite(pin, LOW); // Turn off the output
timerActive = false; // Disable the timer
}
void turnOn() {
digitalWrite(pin, HIGH); // Turn on the output
timerActive = false; // Disable the timer
}
void turnOnFor(unsigned long duration) {
digitalWrite(pin, HIGH); // Turn on the output
timerActive = true; // Enable the timer
startOnTime = millis(); // Remember the current time
onDuration = duration; // Remember how long it has to stay on
}
void refresh() {
if (timerActive // If the timer is running,
&& (millis() - startOnTime >= onDuration)) { // and the output has been on for the desired duration or longer
turnOff(); // Turn it off
}
}
private:
const uint8_t pin;
bool timerActive = false;
unsigned long startOnTime;
unsigned long onDuration;
};
/* ----------------------------------------------------------------------------------------------------------------------- */
class PushButton {
public:
PushButton(uint8_t pin)
: pin(pin) {
pinMode(pin, INPUT_PULLUP); // Set the pin as a digital input, and enable the internal pull-up resistor
}
bool isFalling() { // Returns true if the input pin's state goes from high to low (i.e. if the button is pressed)
bool currentState = digitalRead(pin); // Read the button state
bool falling = false;
if (previousState != currentState) { // If the state changed since last time
if (currentState == LOW) { // If the current state is low
falling = true; // The input is low now, and it was high before, so it was falling
}
previousState = currentState; // Remember the current state
}
return falling;
}
private:
const uint8_t pin;
bool previousState = HIGH;
};
/* ----------------------------------------------------------------------------------------------------------------------- */
TimerOutput led_A = { 2 }; // Initialize a TimerOutput object called 'led_A' on digital pin 2
TimerOutput led_B = { 3 };
TimerOutput led_C = { 4 };
PushButton button_A = { 9 };
PushButton button_B = { 10 };
PushButton button_C = { 11 };
void setup() {}
void loop() {
if (button_A.isFalling()) { // If the first button is pressed
led_A.turnOnFor(3000); // Turn on the first LED for 3 seconds
}
if (button_B.isFalling()) {
led_B.turnOnFor(3000);
}
if (button_C.isFalling()) {
led_C.turnOnFor(3000);
}
led_A.refresh(); // Refresh the first LED
led_B.refresh();
led_C.refresh();
}
As you can see, this code doesn't use any while loops or delays.
Pieter
I think you misunderstood one thnig about my code. The delay I put was so when I pressed the button it wouldn't be changing in a loop, so the person could press it and then the loud would be actived until I pressed it button again.
So you want to toggle the loads? (I.e. one press = on, second press = off.)
Then you need to debounce the pushbuttons, and remember the previous states in order to detect the falling edges:
class PushButton {
public:
PushButton(uint8_t pin) // Constructor (executes when a PushButton object is created)
: pin(pin) { // remember the push button pin
pinMode(pin, INPUT_PULLUP); // enable the internal pull-up resistor
};
bool isFalling() // read the button state check if the button has been pressed, debounce the button as well
{
bool falling = false;
bool state = digitalRead(pin); // read the button's state
int8_t stateChange = state - previousState; // calculate the state change since last time
if (stateChange == fallingEdge) { // If the button is pressed (went from high to low)
if (millis() - previousBounceTime > debounceTime) { // check if the time since the last bounce is higher than the threshold
falling = true; // the button is pressed
}
}
if (stateChange == risingEdge) { // if the button is released or bounces
previousBounceTime = millis(); // remember when this happened
}
previousState = state; // remember the current state
return falling; // return true if the button was pressed and didn't bounce
};
private:
uint8_t pin;
bool previousState = HIGH;
unsigned long previousBounceTime = 0;
const unsigned long debounceTime = 25;
const int8_t risingEdge = HIGH - LOW;
const int8_t fallingEdge = LOW - HIGH;
};
const uint8_t ledPin_A = 2;
const uint8_t ledPin_B = 3;
const uint8_t ledPin_C = 4;
PushButton button_A = { 9 };
PushButton button_B = { 10 };
PushButton button_C = { 11 };
void setup() {
pinMode(ledPin_A, OUTPUT);
pinMode(ledPin_B, OUTPUT);
pinMode(ledPin_C, OUTPUT);
}
void loop() {
static bool ledState_A = false;
static bool ledState_B = false;
static bool ledState_C = false;
if (button_A.isFalling()) {
ledState_A = !ledState_A; // Toggle the LED state
digitalWrite(ledPin_A, ledState_A); // Write the state to the pin
}
if (button_B.isFalling()) {
ledState_B = !ledState_B;
digitalWrite(ledPin_B, ledState_B);
}
if (button_C.isFalling()) {
ledState_C = !ledState_C;
digitalWrite(ledPin_C, ledState_C);
}
}
Pieter
Hi,
Forget the while statements.
You need to detect the buttons BEING pushed, NOT in the pushed state.
This will help
Write code to get just one output to toggle ON and OFF.
Then simply write it two more times with button and load pinouts changed.
Tom... 