Skip to content

Instantly share code, notes, and snippets.

@donovankeith
Last active January 9, 2023 23:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donovankeith/578856d442d1816d2504cfb0a9789d8f to your computer and use it in GitHub Desktop.
Save donovankeith/578856d442d1816d2504cfb0a9789d8f to your computer and use it in GitHub Desktop.
Simple test project for driving RGB led with OSC messages.
/*
Send and receive OSC messages between NodeMCU and another OSC speaking device.
Send Case: Press a physical button (connected to NodeMCU) and get informed about it on your smartphone screen
Receive Case: Switch an LED (connected to NodeMCU) on or off via Smartphone
Written by Jackson Campbell <jcampbell@calarts.edu>
Modified by Donovan Keith <dkeith@calarts.edu>
for [Augmenting Realities](https://sites.google.com/view/augmentingrealities/home)
Based on sketch by Fabian Fiess in November 2016
Inspired by Oscuino Library Examples, Make Magazine 12/2015
*/
// Imports
// ==============================================================================
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
// [OSC for Arduino Library](https://github.com/CNMAT/OSC)
#include <OSCMessage.h> // for sending OSC messages
#include <OSCBundle.h> // for receiving OSC messages
// Settings
// ==============================================================================
// WiFi Network Settings
// ---------------------
char wifiNetworkName[] = "ARclass";
char wifiPassword[] = "uniduino";
// OSC Server/Client Addresses and Ports
// --------------------------------------
const IPAddress destIp(192, 168, 1, 15); // remote IP of the target device
const unsigned int destPort = 9000; // remote port of the target device where the NodeMCU sends OSC to
const IPAddress localIp(192, 168, 1, 177);
const unsigned int localPort = 8000; // local port to listen for UDP packets at the NodeMCU (another device must send OSC messages to this port)
const IPAddress networkGateway(192, 168, 1, 1);
const IPAddress subnet(255, 255, 255, 0);
// Board Pin Mapping
// ---------------------
// Button Input + LED Output
const int buttonPin = 14; // D5 pin at NodeMCU (GPIO 14)
const int redPin = 12; // D6 pin at NodeMCU (GPIO 12)
const int greenPin = 13; // D7 pin at NodeMCU (GPIO 13)
const int bluePin = 15; // D8 pin at NodeMCU (GPIO 15)
int pinCount = 3;
int pins[] = {redPin, greenPin, bluePin};
const int boardLed = LED_BUILTIN; // Builtin LED
// Globals
// ==============================================================================
// State Variables
// ---------------------
boolean buttonChanged = false;
int buttonVal = 1;
unsigned int ledState = 1; // LOW means led is *on*
// Objects
// ---------------------
WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP
// Program Flow
// ==============================================================================
void setup() {
Serial.begin(115200);
setupPins();
ledDemo();
connectToWifi();
}
void loop() {
receiveOSC();
sendOSC();
}
// Helpers
// ==============================================================================
void connectToWifi() {
// Specify a static IP address for NodeMCU - only needeed for receiving messages)
// If you erase this line, your ESP8266 will get a dynamic IP address
// the parameters of Wifi.config are ( STATIC_IP, DNS_IP (router's IP), DOMAIN_IP)
WiFi.config(localIp, networkGateway, subnet);
// Connect to WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifiNetworkName);
WiFi.begin(wifiNetworkName, wifiPassword);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("Starting UDP");
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.localPort());
}
void setupPins() {
// buttonInput + LED Output
pinMode(buttonPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(boardLed, OUTPUT);
}
void blinkRGB(int period){
// Blinks RGB LED Red, Green, then Blue
for (int i=0; i<pinCount; i++){
digitalWrite(pins[i], HIGH);
delay(period);
digitalWrite(pins[i], LOW);
}
delay(period);
}
void blinkWhite(int period){
// Flash White
for (int i=0; i<pinCount; i++){
digitalWrite(pins[i], HIGH);
}
delay(period);
// Turn off all LEDs
for (int i=0; i<pinCount; i++){
digitalWrite(pins[i], LOW);
}
}
void ledDemo() {
// Blinks the RGB LED to establish that all is working.
int period = 500; // Milliseconds
Serial.println("Testing RGB LED...");
blinkRGB(period);
blinkRGB(period);
blinkRGB(period);
blinkWhite(period);
Serial.println("Testing complete.");
}
// OSC I/O
// ==============================================================================
void sendOSC() {
// read buttonInput and send OSC
OSCMessage msgOut("/1/buttonListener/");
if (digitalRead(buttonPin) != buttonVal) {
buttonChanged = true;
buttonVal = digitalRead(buttonPin);
}
if (buttonChanged == true) {
buttonChanged = false;
digitalWrite(boardLed, !buttonVal); // strange, but for the builtin LED 0 means on, 1 means off
Serial.print("Button: ");
Serial.println(buttonVal);
msgOut.add(buttonVal); // add the value to the OSC routing
Udp.beginPacket(destIp, destPort);//Format UDP message
msgOut.send(Udp);
Udp.endPacket();
msgOut.empty();
delay(100);
}
}
void receiveOSC() {
OSCMessage msgIN;
int size;
if ((size = Udp.parsePacket()) > 0) {
while (size--)
msgIN.fill(Udp.read());
if (!msgIN.hasError()) { //This construction is a little counterintuitive...
// if (!=the opposite of) the error check value = 1(true) then...do X
// so... this means if the message has NO ERROR, then...do X
msgIN.route("/1/toggle1", toggleOnOff); // if messages have the routing "xxx/xxx/xxx", execute function
msgIN.route("/1/fader1", Rled); //rgb led pwm color mixing functions
msgIN.route("/1/fader2", Gled);
msgIN.route("/1/fader3", Bled);
}
}
}
// Message Handlers
// ---------------------
void Rled(OSCMessage &msg, int addrOffset ) {
// NOT SURE ABOUT THESE PARAMETERS...
// I THINK THIS MEANS: instantiate "msg" instance (with "&" reference)
// of OSCMessage function. return the offset of the message address as
// "addrOffset" (I don't think we do anything with this variable).
int value = msg.getFloat(0); //TouchOSC only sends floats, but store as int
analogWrite(redPin, value); //Set the led level by writing pwm level to pin
OSCMessage msgOUT("/1/fader1");
Serial.print("Rled = : ");
Serial.println(value);
msgOUT.add(value); //add the value to the msgOUT routing
Udp.beginPacket(Udp.remoteIP(), destPort);
msgOUT.send(Udp); // send the bytes
Udp.endPacket(); // mark the end of the OSC Packet
msgOUT.empty(); // free space occupied by message
}
void Gled(OSCMessage &msg, int addrOffset ) {
int value = msg.getFloat(0); //TouchOSC only sends floats, but store as int
analogWrite(greenPin, value); //Set the led level by writing pwm level to pin
OSCMessage msgOUT("/1/fader2");
Serial.print("Gled = : ");
Serial.println(value);
msgOUT.add(value); //add the value to the msgOUT routing
Udp.beginPacket(Udp.remoteIP(), destPort);
msgOUT.send(Udp); // send the bytes
Udp.endPacket(); // mark the end of the OSC Packet
msgOUT.empty(); // free space occupied by message
}
void Bled(OSCMessage &msg, int addrOffset ) {
int value = msg.getFloat(0); //TouchOSC only sends floats, but store as int
analogWrite(bluePin, value); //Set the led level by writing pwm level to pin
OSCMessage msgOUT("/1/fader3");
Serial.print("Bled = : ");
Serial.println(value);
msgOUT.add(value); //add the value to the msgOUT routing
Udp.beginPacket(Udp.remoteIP(), destPort);
msgOUT.send(Udp); // send the bytes
Udp.endPacket(); // mark the end of the OSC Packet
msgOUT.empty(); // free space occupied by message
}
void toggleOnOff(OSCMessage &msg, int addrOffset) {
ledState = (boolean) msg.getFloat(0);
digitalWrite(boardLed, (ledState + 1) % 2); // Onboard LED works the wrong direction (1 = 0 bzw. 0 = 1)
if (ledState) {
Serial.println("LED on");
}
else {
Serial.println("LED off");
}
ledState = !ledState; // toggle the state from HIGH to LOW to HIGH to LOW ...
}
@youlisse
Copy link

thanks bro

@youlisse
Copy link

i have huge pb with osc route if you'd like to help discord youlisse#9555

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment