Errors with Custom MySensors actuator (Neopixel/ws2812 Node)
-
Greetings,
I've been working with sensor networks with MySensors for quite some time. So far, it's one of the nicest APIs I've worked with in networking. But I wanted to build an actuator that would follow somewhat complicated commands to actuate a Neopixel strip.
I already have the code written, and from after reading all the documentation, should indeed work.
#include <Adafruit_NeoPixel.h> #include <avr/power.h> #include <MySensor.h> #include <SPI.h> Adafruit_NeoPixel strip = Adafruit_NeoPixel(38, 3, NEO_GRB + NEO_KHZ800); MySensor gw; void setup() { Serial.begin(115200); gw.begin(incomingMessage, 10, false); gw.sendSketchInfo("Neopixel Node", "1.0"); gw.present(0, S_CUSTOM); strip.begin(); strip.show(); Serial.println("Neopixel Node device ready"); } void loop() { gw.process(); } void incomingMessage(const MyMessage &message) { Serial.println("Incoming message"); if (message.type == V_STATUS){ // Turns on or off if (message.getInt() == 0){lightsOut(10);} } if (message.type == V_RGB){ // Makes it a solid color String hexstring = message.getString(); long number = (long) strtol( &hexstring[0], NULL, 16); colorWipe(number, 10); } if (message.type == V_VAR1){ //Where we put the modes switch( message.getInt() ){ case 1: Serial.println("Rainbow mode activated"); rainbow(20); break; case 2: Serial.println("Rainbow Cycle mode activated"); rainbowCycle(20); break; case 3: Serial.println("Theater chase lights mode activated"); theaterChaseRainbow(50); break; default: break; } } } void lightsOut(uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, 0); strip.show(); delay(wait); } } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); delay(wait); } } void rainbow(uint8_t wait) { uint16_t i, j; for(j=0; j<256; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 255)); } strip.show(); delay(wait); } } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j; for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } strip.show(); delay(wait); } } //Theatre-style crawling lights. void theaterChase(uint32_t c, uint8_t wait) { for (int j=0; j<10; j++) { //do 10 cycles of chasing for (int q=0; q < 3; q++) { for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, c); //turn every third pixel on } strip.show(); delay(wait); for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } //Theatre-style crawling lights with rainbow effect void theaterChaseRainbow(uint8_t wait) { for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel for (int q=0; q < 3; q++) { for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on } strip.show(); delay(wait); for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } // Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } else { WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } }
But when I compile, it works. Then I get the nice chirps from the gateway showing the devices are talking. I get no st:FAIL or anything. It's all OK in the debug.
As an example, from Node-red, I see the following when the Neopixel Node comes online
12/23/2015, 3:51:35 PM84cc7d74.87704msg : Object{ "payload": "1.5\n", "_msgid": "cdb13c1a.324ec", "rawData": [ "10", "255", "0", "0", "17", "1.5\n" ], "nodeId": 10, "childSensorId": 255, "messageType": 0, "ack": 0, "subType": 17 } 12/23/2015, 3:51:35 PM84cc7d74.87704msg : Object{ "payload": "0\n", "_msgid": "ff17a410.00e858", "rawData": [ "10", "255", "3", "0", "6", "0\n" ], "nodeId": 10, "childSensorId": 255, "messageType": 3, "ack": 0, "subType": 6 } 12/23/2015, 3:51:37 PM84cc7d74.87704msg : Object{ "payload": "Neopixel Node\n", "_msgid": "1e786c77.e18794", "rawData": [ "10", "255", "3", "0", "11", "Neopixel Node\n" ], "nodeId": 10, "childSensorId": 255, "messageType": 3, "ack": 0, "subType": 11 } 12/23/2015, 3:51:37 PM84cc7d74.87704msg : Object{ "payload": "1.0\n", "_msgid": "2dbec95b.d24136", "rawData": [ "10", "255", "3", "0", "12", "1.0\n" ], "nodeId": 10, "childSensorId": 255, "messageType": 3, "ack": 0, "subType": 12 } 12/23/2015, 3:51:37 PM84cc7d74.87704msg : Object{ "payload": "\n", "_msgid": "a4060382.5bfa", "rawData": [ "10", "0", "0", "0", "23", "\n" ], "nodeId": 10, "childSensorId": 0, "messageType": 0, "ack": 0, "subType": 23 }
-
Is this an improper use of S_CUSTOM? If so, can you guide me to the docs that indicate how to properly construct it?
-
Is it possible that my Node-red MYSENCAP node is improperly configured? My settings for it are
{"message-type": "set",
"Node ID" : "10" ,
"Child ID" : "0" ,
"Child Type" : "V_VAR1",
"ACK" : "off" ,
"Presentation" : "off"}
And then I proceed to send a "2" through an Inject node. That should send my Neopixel Node into a rainbowCycle() call.
- I would rather have each ws2312 on its own childID. That way, I could individually address them with "HEX color/childID" and program more emergent behavior. How would the pros at MySensors approach this?
Thank you,
Josh Conway
-