esp8266 opensound control

here some example arduino code for sending and receiving osc via the cheap esp8266 serial wifi module.

note that the opensound control messages here are very basic - only 4 bytes packed into a single 32bit integer.

* upload the code below to an arduino.

* connect esp8266 TX pin to arduino pin0.

* connect esp8299 RX to arduino pin1. it is safest to use a 3v3 lever converter for this line (or at least a voltage divider).

* power the esp8266 (VCC and GND) from an external 3v source. do not use the arduino 3v3pin as it cannot provide the required current. i used a LF33CV voltage regulator to get 3.3v from the 5v supply that also powers the arduino.

* connect esp8288 RESET pin to arduino pin4.

* and last connect esp8266 CH_PD to 3v3

optional: connect a separate usb-serial (ftdi) chip to arduino pins 2 and 3 to use software serial debugging. start debugging in terminal with something like screen /dev/tty.usbserial-A4015TKA 115200

the arduino code sits and waits for an incoming osc message (/tap). it then replies by sending out a counter message (/sti).

//f0 150705
//sending and receiving udp osc with an esp8266
//for an arduino + esp8266 with firmare 0.9.5.2

#include <SoftwareSerial.h>

#define WLAN_SSID  "SSID"
#define WLAN_PASS  "PASS"
#define WLAN_ADDR  "192.168.1.51" //laptop running sc
#define PORT  1112 //incoming osc port
String tag = "/tap"; //incoming osc addy

SoftwareSerial mySerial(2, 3);

uint8_t buf[16];
byte cnt;
byte id, on, hi, lo;
boolean resp;

void setup() {

  //--osc message
  buf[0] = 47;   // /
  buf[1] = 115;  // s
  buf[2] = 116;  // t
  buf[3] = 105;  // i
  buf[4] = 0;
  buf[5] = 0;
  buf[6] = 0;
  buf[7] = 0;
  buf[8] = 44;   // ,
  buf[9] = 105;  // i
  buf[10] = 0;
  buf[11] = 0;
  buf[12] = 4;   // a high   (id)
  buf[13] = 3;   // a low    (on)
  buf[14] = 2;   // b high   (hi)
  buf[15] = 0;   // b low    (lo)

  mySerial.begin(115200);
  Serial.begin(115200);
  Serial.setTimeout(10000);
  mySerial.println("");
  mySerial.println("starting");

  mySerial.print("hard reset...");
  digitalWrite(4, 0);
  pinMode(4, OUTPUT);
  delay(10);
  pinMode(4, INPUT);
  resp = Serial.find("ready\r\n");
  mySerial.println(resp);

  mySerial.print("mode1...");
  Serial.println("AT+CWMODE=1");
  resp = Serial.find("OK\r\n");
  mySerial.println(resp);

  mySerial.print("connecting...");
  do {
    Serial.print("AT+CWJAP=\"");
    Serial.print(WLAN_SSID);
    Serial.print("\",\"");
    Serial.print(WLAN_PASS);
    Serial.println("\"");
    resp = Serial.find("OK\r\n");
    mySerial.println(resp);
  } while (!resp);

  mySerial.print("mux1...");
  Serial.println("AT+CIPMUX=1");
  resp = Serial.find("OK\r\n");
  mySerial.println(resp);

  mySerial.print("udp...");
  Serial.print("AT+CIPSTART=4,\"UDP\",\"");
  Serial.print(WLAN_ADDR);
  Serial.print("\",57120,");
  Serial.print(PORT);
  Serial.println(",0");
  resp = Serial.find("OK\r\n");
  mySerial.println(resp);

  Serial.setTimeout(1000);
}
void loop() {
  while (Serial.available()) {
    String abc = Serial.readStringUntil('\n');
    if (abc.startsWith("+IPD,4,16:" + tag)) {
      id = abc[22];
      on = abc[23];
      hi = abc[24];
      lo = abc[25];
      mySerial.print("id:");
      mySerial.println(id);
      mySerial.print("on:");
      mySerial.println(on);
      mySerial.print("hi:");
      mySerial.println(hi);
      mySerial.print("lo:");
      mySerial.println(lo);

      buf[15] = cnt++;
      Serial.println("AT+CIPSEND=4,16");
      Serial.find(">");
      Serial.write(buf, sizeof(buf));
      resp = Serial.find("OK\r\n");
      mySerial.print("send...");
      mySerial.println(resp);
    }
  }
}

supercollider test code:

(
//--call&response
var last= Main.elapsedTime;
OSCFunc({|msg, time, addr|
        [\id, msg[1]>>24, \on, (msg[1]>>16)&255, \hi, (msg[1]>>8)&255, \lo, msg[1]&255, time-last, addr].postln;
        last= time;
}, \sti);
n= NetAddr("192.168.1.50", 1112); //esp8266 ip address
f= {|id, on, hi, lo| (id&255<<24)|(on&255<<16)|(hi&255<<8)|(lo&255)};
r= Routine.run({
        inf.do{|i|
                n.sendMsg(\tap, f.value(4, 1, i.asInteger>>8&255, i.asInteger%256));
                0.5.wait;
        };
});
)