Arduino > Wemos D1 : OSC avec TinyOsc

1.  TinyOsc

TinyOsc est une logithèque très rapide et performante pour Arduino. Elle peut être téléchargée ici : https://github.com/thomasfredericks/TinyOsc

2.  Exemple

2.1  Configuration réseau

2.2  Circuit

2.3  Code Arduino

/*
RECEIVED OSC MESSAGES:
/led 1 : turn on the builtin LED AND a LED tied to pin 4 (D2 on the Wemos)
/led 0 : turn off the builtin LED AND a LED tied to pin 4 (D2 on the Wemos)
*: please not that on the Wemos, the builtin LED is inverted (i.e. on when off)

SENT OSC MESSAGES:
/button 0 : when pin 0 (D3 on the Wemos) when a button is pressed to GND
/button 1 : when pin 0 (D3 on the Wemos)is high when a button is released to PULL_UP

*/

// INCLUDE ESP8266WiFi:
#include <ESP8266WiFi.h>

// Please change the following values with your network settings:
const char* ssid     = "NETWORK NAME";
const char* password = "NETWORK PASSWORD";

IPAddress ip(192, 168, 25, 10);
IPAddress gateway(192, 168, 25, 1);
IPAddress subnet(255, 255, 255, 0);

// UDP
int udpReceivePort = 7777;
IPAddress udpTxIp = IPAddress(192, 168, 25, 125);
int udpTxPort = 7890;

// INCLUDE ESP8266 UDP
#include <WiFiUdp.h>
WiFiUDP udp;

// UDP BUFFERS
#define UDP_RX_BUFFER_MAX_SIZE 256
char udpRxBuffer[UDP_RX_BUFFER_MAX_SIZE];

#define UDP_TX_BUFFER_MAX_SIZE 256
char udpTxBuffer[UDP_TX_BUFFER_MAX_SIZE];

// OSC PARSER AND PACKER
#include <TinyOsc.h>
TinyOsc osc;

#include <Bounce2.h>
Bounce button;

//===========
//== SETUP ==
//===========
void setup() {

        // INITIATE SERIAL COMMUNICATION FOR DEBUGGING.
        Serial.begin(57600);

        Serial.println("***STARTING WIFI***");

        // BEGIN WIFI
        WiFi.config(ip , gateway , subnet );
        WiFi.begin(ssid, password);

        // WAIT UNTIL CONNECTED
        while (WiFi.status() != WL_CONNECTED) {
                Serial.print(".");
                delay(10);
        }
        //

        // PRINT CONNECTION SETTINGS
        Serial.println();
        Serial.println("WiFi connected, IP address: ");
        Serial.println( WiFi.localIP() );


        udp.begin(udpReceivePort); // BEGIN LISTENING ON UDP PORT udpReceivePort

        // SETUP THE BUILTIN LED
        pinMode(LED_BUILTIN, OUTPUT);

        // SETUP THE OTHER LED
        pinMode(4, OUTPUT);

        // SETUP THE BUTTON ON PIN 0
        button.attach(0, INPUT_PULLUP);
        button.interval(5);

}

// FUNCTION THAT IS CALLED FOR EVERY RECEIVED MESSAGE
void receivedOscMessage() {


        // GET THE TYPE TAGS AS A C STRING POINTER
        char * typeTags = osc.getTypeTags();


        Serial.println("***OSC***");
        Serial.print("Address: ");
        Serial.println(osc.getAddress());
        Serial.print("Type tags: ");
        Serial.println(typeTags);

        // IF THE ADDRESS IS /led AND THERE IS AN INTEGER ('i')
        if ( osc.fullMatch("/led") && typeTags[0] == 'i' ) {
                int state = osc.getNextInt32();
                digitalWrite(LED_BUILTIN, state);
                digitalWrite(4, state);
        }

}


//==========
//== LOOP ==
//==========
void loop() {

        // CHECK FOR OSC MESSAGES OVER UDP
        // ===============================

        // CHECK IF AN UDP PACKET WAS RECEIVED:
        // udp.parsePacket() RETURNS ture IF IT AN UDP PACKET WAS RECEIVED
        if ( udp.parsePacket() ) {

                // COPY THE PACKET INTO A BUFFER THAT WILL THEN BE USED BY TinyOsc
                // udp.read() RETURNS THE NUMBER OF chars THAT WERE RECEIVED
                int packetSize = udp.read(udpRxBuffer, UDP_RX_BUFFER_MAX_SIZE);

                Serial.println("***UDP***");
                Serial.print("Received packet of size: ");
                Serial.println(packetSize);
                Serial.print("From: ");
                IPAddress remoteIp = udp.remoteIP();
                Serial.println(remoteIp);

                // PARSE THE OSC MESSAGES FROM THE BUFFER
                // <TinyOsc>.parse( buffer name, size of the data, callback function)
                // FOR EVERY PARSED OSC MESSAGE IN  udpRxBuffer THE receivedOscMessage WILL BE CALLED
                osc.parse( udpRxBuffer, packetSize, receivedOscMessage);

        }



        // UPDATE THE BUTTON
        button.update();

        if ( button.rose() ) {

                // SEND OSC MESSAGES OVER UDP
                // ===============================

                // <TinyOsc>.writeMessage( name of buffer to write to , the maximum size of the buffer , the address , the format string , data... )
                // THE FORMAT STRING MUST MATCH THE DATA
                // 'i':32-bit integer
                // IN THIS CASE, THE DATA IS 1 (integer)
                int udpTxBufferLength = osc.writeMessage( udpTxBuffer, UDP_TX_BUFFER_MAX_SIZE ,  "/button",  "i",   1 );

                // udpTxBuffer NOW CONTAINS THE OSC MESSAGE AND WE SEND IT OVER UDP
                udp.beginPacket( udpTxIp , udpTxPort );
                udp.write( udpTxBuffer ,  udpTxBufferLength );
                udp.endPacket();

        } else if ( button.fell() ) {

                // <TinyOsc>.writeMessage( name of buffer to write to , the maximum size of the buffer , the address , the format string , data... )
                // THE FORMAT STRING MUST MATCH THE DATA
                // 'i':32-bit integer
                // IN THIS CASE, THE DATA IS 0 (integer)
                int udpTxBufferLength = osc.writeMessage( udpTxBuffer, UDP_TX_BUFFER_MAX_SIZE ,  "/button",  "i",   0 );

                // udpTxBuffer NOW CONTAINS THE OSC MESSAGE AND WE SEND IT OVER UDP
                udp.beginPacket( udpTxIp , udpTxPort );
                udp.write( udpTxBuffer ,  udpTxBufferLength );
                udp.endPacket();
        }
}

2.4  Code Max

<pre><code>
----------begin_max5_patcher----------
483.3ocyU0zaaCCC8rCP9OHHziYYRp1NN659ArC83PQghMQlJrkLjjyRQQ+u
O8gclwhKRpWFvxAQHJJ936QYlWWtHAuScDLXzWPeGkj7pySRvm2SxfiDbC+X
YM2DBDWpZZ.oEup+PKbzFNnqpUCkf3.f3k1Ndc8KnNCXPe6gudJZQUHV0tm+
T9ImxtFgrFrA.nCda41xeHj6exkUarFoYoqIqPzz7fof3ML2J5wQ4R0YGRFI
38skK7VmY0MglFPVccb79ONGYrr.4H+64nUseeMLUcylQgmEpaVnrYoCquWU
eJSQe1WZgXZvBmp+6a0x07FvB5m.IeWM72w3FvX36gy6petFpP2QmRKJlVJX
WTJx23WSixBaNRgSGlMUkvOcU+4LsUKF8rdDOylaKmtMzyumcIhRt4jYzLmM
EaISQqzYSq3Tlsa9+p+ML+gtksllWr1MtfRPab+lh8zYydRzjm8Q6pw3v0B4
Y+0R.M+A+AwMpNc4fn0+MGZDfUfwJjbqPIGEDMFz6qvWMboWCbY2L37SWuLd
EShWu5xaaO.ZS+MhP4d+7rR62WrJtWHi6Iw8Z3fX3JwW.Xt109stdemNTg3i
48evfaTUfV1IBQ673IqG5vSToanrokGoU3o7xEt.9EvaJpMi
-----------end_max5_patcher-----------
</code></pre>

2.5  Code Processing

// INTALL oscP5 FROM THE LIBRARY MANAGER

/*
RECEIVED OSC MESSAGES:
/button 0 : set the background to white
/button 1 : set the background to black

SENT OSC MESSAGES:
/led 1 : sent when the mouse is pressed
/led 0 : sent when the mouse is released

*/

import oscP5.*;
import netP5.*;

OscP5 oscP5;

/* myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters,
* an ip address and a port number. myRemoteLocation is used as parameter in
* oscP5.send() when sending osc packets to another computer, device,
* application. usage see below. for testing purposes the listening port
* and the port of the remote location address are the same, hence you will
* send messages back to this sketch.
*/
NetAddress remoteLocation = new NetAddress("192.168.25.10",7777);


color backgroundColor = color(0);

void setup() {
        size(400,400);

        /* start oscP5, listening for incoming messages at port 7890 */
        oscP5 = new OscP5(this,7890);


}


void draw() {
        background(backgroundColor);
}

void mousePressed() {
        /* in the following different ways of creating osc messages are shown by example */
        OscMessage message = new OscMessage("/led");

        message.add(1); /* add an int to the osc message */

        /* send the message */
        oscP5.send(message, remoteLocation);
}

void mouseReleased() {
        /* in the following different ways of creating osc messages are shown by example */
        OscMessage message = new OscMessage("/led");

        message.add(0); /* add an int to the osc message */

        /* send the message */
        oscP5.send(message, remoteLocation);
}


/* incoming osc message are forwarded to the oscEvent method. */
void oscEvent(OscMessage theOscMessage) {
        /* print the address pattern and the typetag of the received OscMessage */
        println("### received an osc message:");
        println("addrpattern: "+theOscMessage.addrPattern());
        println("typetag: "+theOscMessage.typetag());

        String address = theOscMessage.addrPattern();

        if ( address.equals("/button") ) {

                // Get the first int value
                int intValue = theOscMessage.get(0).intValue();
                if ( intValue == 0 )  backgroundColor = color(0);
                else  backgroundColor = color(255);

        }

}