ESP Mesh Network with OSC
2020-03-23 19:32
electronics
With the painlessMesh library, it turned out easy to set up a decentralised mesh network for a few ESP8266 modules. The example below shows how I set it up and how to send and receive OpenSoundControl (OSC) messages. The code also works on an ESP32.
- Install the painlessMesh and the OSC libraries for Arduino.
- Program a few nodes (ESP8266) so that they all run this code...
//req. libraries: OSC, painlessMesh
#include <Arduino.h>
#include <painlessMesh.h>
#include <WiFiUdp.h>
#include <OSCMessage.h>
#include <OSCData.h>
#define MESH_NAME "networkname" //EDIT mesh name
#define MESH_PASS "networkpass" //EDIT password
#define MAX_CONN 4 //EDIT ESP32 can have more than ESP8266
#define INPORT 19998 //OSC in port
#define OUTPORT 57120 //OSC out port (SC)
IPAddress outIP;
WiFiUDP Udp;
painlessMesh mesh;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
mesh.init(MESH_NAME, MESH_PASS, 5555, WIFI_AP_STA, 1, 0, MAX_CONN);
Udp.begin(INPORT);
}
void pingFunc(OSCMessage &inMsg) {
digitalWrite(LED_BUILTIN, 1 - digitalRead(LED_BUILTIN)); //toggle led
OSCMessage outmsg("/pong");
outmsg.add(mesh.getNodeId()); //uint32
IPAddress ip;
ip= mesh.getStationIP(); //0.0.0.0 if current base station
outmsg.add(ip[0]);
outmsg.add(ip[1]);
outmsg.add(ip[2]);
outmsg.add(ip[3]);
ip= mesh.getAPIP();
outmsg.add(ip[0]);
outmsg.add(ip[1]);
outmsg.add(ip[2]);
outmsg.add(ip[3]);
Udp.beginPacket(outIP, OUTPORT);
outmsg.send(Udp);
Udp.endPacket();
}
void loop() {
mesh.update();
int packetSize= Udp.parsePacket();
if (packetSize) {
OSCMessage inMsg;
while (packetSize--) {
inMsg.fill(Udp.read());
}
if (!inMsg.hasError()) {
outIP= Udp.remoteIP();
inMsg.dispatch("/ping", pingFunc);
}
}
}
- After that power up the nodes and a new WiFi network should show up.
- Connect a laptop to the new mesh network and take note of the IP number assigned.
- Run the test code below on the laptop. It will broadcast a \ping OSC message and listen for \pong replies.
The test code is for SuperCollider but any program that can send OSC should work.
(
OSCFunc({|msg| msg.postln}, \pong);
NetAddr.broadcastFlag= true;
NetAddr("10.214.190.255", 19998).sendMsg(\ping); //EDIT laptop ip number but leave 255 as the last number
)
The painlessMesh library will for sure come in handy when I need a network without a WiFi router, or for when trying to cover a larger area.
A major drawback though seems to be that the maximum number of nodes that can be used is really low. Apparently, an ESP8266 can only handle 5 (TCP/IP) connections at the same time and an ESP32 about three times that. And that is not very many.