Last active
January 9, 2023 23:35
-
-
Save donovankeith/578856d442d1816d2504cfb0a9789d8f to your computer and use it in GitHub Desktop.
Simple test project for driving RGB led with OSC messages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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 <[email protected]> | |
Modified by Donovan Keith <[email protected]> | |
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 ... | |
} |
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
thanks bro