Hi, This is my version of the MAGIC SWITH BOX !!!!
Please comment and give new ideas.
Also ideas for improvement is wellcome.
Have fun/ Hans
/
// This software uses an ARDUINO NANO to make a "MAGIC SWITCH BOX".
// If you using other type of ARDUINO board, please adjust for used light- and switch- pins.
// What is a "MAGIC SWITCH BOX"?? .... check on YouTube! Try.. http://www.youtube.com/watch?v=0lGP8nQLANU
// Written by Hans Naesstroem Stockholm Sweden jun 2014. The program is free to use by anyone.
// The order of lamps is default 1-2-3-4 and after that set by last switch turned off and time out.
// If last switch turned off is 1 you get the new order seq = 1-2-3-4.
// Last off = 2 gets seq = 2-1-3-4. 3 gets seq = 3-4-1-2. and 4 gets seq = 4-3-2-1.
// Condition for reset is: All switches off AND done>0 AND reset_time elapsed --- then resets to new
// seq determent by last switch off, 1-2-3 or 4.
#include <PinChangeInt.h> // multi interrupt pins handler. download if you dont have it installed.
#define pin_sw1 2 // defines for interrups.
#define pin_sw2 3 // pin_sw2 (switch 2) is connected to digital pin 3 and Ground. Switch NO.
#define pin_sw3 4
#define pin_sw4 5
// #define NO_PORTB_PINCHANGES ( Port B is all needed for this project).
#define NO_PORTC_PINCHANGES // not used, so save time and memory.
#define NO_PORTD_PINCHANGES
uint8_t latest_interrupted_pin;
// `latest_interrupted_pin` will allways show what pin that trigged the latest interrupt
const int pin_la1 = 10; // pin_la1 (lamp 1) connected to digital pin 10 and Ground.
const int pin_la2 = 11;
const int pin_la3 = 12;
const int pin_la4 = 13;
int sw1_la =0; // lamp related to switch one, (to be lerned in program run).
int sw2_la =0;
int sw3_la =0;
int sw4_la =0;
int stat_sw1=1; // present status of switch one, active low.
int stat_sw2=1;
int stat_sw3=1;
int stat_sw4=1;
int seq=1; // sequence to lit lamps, 1=1234, 2=2143, 3=3412, 4=4321.
int done=0; // lerned number of switches.
int last_off=1;
long time_out = millis(); // to calculate time_out.
void setup()
{
pinMode(pin_sw1,INPUT_PULLUP); // pin_sw1 (switch 1) connected to digital pin 2 and ground.
pinMode(pin_sw2,INPUT_PULLUP); // internal pullup used.
pinMode(pin_sw3,INPUT_PULLUP);
pinMode(pin_sw4,INPUT_PULLUP);
PCintPort::attachInterrupt (pin_sw1, Int_swi1, CHANGE); // call Int_swi1 when pin_sw1 changes status.
PCintPort::attachInterrupt (pin_sw2, Int_swi2, CHANGE);
PCintPort::attachInterrupt (pin_sw3, Int_swi3, CHANGE);
PCintPort::attachInterrupt (pin_sw4, Int_swi4, CHANGE);
pinMode(pin_la1,OUTPUT); // lamp pin is an output.
pinMode(pin_la2,OUTPUT);
pinMode(pin_la3,OUTPUT);
pinMode(pin_la4,OUTPUT);
digitalWrite(pin_la1,LOW); // turn off all lamps.
digitalWrite(pin_la2,LOW);
digitalWrite(pin_la3,LOW);
digitalWrite(pin_la4,LOW);
Serial.begin(9600); // enable serial monitor for debugging.
}
uint8_t i;
void loop() // MAIN LOOP ---------------------------
{
time_out=millis();
Serial.println ("Running main loop");
do {
latest_interrupted_pin=PCintPort::arduinoPin ;
last_off = latest_interrupted_pin-1;
if (seq<1) {seq=1;}
Serial.print ("sw1_la: "); // comment out all Serial.print when serial monitor not in use.
Serial.print (sw1_la);
Serial.print (stat_sw1);
Serial.print (" sw2_la: ");
Serial.print (sw2_la);
Serial.print (stat_sw2);
Serial.print (" sw3_la: ");
Serial.print (sw3_la);
Serial.print (stat_sw3);
Serial.print (" sw4_la: ");
Serial.print (sw4_la);
Serial.println (stat_sw4);
Serial.print (" done: ");
Serial.println (done);
Serial.print (" seq ");
Serial.println (seq);
Serial.println ("------------------------------------------------");
delay (1000);
}
while (millis()<((time_out)+4000)); // set to preferred time out (4 sec).
Serial.println ("Timed out !!! ...");
if ((stat_sw1==1) && (stat_sw2==1) && (stat_sw3==1) && (stat_sw4==1)&& (done>0)){
Serial.println ("Running reset");
seq=latest_interrupted_pin-1;
if (seq<1) {seq=1;}
sw1_la =0; // lamp related to switch one.
sw2_la =0;
sw3_la =0;
sw4_la =0;
done=0;
}
} // end of main loop.
//______________________________________________________________________
void Int_swi1() // interrupt trigged by swith 1, CHANGE.
{
time_out = millis();
// Serial.println ("Running Int_swi1"); // used for debug run.
if (sw1_la > 0) { stat_sw1 = !stat_sw1; digitalWrite(sw1_la,stat_sw1);
}
else {
if ((done==0) && (seq==1)) { sw1_la = 10;}
if ((done==1) && (seq==1)) { sw1_la = 11;}
if ((done==2) && (seq==1)) { sw1_la = 12;}
if ((done==3) && (seq==1)) { sw1_la = 13;}
if ((done==0) && (seq==2)) { sw1_la = 11;}
if ((done==1) && (seq==2)) { sw1_la = 10;}
if ((done==2) && (seq==2)) { sw1_la = 13;}
if ((done==3) && (seq==2)) { sw1_la = 12;}
if ((done==0) && (seq==3)) { sw1_la = 12;}
if ((done==1) && (seq==3)) { sw1_la = 13;}
if ((done==2) && (seq==3)) { sw1_la = 10;}
if ((done==3) && (seq==3)) { sw1_la = 11;}
if ((done==0) && (seq==4)) { sw1_la = 13;}
if ((done==1) && (seq==4)) { sw1_la = 12;}
if ((done==2) && (seq==4)) { sw1_la = 11;}
if ((done==3) && (seq==4)) { sw1_la = 10;}
digitalWrite (sw1_la,LOW); stat_sw1 = !stat_sw1;
++done; // increment counter for switch learned.
}
}
//______________________________________________________________________
void Int_swi2() // interrupt trigged by swith 2, CHANGE.
{
time_out = millis();
if (sw2_la > 0) { stat_sw2 = !stat_sw2; digitalWrite(sw2_la,stat_sw2); }
else {
if ((done==0) && (seq==1)) { sw2_la = 10;}
if ((done==1) && (seq==1)) { sw2_la = 11;}
if ((done==2) && (seq==1)) { sw2_la = 12;}
if ((done==3) && (seq==1)) { sw2_la = 13;}
if ((done==0) && (seq==2)) { sw2_la = 11;}
if ((done==1) && (seq==2)) { sw2_la = 10;}
if ((done==2) && (seq==2)) { sw2_la = 13;}
if ((done==3) && (seq==2)) { sw2_la = 12;}
if ((done==0) && (seq==3)) { sw2_la = 12;}
if ((done==1) && (seq==3)) { sw2_la = 13;}
if ((done==2) && (seq==3)) { sw2_la = 10;}
if ((done==3) && (seq==3)) { sw2_la = 11;}
if ((done==0) && (seq==4)) { sw2_la = 13;}
if ((done==1) && (seq==4)) { sw2_la = 12;}
if ((done==2) && (seq==4)) { sw2_la = 11;}
if ((done==3) && (seq==4)) { sw2_la = 10;}
digitalWrite (sw2_la,LOW); stat_sw2 = !stat_sw2;
++done; // increment counter for switch learned.
}
}
//______________________________________________________________________
void Int_swi3() // interrupt trigged by swith 3, CHANGE.
{
time_out = millis();
if (sw3_la > 0) { stat_sw3 = !stat_sw3; digitalWrite(sw3_la,stat_sw3);}
else {
if ((done==0) && (seq==1)) { sw3_la = 10;}
if ((done==1) && (seq==1)) { sw3_la = 11;}
if ((done==2) && (seq==1)) { sw3_la = 12;}
if ((done==3) && (seq==1)) { sw3_la = 13;}
if ((done==0) && (seq==2)) { sw3_la = 11;}
if ((done==1) && (seq==2)) { sw3_la = 10;}
if ((done==2) && (seq==2)) { sw3_la = 13;}
if ((done==3) && (seq==2)) { sw3_la = 12;}
if ((done==0) && (seq==3)) { sw3_la = 12;}
if ((done==1) && (seq==3)) { sw3_la = 13;}
if ((done==2) && (seq==3)) { sw3_la = 10;}
if ((done==3) && (seq==3)) { sw3_la = 11;}
if ((done==0) && (seq==4)) { sw3_la = 13;}
if ((done==1) && (seq==4)) { sw3_la = 12;}
if ((done==2) && (seq==4)) { sw3_la = 11;}
if ((done==3) && (seq==4)) { sw3_la = 10;}
digitalWrite (sw3_la,LOW); stat_sw3 = !stat_sw3;
++done; // increment counter for switch learned.
}
}
//______________________________________________________________________
void Int_swi4() // interrupt trigged by swith 4, CHANGE.
{
time_out = millis();
if (sw4_la > 0) { stat_sw4 = !stat_sw4; digitalWrite(sw4_la,stat_sw4); }
else {
if ((done==0) && (seq==1)) { sw4_la = 10;}
if ((done==1) && (seq==1)) { sw4_la = 11;}
if ((done==2) && (seq==1)) { sw4_la = 12;}
if ((done==3) && (seq==1)) { sw4_la = 13;}
if ((done==0) && (seq==2)) { sw4_la = 11;}
if ((done==1) && (seq==2)) { sw4_la = 10;}
if ((done==2) && (seq==2)) { sw4_la = 13;}
if ((done==3) && (seq==2)) { sw4_la = 12;}
if ((done==0) && (seq==3)) { sw4_la = 12;}
if ((done==1) && (seq==3)) { sw4_la = 13;}
if ((done==2) && (seq==3)) { sw4_la = 10;}
if ((done==3) && (seq==3)) { sw4_la = 11;}
if ((done==0) && (seq==4)) { sw4_la = 13;}
if ((done==1) && (seq==4)) { sw4_la = 12;}
if ((done==2) && (seq==4)) { sw4_la = 11;}
if ((done==3) && (seq==4)) { sw4_la = 10;}
digitalWrite (sw4_la,LOW); stat_sw4 = !stat_sw4;
++done; // increment counter for switch learned.
}
}
/[Code]
[/code]