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 | ||
|
ateliers:esp-osc:accueil [2020/01/29 15:49] resonance [Matériaux] |
ateliers:esp-osc:accueil [2020/02/07 09:59] (Version actuelle) laurent [ESP-OSC] |
||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| ====== ESP-OSC ====== | ====== ESP-OSC ====== | ||
| - | * Porteur du projet : reso-nance | + | * Porteur du projet : reso-nance |
| * Date : 29/01/2020 | * Date : 29/01/2020 | ||
| * Licence : libre ! | * Licence : libre ! | ||
| * Contexte : INIT' | * Contexte : INIT' | ||
| - | * Fichiers | + | * Support |
| - | * Lien : lien vers un site éventuellement | + | * Lien : [[https:// |
| ===== Description ===== | ===== Description ===== | ||
| Réalisation d'un contrôleur analogique basé sur un ESP8266 communicant en OSC via wifi avec un ordinateur | Réalisation d'un contrôleur analogique basé sur un ESP8266 communicant en OSC via wifi avec un ordinateur | ||
| Ligne 16: | Ligne 15: | ||
| * ordinateur | * ordinateur | ||
| ===== Tutoriel ===== | ===== Tutoriel ===== | ||
| - | Photos | + | ==== 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' | ||
| + | |||
| + | 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' | ||
| + | Serial.println(" | ||
| + | WiFi.mode(WIFI_STA); | ||
| + | WiFi.begin(nomDuReseau, | ||
| + | ESP.wdtFeed(); | ||
| + | yield(); // rends la main à l' | ||
| + | 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' | ||
| + | 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 ==== | ||
| + | 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' | ||
| + | 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' | ||
| + | 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==== | ||
| + | * Gestion des preférences arduino pour l' | ||
| + | * Code, libs et exemples ESP/OSC Arduino [[https:// | ||
| + | |||
| ===== Photos ===== | ===== Photos ===== | ||
| Autres photos, galerie, ... | Autres photos, galerie, ... | ||