Paso 13: Código Arduino, parte 1
Definir algunos pines de Arduino:
digitales pins
const int LEDPIN=13; // light up when audio detected const int PIN_STROBE=4; // spectrum shield const int PIN_RESET=5; // spectrum shield const int PIN_MOTOR_L=3; //PWM to motor open mouth const int PIN_MOTOR_R=6; //PWM to motor close mouth const int PIN_MOTOR_SLEEP=7; //sleep fxn on motor board const int PIN_MOTOR_STALL=8; //stall warning on motor board
//analog pins const int PIN_LEFT=0; // L analog from spectrum shield const int PIN_RIGHT=1; // R analog from spectrum shield const int PIN_MOTOR_POT=3; //analog potentiometer on motor
Resulta que realmente no necesita "cerrar" la boca con el motor-la caja de cambios parece relajar a la posición cerrada por sí mismo. Esto facilita control de movimiento incluso puesto que sólo tenemos que "abrir" la boca, es decir, correr el motor en una dirección. Todavía, podría así cable para arriba y programa para él por si acaso.
Tenemos que crear dos matrices para mantener la señal de cada uno de siete bandas en los canales de la L y R
// spectrum shield band arrays int left[7]; int right[7];
Establecer el mínimo y máximo para el movimiento de la mandíbula:
int minRotation = 400; //approximate reading when mouth closed int maxRotation = 600; //approximate reading when mouth open
Inicializar:
void setup() {<br> pinMode(LEDPIN, OUTPUT); // LED //initialize spectrum board related pins pinMode(PIN_RESET, OUTPUT); // reset pinMode(PIN_STROBE, OUTPUT); // strobe digitalWrite(PIN_RESET,LOW); // reset low digitalWrite(PIN_STROBE,HIGH); //pin 5 is RESET on the shield }
Para leer el analizador de espectro, uso llamar a los siguientes:
void readMSGEQ7()<br>{ //reset the data digitalWrite(PIN_RESET, HIGH); digitalWrite(PIN_RESET, LOW); //loop thru all 7 bands int sumRight = 0; int sumLeft = 0; for(int band=0; band < 7; band++) { digitalWrite(PIN_STROBE,LOW); // go to the next band delayMicroseconds(20); //gather some data left[band] = analogRead(PIN_LEFT); // store left band reading //right[band] = left[band]; //use this only for MONO! right[band] = analogRead(PIN_RIGHT); // store right band reading digitalWrite(PIN_STROBE,HIGH); // reset the strobe pin sumRight = sumRight+right[band]; // get the sum from all bands sumLeft = sumLeft+left[band]; // get the sum from all bands if(left[band] > 100 || right[band] > 100) { digitalWrite(LEDPIN,HIGH); // sound detected } else { digitalWrite(LEDPIN,LOW); // reset low } } }
Esta rutina crea un retraso de 7 x 20 mseg (millisec 140). Acaba de decir. Cuando los motores en marcha, siempre es bueno tener retrasos duros en mente (ya que usted no tendrá ningún control del motor mientras el retardo de activa, podría ser correr a toda velocidad).
Después de llamar a readMSGEQ7, podemos fijar el motor a una posición basada en la señal de audio. En este ejemplo utilizo el total de la señal de todas las bandas de 7, pero sólo el canal izquierdo (para que el movimiento de la boca no se verán afectado por audio de canal derecho). La máxima señal de cada canal es de 1024, así que la suma máxima teórica es de 7 canales x 1024 = 7168. Prácticamente el máximo no conseguirá más de 5000-6000. Podría obtener una señal de entrada media y establecer min/max de eso, pero yo prefiero algo más sencillo. Primero limitará a la suma de "sumLeft"
if (sumLeft > 1024) {sumLeft = 1024}; //constrain to 1024 max
Y luego sumLeft al min y max de la posición de la mandíbula. Simple.
int mouthPosition = map(sumLeft, 0, 1024, minRotation, maxRotation);
Establecer algunos límites para la posición de la boca como destino de alta y destino baja (esto evita que el motor intentando llegar a la posición exacta y permite en cambio una gama (+ /-"posError").
targetH = target_mouthPosition + posError;<br>targetL = target_mouthPosition - posError;