【问题标题】:How can I make a NeoPixels LED animation be toggled on/off by an OSC message?如何通过 OSC 消息打开/关闭 NeoPixels LED 动画?
【发布时间】:2019-07-29 14:38:56
【问题描述】:

目前我正在尝试弄清楚如何使用 OSC 控制我的 Adafruit NeoPixels 条带。更具体地说,我正在使用 TouchOSC 通过 WiFi 从连接到我的 NeoPixels 的 NodeMCU ESP8266 微控制器发送/接收消息。

我已经下载了一些其他人制作的测试代码,用于监听 OSC 消息以打开/关闭 NodeMCU 板上的微型 LED。当控制器收到消息时,它会将消息发送回 TouchOSC 客户端,以告知灯是否亮起(它是一个切换按钮)。这一切都很好。

我编写了一个简单的函数,可以为连接到 NodeMCU 板的 NeoPixel LED 灯条设置动画。就其本身而言,这也可以很好地工作。

我一直在努力寻找一种方法,让我的函数 [称为 gwBlink() 的函数] 在 LED 开启时循环运行。

我已附上代码。有人可以告诉我我做错了什么吗?我将永远感激任何帮助! :)

TouchOSC 界面:
/**
 * 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
 * Created by Fabian Fiess in November 2016
 * Inspired by Oscuino Library Examples, Make Magazine 12/2015
 */

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <OSCMessage.h>                // for sending OSC messages
#include <OSCBundle.h>                 // for receiving OSC messages
#include <Adafruit_NeoPixel.h>

#define PIN 3

Adafruit_NeoPixel strip = Adafruit_NeoPixel(58, 3, NEO_GRB + NEO_KHZ800);

char ssid[] = "XXX";                 // your network SSID (name)
char pass[] = "XXX";              // your network password

// Button Input + LED Output
const int btnPin = 12;                 // D6 pin at NodeMCU
const int ledPin = 14;                 // D5 pin at NodeMCU
const int boardLed = LED_BUILTIN;      // Builtin LED

boolean btnChanged = false;
int btnVal = 1;  

WiFiUDP Udp;                           // A UDP instance to let us send and receive packets over UDP
const IPAddress destIp(192,168,0,10);   // remote IP of the target device (i.e. THE PHONE)
const unsigned int destPort = 12000;    // remote port of the target device where the NodeMCU sends OSC to
const unsigned int localPort = 10000;   // local port to listen for UDP packets at the NodeMCU (another device must send OSC messages to this port)

unsigned int ledState = 1;             // LOW means led is *on*

void setup() {
    strip.begin();
    strip.show();
    Serial.begin(115200);

    // 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
    WiFi.config(IPAddress(192,168,0,13),IPAddress(192,168,0,1), IPAddress(255,255,255,0)); 

    // Connect to WiFi network
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, pass);

    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());

    // btnInput + LED Output
    pinMode(btnPin, INPUT);
    pinMode(ledPin, OUTPUT);
    pinMode(boardLed, OUTPUT); 
}

void loop() {
    receiveOSC();
    sendOSC();
}

void sendOSC(){
    // read btnInput and send OSC
    OSCMessage msgOut("/1/buttonListener");

    if(digitalRead(btnPin) != btnVal) {
        btnChanged = true;
        btnVal = digitalRead(btnPin);
    }

    if(btnChanged == true){
        btnChanged = false;
        digitalWrite(ledPin, btnVal);
        digitalWrite(boardLed, (btnVal + 1) % 2);    // strange, but for the builtin LED 0 means on, 1 means off
        Serial.print("Button: ");
        Serial.println(btnVal);
        msgOut.add(btnVal);
    }

    Udp.beginPacket(destIp, destPort);
    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()){
            msgIN.route("/1/toggleLED",toggleOnOff);

        }
    }
}

void gwBlink() {
  // LED strip animation
  uint16_t i, j;
  for(i = 0; i < strip.numPixels(); i = i + 2) {
    strip.setPixelColor(i, 0, 182, 90);
  }
  for(j = 1; j < strip.numPixels(); j = j + 2) {
    strip.setPixelColor(j, 128, 128, 128);
  }
  strip.show();
  delay(100);

  for(i = 0; i < strip.numPixels(); i = i + 2) {
    strip.setPixelColor(i, 128, 128, 128);
  }

  for(j = 1; j < strip.numPixels(); j = j + 2) {
    strip.setPixelColor(j, 0, 182, 90);
  }
  strip.show();
  delay(100);
}

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)
  digitalWrite(ledPin, ledState);               // External LED

  if (ledState) {
    Serial.println("LED on");
    gwBlink();
  }
  else {
    Serial.println("LED off");
    strip.clear();
  }
  ledState = !ledState;                         // toggle the state from HIGH to LOW to HIGH to LOW ...
}

这段代码实际上可以很好地打开/关闭板上的小 LED,但我的动画功能没有被触发。

【问题讨论】:

    标签: arduino arduino-esp8266 osc


    【解决方案1】:

    我使用 NeoPixels 的时间很短,但在尝试同时使用它们和串行监视器时遇到了问题。一旦我禁用了串行命令 (//Serial.begin(115200);),它们就可以正常工作了。文档没有明确说明这一点,我在一个线程中发现了它,其中 Adafruit 管理员在尝试将 NeoPixels 更新为“痛苦”时提到使用串行。

    如果注释掉 Serial.begin 可以解决您的问题,那么我想您可以尝试:

    *if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.print(inByte, DEC);
    }*
    

    ...idk,但值得一试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 2021-03-12
      • 1970-01-01
      相关资源
      最近更新 更多