Multiplexer implementation

Hi everyone, I have a working Auction code that I need to improve from the actual 2 buttons and leds up to 10 of both. I'll use two 16 channels Multiplexers, model CD74HC4067 (one as Multiplexer for the buttons and one as Demultiplexer for the leds ). I tried o look for tutorials but didn't work.
Any kind of help would be appreciated :slight_smile: )
just remember that I already put randomly all the buttons and leds pins, excpet for the first two that i used to try the code with my Arduino Uno.

const int BUZZER = 5;
//------------------------------------------------
//LED ADDRESSING

const int LED_A = 13;
const int LED_B = 8;
const int LED_C = 20;
const int LED_D = 21;
const int LED_E = 22;
const int LED_F = 23;
const int LED_G = 24;
const int LED_H = 25;
const int LED_I = 26;
const int LED_L = 27;
//------------------------------------------------
// BUTTONS ADDRESSING
const int BUTTON_A = 2;
const int BUTTON_B = 3;
const int BUTTON_C = 28;
const int BUTTON_D = 29;
const int BUTTON_E = 30;
const int BUTTON_F = 31;
const int BUTTON_G = 32;
const int BUTTON_H = 33;
const int BUTTON_I = 34;
const int BUTTON_L = 35;
//--------------------------------------------------
//BIDDER NAMES

String but1 = "Pino";
String but2 = "Manuel";
String but3 = "Luca";
String but4 = "Giuseppe";
String but5 = "Simone";
String but6 = "Danilo";
String but7 = "Daniele";
String but8 = "Mario";
String but9 = "Pino";
String but10 = "Manuel";
String winner;

int pinButton[] = { BUTTON_A, BUTTON_B, BUTTON_C, BUTTON_D, BUTTON_E, BUTTON_F, BUTTON_G, BUTTON_G, BUTTON_I, BUTTON_L };

boolean AuctionFinish = false;
boolean running = false;
static unsigned long lastAuctionTime;
int count = 0;

int lastBidder;

void isr_A() { if(lastBidder != BUTTON_A) { startAuction(BUTTON_A); } }
void isr_B() { if(lastBidder != BUTTON_B) { startAuction(BUTTON_B); } }
void isr_C() { if(lastBidder != BUTTON_C) { startAuction(BUTTON_C); } }
void isr_D() { if(lastBidder != BUTTON_D) { startAuction(BUTTON_D); } }
void isr_E() { if(lastBidder != BUTTON_E) { startAuction(BUTTON_E); } }
void isr_F() { if(lastBidder != BUTTON_F) { startAuction(BUTTON_F); } }
void isr_G() { if(lastBidder != BUTTON_G) { startAuction(BUTTON_G); } }
void isr_H() { if(lastBidder != BUTTON_H) { startAuction(BUTTON_H); } }
void isr_I() { if(lastBidder != BUTTON_I) { startAuction(BUTTON_I); } }
void isr_L() { if(lastBidder != BUTTON_L) { startAuction(BUTTON_L); } }

void deactivateButtons() {
    attachInterrupt(digitalPinToInterrupt(BUTTON_A), isr_A, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_B), isr_B, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_C), isr_C, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_D), isr_D, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_E), isr_E, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_F), isr_F, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_G), isr_G, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_H), isr_H, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_I), isr_I, LOW);
    attachInterrupt(digitalPinToInterrupt(BUTTON_L), isr_L, LOW);
}

void activateButtons() {
    attachInterrupt(digitalPinToInterrupt(BUTTON_A), isr_A, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_B), isr_B, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_C), isr_C, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_D), isr_D, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_E), isr_E, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_F), isr_F, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_G), isr_G, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_H), isr_H, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_I), isr_I, FALLING);
    attachInterrupt(digitalPinToInterrupt(BUTTON_L), isr_L, FALLING);
}

void setup() {
    Serial.begin(9600);

    pinMode(BUZZER, OUTPUT);
  
    pinMode(LED_A, OUTPUT);
    pinMode(LED_B, OUTPUT);
    pinMode(LED_C, OUTPUT);
    pinMode(LED_D, OUTPUT);
    pinMode(LED_E, OUTPUT);
    pinMode(LED_F, OUTPUT);
    pinMode(LED_G, OUTPUT);
    pinMode(LED_H, OUTPUT);
    pinMode(LED_I, OUTPUT);
    pinMode(LED_L, OUTPUT);

    pinMode(BUTTON_A, INPUT_PULLUP);
    pinMode(BUTTON_B, INPUT_PULLUP);
    pinMode(BUTTON_C, INPUT_PULLUP);
    pinMode(BUTTON_D, INPUT_PULLUP);
    pinMode(BUTTON_E, INPUT_PULLUP);
    pinMode(BUTTON_F, INPUT_PULLUP);
    pinMode(BUTTON_G, INPUT_PULLUP);
    pinMode(BUTTON_H, INPUT_PULLUP);
    pinMode(BUTTON_I, INPUT_PULLUP);
    pinMode(BUTTON_L, INPUT_PULLUP);

    activateButtons();
    deactivateLed();
  
  Serial.println("--- System ready to start an auction ---");
}

void deactivateLed() {
    digitalWrite(LED_A, LOW);
    digitalWrite(LED_B, LOW);
    digitalWrite(LED_C, LOW);
    digitalWrite(LED_D, LOW);
    digitalWrite(LED_E, LOW);
    digitalWrite(LED_F, LOW);
    digitalWrite(LED_G, LOW);
    digitalWrite(LED_H, LOW);
    digitalWrite(LED_I, LOW);
    digitalWrite(LED_L, LOW);
}

int searchButton(int button) {
    int pos = -1;
    for (int i = 0; i < sizeof(pinButton); i++) {
        if (button == pinButton[i]) {
            pos = i;
            break;
        }
    }
    return pos;
}

void loop() {
    if ((running) && (millis() - lastAuctionTime >= 25)) {
        static unsigned long lastBuzzerTime = 0;

        noTone(BUZZER);
        if (millis() - lastBuzzerTime >= 1000) {  
            tone(BUZZER, 500, 800); 
            count++;
            Serial.println(count);
            lastBuzzerTime = millis();
        }
        if (count == 3) {
            running = false;
            AuctionFinish = true;
            deactivateButtons();
        }

        lastAuctionTime = millis();
    } else if (AuctionFinish) {
    unsigned long LoopStartTime = millis();
      Serial.println(String("---  The Auction winner is:  ") + winner + String("!  ---"));
      AuctionFinish = false;
    Serial.println("---  Auction completed ---");
      delay(6000);
      activateButtons();
        lastBidder = -1;
      deactivateLed();
    Serial.println("\n---  It is possible to start an Autcion  ---");
      tone(BUZZER, 1500, 150);
        delay(200);
        tone(BUZZER, 1500, 150);
        delay(200);
        tone(BUZZER, 1500, 150);
        delay(200);
        tone(BUZZER, 1500, 150);
        delay(200);
        tone(BUZZER, 1500, 150);
    }
}

void startAuction(int button) {
    deactivateLed();
    running = true;
    winner = "";
    lastAuctionTime = 0;
    count = 0;
  
  switch (searchButton(button)) {
    case 0:
      winner = but1;
      lastBidder = BUTTON_A;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_A, HIGH);
      break;
    case 1:
      winner = but2;
      lastBidder = BUTTON_B;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_B, HIGH);
      break;
    case 2:
      winner = but3;
      lastBidder = BUTTON_C;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_C, HIGH);
      break;
    case 3:
      winner = but4;
      lastBidder = BUTTON_D;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_D, HIGH);
      break;
    case 4:
      winner = but5;
      lastBidder = BUTTON_E;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_E, HIGH);
      break;
    case 5:
      winner = but6;
      lastBidder = BUTTON_F;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_F, HIGH);
      break;
    case 6:
      winner = but7;
      lastBidder = BUTTON_G;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_G, HIGH);
      break;
    case 7:
      winner = but8;
      lastBidder = BUTTON_H;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_A, HIGH);
      break;
    case 8:
      winner = but9;
      lastBidder = BUTTON_I;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_I, HIGH);
      break;
    case 9:
      winner = but10;
      lastBidder = BUTTON_L;
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED_L, HIGH);
      break;
    default:
      break;
  }
}

Your plan to use interrupts will run counter to a plan to use multiplexers.

So I am not reading your code, what can never be a good point of departure, and instead ask you to

Describe the auction system like you were telling a friend about this cool auction device and how it works. Not in programming terms, just a regular story about seeing a cool auction device being used.

Then we can talk about how to go about building such a thing for yourself. Out of what you imagine it should be, first.

HTH

a7

I'm a rookie on Arduino and trust your words, but(just for information, maybe can be helpful) some tutorials that I saw on Youtube say that in order to use interrupts I have to do something with EN pin.
Anyway, the Auction system works as follows:
When Arduino turns on, the first button that gets pressed starts the buzzer that beeps three short times and a longer one to signal the Auction's finish. Meanwhile, the other button can restart the beeping(as a typical auction should be),and so on, untill the buzzer beeps three times. There are also some leds linked to each button, to tell who is winning the auction.
After 6 seconds from the Auction's end, five beeps signal that is possible to start a new auction.
There are also some serial monitor messages that i put in the code to verify that the phases of the auction worked as they should, i'd like to show them on a display, but it's not a priority.
Actually, I couldn't code a "buttons' block" between the auction's end and the new auction availability, bht it's not a real problem.

Then leave interrupts alone for a while.

tutorials that I saw on Youtube

There is no vetting or editorial moderation on YT. So it attracts a lot of posers seeking attention. Not a good place to learn, and there are other sites that are equally popular and equally useless for learning.

That code almost makes me laugh, except that I'm afraid a lot of people won't get the joke.

Ok I'll accept jokes for this time :slightly_smiling_face:, but can you help with my problem too? Do you have any suggestion?

Poll the buttons, like all the 1,000,000 other sketches that read buttons do. You don't have to look far, there are example sketches for reading buttons that ship with the IDE.

A strange thing - I see no reference to multiplexers in the code, and no mention of how you would use them, in the text explanation you posted.

Using a mux as a LED driver is particularly weird. Normally a shift register or better yet, a LED controller IC would be used. A mux has no latch so you can only drive one LED at a time.

There are no mention in the code, because that is working, but I don't know how to put in the few multiplexer's stuff i learned with tutorials.
Anyway, leds are not a big deal, i have 13 digital output on my Arduino board, I could put them there.
The main problem is how to read 10 buttons with MUX

You succeeded in that by expansion. I am guessing the reason you are stuck, you don't really have any clue how the code works. Or, maybe, how a mux works. Am I right?

Please post a system diagram. It can be crude at this point. Just to get on track.

That isn't a problem. It's a mistake. Like, how to make brownies with an espresso machine, or something...

I've read this Datasheet for reference.
CD74HC4067.pdf (144,0 KB)

We all know the IC. It's not the right tool for this job. Trust me. I've been doing this for a long time...

1 Like

Ok, so do you think that the possible solutions are shift registers(actually my first option, shame on me)?

OK, a dim picture is slowly emerging. I have glanced at your code and you seem to have picked up some useable ideas about the logic and flow.

It is always good to have copious serial printing so you can see without trouble where your code is at and what some variables values might be, so good start there.

But you really should learn more about basic programming. Anytime that cut, paste and edit is the way you are crafting your code is a certain sign that you have yet to discover the true magic of programming, that is the exploitation of patterns. The above case, for example, to an experience reader of noob code (!), boils away to

 case X:
      winner = but X + 1
      lastBidder = BUTTON X + 1
      Serial.println(String("Actual winner: ") + winner);
      digitalWrite(LED 10 - X, HIGH);
      break;

which please understand is no longer valid code, but it is the pattern. Of every case...

Which means you need to slow your roll and learn about arrays, at least, and a few other basic elements of programming in any language, before you choke on what you've bitten off.

A few hours off to the side will equip you to tackle this in a smarter way and will stand you in good stead for all future programming endeavors.

I know it's hard to delay gratification, but srsly you will look back one day and laugh as we all do looking back at code we wrote 1, 5 or 10 years ago. Programming can be a constant source of new things to learn, and your projects will be more fun when you can cut them like butter.

I still don't get the way the auction works, or how the lights associated with the buttons are to function, or why in the middle of an auction you worry already about the next auction.

Auctions to me involve bidding amounts, seeing if someone outbids you and so forth. There;s also the so-called Dutch auction, is that what you are going for? Your description is so poor of detail I cannot even tell.

But getting the story straight and specifying in what may seem is excruciating detail is essential, before a single line of code is written.

HTH

a7

Please post a basic diagram so we know what ins and outs and other stuff is involved.

I'll post it in a few hours, now it's not possible.
Thanks for your help.

1 Like

Basically, me and my friends will be seated at a table shouting the amount of our bids(exactly like real auctions), so i don't need to put an amount printing code.
Leds are linked to the buttons just to remember ti the temporary winner that he is actually winning the auction.
Plus, wunner's led remains on , so everyone can be sure of who won the Auction.
As an example of how the code actuallt works, let's take Buttons A & B, that are paired with Leds A & B.
Mine is A, yours is B.
I start an auction and press the button, my led turns on and the buzzer starts beeping up to three times, unless you oress your button, turn my led off, turn your on, and restart the beeping countdown.
That's it, I only need to do it on 10 buttone instead of 2.
The other stuff is just accessories.

But... now you are suggesting the buttons aren't located in the same device? So there is some hand held unit (on a wire?)... in that case, a drawing of the physical layout would be helpful as well. Digital signals require special care and conditioning, in order to run on long lengths of wire. If you have 10 of these things, you have quite an octopus of wiring to deal with. It would behoove you to explain all that clearly.

Please understand, you have been mulling over your concept and have the details in your head, but we can't see in there. :slight_smile:

The idea is to put the arduino in a box that will be at the center of the table.
Then i'll put buttons and leds in separated boxes(something like tv shows buttons) that will be linked to Arduino by wires that will pass in tubes.

That would be a segue to a failure using typical Arduino experimenter bunged up wiring. So you should consider it an additional challenge.

I certainly have to learn and would love to but the problem is that for this project I have no much time, I need it to be ready by September 1st.
Anyway, are you 100% sure that I cannot use MUX with interrupts? If so, I'll have to buy shift registers too.

About of this code, I guess that I have to put it in a for cycle to make it pass through all the Buttons and Leds, or the Switch function already does it?