Stap 13: Arduino code, deel 1
Enkele PIN op de Arduino definiëren:
digitale pinnen
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
Het blijkt dat je echt niet hoeft te "sluiten" de mond met de motor-de versnellingsbak blijkt te ontspannen naar de gesloten positie door zelf. Dit maakt controle van verplaatsingen nog gemakkelijker omdat we slechts hoeven te "openen" van de mond, dat wil zeggen de motor uitvoeren in één richting. Toch kan ook draad op opwaarts en programma voor het geval.
We moeten twee matrices te houden van het signaal van elk van de zeven bands op zowel de L als de R-kanalen instellen
// spectrum shield band arrays int left[7]; int right[7];
Stel de min en max voor het kaak-verkeer:
int minRotation = 400; //approximate reading when mouth closed int maxRotation = 600; //approximate reading when mouth open
Initialiseren:
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 }
Om te lezen het spectrum-analyzer, gebruik de volgende functie aanroepen:
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 } } }
Deze routine maakt een 7 x 20 msec (140 millisec) vertraging. Enkel zeggend. Bij het uitvoeren van motoren, is het altijd goed hard vertragingen in gedachten te houden (want u geen controle van de motor terwijl actief hebben zal, dat het kan worden uitgevoerd op volle snelheid vertraging).
Na het aanroepen van readMSGEQ7, kunnen we de motor ingesteld op een standpunt op basis van het audiosignaal. In dit voorbeeld gebruik ik de totale signaal uit alle 7 bands, maar alleen het linker kanaal (dus de beweging van de mond zal niet worden beïnvloed door audio op het juiste kanaal). Het max signaal van elk kanaal is 1024, dus de theoretische max som 7 kanalen x 1024 = 7168 is. De max krijgt praktisch niet meer dan 5000-6000. Je kon krijgen een gemiddelde ingangssignaal en instellen van min/max van dat, maar ik heb liever iets eenvoudiger. Eerst zal ik beperken de som "sumLeft"
if (sumLeft > 1024) {sumLeft = 1024}; //constrain to 1024 max
En dan ik aan de min en max van de positie van de kaak sumLeft toewijzen. Eenvoudig.
int mouthPosition = map(sumLeft, 0, 1024, minRotation, maxRotation);
Sommige grenzen voor de positie van de mond als doel hoog ingesteld en gericht op lage (dit voorkomt dat de motor probeert te krijgen tot de exacte positie en in plaats daarvan staat een bereik (+/-"posError").
targetH = target_mouthPosition + posError;<br>targetL = target_mouthPosition - posError;