Stap 2: De code uploaden naar de Arduino
Nu heb je de onderstaande code uploaden naar je Arduino. U kunt ook de Arduino schets downloaden via de link onderaan de pagina. Voordat u de code uploaden, moet u goed de BitVoicer Server bibliotheken installeren in de Arduino IDE (een .zip bibliotheek importeren).
#include <BVSP.h>#include <BVSMic.h> #include <BVSSpeaker.h> #include <DAC.h>// Defines the Arduino pin that will be used to capture audio #define BVSM_AUDIO_INPUT 7// Defines the LED pins #define RED_LED_PIN 6 #define YELLOW_LED_PIN 9 #define GREEN_LED_PIN 10// Defines the constants that will be passed as parameters to // the BVSP.begin function const unsigned long STATUS_REQUEST_TIMEOUT = 3000; const unsigned long STATUS_REQUEST_INTERVAL = 4000;// Defines the size of the mic audio buffer const int MIC_BUFFER_SIZE = 64;// Defines the size of the speaker audio buffer const int SPEAKER_BUFFER_SIZE = 128;// Defines the size of the receive buffer const int RECEIVE_BUFFER_SIZE = 2;// Initializes a new global instance of the BVSP class BVSP bvsp = BVSP();// Initializes a new global instance of the BVSMic class BVSMic bvsm = BVSMic();// Initializes a new global instance of the BVSSpeaker class BVSSpeaker bvss = BVSSpeaker();// Creates a buffer that will be used to read recorded samples // from the BVSMic class byte micBuffer[MIC_BUFFER_SIZE];// Creates a buffer that will be used to write audio samples // into the BVSSpeaker class byte speakerBuffer[SPEAKER_BUFFER_SIZE];// Creates a buffer that will be used to read the commands sent // from BitVoicer Server. // Byte 0 = pin number // Byte 1 = pin value byte receiveBuffer[RECEIVE_BUFFER_SIZE];// These variables are used to control when to play // "LED Notes". These notes will be played along with // the song streamed from BitVoicer Server. bool playLEDNotes = false; unsigned int playStartTime = 0;void setup() { // Sets up the pin modes pinMode(RED_LED_PIN, OUTPUT); pinMode(YELLOW_LED_PIN, OUTPUT); pinMode(GREEN_LED_PIN, OUTPUT); // Sets the initial state of all LEDs digitalWrite(RED_LED_PIN, LOW); digitalWrite(YELLOW_LED_PIN, LOW); digitalWrite(GREEN_LED_PIN, LOW); // Starts serial communication at 115200 bps Serial.begin(115200); // Sets the Arduino serial port that will be used for // communication, how long it will take before a status request // times out and how often status requests should be sent to // BitVoicer Server. bvsp.begin(Serial, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL); // Defines the function that will handle the frameReceived // event bvsp.frameReceived = BVSP_frameReceived; // Sets the function that will handle the modeChanged // event bvsp.modeChanged = BVSP_modeChanged; // Sets the function that will handle the streamReceived // event bvsp.streamReceived = BVSP_streamReceived; // Prepares the BVSMic class timer bvsm.begin(); // Sets the DAC that will be used by the BVSSpeaker class bvss.begin(DAC); }void loop() { // Checks if the status request interval has elapsed and if it // has, sends a status request to BitVoicer Server bvsp.keepAlive(); // Checks if there is data available at the serial port buffer // and processes its content according to the specifications // of the BitVoicer Server Protocol bvsp.receive(); // Checks if there is one SRE available. If there is one, // starts recording. if (bvsp.isSREAvailable()) { // If the BVSMic class is not recording, sets up the audio // input and starts recording if (!bvsm.isRecording) { bvsm.setAudioInput(BVSM_AUDIO_INPUT, DEFAULT); bvsm.startRecording(); } // Checks if the BVSMic class has available samples if (bvsm.available) { // Makes sure the inbound mode is STREAM_MODE before // transmitting the stream if (bvsp.inboundMode == FRAMED_MODE) bvsp.setInboundMode(STREAM_MODE); // Reads the audio samples from the BVSMic class int bytesRead = bvsm.read(micBuffer, MIC_BUFFER_SIZE); // Sends the audio stream to BitVoicer Server bvsp.sendStream(micBuffer, bytesRead); } } else { // No SRE is available. If the BVSMic class is recording, // stops it. if (bvsm.isRecording) bvsm.stopRecording(); } // Plays all audio samples available in the BVSSpeaker class // internal buffer. These samples are written in the // BVSP_streamReceived event handler. If no samples are // available in the internal buffer, nothing is played. bvss.play(); // If playLEDNotes has been set to true, // plays the "LED notes" along with the music. if (playLEDNotes) playNextLEDNote(); }// Handles the frameReceived event void BVSP_frameReceived(byte dataType, int payloadSize) { // Checks if the received frame contains binary data // 0x07 = Binary data (byte array) if (dataType == DATA_TYPE_BINARY) { // If 2 bytes were received, process the command. if (bvsp.getReceivedBytes(receiveBuffer, RECEIVE_BUFFER_SIZE) == RECEIVE_BUFFER_SIZE) { analogWrite(receiveBuffer[0], receiveBuffer[1]); } } // Checks if the received frame contains byte data type // 0x01 = Byte data type else if (dataType == DATA_TYPE_BYTE) { // If the received byte value is 255, sets playLEDNotes // and marks the current time. if (bvsp.getReceivedByte() == 255) { playLEDNotes = true; playStartTime = millis(); } } }// Handles the modeChanged event void BVSP_modeChanged() { // If the outboundMode (Server --> Device) has turned to // FRAMED_MODE, no audio stream is supposed to be received. // Tells the BVSSpeaker class to finish playing when its // internal buffer become empty. if (bvsp.outboundMode == FRAMED_MODE) bvss.finishPlaying(); } // Handles the streamReceived event void BVSP_streamReceived(int size) { // Gets the received stream from the BVSP class int bytesRead = bvsp.getReceivedStream(speakerBuffer, SPEAKER_BUFFER_SIZE); // Enqueues the received stream to play bvss.enqueue(speakerBuffer, bytesRead); }// Lights up the appropriate LED based on the time // the command to start playing LED notes was received. // The timings used here are syncronized with the music. void playNextLEDNote() { // Gets the elapsed time between playStartTime and the // current time. unsigned long elapsed = millis() - playStartTime; // Turns off all LEDs allLEDsOff(); // The last note has been played. // Turns off the last LED and stops playing LED notes. if (elapsed >= 11500) { analogWrite(RED_LED_PIN, 0); playLEDNotes = false; } else if (elapsed >= 9900) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 9370) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 8900) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 8610) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 8230) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 7970) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 7470) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 6760) analogWrite(GREEN_LED_PIN, 255); // E note else if (elapsed >= 6350) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 5880) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 5560) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 5180) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 4890) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 4420) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 3810) analogWrite(GREEN_LED_PIN, 255); // E note else if (elapsed >= 3420) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 2930) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 2560) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 2200) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 1930) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 1470) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 1000) analogWrite(GREEN_LED_PIN, 255); // E note }// Turns off all LEDs. void allLEDsOff() { analogWrite(RED_LED_PIN, 0); analogWrite(YELLOW_LED_PIN, 0); analogWrite(GREEN_LED_PIN, 0); }
Deze sketch heeft zeven grote delen:
- Bibliotheek verwijzingen en variabele verklaring: de eerste vier regels bevatten verwijzingen naar de BVSP, BVSMic, BVSSpeaker en DAC bibliotheken. Deze bibliotheken worden geleverd door BitSophia en kunnen worden gevonden in de BitVoicer Server-installatiemap. De DAC-bibliotheek wordt opgenomen automatisch als u een verwijzing naar de BVSSpeaker-bibliotheek toevoegen. De andere lijnen verklaar constanten en variabelen in de sketch gebruikt. De klasse BVSP wordt gebruikt om te communiceren met de Server van de BitVoicer, de klasse BVSMic wordt gebruikt om te vangen en opslaan van audio-samples en de klasse BVSSpeaker wordt gebruikt voor het reproduceren van audio met behulp van de DUE- DAC.
- Setup-functie: deze functie worden de volgende acties uitgevoerd: stelt de pin-modi en hun oorspronkelijke toestand; initialiseert de seriële communicatie; en de klassen BVSP, BVSMic en BVSSpeaker geïnitialiseerd. Ook daarin "gebeurtenis-handlers" (zij zijn eigenlijk functioneren pointers) voor de gebeurtenissen van het frameReceived, modeChanged en streamReceived van de BVSP klasse.
- Lus functie: deze functie voert vijf belangrijke acties: verzoekt status info naar de server (keepAlive() functie); controleert of de server geen gegevens heeft verzonden en verwerkt de ontvangen gegevens (receive() functie); Hiermee bepaalt u de opname en het verzenden van audio-streams (isSREAvailable(), startRecording(), stopRecording() en sendStream() functies); speelt de audio-samples in de wachtrij in de BVSSpeaker-klasse (play() functie); en wenst dat het playNextLEDNote() functioneren die bepaalt hoe de LEDs moeten knipperen nadat de opdracht playLEDNotes wordt ontvangen.
- BVSP_frameReceived functie: deze functie wordt aangeroepen telkens wanneer de receive() functie identificeert die een volledige frame is ontvangen. Hier voer ik de opdrachten uit vanaf BitVoicer Server verzonden. Opdrachten waarmee de LEDs 2 bytes bevat. De eerste byte geeft de pin en de tweede byte geeft de waarde van de pin. Ik gebruik de functie analogWrite() om de juiste waarde ingesteld op de pin. Ik controleer ook als de playLEDNotes-opdracht, die van Byte type is, heeft ontvangen. Wanneer het heeft ontvangen, troep mij playLEDNotes true en aangeven van de huidige tijd. Ditmaal worden door de functie playNextLEDNote gebruikt voor het synchroniseren van de LED's met het nummer.
- BVSP_modeChanged functie: deze functie wordt aangeroepen telkens wanneer de receive() functie een moduswijziging in de uitgaande richting identificeert (Server--> Arduino). WOW!!! Wat is dat?! BitVoicer Server kunt verzenden de Arduino ingelijste gegevens of audiostreams . Voordat de mededeling van de ene modus naar de andere gaat, stuurt BitVoicer Server een signaal. De klasse BVSP identificeert dit signaal en verhoogt de modeChanged-gebeurtenis. In de BVSP_modeChanged functie, als ik bemerk dat de mededeling gaat van streaming modus naar ingelijste modus, weet ik dat de audio is afgelopen, zodat ik kan vertellen de BVSSpeaker klasse om te stoppen met afspelen van audio-samples.
- BVSP_streamReceived functie: deze functie wordt aangeroepen telkens wanneer de receive() functie identificeert dat audio-samples zijn ontvangen. Ik gewoon ophalen van de monsters en hen in de klasse BVSSpeaker wachtrij zodat de play() functie kan reproduceren.
- playNextLEDNote functie: deze functie kan alleen worden uitgevoerd als de BVSP_frameReceived-functie de playLEDNotes-opdracht identificeert. Het controleert en de LEDs synchroniseert met de audio vanaf BitVoicer Server verzonden. Ik gebruikte om de LED's worden gesynchroniseerd met de audio en weet de juiste timing, Sonic Visualizer. Deze gratis software stond me toe om te zien dat de audio golven zodat ik kon gemakkelijk vertellen wanneer een piano-toets is ingedrukt. Het toont ook een tijdlijn en dat is hoe ik de milliseconden die wordt gebruikt in deze functie. Klinkt als een dwaze truc en het is. Ik denk dat het mogelijk is om te analyseren de audio stream en de bijbehorende LED inschakelen, maar dat is buiten mijn bereik.