How to get the latest interrupted PCInt pin ?

Hello everyone!

I would like to carry out the project initiated here: Final MAGIC SWITCH BOX a great magic illusion trick

Unfortunately, I was unable to get this code to work.

First, I tried to make "PinChangeInt.h" work with the examples here: https://github.com/GreyGnome/PinChangeInt/tree/master/Examples
But none of them seem to work... It seems that the library is now deprecated.

So I switched to the "PinChangeInterrupt.h" library (version 1.2.9). I tested the examples here: https://github.com/NicoHood/PinChangeInterrupt/tree/master/examples

And these work work!

And now, a question appears: how do I retrieve the last interrupted pin so that the code can run normally?

Here's the code I'm using for the moment (I've replaced what I'm looking for with "?") :

// 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 <PinChangeInterrupt.h>
#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 = -1;
// `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);

    attachPCINT(digitalPinToPCINT(pin_sw1), Int_swi, CHANGE);
    attachPCINT(digitalPinToPCINT(pin_sw2), Int_swi, CHANGE);
    attachPCINT(digitalPinToPCINT(pin_sw3), Int_swi, CHANGE);
    attachPCINT(digitalPinToPCINT(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 = ? ;
        last_off = latest_interrupted_pin - 1;
        // Serial.print("latest_interrupted_pin");
        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 = ? ;
        // Serial.print("latest_interrupted_pin");
        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 = ? ;
    int sw = latest_interrupted_pin - 2;
    Serial.print("latest_interrupted_pin :");
    Serial.println(latest_interrupted_pin);

    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.
    }
}

I'm working with an arduino nano V3, IDE: arduino IDE 2.2.1

Here are the connections :

Thanks for your help, I hope the problem comes from there.

Official Arduino.cc shows Nico Hood library is supported:

And DroneBotWorkshop has thorough examples (including PCInt near the end of his video)
https://dronebotworkshop.com/interrupts/

1 Like

Another magic box option:
" magic switchboard by aeropic - Thingiverse

Hi,
I'm tying to built same Magic switch box project based on Arduino Nano. did you manage to solve your problem?i'm stuck with the same
thanks!

can you help us please
how can you convert PCintPort::arduinoPin ;

like you have convert
PCintPort::attachInterrupt (pin_sw1, Int_swi, CHANGE);
whith
attachPCINT(digitalPinToPCINT(pin_sw1), Int_swi, CHANGE);

thanks

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.