I have 12 buttons but only 8 of them are working

Hi

Sorry if this is something very simple, but I’m new to Arduino and coding.

I’m trying the MIDI capabilities of the Sparkfun Pro Micro, and I’m making a controller for Ableton Live.
I’m using the same code as the MIDI Device Tutorial:
MIDI Device Tutorial

I want to use 12 buttons , but for some reason, only 8 of them work. My guess is that it has something to do with uint8_t, but to be honest I have no idea.

Any guidance would be appreciated.

Here’s my code:

/*
   This examples shows how to make a simple seven keys MIDI keyboard with volume control

   Created: 4/10/2015
   Author: Arturo Guadalupi <a.guadalupi@arduino.cc>
   
   http://www.arduino.cc/en/Tutorial/MidiDevice
*/

#include "MIDIUSB.h"
#include "PitchToNote.h"
#define NUM_BUTTONS  12

const uint8_t button1 = 2;
const uint8_t button2 = 3;
const uint8_t button3 = 4;
const uint8_t button4 = 5;
const uint8_t button5 = 6;
const uint8_t button6 = 7;
const uint8_t button7 = 8;
const uint8_t button8 = 9;
const uint8_t button9 = 10;
const uint8_t button10 = 16;
const uint8_t button11 = 14;
const uint8_t button12 = 15;


const uint8_t buttons[NUM_BUTTONS] = {button1, button2, button3, button4, button5, button6, button7, button8, button9, button10, button11, button12};
const byte notePitches[NUM_BUTTONS] = {C3, D3, E3, F3, G3, A3, B3, C4, D4, E4, F4, G4};

uint8_t notesTime[NUM_BUTTONS];
uint8_t pressedButtons = 0x00;
uint8_t previousButtons = 0x00;
uint8_t intensity;

void setup() {
  for (int i = 0; i < NUM_BUTTONS; i++)
    pinMode(buttons[i], INPUT_PULLUP);
}


void loop() {
  readButtons();
  readIntensity();
  playNotes();
}

// 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).

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

void readButtons()
{
  for (int i = 0; i < NUM_BUTTONS; i++)
  {
    if (digitalRead(buttons[i]) == LOW)
    {
      bitWrite(pressedButtons, i, 1);
      delay(50);
    }
    else
      bitWrite(pressedButtons, i, 0);
  }
}

void readIntensity()
{
  int val = 1023;
  intensity = (uint8_t) (map(val, 0, 1023, 0, 127));
}

void playNotes()
{
  for (int i = 0; i < NUM_BUTTONS; i++)
  {
    if (bitRead(pressedButtons, i) != bitRead(previousButtons, i))
    {
      if (bitRead(pressedButtons, i))
      {
        bitWrite(previousButtons, i , 1);
        noteOn(0, notePitches[i], intensity);
        MidiUSB.flush();
      }
      else
      {
        bitWrite(previousButtons, i , 0);
        noteOff(0, notePitches[i], 0);
        MidiUSB.flush();
      }
    }
  }
}

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

Try changing the data type of pressedButtons and previousButtons to uint16_t (unsigned int data type in Arduino) so they can hold more than 8 bits.

groundFungus: Try changing the data type of pressedButtons and previousButtons to uint16_t (unsigned int data type in Arduino) so they can hold more than 8 bits.

That did it!. It was so simple... I still have a lot to learn, thanks for the help.

bitWrite(pressedButtons, i, 1);

Here is (one of) your problems. Trying to write more than 8 bits in an 8-bit int. Change the size of these variables to fit what you try to write in them.

Your button debouncing is pretty crude (you’re just using a delay between digitalReads). Also, the intensity function you’re using doesn’t do anything, so you can just delete it and make ‘intensity’ a constant value of 127.

If you’re interested in a high level library that takes care of button debounce etc., you can take a look at my MIDI Controller library.

For example, your code would look like this:

#include <MIDI_Controller.h> // Include the library
#include <pitchToNote.h>

const uint8_t velocity = 0b1111111; // Maximum velocity (0b1111111 = 0x7F = 127)
const uint8_t channel = 1; // MIDI channel 1

// Create an array of new instances of the class 'Digital', called 'buttons', 
// on pins 2, 3, ... 10, 16, 14 and 15, that send MIDI messages with notes 
// C3, D3, ... G4 on MIDI channel 1, with maximum velocity (127)
Digital buttons[] = {
  { 2, pitchC3, channel, velocity }, // button connected to pin 2, sends MIDI note C3 on channel 1 with velocity 127
  { 3, pitchD3, channel, velocity },
  { 4, pitchE3, channel, velocity },
  { 5, pitchF3, channel, velocity },
  { 6, pitchG3, channel, velocity },
  { 7, pitchA3, channel, velocity },
  { 8, pitchB3, channel, velocity },
  { 9, pitchC4, channel, velocity },
  {10, pitchD4, channel, velocity },
  {16, pitchE4, channel, velocity },
  {14, pitchF4, channel, velocity },
  {15, pitchG4, channel, velocity }
};

void setup() {}

void loop() {  // Refresh the buttons (check whether a button's state has changed since last time, if so, send it over MIDI)
  MIDI_Controller.refresh();
}

Pieter

PieterP: For example, your code would look like this:

[...]
void setup() {}

void loop() {  // Refresh the buttons (check whether a button's state has changed since last time, if so, send it over MIDI)   MIDI_Controller.refresh(); }

Now where's the fun in that?!