Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. RGB Light, cancel loop?

RGB Light, cancel loop?

Scheduled Pinned Locked Moved Troubleshooting
11 Posts 6 Posters 4.9k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AWI
    Hero Member
    wrote on last edited by
    #2

    Put the gw.process inside your while (isShow==1) loop should help. You are not receiving anything when inside that loop...

    M 1 Reply Last reply
    1
    • A AWI

      Put the gw.process inside your while (isShow==1) loop should help. You are not receiving anything when inside that loop...

      M Offline
      M Offline
      msebbe
      wrote on last edited by msebbe
      #3

      @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.

      1 Reply Last reply
      0
      • T Offline
        T Offline
        TD22057
        Hardware Contributor
        wrote on last edited by
        #4

        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.

        M 1 Reply Last reply
        0
        • T TD22057

          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.

          M Offline
          M Offline
          msebbe
          wrote on last edited by msebbe
          #5

          @TD22057 Okey, thank you. I will try with millis when I have time this weekend :+1:

          A 1 Reply Last reply
          0
          • M msebbe

            @TD22057 Okey, thank you. I will try with millis when I have time this weekend :+1:

            A Offline
            A Offline
            AWI
            Hero Member
            wrote on last edited by
            #6

            @msebbe another option is to replace the delay( time ) with gw.wait( time ). This will allow for reception of messages and still use a simple "delay".

            1 Reply Last reply
            0
            • M Offline
              M Offline
              msebbe
              wrote on last edited by
              #7

              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);
              }
              
              1 Reply Last reply
              0
              • V Offline
                V Offline
                vil1driver
                wrote on last edited by vil1driver
                #8

                hi,

                what difference between what I had named rgbShow and your moodlight ?

                M 1 Reply Last reply
                0
                • V vil1driver

                  hi,

                  what difference between what I had named rgbShow and your moodlight ?

                  M Offline
                  M Offline
                  msebbe
                  wrote on last edited by msebbe
                  #9

                  @vil1driver

                  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!

                  B 1 Reply Last reply
                  0
                  • M msebbe

                    @vil1driver

                    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!

                    B Offline
                    B Offline
                    BulldogLowell
                    Contest Winner
                    wrote on last edited by
                    #10

                    @msebbe

                    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;
                      }
                    }
                    

                    segment here 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);
                      }
                    }
                    
                    1 Reply Last reply
                    1
                    • Y Offline
                      Y Offline
                      yugoos
                      wrote on last edited by
                      #11

                      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.

                      1 Reply Last reply
                      2

                      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                      With your input, this post could be even better 💗

                      Register Login
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      14

                      Online

                      12.0k

                      Users

                      11.2k

                      Topics

                      113.4k

                      Posts


                      Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • MySensors
                      • OpenHardware.io
                      • Categories
                      • Recent
                      • Tags
                      • Popular