RGB Light, cancel loop?
-
Put the gw.process inside your while (isShow==1) loop should help. You are not receiving anything when inside that loop...
-
Put the gw.process inside your while (isShow==1) loop should help. You are not receiving anything when inside that loop...
@AWI Hi, thanks for reply.
I tried putting gw.process on a few different places now but it still seems like it gets stuck in the loop rainbow();
If I remove rainbow(); from the main loop, everything seems to work according to the debug messages. Except for that there is no lights but.. Either I need to listen to messages from gw in the rainbow(); or this to be reworked in some way.
-
I think the issue is that you shouldn't be calling delay() basically anywhere. The main loop() needs to run at a reasonable rate (i.e. be called at least every millisecond). One option: make rainbow() just show one time (remove the outer loop and delay calls) and pass in the current j variable as an argument. Then in loop(), use a timer to test if enough time has passed to re-call rainbow(). Any arduino ellapsed time/timer libraries will work fine. Here is an example: http://playground.arduino.cc/Code/ElapsedMillis. In that example, change the ledState/digitalWrite lines to call the new rainbow() function.
-
I think the issue is that you shouldn't be calling delay() basically anywhere. The main loop() needs to run at a reasonable rate (i.e. be called at least every millisecond). One option: make rainbow() just show one time (remove the outer loop and delay calls) and pass in the current j variable as an argument. Then in loop(), use a timer to test if enough time has passed to re-call rainbow(). Any arduino ellapsed time/timer libraries will work fine. Here is an example: http://playground.arduino.cc/Code/ElapsedMillis. In that example, change the ledState/digitalWrite lines to call the new rainbow() function.
-
This is my attempt at millis... I can still not get it to stop. :sadface:
#define SN "Moodlight" #define SV "v1.0" #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif #include <SPI.h> #include <MySensor.h> #define NEO_PIN 4 // NeoPixels input pin #define NUMPIXELS 16 // Number of nexpixels in ring/strip #define interval 50 Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, NEO_PIN, NEO_GRB + NEO_KHZ800); long previousMillis = 0; int l = 0; int isShow; MySensor gw; MyMessage rgbShowState(0, V_LIGHT); void setup() { gw.begin(incomingMessage, AUTO, true); gw.sendSketchInfo(SN, SV); gw.present(0, S_LIGHT, "Moodlight", false); // Correct RGB show state for first start and load it (set to 'On' at first start) gw.saveState(0, constrain((int8_t)gw.loadState(0), 0, 1)); isShow=gw.loadState(0); // Send RGB show state to controler (request ack back: true/false) gw.send( rgbShowState.set(isShow), false); if (isShow==1){Serial.println("RGB show running..."); } Serial.println("Ready to receive messages..."); strip.begin(); strip.show(); } void loop() { // Process incoming messages (like config and light state from controller) gw.process(); // LEDs off if state 0 if (isShow == 0) { strip.Color(0,0,0); } // Run RGB show if state 1 if (isShow == 1) { newRainbow(); } } void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { // Incoming on/off command sent from controller ("1" or "0") int lightState = message.getString()[0] == '1'; // if receive RGB Show On commands, start the show if (message.sensor==0 && lightState==1){ rgbShowOn(); } // if receive RGB Show Off commands, stop the show else if (message.sensor==0 && lightState==0){ rgbShowOff(); } } } void rgbShowOn() { // define show On isShow = 1; // Write some debug info Serial.println("Show must go on"); } void rgbShowOff() { // define show Off isShow = 0; Serial.println("Stop the show"); } void newRainbow() { if (millis() - previousMillis > interval * 2) { for (int h = 0; h < strip.numPixels(); h++) { strip.setPixelColor(h, Wheel((h + l) & 255)); } l++; if (l >= 256) l = 0; strip.show(); previousMillis = millis(); } } // 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); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } -
hi,
what difference between what I had named rgbShow and your moodlight ?
-
hi,
what difference between what I had named rgbShow and your moodlight ?
I guess it is that neopixel cant run with your RGB-3D since it only has 3 pins - VCC, GND, DATA.
Edit : I figured it out! I will add some more functions to it and then share it.
Thx for help!
-
I guess it is that neopixel cant run with your RGB-3D since it only has 3 pins - VCC, GND, DATA.
Edit : I figured it out! I will add some more functions to it and then share it.
Thx for help!
an easy way would be a non-blocking function that breathes the LED... I did this for a recent project:
void breatheUpdate(const uint8_t * segment, const uint8_t numLeds, const uint32_t increment, const uint8_t step) { static uint32_t lastTimeChange = 0; static uint8_t direction = 1; const static uint8_t lowLimit = 50; static uint8_t value = lowLimit; if(millis() - lastTimeChange > increment) { value +=(direction * step); value = constrain(value, lowLimit, 255); if (value <= lowLimit || value >= 255) { direction = direction * -1; } for(uint8_t i = 0; i < numLeds; i++) { myPixels.setPixelColor(segment[i], myPixels.Color(0, 0, value)); } myPixels.show(); lastTimeChange += increment; } }segmenthere is an array of leds, but you can convert the function to a single neopixel easily.loop()would look like this:void loop() { gw.process(); if (isShow) { breatheUpdate(mySegment, sizeof(mySegment), breatheRate, 1); } } -
I made a ws2812 (neopixel) sketch not to long ago, maybe you can use some or all of the code.
my loop only contains gw.process() for incomming messages (color, brightness, off).
I made no loops for color shows because i'm not interested in that but is should not be to difficult to adapt the code, there is however a short colorwhipe (chaser) when changing the strip color#include <MySensor.h> #include <SPI.h> #include "Adafruit_NeoPixel.h" #define NUMPIXELS 4 // Number of connected pixels on a single datapin #define PIN 4 // Digital output pin #define NODE_ID AUTO //254 for testing purpose #define CHILD_ID 0 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); long RGB_values[3] = {0,0,0}; MySensor gw; void setup() { gw.begin(incomingMessage, NODE_ID, false); gw.sendSketchInfo("RGB Node", "1.0"); gw.present(CHILD_ID, S_RGB_LIGHT); strip.begin(); strip.show(); // Update the strip, to start they are all 'off' } void loop() { gw.process(); } void incomingMessage(const MyMessage &message) { if (message.type==V_RGB) { // starting to process the hex code String hexstring = message.getString(); //here goes the hex color code coming from through MySensors (like FF9A00) long number = (long) strtol( &hexstring[0], NULL, 16); RGB_values[0] = number >> 16; RGB_values[1] = number >> 8 & 0xFF; RGB_values[2] = number & 0xFF; colorWipe(Color(RGB_values[0],RGB_values[1],RGB_values[2]), 60); } if (message.type==V_DIMMER) { strip.setBrightness(round((2.55*message.getInt()))); strip.show(); } if (message.type==V_LIGHT) { if (message.getInt() == 0) { strip.clear(); strip.show(); } } } void colorWipe(uint32_t c, uint8_t wait) { int i; for (i=0; i < strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); delay(wait); } } /* Helper functions */ // Create a 15 bit color value from R,G,B uint32_t Color(byte r, byte g, byte b) { uint32_t c; c = r; c <<= 8; c |= g; c <<= 8; c |= b; return c; }It's not the cleanest code but it works for me...
have fun.