Arduino & max to trigger sound

Connor Smith's icon

Hello i made a post before but was not very clear, I am trying to create an arduino project that where when a sensor is hit it starts an led flashing and sends a signal to max to play audio and mute the tracks uneeded,
the arduino code and max patch are below:

test1.maxpat
text/plain 22.15 KB


#define LEDPIN1 2 // status LED pin1
#define LEDPIN2 3 // status LED pin2
#define LEDPIN3 4 // status LED pin3
#define PIEZOTHRESHOLD 5 // analog threshold for piezo sensing
#define PADNUM 3 // number of pads using Analog In 0-2

int val[] = {0, 0, 0}; // Values of each piezo
bool isHigh[] = {false, false, false};
bool isHighPrev[] = {false, false, false};
int midiNotes[] = {35, 38, 42}; // Bass, snare and hihat
bool state0, state1, state2, state3; // Logic to track game state
int lastPressed;
unsigned long baseTime, elapsedTime;

void setup() {
pinMode(LEDPIN1, OUTPUT);
pinMode(LEDPIN2, OUTPUT);
pinMode(LEDPIN3, OUTPUT);
Serial.begin(9600); // set serial output rate
state0 = true;
state1 = false;
state2 = false;
state3 = false;
lastPressed = 5;
}

void loop() {

// A&I Coursework 2
// Scott Anderson
// The aim of this game is to light all LEDs by pressing the corresponding piezo sensor
// The player has 10 seconds after each succesfull press to activate another LED or the
// game wil be reset.

// At every cycle, check if any piezo sensors have been pressed
// Loop through each piezo analogue output and store data
for(int i = 0; i < PADNUM; i++) {
val[i] = analogRead(i);
isHigh[i] = false;
if( val[i] >= PIEZOTHRESHOLD ) {
isHigh[i] = true;
}
}

// The game can be in one of four states:
// state0 - no LEDs are alight
// state1 - one LED is lit
// state2 - two LEDs are lit
// state3 - all three LEDs are lit

// Check to see which state we are in
if(state0 == true){
// Have any of the piezo sensors been pressed?
bool pressed = false;
for(int i = 0; i < PADNUM; i++) {
if( isHigh[i] == true){
pressed = true;
lastPressed = i;
if(i==0) digitalWrite(LEDPIN1,HIGH);
if(i==1) digitalWrite(LEDPIN2,HIGH);
if(i==2) digitalWrite(LEDPIN3,HIGH);
}
}

if(pressed == true){
// At least one of the sensors has been activated. Need to move to state1 and begin the
// timer. First, set state0 to false
state0 = false;
// Now move to state1
state1 = true;
// Begin timer. Set baseline elapsed time
baseTime = millis();
// Send command to Max8 to play first sound
Serial.println(111);
}
return;
}

if(state1 == true){
// We can only be in state1 for 10 seconds before going back to state0. Check this first
if(millis() - baseTime > 10000){
state1 = false;
state0 = true;
digitalWrite(LEDPIN1,LOW);
digitalWrite(LEDPIN2,LOW);
digitalWrite(LEDPIN3,LOW);
}
// Have any additional piezo sensors been pressed?
bool pressed = false;
for(int i = 0; i < PADNUM; i++) {
if( isHigh[i] == true){
// Need to check this is a different sensor
if(i != lastPressed){
pressed = true;
lastPressed = i;
if(i==0) digitalWrite(LEDPIN1,HIGH);
if(i==1) digitalWrite(LEDPIN2,HIGH);
if(i==2) digitalWrite(LEDPIN3,HIGH);
}
}
}

if(pressed == true){
// At least one of the sensors has been activated. Need to move to state2
state1 = false;
state2 = true;
// Begin timer. Set baseline elapsed time
baseTime = millis();
// Send command to Max8 to play second sound
Serial.println(222);
}
return;
}

if(state2 == true){
// We can only be in state1 for 5 seconds before going back to state0. Check this first
if(millis() - baseTime > 5000){
state2 = false;
state0 = true;
digitalWrite(LEDPIN1,LOW);
digitalWrite(LEDPIN2,LOW);
digitalWrite(LEDPIN3,LOW);
}
// Have any additional piezo sensors been pressed?
bool pressed = false;
for(int i = 0; i < PADNUM; i++) {
if( isHigh[i] == true){
// Need to check this is the last sensor
if(i != lastPressed){
pressed = true;
if(i==0) digitalWrite(LEDPIN1,HIGH);
if(i==1) digitalWrite(LEDPIN2,HIGH);
if(i==2) digitalWrite(LEDPIN3,HIGH);
}
}
}

if(pressed == true){
// At least one of the sensors has been activated. Need to move to state3
state2 = false;
state3 = true;
// Begin timer. Set baseline elapsed time
baseTime = millis();
// Send command to Max8 to play third sound
Serial.println(333);
}
return;
}

if(state3 == true){
// SUCCESS - You've won the game...
digitalWrite(LEDPIN1,HIGH);
digitalWrite(LEDPIN2,HIGH);
digitalWrite(LEDPIN3,HIGH);
delay(500);
digitalWrite(LEDPIN1,LOW);
digitalWrite(LEDPIN2,LOW);
digitalWrite(LEDPIN3,LOW);
delay(500);

// After flashing for 5 seconds, go back to state0
if(millis() - baseTime > 5000){
state2 = false;
state0 = true;
digitalWrite(LEDPIN1,LOW);
digitalWrite(LEDPIN2,LOW);
digitalWrite(LEDPIN3,LOW);
}
}
}

TFL's icon

What is your question?

Some insights:
- Instead of attaching the patch as a .maxpat, select all the relevant objects in your patch, go to Edit -> Copy compressed, then paste the result in your post on the forum.

- No need to "open sound.wav" every time you want to play it. Do it just once when the patch opens (using [loadbang] or [loadmess]). Then you only need to send 1 or 0 to the [sfplay~] to make it play/stop your sound.

- One audio output [ezdac~] is enough
- [if $i1 == 333 then 1 else 0] can be replaced by a simple [== 333]

Also, as we cannot replicate your Arduino setup, can you tell us what you get from the [serial] object?