Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente Prochaine révision Les deux révisions suivantes | ||
ateliers:esp-osc:accueil [2020/01/30 10:04] laurent [UDP & BROADCAST] |
ateliers:esp-osc:accueil [2020/01/30 10:44] laurent [OSC] |
||
---|---|---|---|
Ligne 18: | Ligne 18: | ||
==== UDP & BROADCAST==== | ==== UDP & BROADCAST==== | ||
L'OSC peut circuler sur le réseau au protocole TCP ou UDP. Le TCP permet de vérifier que le destinataire à reçu le message et que son contenu n'est pas corrompu. L'UDP envoie le message sans se préoccuper de sa réception. En conséquence, | L'OSC peut circuler sur le réseau au protocole TCP ou UDP. Le TCP permet de vérifier que le destinataire à reçu le message et que son contenu n'est pas corrompu. L'UDP envoie le message sans se préoccuper de sa réception. En conséquence, | ||
+ | |||
+ | Pour envoyer des données en UDP depuis un ESP8266, on peut utiliser le code suivant, commenté ligne par ligne. Il est également disponible sur le [[https:// | ||
+ | ++++ envoiUDP.ino| | ||
+ | <code cpp># | ||
+ | #include < | ||
+ | |||
+ | static char* nomDuReseau = " | ||
+ | static char* motDePasse = " | ||
+ | static const int portUDP = 8000; // port auquel les paquets seront envoyés, doit être identique à celui du récepteur | ||
+ | static IPAddress IPcible = IPAddress({10, | ||
+ | WiFiUDP UDP; | ||
+ | |||
+ | void setup() { | ||
+ | Serial.begin(115200); | ||
+ | while (true) { // tant que la connection n'est pas établie, on restera coincé ici | ||
+ | Serial.println(" | ||
+ | WiFi.mode(WIFI_STA); | ||
+ | WiFi.begin(nomDuReseau, | ||
+ | ESP.wdtFeed(); | ||
+ | yield(); // rends la main à l'ESP | ||
+ | if ( WiFi.waitForConnectResult() == WL_CONNECTED ) {break;} // si la connection est établie, on sort de la boucle infinie | ||
+ | } | ||
+ | Serial.print(" | ||
+ | Serial.println(WiFi.localIP()); | ||
+ | UDP.begin(portUDP); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | Serial.println(" | ||
+ | UDP.beginPacket(IPcible, | ||
+ | UDP.write(" | ||
+ | UDP.endPacket(); | ||
+ | yield(); // rends la main à l'ESP | ||
+ | delay(1000); | ||
+ | } | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | Pour afficher l'UDP reçu, un script python écoutant l'UDP entrant est également fourni | ||
+ | ++++ receptionUDP.py| | ||
+ | <code python># | ||
+ | # -*- coding: utf-8 -*- | ||
+ | |||
+ | import socket | ||
+ | |||
+ | port = 8000 | ||
+ | # little trick to get the local ip address. | ||
+ | s = socket.socket(socket.AF_INET, | ||
+ | s.connect((" | ||
+ | IP = s.getsockname()[0] | ||
+ | |||
+ | sock = socket.socket(socket.AF_INET, | ||
+ | sock.bind((IP, | ||
+ | print(" | ||
+ | |||
+ | while True: | ||
+ | try : | ||
+ | data, addr = sock.recvfrom(1024) | ||
+ | print (" | ||
+ | except KeyboardInterrupt : | ||
+ | print(" | ||
+ | raise SystemExit | ||
+ | </ | ||
+ | ++++ | ||
==== OSC ==== | ==== OSC ==== | ||
+ | L'OSC est un format de donnée constitué d'une adresse et éventuellement d' | ||
+ | {{ : | ||
+ | L' | ||
+ | Les **arguments** peuvent être aussi nombreux que nécessaire et contenir des entiers, des chaînes de caractères, | ||
+ | |||
+ | Pour créer un message OSC, on utilisera la bibliothèque OSC, disponible dans le gestionnaire de bibliothèque d' | ||
+ | Pour éviter de surcharger le réseau, nous n' | ||
+ | ++++ envoiOSC.ino| | ||
+ | <code cpp># | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | static char* nomDuReseau = " | ||
+ | static char* motDePasse = " | ||
+ | static const int portOSC = 8000; // port auquel les paquets seront envoyés, doit être identique à celui du récepteur | ||
+ | static IPAddress IPcible = IPAddress({10, | ||
+ | static int tolerance = 2; // différence minimale entre la la valeur actuelle et la précédente à partir de laquelle les messages seront envoyés | ||
+ | int valeurPrecedente = 0; // stockera la valeur précédente | ||
+ | WiFiUDP UDP; | ||
+ | |||
+ | void setup() { | ||
+ | Serial.begin(115200); | ||
+ | while (true) { // tant que la connection n'est pas établie, on restera coincé ici | ||
+ | Serial.println(" | ||
+ | WiFi.mode(WIFI_STA); | ||
+ | WiFi.begin(nomDuReseau, | ||
+ | ESP.wdtFeed(); | ||
+ | yield(); // rends la main à l'ESP | ||
+ | if ( WiFi.waitForConnectResult() == WL_CONNECTED ) {break;} // si la connection est établie, on sort de la boucle infinie | ||
+ | } | ||
+ | Serial.print(" | ||
+ | Serial.println(WiFi.localIP()); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | int valeurActuelle = analogRead(0); | ||
+ | if (valeurActuelle < valeurPrecedente-tolerance || valeurActuelle > valeurPrecedente+tolerance) { // si la valeur à changée significativement | ||
+ | envoieOSC(valeurActuelle); | ||
+ | valeurPrecedente = valeurActuelle; | ||
+ | } | ||
+ | yield(); // rends la main à l'ESP | ||
+ | delay(2); // une courte sieste lui permettra de travailler plus longtemps | ||
+ | } | ||
+ | |||
+ | void envoieOSC(int valeur) { | ||
+ | Serial.print(" | ||
+ | static char* addresseOSC = "/ | ||
+ | OSCMessage* message = new OSCMessage(addresseOSC); | ||
+ | message-> | ||
+ | UDP.beginPacket(IPcible, | ||
+ | message-> | ||
+ | UDP.endPacket(); | ||
+ | delete(message); | ||
+ | ESP.wdtFeed(); | ||
+ | yield(); | ||
+ | } | ||
+ | </ | ||
+ | ++++ | ||
+ | Un exemple de réception d'OSC est fourni sous forme d'un script python utilisant la bibliothèque [[http:// | ||
+ | ++++ receptionOSC.py| | ||
+ | <code python># | ||
+ | # -*- coding: utf-8 -*- | ||
+ | import liblo, sys | ||
+ | |||
+ | defaultPort=8000 | ||
+ | portNumber = defaultPort | ||
+ | if len(sys.argv) != 2 : print(" | ||
+ | else : | ||
+ | try : | ||
+ | portGiven = int(sys.argv[1]) | ||
+ | if portGiven >= 1025 and portGiven <= 65535 : portNumber = portGiven | ||
+ | except : | ||
+ | print(" | ||
+ | raise SystemExit | ||
+ | |||
+ | try: | ||
+ | server = liblo.Server(portNumber) | ||
+ | print(" | ||
+ | except liblo.ServerError as err: | ||
+ | print(str(err)) | ||
+ | raise SystemExit | ||
+ | |||
+ | def printOSC(path, | ||
+ | print(" | ||
+ | for a, t in zip(args, types): | ||
+ | print (" | ||
+ | print(" | ||
+ | server.add_method(None, | ||
+ | # loop and dispatch messages every 100ms | ||
+ | while True: | ||
+ | try : server.recv(100) | ||
+ | except KeyboardInterrupt : | ||
+ | | ||
+ | raise SystemExit | ||
+ | </ | ||
+ | ++++ | ||
==== ARDUINO==== | ==== ARDUINO==== | ||
* Gestion des preférences arduino pour l' | * Gestion des preférences arduino pour l' |