Can't figure out why mux is outputting alternating values

I am testing out this multiplexer code I wrote. If I manually set the selector pins to Y0, Y1, Y2, etc… each individual button functions properly. However, when I use the PORTB code to cycle through the selector pins, my serial monitor just returns a constant stream of 0,1,0,1,0,1, at the speed of the debounce, which I believe is just the alternating Serial.println of my if statements. I am guessing it has something to do with the “i” variables not properly storing values as intended, but I am not sure.

This is a Leonardo board, 16 channel mux, selector pins on 8-11, digital input on pin 7.
thanks

#include <frequencyToNote.h>
#include <MIDIUSB.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).
// controlChange(0, 10, 65); // Set the value of controller 10 on channel 0 to 65

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

#define numPots 0
#define numButtons 4

int MP1_PIN1[4] = {0,0,1,1};
int MP1_PIN2[4] = {0,1,0,1};
int MP1_PIN3[4] = {0,0,1,0};
int MP1_PIN4[4] = {0,0,0,0};

//0,0,0,0 is button 1
//0,1,0,0 is button 2
//1,0,1,0 is button 3
//1,0,0,0 is button 4
//1,1,0,0 is also button 4?


int lastButtonState[numButtons];
int lastPotValue[numPots];

unsigned long lastDebounce = 0;

int potValue[numPots];
int buttonValue[numButtons];

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(7, INPUT_PULLUP);

  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);


}

void loop() {
  
  unsigned long currentTime = millis();


  for (int i=0; i<numButtons;i++){
    PORTB = (PORTB & B00001111) | (i<<4);
//    digitalWrite(8, MP1_PIN1[i]);
//    digitalWrite(9, MP1_PIN2[i]);
//    digitalWrite(10, MP1_PIN3[i]);
//    digitalWrite(11, MP1_PIN4[i]);
    
    buttonValue[i] = digitalRead(7);
    if (buttonValue[i] == LOW && currentTime - lastDebounce > 500){
      if (lastButtonState[i] == 0){
        controlChange(1,51+i,127);
        MidiUSB.flush();
        Serial.println(lastButtonState[i]);
        lastButtonState[i] = 1;
        lastDebounce = currentTime;
        
      }
      else {
        controlChange(1,51+i,0);
        MidiUSB.flush();
        Serial.println(lastButtonState[i]);
        lastButtonState[i] = 0;
        lastDebounce = currentTime;
      }
    }
  }
}

I thought pins 8, 9, 10, and 11 were the BOTTOM four bits of PORTB. You are putting 'i' in the TOP four bits pf PORTB.

Perhaps you meant:

    PORTB = (PORTB & B11110000) | i;

It looks like something is strange in your wiring. Why are you using addresses 0, 2, 5, and 3 to read buttons 0, 1, 2, and 3?!? Are the buttons wired to the wrong inputs or are the address pins wired to the wrong Arduino pins?!? Or both?

johnwasser: I thought pins 8, 9, 10, and 11 were the BOTTOM four bits of PORTB.

On an Uno, yes, but

Aimbit: This is a Leonardo board,

oqibidipo:
On an Uno, yes, but

This is a Leonardo board,

Oops. I missed that.
Yes, on the Leonardo, Pins 8, 9, 10, and 11 are PB4, PB5, PB6, and PB7 so the line was correct as written:

    PORTB = (PORTB & B00001111) | (i<<4);

That still leaves the question of the strange address order.

johnwasser:
Oops. I missed that.
Yes, on the Leonardo, Pins 8, 9, 10, and 11 are PB4, PB5, PB6, and PB7 so the line was correct as written:

    PORTB = (PORTB & B00001111) | (i<<4);

That still leaves the question of the strange address order.

Ok, maybe I am misunderstanding how that for loop works. Someone actually gave it to me and said its preferable to other methods. But it may not be activating the ports I am intending it to. I am using an HP4067 multiplex breakout board (not HC), but it appears to just be a variant of the HC model.
This is what PORTB puts out when I have the buttons set to 4

1
17
33
49

I’m not sure how to interpret what this means :slight_smile:

Aimbit: This is what PORTB puts out when I have the buttons set to 4

1 17 33 49

I'm not sure how to interpret what this means :)

You could display them in binary or hex to make it easier to see what each bit is doing:

| decimal | binary | hexadecimal | | - | - | - | | 1 | 0000 0001 | 0x01 | | 17 | 0001 0001 | 0x11 | | 33 | 0010 0001 | 0x21 | | 49 | 0011 0001 | 0x31 |

The low four bits are whatever is happening on PB3, PB2, PB1, and PB0. The high four bits are the ones you set to the values of 'i': 0, 1, 2, and 3.

what is PORTB in the above code? where was it declared?

krisferrari: what is PORTB in the above code? where was it declared?

PORTB is a reference to the output register of Port B. Bits written to the PORTB register shows up as logic levels on the PORTB pins. You need to find a chart that shows which Arduino pin corresponds to each bit in each PORT.

Port B also has a Data Direction Register (DDRB) that is used to set the pin to INPUT or OUTPUT (via the pinMode() function), and a Port INput register (PINB) which you read to get the logic levels at the pins.

All are defined deep in the Arduino.h file that is automatically included at the top of your sketch.