Reading 8 buttons and 1 joystick Arduino to max
What will be the best way of doing the above and receiving the data inside max?
here is my Arduino code:
const int numButtons = 8;
const int buttonPins[numButtons] = {2, 3, 4, 5, 6, 7, 8, 9};
const int joyX = A0;
const int joyY = A1;
const int joyButton = 10;
const unsigned long debounceDelay = 20; // Debounce time in ms
unsigned long lastDebounceTime[numButtons] = {0};
int buttonStates[numButtons] = {1}; // Default HIGH (INPUT_PULLUP)
int lastButtonStates[numButtons] = {1};
unsigned long lastReadTime = 0;
const unsigned long readInterval = 50; // Read every 50ms
void setup() {
Serial.begin(115200);
for (int i = 0; i < numButtons; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode(joyButton, INPUT_PULLUP);
}
void loop() {
unsigned long currentMillis = millis();
// Read Buttons with Debounce
for (int i = 0; i < numButtons; i++) {
int reading = digitalRead(buttonPins[i]);
if (reading != lastButtonStates[i]) {
lastDebounceTime[i] = currentMillis;
}
if ((currentMillis - lastDebounceTime[i]) > debounceDelay) {
buttonStates[i] = reading;
}
lastButtonStates[i] = reading;
}
// Read and Send Data at Interval
if (currentMillis - lastReadTime >= readInterval) {
lastReadTime = currentMillis;
// Read Joystick
int xVal = analogRead(joyX);
int yVal = analogRead(joyY);
int joyBtnState = digitalRead(joyButton);
// Send data to Max/MSP
Serial.print("B "); // Identifier for buttons
for (int i = 0; i < numButtons; i++) {
Serial.print(buttonStates[i]);
Serial.print(" ");
}
Serial.print("J "); // Identifier for Joystick
Serial.print(xVal);
Serial.print(" ");
Serial.print(yVal);
Serial.print(" ");
Serial.println(joyBtnState);
}
}
how can I unpack this data inside max?
print ID for each element followed by it's value.
for example if you use for loop to read 8 buttons, then first
print i , then space followed by button readout.
then use route 0 1 2 3 4 5 6 7 in max to output 8 buttons
for (int i = 0; i < 8; i++) {
Serial.print(i); Serial.print(" "); Serial.println(buttonStates[i]);
}
print ID for each element followed by it's value.
ID you mean for each button? for example A B C D E F G H
and for each pot: X and Y ?
I should use the built in pull-up resistor for buttons right?
and if debounce is needed - better doing it inside Arduino then in Max?
Here is my Arduino latest code:
const int numButtons = 8;
const int buttonPins[numButtons] = {2, 3, 4, 5, 6, 7, 8, 9};
const char buttonIDs[numButtons] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
const int joyX = A0;
const int joyY = A1;
const int joyButton = 10;
const unsigned long debounceDelay = 20; // Debounce time in ms
unsigned long lastDebounceTime[numButtons] = {0};
int buttonStates[numButtons]; // Default HIGH (INPUT_PULLUP)
int lastButtonStates[numButtons];
unsigned long lastReadTime = 0;
const unsigned long readInterval = 50; // Read every 50ms
// Joystick filtering
const int threshold = 10; // Minimum change required to send new data
int lastXVal = 0;
int lastYVal = 0;
int lastJoyBtnState = HIGH;
void setup() {
Serial.begin(115200);
for (int i = 0; i < numButtons; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
buttonStates[i] = HIGH; // Initialize to HIGH
lastButtonStates[i] = HIGH;
}
pinMode(joyButton, INPUT_PULLUP);
lastXVal = analogRead(joyX);
lastYVal = analogRead(joyY);
lastJoyBtnState = digitalRead(joyButton);
}
void loop() {
unsigned long currentMillis = millis();
// Read Buttons with Debounce
for (int i = 0; i < numButtons; i++) {
int reading = digitalRead(buttonPins[i]);
if (reading != lastButtonStates[i]) {
lastDebounceTime[i] = currentMillis;
}
if ((currentMillis - lastDebounceTime[i]) > debounceDelay) {
if (buttonStates[i] != reading) {
buttonStates[i] = reading;
Serial.print(buttonIDs[i]); // Print button ID
Serial.print(" ");
Serial.println(!reading); // Print 1 for pressed, 0 for released
}
}
lastButtonStates[i] = reading;
}
// Read Joystick
int xVal = analogRead(joyX);
int yVal = analogRead(joyY);
int joyBtnState = digitalRead(joyButton);
// Check if joystick values changed beyond threshold
if (abs(xVal - lastXVal) > threshold) {
Serial.print("X ");
Serial.println(xVal);
lastXVal = xVal;
}
if (abs(yVal - lastYVal) > threshold) {
Serial.print("Y ");
Serial.println(yVal);
lastYVal = yVal;
}
if (joyBtnState != lastJoyBtnState) {
Serial.print("J ");
Serial.println(!joyBtnState);
lastJoyBtnState = joyBtnState;
}
}
I print each value independetly.
For some reason I don't get the data inside max. Here is my patch:
I try to add the dtr 1 message to the serial object and this not solved the problem.
I'm using Arduino Uno, Max 8.6.2, Mac M1 Pro Sonoma 14.5
edit: I needed to close arduino, now everything is working as expected
with IDs I meant count which you have anyway when scanning buttons.
I posted it in my first reply.
You add so many unneeded declarations .