Hi everyone,
I am brand new to arduino and quite frankly have no clue what im doing.
Over this last week I have built a midi controller with 16 buttons, 3 potentiometers and a screen.
All seemed to be well, but for some reason the second button in the layout (using pin 3) when either pressed multiple times or when other buttons are pressed and then that button is pressed, stops working entirely and in my DAW (Abelton) the thing I have pressed stay iluminated like its being pressed and not let go, but still all the other buttons work.
There must be something stupid I must be missing here, any and all help is greatly appreciated.
#define ATMEGA32U4 1
#define USING_BUTTONS 1
#define USING_POTENTIOMETERS 1
#ifdef ATMEGA328
#include <MIDI.h>
#elif ATMEGA32U4
#include "MIDIUSB.h"
#endif
#ifdef USING_POTENTIOMETERS
#include <ResponsiveAnalogRead.h>
#endif
#ifdef USING_BUTTONS
const int N_BUTTONS = 16;
const int BUTTON_ARDUINO_PIN[16] = {A5, A4, A3, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
int buttonCState[N_BUTTONS] = {};
int buttonPState[N_BUTTONS] = {};
byte pin13index = 12;
unsigned long lastDebounceTime[N_BUTTONS] = { 0 };
unsigned long debounceDelay = 50;
#endif
#ifdef USING_POTENTIOMETERS
const int N_POTS = 3;
const int POT_ARDUINO_PIN[3] = {A0, A1, A2};
int potCState[N_POTS] = { 0 };
int potPState[N_POTS] = { 0 };
int potVar = 0;
int midiCState[N_POTS] = { 0 };
int midiPState[N_POTS] = { 0 };
const int TIMEOUT = 300;
const int varThreshold = 20;
boolean potMoving = true;
unsigned long PTime[N_POTS] = { 0 };
unsigned long timer[N_POTS] = { 0 };
int reading = 0;
float snapMultiplier = 0.01;
ResponsiveAnalogRead responsivePot[N_POTS] = {};
int potMin = 10;
int potMax = 1023;
#endif
byte midiCh = 0;
byte note = 36;
byte cc = 1;
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SSD1306_I2C_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
#ifdef USING_BUTTONS
for (int i = 0; i < N_BUTTONS; i++) {
pinMode(BUTTON_ARDUINO_PIN[i], INPUT_PULLUP);
}
#ifdef pin13
pinMode(BUTTON_ARDUINO_PIN[pin13index], INPUT);
#endif
#endif
#ifdef USING_POTENTIOMETERS
for (int i = 0; i < N_POTS; i++) {
responsivePot[i] = ResponsiveAnalogRead(0, true, snapMultiplier);
responsivePot[i].setAnalogResolution(1023);
}
#endif
if (!display.begin(SSD1306_I2C_ADDRESS, OLED_RESET)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 5);
display.println("CAMDEN");
display.setCursor(0, 18);
display.println("TOWN");
display.display();
}
void loop() {
#ifdef USING_BUTTONS
buttons();
#endif
#ifdef USING_POTENTIOMETERS
potentiometers();
#endif
}
#ifdef USING_BUTTONS
void buttons() {
for (int i = 0; i < N_BUTTONS; i++) {
buttonCState[i] = digitalRead(BUTTON_ARDUINO_PIN[i]);
#ifdef pin13
if (i == pin13index) {
buttonCState[i] = !buttonCState[i];
}
#endif
if ((millis() - lastDebounceTime[i]) > debounceDelay) {
if (buttonPState[i] != buttonCState[i]) {
lastDebounceTime[i] = millis();
if (buttonCState[i] == LOW) {
#ifdef ATMEGA328
MIDI.sendNoteOn(note + i, 127, midiCh);
#elif ATMEGA32U4
noteOn(midiCh, note + i, 127);
MidiUSB.flush();
#elif TEENSY
usbMIDI.sendNoteOn(note + i, 127, midiCh);
#elif DEBUG
Serial.print(i);
Serial.println(": button on");
#endif
} else {
#ifdef ATMEGA328
MIDI.sendNoteOn(note + i, 0, midiCh);
#elif ATMEGA32U4
noteOn(midiCh, note + i, 0);
MidiUSB.flush();
#elif TEENSY
usbMIDI.sendNoteOn(note + i, 0, midiCh);
#elif DEBUG
Serial.print(i);
Serial.println(": button off");
#endif
}
buttonPState[i] = buttonCState[i];
}
}
}
}
#endif
#ifdef USING_POTENTIOMETERS
void potentiometers() {
for (int i = 0; i < N_POTS; i++) {
reading = analogRead(POT_ARDUINO_PIN[i]);
responsivePot[i].update(reading);
potCState[i] = responsivePot[i].getValue();
potCState[i] = analogRead(POT_ARDUINO_PIN[i]);
midiCState[i] = map(potCState[i], potMin, potMax, 0, 127);
if (midiCState[i] < 0) {
midiCState[i] = 0;
}
if (midiCState[i] > 127) {
midiCState[i] = 0;
}
potVar = abs(potCState[i] - potPState[i]);
if (potVar > varThreshold) {
PTime[i] = millis();
}
timer[i] = millis() - PTime[i];
if (timer[i] < TIMEOUT) {
potMoving = true;
} else {
potMoving = false;
}
if (potMoving == true) {
if (midiPState[i] != midiCState[i]) {
#ifdef ATMEGA328
MIDI.sendControlChange(cc + i, midiCState[i], midiCh);
#elif ATMEGA32U4
controlChange(midiCh, cc + i, midiCState[i]);
MidiUSB.flush();
#elif TEENSY
usbMIDI.sendControlChange(cc + i, midiCState[i], midiCh);
#elif DEBUG
Serial.print("Pot: ");
Serial.print(i);
Serial.print(" ");
Serial.println(midiCState[i]);
#endif
potPState[i] = potCState[i];
midiPState[i] = midiCState[i];
}
}
}
}
#endif
#ifdef ATMEGA32U4
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);
}
void controlChange(byte channel, byte control, byte value) {
midiEventPacket_t event = { 0x0B, 0xB0 | channel, control, value };
MidiUSB.sendMIDI(event);
}
#endif