Go Down

Topic: Final MAGIC SWITCH BOX a great magic illusion trick (Read 997 times) previous topic - next topic

HasseBasse

Aug 02, 2014, 06:40 am Last Edit: Aug 06, 2014, 11:00 am by HasseBasse Reason: 1
Here is my final optimised code version.
Have fun!




Code: [Select]
// This software uses an ARDUINO NANO to make a "MAGIC SWITCH BOX". A great magic illusion trick.
// 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! http://www.youtube.com/watch?v=0lGP8nQLANU
// My verion have the function for user  to secretly select 4 versions of lamp-light sequense.
// 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 off = 2 gets seq 2 = 2-1-3-4. 3 gets seq 3 = 3-4-1-2. and 4 gets seq 4 = 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.
// Remember to start unit with all switches in OFF (open) state.

#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 swi[]={0,0,0,0};  // switches related to lamps, (to be lerned in program run).
int stat[]={1,1,1,1};  // initiate status of switches, active low.

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;  
unsigned 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_swi, CHANGE); // call Int_swi when pin_sw1 changes status.
 PCintPort::attachInterrupt (pin_sw2, Int_swi, CHANGE);
 PCintPort::attachInterrupt (pin_sw3, Int_swi, CHANGE);
 PCintPort::attachInterrupt (pin_sw4, Int_swi, 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();
do {    
      latest_interrupted_pin=PCintPort::arduinoPin ;
      last_off = latest_interrupted_pin-1;      
    if (seq<1) {seq=1;}                 // You may comment out all Serial.print when serial monitor not in use.
       Serial.print ("swi[0]: "); Serial.print (swi[0]); Serial.print ("  stat[0]: "); Serial.println (stat[0]);                      
       Serial.print ("swi[1]: "); Serial.print (swi[1]); Serial.print ("  stat[1]: "); Serial.println (stat[1]);
       Serial.print ("swi[2]: "); Serial.print (swi[2]); Serial.print ("  stat[2]: "); Serial.println (stat[2]);        
       Serial.print ("swi[3]: "); Serial.print (swi[3]); Serial.print ("  stat[3]: "); Serial.println (stat[3]);
       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[0]==1) && (stat[1]==1) && (stat[2]==1) && (stat[3]==1)&& (done>0)){
       Serial.println ("Running reset");
      latest_interrupted_pin=PCintPort::arduinoPin ;        
      seq=latest_interrupted_pin-1;  
  if (seq<1) {seq=1;}
      swi[0] =0;  swi[1] =0;   swi[2] =0;   swi[3] =0;    // lamps related to switches.
      done=0;
}
    }                      // END MAIN LOOP. -------------------------------

void Int_swi()    // interrupt trigged by switches, CHANGE.  ---------------------------------------
{  
time_out = millis();  
      latest_interrupted_pin=PCintPort::arduinoPin ;
int  sw = latest_interrupted_pin-2; // sw = 0,1,2 or 3

if (swi[sw] > 0)  {stat[sw] = !stat[sw]; digitalWrite(swi[sw],stat[sw]); } // turn on/off lamp
else {
   switch (seq){
     case 1: {swi[sw] = done+10;} break;
     case 2: {{swi[sw] = 11-done;}
       if (swi[sw]<10) {swi[sw]= (10+done);}} break;  
     case 3: {{swi[sw] = 12+done;}
       if (swi[sw]>13) {swi[sw] = (8+done);}} break;  
     case 4: {swi[sw] = 13-done;} break;
  }
           digitalWrite (swi[sw],LOW); stat[sw] = !stat[sw]; // turn on lamp
 ++done;   // increment counter for switches learned.
   }
       }

raschemmel

Thanks for the post,
You just need to do one more thing:

Quote
click the MODIFY button in the upper right of the post window.
Highlight all you code.
click the "#" CODE TAGS button on the toolbar above just to the left of the QUOTE button.
click SAVE (at the bottom).
When you post code on the forum, please make a habit of using the code tags "#" button.   
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,
DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

the133448

Just a question,


How would we conenct up the lamps and switches?

Genuiely confused

raschemmel

Start your own post .
It is considered impolite to hijack someone else's thread.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,
DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Peter_I


Start your own post .
It is considered impolite to hijack someone else's thread.


What is the impoliteness?

As I read it, the133448 is asking how the box is wired up?
"Nothing is foolproof to a sufficiently talented fool"

Go Up