ESP8266 OpenSound Control Teensy
2016-04-30 17:29
electronics
Today I ported my Open Sound Control ESP8266 example for Arduino to run on a Teensy 3.
The version below is a bit simpler but still works the same. It is just to show how to send and receive OSC messages directly in SuperCollider or MaxMSPJitter.
Teensy code:
//f0 150705 - modified for Teensy3 160430
//sending and receiving UDP OSC with an ESP8266
//for Teensy + ESP8266 with firmware 0.9.5.2
#define WLAN_SSID "ssid"
#define WLAN_PASS "pass"
#define WLAN_ADDR "192.168.1.3" //laptop running SC EDIT
#define ADDR "/tap" //incoming OSC addy
#define PORT 1112 //incoming OSC port
uint8_t buf[16];
char indata[12];
char inbuffer[256];
char OKrn[] = "OK\r\n";
byte wait_for_esp_response(int timeout, char* term = OKrn) {
unsigned long t = millis();
bool found = false;
int i = 0;
int len = strlen(term);
while (millis() < (t + timeout)) {
if (Serial1.available()) {
inbuffer[i++] = Serial1.read();
if (i >= len) {
if (strncmp(inbuffer + i - len, term, len) == 0) {
found = true;
break;
}
}
}
}
inbuffer[i] = 0;
return found;
}
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
buf[13] = 3; // b
buf[14] = 2; // c
buf[15] = 0; // d
pinMode(23, OUTPUT);
Serial.begin(115200); //USB serial for feedback
delay(400);
Serial1.begin(115200); //Teensy hardware pins 0 and 1
Serial.println("starting");
Serial.print("hard reset...");
pinMode(4, OUTPUT);
delay(10);
pinMode(4, INPUT);
Serial.print("ready...");
boolean resp = wait_for_esp_response(1000, "ready\r\n");
Serial.println(resp);
Serial.print("mode1...");
Serial1.println("AT+CWMODE=1");
resp = wait_for_esp_response(1000);
Serial.println(resp);
Serial.print("connecting...");
do {
Serial1.print("AT+CWJAP=\"");
Serial1.print(WLAN_SSID);
Serial1.print("\",\"");
Serial1.print(WLAN_PASS);
Serial1.println("\"");
resp = wait_for_esp_response(3000);
Serial.print(resp);
} while (!resp);
Serial.print("\nmux1...");
Serial1.println("AT+CIPMUX=1");
resp = wait_for_esp_response(1000);
Serial.println(resp);
Serial.print("udp...");
Serial1.print("AT+CIPSTART=4,\"UDP\",\"");
Serial1.print(WLAN_ADDR);
Serial1.print("\",57120,");
Serial1.print(PORT);
Serial1.println(",0");
resp = wait_for_esp_response(1000);
Serial.println(resp);
Serial.println("setup done");
}
void loop() {
if (wait_for_esp_response(1000, "\r\n+IPD,4,16:")) {
if (wait_for_esp_response(1000, ADDR)) {
Serial1.readBytes(indata, 12);
buf[12] = indata[8] + 1; //add one to incomming values
buf[13] = indata[9] + 1;
buf[14] = indata[10] + 1;
buf[15] = indata[11] + 1;
Serial.println(int(indata[8]));
Serial.println(int(indata[9]));
Serial.println(int(indata[10]));
Serial.println(int(indata[11]));
Serial1.println("AT+CIPSEND=4,16");
if (wait_for_esp_response(1000, "> ")) {
Serial1.write(buf, sizeof(buf));
if (wait_for_esp_response(1000)) {
Serial.println("reply sent!");
}
}
}
}
}
SuperCollider code:
(
//--call&response
var send= 0, last= Main.elapsedTime;
OSCdef(\sti, {|msg, time, addr|
//should receive the values you sent +1
([msg[1]>>24, (msg[1]>>16)&255, (msg[1]>>8)&255, msg[1]&255]).post;
(" % sec since last: %, % sec since sent").format(addr, time-last, time-send).postln;
last= time;
}, \sti);
n= NetAddr("192.168.1.4", 1112); //esp8266 ip address EDIT
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, 3, i.asInteger%256, 1));
send= Main.elapsedTime;
0.5.wait;
};
});
)
Note: my new and better way to do this is described in this post: /f0blog/f0led/
Updates:
- 180212: removed an unneeded wait for response. Thanks Niklas!
Attachments: | |
---|---|
teensy_esp8266_osc.maxpat.zip |