Paso 2: Código de Arduino
Aquí está el código. La interrupción define una bandera (pbPress) y contador (menuState) entre 0 - 4. Utilizando mientras (pbPress == 0) {}; Me quedo en uno de los siguientes elementos del menú; Apagado, Audio, Flash rápido, Flash lento y por. Cada vez que se presiona el interruptor momentáneo se dispara una interrupción, el menú se avanza un paso y se establece el indicador pbPress a 1 que se rompe la rutina de las existentes en bucle y reinicia la instrucción switch avanzando al caso siguiente con el siguiente tiempo del lazo. Cuando el menú está en Audio, el microcontrolador muestrea la señal de audio en el pin A0 y calcula si la señal es mayor que uno de los tres valores en la matriz de corte []. Estos valores se determinaron empíricamente por ensayo y error con diferentes niveles de sonido ambiental. El elemento de corte [] que se utiliza depende de la posición del interruptor de S2_AUDIO_LEVEL correspondiente a 0 - bajo, alto - MED y 2 - 1. Confusamente, la baja corresponde a la alta sensibilidad (sonidos bajos activan el alambre en) y así sucesivamente.
int triacGatePin = 5; // drive el inverter thru optoisolator controlling triacint monitorPin = 0; //from microphone //for audio processing int digInputA = 3; //pins to check for audio switch position int digInputB = 4; //pins to check for audio switch position int cutOff[] = {70, 110, 260}; //value to compare peaktopeak with const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz) unsigned int sample; unsigned int signalMax, peakToPeak = 0; unsigned int signalMin = 1024; int menuState = 0; // variable to be updated by the interrupt int pbPress = 0; int triacState = LOW; long previousMillis = 0; long flashInterval = 0; //variables to keep track of the timing of recent interrupts volatile unsigned long button_time = 0; volatile unsigned long last_button_time = 0; void setup() { pinMode(triacGatePin, OUTPUT); pinMode(digInputA, INPUT); pinMode(digInputB, INPUT); //enable interrupt 0 (pin 2) which is connected to a button //jump to the increment function on falling edge attachInterrupt(0, increment, FALLING); //turn on interrupt for pin 2 } void loop() { if (pbPress == 1){ pbPress = 0; switch (menuState){ case 0: //off while(pbPress == 0){ //wait for next pbPress delay(10); } break; case 1: //audio while(pbPress == 0){ int audioLevel = getSwitchState(); // collect data for 50 mS unsigned long startMillis= millis(); // Start of sample window while (millis() - startMillis < sampleWindow) { sample = analogRead(monitorPin); if (sample < 1024) // toss out spurious readings { if (sample > signalMax) { signalMax = sample; // save just the max levels } else if (sample < signalMin) { signalMin = sample; // save just the min levels } } } peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude if (peakToPeak > cutOff[audioLevel]){ //turn on led digitalWrite(triacGatePin, HIGH); }else{ digitalWrite(triacGatePin, LOW); } resetValues(); } break; case 2: //switch fast bink flashInterval = 120; while(pbPress == 0){ unsigned long currentMillis = millis(); if(currentMillis - previousMillis > flashInterval) { // save the last time you blinked the LED previousMillis = currentMillis; // if the LED is off turn it on and vice-versa: if (triacState == LOW){ triacState = HIGH; }else{ triacState = LOW; } // set the LED with the triacState of the variable: digitalWrite(triacGatePin, triacState); } } break; case 3: //switch slow blink flashInterval = 700; while(pbPress == 0){ unsigned long currentMillis = millis(); if(currentMillis - previousMillis > flashInterval) { // save the last time you blinked the LED previousMillis = currentMillis; // if the LED is off turn it on and vice-versa: if (triacState == LOW){ triacState = HIGH; }else{ triacState = LOW; } // set the LED with the triacState of the variable: digitalWrite(triacGatePin, triacState); } } break; case 4: //switch on triacState = HIGH; digitalWrite(triacGatePin, triacState); while(pbPress == 0){ //wait for pbPress delay(10); } triacState = LOW; digitalWrite(triacGatePin, triacState); break; } } delay(100); } // Interrupt service routine for interrupt 0 void increment() { button_time = millis(); //check to see if increment() was called in the last 250 milliseconds if (button_time - last_button_time > 250) { pbPress = 1; if (menuState == 4){ menuState = 0; }else{ menuState += 1; } last_button_time = button_time; } } //for audio processing void resetValues(){ signalMax = 0; signalMin = 1024; peakToPeak = 0; } int getSwitchState(){ int pin2 = digitalRead(digInputA); int pin3 = digitalRead(digInputB); if (pin2 == 0){ return 1; //Medium volume } if(pin3 == 0){ return 2; //High volume; }else{ return 0; //Low volume; } }