Detecting switches in order

im VERY new to Arduino, and really want to learn. however, i have a project i am making for my grandson, and need it completed shortly. I just dont have time right now to learn how to code. You can teach and old dog new tricks, but it takes time! basically, i have a series of ten toggle switches that need to be turned on in the correct order. doing so will light a green LED, failing will light a red LED. Is anyone out there kind enough to provide the code for me??? it would be greatly appreciated, both by myself and my granson.

You may find someone here, but the fastest way to get help is to make a start, and we help you, or visit HERE, and someone may feel like helping outright, or you can pay a tiny amount to get another learner on-side to push you through.

Generally the helpers on here are already employed & busy - happy to ‘help’, but can’t dedicate more than a few minutes to a specific request at any given time.

This is a fairly simple project, so it’s a good one for you to get your teeth into, and the young fella will think you’re a genius !

Consider getting your grandson to help you you both could have a lot of fun.

Hello
You may start with coding and we will guide you to find a solution.

Hi philport,
welcome to the world of arduino! you can start without knowing many things.
Prepare your arduino like this, the code is coming soon !

for the 10 toggle:
pin2----1Kresistor---toggle---pin"Gnd"
pin3----1Kresistor---toggle---pin"Gnd"
...
pin11----1Kresistor---toggle---pin"Gnd"

for the 2 leds:
pinA0---1Kresistor, or less---GreenLed---pin "Gnd
pinA1---1Kresistor, or less---RedLed------pin "Gnd"
(+ of the led on the resistor side)

Thank you so much. i've been involved in electronics for a long time, but that was back in the days of discrete componentry!
This whole Arduino thing is very new to me, but imreally looking forward to it! many thanks

That’s a tough puzzle.

How about a string of LEDs that light up in order if the player is getting the order of the N switches correct?

So the first wrong toggle lights a red lamp briefly, either one associated with it or the honest one in a row we’ve been getting to go green. Then turns off all LEDs.

This is easier but still a challenge. It can be solved with patience and note taking and fewer than 12000 attempts.

There are other games that could be implemented with ten switches and ten LEDs.

I’d also go with a smaller number like 7 switches and 7 LEDs. Plenty IMO.

Sounds like fun already.

a7

Hello
I´ve used the lunch break to code simple example has to be modified and extended to your needs.

/* BLOCK COMMENT
  ATTENTION: This Sketch contains elements of C++.
  https://www.learncpp.com/cpp-tutorial/
  https://forum.arduino.cc/t/detecting-switches-in-order/933035/4
*/
#define ProjectName "Detecting switches in order"
// HARDWARE AND TIMER SETTINGS
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
constexpr byte toggleSwitchOne {A0};      // portPin o---|button|---GND
constexpr byte toggleSwitchTwo {A1};      // portPin o---|button|---GND
constexpr byte LedRedPin {3};             // portPin o---|220|---|LED|---GND

// CONSTANT DEFINITION
enum {Red};
constexpr byte Leds[] {LedRedPin};

// VARIABLE DECLARATION AND DEFINITION
struct KEY {
  byte pin;
  bool keyState;
} keys[] {
  {toggleSwitchOne, HIGH},
  {toggleSwitchTwo, HIGH},
};
constexpr unsigned int sizeOfKey {sizeof(keys) / sizeof(keys[0])};

bool getKeyNow() {
  int check_ = 0;
  for (auto &key : keys) if (!digitalRead(key.pin) == key.keyState) check_++;
  return (check_ == sizeOfKey);
}
// -------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial.println(F("."));
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  pinMode (LED_BUILTIN, OUTPUT);  // used as heartbeat indicator
  for (auto key : keys) pinMode(key.pin, INPUT_PULLUP);
  for (auto Led_ : Leds) pinMode(Led_, OUTPUT);
}
void loop () {
  digitalWrite(LED_BUILTIN, (millis() / 500) % 2);
  digitalWrite(Leds[Red], getKeyNow());
}

Have a nice day and enjoy coding in C++.

That's it!
the code is here. Thanks for the other friends who gave their ideas.
You have to copy the code in a new IDE sketch, compile it, and send it to the arduino; do you know how to do that?

At reset, the red and green LEDs blink for 2 seconds.
The first set is: (pin) 2,3,4,5,6,7,8,9,10,11. If the continuation is successful (the green LED is always on) at the end green and red flash. Easy! If there is a mistake, the red LED flashes, and you go to the second game.

In the second game, the sequence is : 5,6,10,2,4,8,7,11,3,9
Ahahaha, more difficult!

(I did not test with toggle, but with keys. it should be fine)


/* ************************************************************************
 
for arduino uno, mini, nano
10 keys (or toggle) to be activated in the right order

wiring :

pin  0 (RX reserved)  
pin  1 (TX reserved)
pin  2 -> toggle  2         // pin2-------1K resistor------toggle or key-------pin"Gnd"
pin  3 -> toggle  3         // pin3-------1K resistor------toggle or key-------pin"Gnd"
pin  4 -> toggle  4         // and so on 
pin  5 -> toggle  5         // toggle are named 2,3,4..11 as the pin number, for simplicity
pin  6 -> toggle  6 
pin  7 -> toggle  7 
pin  8 -> toggle  8 
pin  9 -> toggle  9 
pin 10 -> toggle 10
pin 11 -> toggle 11

pin A0 -> green Led        // pinA0-----1K resistor or less----- + led - -------pin"Gnd"
pin A1 -> red   Led        // pinA1-----1K resistor or less----- + led - -------pin"Gnd"

*/


 #define NbreToggle 10                                       // 

 word    PPImuSta ;                                          // reflète l'état instantané des touches
 word    PPImuMem;                                           //               (stockage intermédiaire)
 word    PPImuFro;                                           // reflète l'appui (front) d'une touche
 word    PPImuRel;                                           // reflète le relachement  d'une touche

 int     toggleProgress;                                     // 1,2,3,4...10   1,2,3,4..10  and so on

 word    blinkLedRed;
 word    blinkLedGreen;
 byte    imagePORTC = B00000001;

 unsigned long previousmillisKeys;                           // debounce timer
 unsigned long previousmillisLeds;                           // led duration timer 
 

 const word    TabReset [] = {                                                                // easy game,
                    0b0000000000000100,                      // expected pressure  1 =  pin2  // in the order,
                    0b0000000000001000,                      // expected pressure  2 =  pin3
                    0b0000000000010000,                      // expected pressure  3 =  pin4  // run once  
                    0b0000000000100000,                      // expected pressure  4 =  pin5  // before real game below  
                    0b0000000001000000,                      // expected pressure  5 =  pin6  
                    0b0000000010000000,                      // expected pressure  6 =  pin7  
                    0b0000000100000000,                      // expected pressure  7 =  pin8  
                    0b0000001000000000,                      // expected pressure  8 =  pin9  
                    0b0000010000000000,                      // expected pressure  9 = pin10  
                    0b0000100000000000                       // expected pressure 10 = pin11 
              };   //, *tab1;
                

const word    TabTwo [] = {                                                                   // real game,
                    0b0000000000100000,                      // expected pressure 1  =  pin5  // not in the order
                    0b0000000001000000,                      // expected pressure 2  =  pin6  
                    0b0000010000000000,                      // expected pressure 3  =  pin10  
                    0b0000000000000100,                      // expected pressure 4  =  pin2
                    0b0000000000010000,                      // expected pressure 5  =  pin4  
                    0b0000000100000000,                      // expected pressure 6  =  pin8  
                    0b0000000010000000,                      // expected pressure 7  =  pin7  
                    0b0000100000000000,                      // expected pressure 8  =  pin11 
                    0b0000000000001000,                      // expected pressure 9  =  pin3 
                    0b0000001000000000                       // expected pressure 10 =  pin9  
              };   //, *tab2;                
 
const word *tab;




void setup() {                                               // INITIALIZATION CODE 
  DDRC  |= B00000011;                                        // A0, A1 as output       (pinA0...pinA1) 
  PORTD |= B11111100;                                        // PC7..PC2 with pullups  (pin7....pin2)
  PORTB |= B00001111;                                        // PB3..PB0 with pullups  (pin11...pin8)  
  Serial.begin(9600);                                        // or 115200 (9600 is the default serial-monitor)
  Serial.println(" **** Hi **** ");                          // Hi
  blinkLedGreen = blinkLedRed = 80;                          // both Leds on reset
  tab = TabReset;                                            // at reset, game is: 1,2,3,4,5,6,7,8,9,10 (TabReset)
}



void loop() {                                                // MAIN CODE 
  SeeIfToggleOrKeysPressed();                                // pressure or change has been applied ?
  blinkLeds();                                               // Leds treatment
}  

                                          

                                                             // VARIOUS FUNCTIONS CODES
void SeeIfToggleOrKeysPressed(void) { //-------------------- // detection 1..16 keys :
  if (millis() - previousmillisKeys > 20) {                  // xx ms delay for debounce, usually 10 or 20 (ms)
    previousmillisKeys = millis();                           //
  
    word iii = ((~PIND & 0xFC) | ((~PINB & 0x0F) << 8));     // PORTD and B reading
    word jjj = PPImuSta;                                     // (debounce, rise, release and state detection)
    PPImuSta = iii & PPImuMem;                               // stable (subsiste pendant tout le temps de l'appui)
    PPImuMem = iii;                                          //                  (besoin interne, non exploitable)
    PPImuFro = (jjj ^ PPImuSta) & PPImuSta;                  // fugitif (front montant)   
    PPImuRel = (iii ^ jjj) & jjj;                            // fugitif : front descendant (relachement touche)  

    //-------------------------------------------------------// keys treatment :
    if (PPImuFro) OneInputPinJustChanged(PPImuFro);          // one key just pressed (or toggle just changed)
  }                                                          //
}                                                            //




void OneInputPinJustChanged(word Fro) { 
  toggleProgress++;                                          // increment counter, first or next expected pressure
  if (toggleProgress <= NbreToggle)  {                       // 
    if (PPImuFro == tab[toggleProgress-1]) blinkLedGreen = 20; // good choice for this one...
    else {blinkLedRed = 60; SetNewGame();}                   // error !
  } else SetNewGame();

  if (toggleProgress == NbreToggle) {                        //
    blinkLedGreen = blinkLedRed = 80;                        // MATCHED 10 KEYS !
    SetNewGame();                                            //
  }  
}


  
  
void blinkLeds(void) {      
  if (millis() - previousmillisLeds > 40) {                  // 
    previousmillisLeds = millis();   
  
    if (blinkLedGreen) blinkLedGreen--;
    if (blinkLedRed)   blinkLedRed--;    
  
    imagePORTC ^= B00000011;
    if (!blinkLedGreen) imagePORTC &= B11111110;                           // Green OFF
    if (!blinkLedRed)   imagePORTC &= B11111101;                           // Red OFF
    if (!blinkLedGreen && (toggleProgress > 0)) imagePORTC |= B00000001;   // leave Green Led ON when success in progress
    if (!blinkLedGreen && !blinkLedRed && !toggleProgress) imagePORTC &= B11111100;   // Green/Red OFF at NewGame
    PORTC = imagePORTC & B00000011;
  }
}    
   
   
   
   
void SetNewGame(void) {   
  tab = TabTwo;                                              // after 1st simple game at reset), the 2nd table is used
  toggleProgress = 0;                                        // come back to the begin
                                                             // (not here)  PORTC &= B11111100;
} 
  
  

  

Thank you SO much. I will give it a go, then get stuck into this Arduino stuff properly. It is encouraging to know there are so many helpful people out there. Once again, than you to all!

The code in #9 is functional. I tried slide switches (OK), but pushbuttons don't need to be reset.

The timing of the blinx was not very visible in the wokwi, so I changed them a bit.



Perhaps as a keypad entry to the nuclear facility, this is a good puzzle. For having any fun at all, or exercising or challenging problem-solving and puzzle chops, it is ridiculously too hard.

Unless the challenge involves finding the cheat sheet which is somewhere hidden.

I understand the code is intended as a point of departure. As such, it is decidedly not noob friendly. I think it would be hard for someone not able to simply read the code and understand it fully to add things like better feedback, stronger rewards &c.

It does come very close to the OP's specification. I read it to mean that no light comes on until the ten switches or pushbuttons have been pressed or toggled, then you get a red or green LED. That mkes it even more ridiculously too hard.

a7

Funny! I hadn't thought about the wokwi simulation. The blinking is very slow in simulation, but this tool is interesting, maybe especially for what is not related to real time.

I had started to follow philport's indications, turning on the leds at the end, as he specified, but it was too frustrating. I think he expressed quickly and roughly his objective, without seeing this detail of operation.

(anyway, it's easy to do, just put a ;// to the line:

if (PPImuFro == tab[toggleProgress-1]) ;// blinkLedGreen = 20;

I'll change some variable names in the code, to make it more readable.

I'm not sure the code is not noob friendly; I'm using a bit of combinatorial logic in the organization of the code, which seems unusual, but in fact it's easier to read and intervene. You just have to get familiar with Boolean logic, it's easy, I started learning it at 14, and I liked it a lot! only 4 simple functions to know, it's within my reach.

Indeed, the game is quickly complicated. Maybe philport thought of something to adapt on the 10 toggles? you can put a mask on the toggles, with symbols, a story, and play to find the logical sequence. Very good for the logic and the memory!

I will add to the code the possibility to choose the number of toggles to find, between 1 and 10. This will make the game easier. I'll try it, without doing something too complicated.

Ypu obvsly associate with smarter noobs than I do.

When I read a little toy program meant for the Aduino, and in particular noobs, I don't like to see a loop() that immediately passes off control to other functions. I can read and find where the significant things happen, but it is a slog. Not helped with binary and direct port manipulation. Not helped with functions that take and ignore an argument. &c. Not helped with odd identifiers left over from some other project.

I think in a tiny program, there ought to be something one can easily read and such a thing would be a guide not only to understanding the rest of the program, but to developing it as well. I look at the loop() function, then the setup(). At that point, I should have a good idea of what (else) to look for.

Below is just my loop(), use your imagination and the code rights itself. The process is manifest.

unsigned char nIn = 0;    // number of correct steps taken sofa

void loop() {
  unsigned char pKey = scanKeys();

  if (pKey == NOKEY)
    return;

// presst a key, all key are valid so
  if (pKey == combo[nIn]) {
    goodFlash();
    nIn++;

    if (nIn == SEVEN) {
      reward();
      newCombo();
      reset();
    }
  }
  else {
    badFlash();
    reset();
  }
}

I had more trouble than fun getting the guts of this to work than I care to admit, but this loop() is where I started, back of the envelop, and where it ended up.

I would use the same technique as you for doling out the LEDs or other reward/punishment feedback; we might both lose a slew of noobs doing that.

I did realize finally that your code does do the incremental solving feedback, so it is not dreadfully ridiculuously hard. In my thousands of hours playing games on computers variously I have never seen a guess-it-one-at-a-time with a length of 10. That is painful and way beyond the point of learning how to solve one kind of puzzle. Four is too few, but I am too lazy to see where I have to start using pencil and paper to keep track of the progress.

And too lazy to even wire up switches in wokwi. :expressionless:

a7

Waiting for philport to come back, alto777 : the corrected version, for you, as you said above.
(I play with message, and have deleted the previous one, I am noob with messages...)

 word   KeyDown, KeyStat, kkk;                                  // keys, switches, toggles, reeds, bare wires
 word   LedGreen=80,LedRed=80;                                  // blink duration (green on pin A0, red on A1)
 byte   imagePORTC= B00000001;                                  // outputs A0,A1 (01 de-synchronise red-green)
 byte   GoodKey;                                                // 1,2,3,4...10      1,2,3,4..10  and so on
 word   set [] = {4,8,16,32,64,128,256,512,1024,2048};          // easy game : pins 2,3,4,5,6,7,8,9,10,11
                
void setup() {                                                  // INITIALIZATION CODE 
  DDRC  |= B00000011;                                           // A0, A1 as output       (pinA0...pinA1) 
  PORTD |= B11111100;                                           // PC7..PC2 with pullups  (pin7....pin2)
  PORTB |= B00001111;                                           // PB3..PB0 with pullups  (pin11...pin8)  
}

void loop() {                                                   // MAIN CODE 
  delay(40);                                                    //
  
  word iii = ((~PIND & 0xFC) | ((~PINB & 0x0F) << 8)); //-------// PORTD AND B (input pins) READING BLOC
  word jjj = KeyStat;                                           // debounce, state, and front detections
  KeyStat  = iii & kkk;                                         // while key is maintained pressed
  KeyDown  = (jjj ^ KeyStat) & KeyStat;                         // when key is just pressed down
  kkk      = iii;                                               // key configuration stored for next use

  if (KeyDown) { //---------------------------------------------// KEY PRESSED TREATMENT BLOC ----------
    GoodKey++;                                                  // first/next key and value to compare
    if (KeyDown == set[GoodKey-1]) LedGreen = 20;               // good choice for this one...green led
    else {LedRed = 60; GoodKey = 0;}                            // error ! red led and start a new game
    if (GoodKey >= 10) {LedGreen=LedRed=80;GoodKey=0;}          // green/red led blinks together, bingo! 
  }                         

  if (LedGreen) LedGreen--; //----------------------------------// BLINKING LEDS TREATMENT BLOC --------
  if (LedRed)   LedRed--;                                       // blinking in progress 
  if (1 == 1)                 imagePORTC ^= B00000011;          // it blinks here, all the time
  if (!LedGreen)              imagePORTC &= B11111110;          // Green OFF at the end of the term
  if (!LedRed)                imagePORTC &= B11111101;          // Red OFF   at the end of the term
  if (!LedGreen && GoodKey)   imagePORTC |= B00000001;          // maintains Green ON while success
  PORTC =                     imagePORTC &  B00000011;          // set pins A0 A1 (LED green & red)
}