Intelligent Push Button - 4 LEDS

Hello,

I have this project with a relay. My kitchen lamp has 4 light bulbs but I just have one ON/OFF switch to control all 4's.

I want to use an Arduino to code and close the relays output according to on how I use the switch (in time).

  1. A series of incremental relay activated: SWITCH PRESSED OFF-ON all 4 lamps at first (4 relays closed), SWITCH PRESSED OFF-ON 1 lamp, SWITCH PRESSED OFF-ON 2 lamps, SWITCH PRESSED OFF-ON 3 lamp, SWITCH PRESSED OFF-ON 4 lamp.

  2. Activating the switch quickly OFF-ON-OFF-ON could go directly to the 1 lamp relay setting OR all 4 lamps relay setting.

I made tests with a MOMENTARY PUSH BUTTON (this is not the usual house light switch).

I found this project and modified it to add a function to turn the lights.

However, this project is only a template with 2 LEDS. I need to work with 4 LEDS and a different switch.

My question is:
Does anybody have a suggestion on how I could emulate the OFF-ON trigger action with a Push Button on a Breadboard and how to translate that into programming?

Here is what I have so far. Please bare with me I have no programming background:

Source: https://programmingelectronics.com/make-one-button-functionality-two-arduino/

/*Using a Single Button, create mutliple options based on how long the button is pressed

The circuit:

  • LED attached from pin 13 to ground through a 220 ohm resistor

  • LED attached from pin 12 to ground through a 220 ohm resistor

  • one side of momentary pushbutton attached to pin 2

  • other side of momentary pushbutton attached to Ground

  • Note 1: on most Arduinos there is already an LED on the board
    attached to pin 13.

  • Note 2: In this circuit, when the button is pressed, Ground Voltage is what will be applied.

Created DEC 2014 by Scuba Steve
Modified JAN 2015 by Michael James
Both members of https://programmingelectronics.com

This code is in the public domain
*/

/////////Declare and Initialize Variables////////////////////////////

//We need to track how long the momentary pushbutton is held in order to execute different commands
//This value will be recorded in seconds
float pressLength_milliSeconds = 0;

// Define the minimum length of time, in milli-seconds, that the button must be pressed for a particular option to occur
int optionOne_milliSeconds = 100;
int optionTwo_milliSeconds = 2000;
int optionThree_milliSeconds = 4000;

//The Pin your button is attached to
int buttonPin = 2;

//Pin your LEDs are attached to
int ledPin_Option_1 = 13;
int ledPin_Option_2 = 12;

void setup(){

// Initialize the pushbutton pin as an input pullup
// Keep in mind, when pin 2 has ground voltage applied, we know the button is being pressed
pinMode(buttonPin, INPUT_PULLUP);

//set the LEDs pins as outputs
pinMode(ledPin_Option_1, OUTPUT);
pinMode(ledPin_Option_2, OUTPUT);

//Start serial communication - for debugging purposes only
Serial.begin(9600);

} // close setup

void loop() {

//Record roughly the tenths of seconds the button in being held down
while (digitalRead(buttonPin) == LOW ){

delay(100); //if you want more resolution, lower this number
pressLength_milliSeconds = pressLength_milliSeconds + 100;

//display how long button is has been held
Serial.print("ms = ");
Serial.println(pressLength_milliSeconds);

}//close while

//Different if-else conditions are triggered based on the length of the button press
//Start with the longest time option first

//Option OFF - Execute the third option (LOW) if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionThree_milliSeconds){

digitalWrite(ledPin_Option_1, LOW);
digitalWrite(ledPin_Option_2, LOW);

}

//Option 2 - Execute the second option if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionTwo_milliSeconds){

digitalWrite(ledPin_Option_2, HIGH);

}
//Option OFF - Execute the third option (LOW) if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionThree_milliSeconds){

digitalWrite(ledPin_Option_1, LOW);
digitalWrite(ledPin_Option_2, LOW);

}
//option 1 - Execute the first option if the button is held for the correct amount of time
else if(pressLength_milliSeconds >= optionOne_milliSeconds){

digitalWrite(ledPin_Option_1, HIGH);

}
//Option OFF - Execute the third option (LOW) if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionThree_milliSeconds){

digitalWrite(ledPin_Option_1, LOW);
digitalWrite(ledPin_Option_2, LOW);

}

//close if options

//every time through the loop, we need to reset the pressLength_Seconds counter
pressLength_milliSeconds = 0;

} // close void loop

the easiest way to code what you describe is with a state machine.
here the states and events are pretty simple and could be depicted this way:

you can use the OneButton library to make the handling of the events easy (then it's not fast Click that you can detect but a double click) and you just need to have a variable to save in which state you are.

when you detect the event, you check in which state you are, you go to the next one and perform the necessary changes to your relays

(you could also add an arrow from each intermediary stage to the right one with a double click)

Yes that's exactly what I need a state machine, but I have problems with the programming.

Could you help with this? There is a syntax error...

Thank you
Regards

/*Using a Single Button, create mutliple options based on how long the button is pressed

--->> Modified to: read state of light to light up a serie of LED one by one

The circuit:

  • LED attached from pin 13 to ground through a 220 ohm resistor

  • LED attached from pin 12 to ground through a 220 ohm resistor

  • one side of momentary pushbutton attached to pin 2

  • other side of momentary pushbutton attached to Ground

  • Note 1: on most Arduinos there is already an LED on the board
    attached to pin 13.

  • Note 2: In this circuit, when the button is pressed, Ground Voltage is what will be applied.

Created DEC 2014 by Scuba Steve
Modified JAN 2015 by Michael James
Both members of https://programmingelectronics.com

This code is in the public domain
*/

/////////Declare and Initialize Variables////////////////////////////

//We need to track how long the momentary pushbutton is held in order to execute different commands
//This value will be recorded in seconds
float pressLength_milliSeconds = 0;

// Define the minimum length of time, in milli-seconds, that the button must be pressed for a particular option to occur
int optionOne_milliSeconds = 100;
// int optionTwo_milliSeconds = 2000;
int optionThree_milliSeconds = 3000;
int optionFour_milliSeconds = 4000;
int optionFive_milliSeconds = 2000;

//The Pin your button is attached to
int buttonPin = 2;

//Pin your LEDs are attached to
int ledPin_Option_1 = 13;
int ledPin_Option_2 = 12;
int ledPin_Option_3 = 11;
int ledPin_Option_4 = 10;

void setup(){

// Initialize the pushbutton pin as an input pullup
// Keep in mind, when pin 2 has ground voltage applied, we know the button is being pressed
pinMode(buttonPin, INPUT_PULLUP);

//set the LEDs pins as outputs
pinMode(ledPin_Option_1, OUTPUT);
pinMode(ledPin_Option_2, OUTPUT);
pinMode(ledPin_Option_3, OUTPUT);
pinMode(ledPin_Option_4, OUTPUT);

//Start serial communication - for debugging purposes only
Serial.begin(9600);

} // close setup

void loop() {

//Record roughly the tenths of seconds the button in being held down
while (digitalRead(buttonPin) == LOW ){

delay(100); //if you want more resolution, lower this number
pressLength_milliSeconds = pressLength_milliSeconds + 100;

//display how long button is has been held
Serial.print("ms = ");
Serial.println(pressLength_milliSeconds);

}//close while

//Different if-else conditions are triggered based on the current state of DigitalRead
//Start with the longest time option first

//Option OFF - Execute the 5th option (LOW) if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionFive_milliSeconds){

digitalWrite(ledPin_Option_1, LOW);
digitalWrite(ledPin_Option_2, LOW);
digitalWrite(ledPin_Option_3, LOW);
digitalWrite(ledPin_Option_4, LOW);

}

// If no lights are HIGH make the 1st LED only = HIGH
if (digitalRead(ledPin_Option_1) == LOW )
(digitalRead(ledPin_Option_2) == LOW )
(digitalRead(ledPin_Option_3) == LOW )
(digitalRead(ledPin_Option_4) == LOW ) {

digitalWrite(ledPin_Option_1, HIGH);
digitalWrite(ledPin_Option_2, LOW);
digitalWrite(ledPin_Option_3, LOW);
digitalWrite(ledPin_Option_4, LOW);
}

//Option OFF - Execute the 5th option (LOW) if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionFive_milliSeconds){

digitalWrite(ledPin_Option_1, LOW);
digitalWrite(ledPin_Option_2, LOW);
digitalWrite(ledPin_Option_3, LOW);
digitalWrite(ledPin_Option_4, LOW);

}

// If LED 1 is HIGH make the 2nd LED = HIGH
if (digitalRead(ledPin_Option_1) == HIGH )
(digitalRead(ledPin_Option_2) == LOW )
(digitalRead(ledPin_Option_3) == LOW )
(digitalRead(ledPin_Option_4) == LOW ) {

digitalWrite(ledPin_Option_1, HIGH);
digitalWrite(ledPin_Option_2, HIGH);
digitalWrite(ledPin_Option_3, LOW);
digitalWrite(ledPin_Option_4, LOW);
}

//Option OFF - Execute the 5th option (LOW) if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionFive_milliSeconds){

digitalWrite(ledPin_Option_1, LOW);
digitalWrite(ledPin_Option_2, LOW);
digitalWrite(ledPin_Option_3, LOW);
digitalWrite(ledPin_Option_4, LOW);

}

// If LED 1,2 are HIGH make the 3rd LED = HIGH
if (digitalRead(ledPin_Option_1) == HIGH )
(digitalRead(ledPin_Option_2) == HIGH )
(digitalRead(ledPin_Option_3) == LOW )
(digitalRead(ledPin_Option_4) == LOW ) {

digitalWrite(ledPin_Option_1, HIGH);
digitalWrite(ledPin_Option_2, HIGH);
digitalWrite(ledPin_Option_3, HIGH);
digitalWrite(ledPin_Option_4, LOW);
}

//Option OFF - Execute the 5th option (LOW) if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionFive_milliSeconds){

digitalWrite(ledPin_Option_1, LOW);
digitalWrite(ledPin_Option_2, LOW);
digitalWrite(ledPin_Option_3, LOW);
digitalWrite(ledPin_Option_4, LOW);

}

// If LED 1,2,3 are HIGH make the 4th LED = HIGH
if (digitalRead(ledPin_Option_1) == HIGH )
(digitalRead(ledPin_Option_2) == HIGH )
(digitalRead(ledPin_Option_3) == HIGH )
(digitalRead(ledPin_Option_4) == LOW ) {

digitalWrite(ledPin_Option_1, HIGH);
digitalWrite(ledPin_Option_2, HIGH);
digitalWrite(ledPin_Option_3, HIGH);
digitalWrite(ledPin_Option_4, HIGH);
}

//Option OFF - Execute the 5th option (LOW) if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionFive_milliSeconds){

digitalWrite(ledPin_Option_1, LOW);
digitalWrite(ledPin_Option_2, LOW);
digitalWrite(ledPin_Option_3, LOW);
digitalWrite(ledPin_Option_4, LOW);

}

//close if options

//every time through the loop, we need to reset the pressLength_Seconds counter
pressLength_milliSeconds = 0;

} // close void loop

Use code tags, not quote to post your code

If there is a syntax error and you want us to find it, why don't you share what the compiler or pre-processor is telling you? Don't you think that would be relevant?

Why use a float for pressLength_milliSeconds ?

Why delay(100);  //if you want more resolution, lower this number ? Just let the processor count for you. Mesure millis() when pressed down and millis when released, do the difference and you have your duration exactly. (Mind bouncing)

Why do you have many times

      //Option OFF - Execute the 5th option (LOW) if the button is held for the correct amount of time
    if (pressLength_milliSeconds >= optionFive_milliSeconds){

Your code does not represent efficiently the state machine above. In should read as this (recording stage in a variable help, use enum to define meaningful stages names)

Segmenting on actions first and stages later

If short press
Depending on current stage, trigger actions and set next stage
Else if long press
Depending on current stage, trigger actions and set next stage

Or segmenting on stages and then actions

Depending on current stage
If short press do relevant action and set next stage
else if long press do relevant action and set next stage

Hi J-M-L, thank you so much for the reply. Sorry for the lack of details in my last post.

I started from a template project that had a pushbutton timer. I've modified it to a state machine.

Here is the new code below.

It doesn't seems to work even though there are no compilation errors.

What's funny is that my pushbutton return inverted values with INPUT_PULLUP. It returns 1 when idle and 0 when pressed. Could it be a wiring issue on my breadboard?

Coming back to the code, I can't seems to achieve the purpose of the loop. No lights will go HIGH with the following code. The wiring doesn't seems to be the problem.

Once again, a newbe here... thank you for your patience.

Any clues?

/////////Declare and Initialize Variables////////////////////////////

//The Pin your button is attached to
int buttonPin = 2;

// variables will change:
int buttonState = 1;         // variable for reading the pushbutton status

//Pin your LEDs are attached to
int ledPin_Option_1 = 13;
int ledPin_Option_2 = 12;
int ledPin_Option_3 = 11;
int ledPin_Option_4 = 10;


//Variables will change
int ledState_Option_1 = LOW;
int ledState_Option_2 = LOW;
int ledState_Option_3 = LOW;
int ledState_Option_4 = LOW;


void setup() {

  // Initialize the pushbutton pin as an input pullup
  // Keep in mind, when pin 2 has ground voltage applied, we know the button is being pressed
  pinMode(buttonPin, INPUT_PULLUP);     

  //set the LEDs pins as outputs
  pinMode(ledPin_Option_1, OUTPUT); 
  pinMode(ledPin_Option_2, OUTPUT); 
  pinMode(ledPin_Option_3, OUTPUT); 
  pinMode(ledPin_Option_4, OUTPUT);

  //Start serial communication - for debugging purposes only
  Serial.begin(9600);  

}

void loop() {

////////////////PUSH BUTTON STATE
  // read the input pin of button:
  int buttonState = digitalRead(buttonPin);

/*  
  // print out the state of the button:
  Serial.println(buttonState);
  delay(1);        // delay in between reads for stability

 */ 

    // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  
//////////////////LED OPTION 1 - STATE
    // read the input pin of LED:
  int ledState_Option_1 = digitalRead(ledPin_Option_1);

/* 
  // print out the state of the LED:
  Serial.println(ledState_Option_1);
  delay(1);        // delay in between reads for stability
*/

    // read the state of the LED value:
  ledState_Option_1 = digitalRead(ledPin_Option_1);

  


/////////////////LED OPTION 2 - STATE  
    // read the input pin of LED:
  int ledState_Option_2 = digitalRead(ledPin_Option_2);

/*
  // print out the state of the LED:
  Serial.println(ledState_Option_2);
  delay(1);        // delay in between reads for stability
*/

    // read the state of the LED value:
  ledState_Option_2 = digitalRead(ledPin_Option_2);

  
  

////////////////LED OPTION 3 - STATE  
    // read the input pin of LED:
  int ledState_Option_3 = digitalRead(ledPin_Option_3);

/* 
  // print out the state of the LED:
  Serial.println(ledState_Option_3);
  delay(1);        // delay in between reads for stability

*/
    // read the state of the LED value:
  ledState_Option_3 = digitalRead(ledPin_Option_3);

  


///////////////LED OPTION 4 - STATE  
    // read the input pin of LED:
  int ledState_Option_4 = digitalRead(ledPin_Option_4);

/* 
  // print out the state of the LED:
  Serial.println(ledState_Option_4);
  delay(1);        // delay in between reads for stability

*/
    // read the state of the LED value:
  ledState_Option_4 = digitalRead(ledPin_Option_4);

  

//////////////////////////////////////////////////////////////////////////////////////////////////

 

  // check if the pushbutton is pressed.
  // if it is, the buttonState is LOW
  // If no ledState_Option are HIGH make the 1st LED only = HIGH
  if (( buttonState == LOW) && (digitalRead(ledState_Option_1) == LOW ) &&  (digitalRead(ledState_Option_2) == LOW ) && (digitalRead(ledState_Option_3) == LOW ) && (digitalRead(ledState_Option_4) == LOW )) 
 
  {  
    digitalWrite(ledPin_Option_1, HIGH);
    digitalWrite(ledPin_Option_2, LOW);
    digitalWrite(ledPin_Option_3, LOW);
    digitalWrite(ledPin_Option_4, LOW);
  }


    // check if the pushbutton is pressed.
  // if it is, the buttonState is LOW 
  // If ledState_Option_1 HIGH make the 1st & 2nd LED only = HIGH
  if (( buttonState == LOW) && (digitalRead(ledState_Option_1) == HIGH ) &&  (digitalRead(ledState_Option_2) == LOW ) && (digitalRead(ledState_Option_3) == LOW ) && (digitalRead(ledState_Option_4) == LOW )) 
  
  {  
    digitalWrite(ledPin_Option_1, HIGH);
    digitalWrite(ledPin_Option_2, HIGH);
    digitalWrite(ledPin_Option_3, LOW);
    digitalWrite(ledPin_Option_4, LOW);
  }
}

What's funny is that my pushbutton return inverted values with INPUT_PULLUP. It returns 1 when idle and 0 when pressed. Could it be a wiring issue on my breadboard?

that's the way INPUT_PULLUP works. it saves a resistor in your wiring of the button because you use one already embedded in your Arduino.

OK - used a bit of my lunch time to prepare an example of basic state machine with 4 leds and one button, using the OneButton Library to make things simpler. of course you could implement the handling of the button yourself in the loop for the detection of single click or double click.

I've decided to implement the following state machine:

That's what the wiring looks like:

4 pins 8,9,10,11 connecting to the Anodes of 4 Leds with cathodes connected to ground through current limitation resistances of 200Ω (adjust to the type of LED you use, usually between 200Ω and 300Ω would do)

One momentary push button connected to pin 4, configured as INPUT_PULLUP, connecting to ground.

Given I'm using the OneButton Library, I've chosen to segment my code on actions first and then states when I get the action, so the code is basically this simple:


If singleClick detected then
Depending on current state, trigger relevant actions and set next state

if doubleClick detected then
Depending on current state, trigger relevant actions and set next state

Once you have a clear mind about this, the code is trivial and is only a few lines long:

#include <OneButton.h>
const byte buttonPin = 4;
OneButton button(buttonPin, true); // true to force INPUT_PULLUP

const byte redLedPin = 8;
const byte orangeLedPin = 9;
const byte yellowLedPin = 10;
const byte greenLedPin = 11;

// to memorize our current State
enum {REST, LEDs0, LEDs01, LEDs012, ALL_LEDs} ledState;

// helper function to set the initial state
void setRestState()
{
  digitalWrite(greenLedPin, LOW);
  digitalWrite(yellowLedPin, LOW);
  digitalWrite(orangeLedPin, LOW);
  digitalWrite(redLedPin, LOW);
  ledState = REST;
}

void simpleclick()
{
  switch (ledState) {
    case REST:
      // I was at REST, got one click, so need to turn on the first LED
      digitalWrite(greenLedPin, HIGH);
      ledState = LEDs0;
      break;

    case LEDs0:
      // I was with LED0 on, got one click, so need to turn on the second LED
      digitalWrite(yellowLedPin, HIGH);
      ledState = LEDs01;
      break;

    case LEDs01:
      //you get the idea :-)
      digitalWrite(orangeLedPin, HIGH);
      ledState = LEDs012;
      break;

    case LEDs012:
      digitalWrite(redLedPin, HIGH);
      ledState = ALL_LEDs;
      break;

    case ALL_LEDs:
      setRestState();
      break;
  }
}

void doubleclick()
{
  switch (ledState) {
    case REST:
    case LEDs0:
    case LEDs01:
    case LEDs012:
      // If I was in any state, except all LEDs on, then a doubleClick turns on every leds
      digitalWrite(greenLedPin, HIGH);
      digitalWrite(yellowLedPin, HIGH);
      digitalWrite(orangeLedPin, HIGH);
      digitalWrite(redLedPin, HIGH);
      ledState = ALL_LEDs;
      break;

    case ALL_LEDs:
      // all LEDS are on, I receive a doubleClick turns off every leds
      setRestState();
      break;
  }
}


void setup() {
  pinMode (redLedPin, OUTPUT);
  pinMode (orangeLedPin, OUTPUT);
  pinMode (yellowLedPin, OUTPUT);
  pinMode (greenLedPin, OUTPUT);
  
  // Initial conditions
  setRestState(); 

  //Possible events
  button.attachDoubleClick(doubleclick); 
  button.attachClick(simpleclick);
}

void loop() {
  // check our buttons
  button.tick();

  // here you could do something else as long as you keep it short
  
}

makes sense?

Hi J-M-L, thank you so much for your time. Brilliant coding!

I've downloaded the OneButton Library and uploaded the code.

The library is meant to go with a breadboard pushbutton of course. My installation on site will have a ON/OFF light switch. This library won't work I think.

The PB library works with a "hold the button count" I think, while a traditional light switch has a constant contact. We might want to think about the "Double-click" triggering with those.

Could you help me with the button configuration in the loop? I will need to do a lot of tests with the timing and calibration with the actual hardware on the light switch I have...

For the wiring on-site, I thought of just hooking up the Arduino in the ceiling. I have taken a few pictures on the current state of the lamp wiring. Keep in mind that I am an expat located in Asia. Color code and regulations are different.

Here are a few pictures. I realize I will probably make a hole in the ceiling for the Arduino. I thought there was a hole in the gypsum behind the black block lamp fixture.

Any comments?
P.S.: We use one switch for this project. The other switches are not for this kitchen lamp.

As for the coding architecture:
I think I will additionnal additional functions for light bulb pairs, most probably in X's (diagonal). I could get some different color signature ((ex.: (2) cool daylight vs (2) warm white 2700k)). This allow to choose according to the ambiant mood or time of the day, weekend vs weekdays, etc. This could be added later as a function along with a RTC if needed (I have some spare Arduino DS3231 AT24C32 IIC Module Precision RTC Real Time Clock Quare Memory)

Thanks again, brilliant!

I forgot to post a picture of my Relay Shield. I tested it with a ON/OFF relay program and it works.
for another light project but in the bathroom this time with a movement sensor.

Well a switch is kinda like a momentary push button if the user does "ON - OFF" and a double click is "ON - OFF - ON - OFF" quickly.

The questions I have are :

  • that switch today is powering the 4 lamps so have you planned to re-wire differently so that the relays are always getting power? (will be needed - CAREFUL playing with high current. Ensure you know what you are doing. Don't kill yourself or put fire to your home. Use properly certified relays etc....)
  • Also your arduino won't like the 220V (or 110V) AC from your switch. What's your plan there to detect the pulse?
  • and your arduino will need power of course :slight_smile:

I'll look at pictures later

I haven't done an apprenticeship. I will need advice when you have time to look at the pictures.

Nevertheless, I agree, it looks like I forgot that there isn't any constant power from a light switch. We have a problem.

Also your arduino won't like the 220V (or 110V) AC from your switch. What's your plan there?

What do you mean "it won't like" ? It's 230v. I have no plan, this is unexpected. My first problem.

What would be the easiest way to rewire the kitchen light using existing pulled-in electrical wires from the switch?

Thanks again.

I'll give it a try later on, as general ideas but I would advise strongly against you doing it since you appear to have too limited electricity knowledge - a mistake happens quickly. Electricity kills people and destroys homes every year. Don't be in that camp... I would advise to get it done by professional help from a real electrician.

J-M-L:
I'll give it a try later on, as general ideas but I would advise strongly against you doing it since you appear to have too limited electricity knowledge - a mistake happens quickly. Electricity kills people and destroys homes every year. Don't be in that camp... I would advise to get it done by professional help from a real electrician.

Thanks, I will definitely request help from a professional.

I took some pictures. It's just an interrupted red wire at the back that runs from the switch to the lamp terminal.

Any suggestions are welcomed.

P.S.: Vous parlez français? Je suis un Québécois vivant en Indonésie. Message privé bienvenue. Cordialement

The switch pictures...

Hi - if you read french, have a look at this small tutorial in french where I was discussing driving a two-way switch with a button and electronics

I don't use MP because I feel posting in the forum can help everyone coming back here and lets also domain experts chip in with their view and advice. While I've some good understanding, I'm not an electrician either so take all the below as food for thoughts. let experts help.

Your current setting looks like this: you have a standard switch

from the connection side:

and when you press the button you connect the circuit and the lamp goes on.

So you have multiple problems with your set up:

you need to have constant power, 7 to 12V not 220V for your arduino. The switch turns off the current at the lamp level so you're stuck if you keep the wiring as it is. if you want to have all the electronics hidden with the lamp "base", the power needs to be always on there.

--> you need to unplug the lamp, unplug the switch and just route the power always to the ceiling. then you need a power adaptor 220V AC --> 9V and power your arduino and relays, connect the bulbs to the relays.

Your second problem is how does the switch works now that it's no longer connected to anything.
--> you need to put in 2 new wires routed form the ceiling to the switch. it might be easy or difficult depending on the physical set up. if you are lucky, there is a tube going from the switch to the ceiling, within the walls and it's large enough with no sharp angle, then it's easy to fit a pair of wires in there with a cable guide.

--> if you manage to do this, then you can "just" (distance will play a role too, your arduino 5V might need to be amplified if the resistance of the wire is too high and you won't read a 1 when you press the switch) plug one of the wire to GND, the other to a pin and at the switch level connect them one to the former Live and one to the connected position and now you have your push button

would look something like this (of course wiring the relays in the right way, with the same power cables as the arduino power adapter for the lamp side and from the arduino on the other side)

alternatively, you can have the arduino near the switch but then you need to route the wires form the 4 bulbs through the wall so that then arrive near the arduino / relays.

makes sense?

AGAIN THIS IS DANGEROUS !

HI, thanks for your reply. The PM was just on the personal level, to get to know each other... I understand if you don't have time.

On the project...

Instead of pulling wires, I thought of doing this:

2 arduino with wireless shields and PS
-One near the switch
-One near the lamp with SRS or SSR

The hot wire for the switch is bypassed, providing constant power at the top of the lamp (with a fuse or a breaker for safety and maintenance). It also provide power for the "switch arduino"

The Switch is therefore just used for an input to the Arduino, and isn't hot anymore.

Easy-peasy no cable pull?

How do you think... did I forget something?

Thanks.

sure if you are ready to remove the switch, just use a simple IR remote control for example, then you have multiple buttons and you can drive what you want - no need for 2 arduinos, just 1.

There are even relays that you can control through IR, so no arduino needed at all :slight_smile:

or full boards

I need to think about that for a night or so... thanks again.

OK I had some thoughts about this. I like the diagram with 1 arduino at the base of the lamp, pulling 2 electronic wires to the switch.

I have ordered a cable puller, it should take a while to arrive:
http://www.ebay.com/itm/122367424095?_trksid=p2057872.m2749.l2649&var=422849477235&ssPageName=STRK%3AMEBIDX%3AIT

distance will play a role too, your arduino 5V might need to be amplified if the resistance of the wire is too high

I wanted to ask you about the need to amplify the 5v. Is it complicated or expensive?

Also, for the interference with the proximity of a hot red electrical cable. Is this an issue that could cause the switch and the system to be glitchy? Ever had problems like these in your setup at your house?

For the programming...
I will need to calibrate the #include <OneButton.h> library.
Does this works?

Souce: editing a library - Development - Arduino Forum

If you copy (or move) the library source files (.cpp and .h) files into your sample sketch directory, they will show up as separate tabs in the IDE. Doing it this way you can edit, compile and catch errors visualized in the IDE as well as upload and test without leaving the IDE.

Once you're happy with the library, you copy (or move) it back to the library folder.

Is there any better way other than starting from scratch the coding?

I will modify your code and republish it in this thread.

I wanted to ask you:
In your code, you have a void setup and a void loop at the bottom. Since I am a beginner, should I copy those at the top?

I don't understand, can you explain me why your "cases" are outside the void loop? Shouldn't they be inside?

Source:

#include <OneButton.h>
const byte buttonPin = 4;
OneButton button(buttonPin, true); // true to force INPUT_PULLUP


const byte redLedPin = 8;
const byte orangeLedPin = 9;
const byte yellowLedPin = 10;
const byte greenLedPin = 11;

// to memorize our current State
enum {REST, LEDs0, LEDs01, LEDs012, ALL_LEDs} ledState;

// helper function to set the initial state
void setRestState()
{
  digitalWrite(greenLedPin, LOW);
  digitalWrite(yellowLedPin, LOW);
  digitalWrite(orangeLedPin, LOW);
  digitalWrite(redLedPin, LOW);
  ledState = REST;
}

void simpleclick()
{
  switch (ledState) {
    case REST:
      // I was at REST, got one click, so need to turn on the first LED
      digitalWrite(greenLedPin, HIGH);
      ledState = LEDs0;
      break;

    case LEDs0:
      // I was with LED0 on, got one click, so need to turn on the second LED
      digitalWrite(yellowLedPin, HIGH);
      ledState = LEDs01;
      break;

    case LEDs01:
      //you get the idea :-)
      digitalWrite(orangeLedPin, HIGH);
      ledState = LEDs012;
      break;

    case LEDs012:
      digitalWrite(redLedPin, HIGH);
      ledState = ALL_LEDs;
      break;

    case ALL_LEDs:
      setRestState();
      break;
  }
}

void doubleclick()
{
  switch (ledState) {
    case REST:
    case LEDs0:
    case LEDs01:
    case LEDs012:
      // If I was in any state, except all LEDs on, then a doubleClick turns on every leds
      digitalWrite(greenLedPin, HIGH);
      digitalWrite(yellowLedPin, HIGH);
      digitalWrite(orangeLedPin, HIGH);
      digitalWrite(redLedPin, HIGH);
      ledState = ALL_LEDs;
      break;

    case ALL_LEDs:
      // all LEDS are on, I receive a doubleClick turns off every leds
      setRestState();
      break;
  }
}


void setup()

{
  pinMode (redLedPin, OUTPUT);
  pinMode (orangeLedPin, OUTPUT);
  pinMode (yellowLedPin, OUTPUT);
  pinMode (greenLedPin, OUTPUT);
  
  // Initial conditions
  setRestState(); 

  //Possible events
  button.attachDoubleClick(doubleclick); 
  button.attachClick(simpleclick);
}

void loop() {
  // check our buttons
  button.tick();

  // here you could do something else as long as you keep it short
  
}

Thanks Again.