NUM_LEDS value in LED-Strip Sketch can not be more than "201"?



  • Hello,

    I am having a strange phenomenon here... I made a sketch for mysensors which works perfectly fine. Its a Flameeffekt where you can set the flameheight and intensity with the dimmer (lower value = more and highter flames). Its quite cool and works fine...

    /*
     * Example Dimmable Light
     * Code adapted from http://github.com/mysensors/MySensors/tree/master/examples/DimmableLight
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_NODE_ID 129
    #define MY_RADIO_RF24
    //#define MY_RADIO_RFM69
    #define MY_RF24_CE_PIN 10 
    #define MY_RF24_CS_PIN 9
    
    #include <MySensors.h>
    
    #define CHILD_ID 2
    
    
    #define LIGHT_OFF 0
    #define LIGHT_ON 1
    
    #define SN "Baum"
    #define SV "1.0"
    /*
    int16_t last_state = LIGHT_ON;
    int16_t last_dim = 100;
    
    MyMessage light_msg( CHILD_ID_LIGHT, V_STATUS );
    MyMessage dimmer_msg( CHILD_ID_LIGHT, V_PERCENTAGE );
    */
    
    
    int16_t last_state = LIGHT_OFF;
    int16_t last_dim = 100;
    
    char rgb[7] = "00ff00"; // RGB value.
    int currentLevel = 0;  // Current dimmer level.
    
    int red = 100;
    int green = 100;
    int blue = 100;
    
    MyMessage dimmerMsg(CHILD_ID, V_PERCENTAGE);
    MyMessage lightMsg(CHILD_ID, V_STATUS);
    MyMessage rgbMsg(CHILD_ID, V_RGB);
    
    
    
    #include <Adafruit_NeoPixel.h>
    #ifdef __AVR__
      #include <avr/power.h>
    #endif
    
    #define NUM_LEDS 200
    #define PIN 2
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
    
    int yada = 255;
    
    uint32_t magenta_ada = strip.Color(200, 0, 200);
    uint32_t red_ada = strip.Color(200, 0, 0);
    uint32_t black_ada = strip.Color(0, 0, 0);
    
    void setup()
    {
      
      //update_light();
      Serial.println( "Blutmond - Digitalled Node ready to receive messages..." );
      
      strip.begin();
      strip.Color(55, 0, 33);
      strip.setBrightness(100);
      //strip.fill(black_ada);
      //strip.show(); // Initialize all pixels to 'off'
    
    }
    
    
    
    void loop()
    {
      //In MySensors2.x, first message must come from within loop()
      static bool first_message_sent = false;
      if ( first_message_sent == false ) {
        Serial.println( "Sending initial state..." );
        send_dimmer_message();
        send_status_message();
        send_rgb_message();
        first_message_sent = true;
      }
    
     
        int yadacooling = 255/100 * last_dim;
        int yadasparkling = 255/100 * (100 - last_dim);
        int yadaspeed = 120/100 * last_dim;
        
        Fire(yadacooling,yadasparkling,yadaspeed);
      
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway
      sendSketchInfo( SN, SV );
      present( CHILD_ID, S_RGB_LIGHT );
    }
    
    void receive(const MyMessage &message)
    {
      
      
       if (message.type == V_RGB) {
        // Retrieve the RGB value from the incoming message.
        // RGB LED not implemented, just a dummy print.
        String hexstring = message.getString();
        hexstring.toCharArray(rgb, sizeof(rgb));
    
        
        Serial.print("Changing color to ");
        Serial.println(rgb);
        
         //getRGB(rgb);
    
      String rgb2 = rgb;
        Serial.println(rgb2);
      rgb2.toUpperCase();
      char c[7];
      rgb2.toCharArray(c, 8);
    
      red = hexcolorToInt(c[0], c[1]);
      green = hexcolorToInt(c[2], c[3]);
      blue = hexcolorToInt(c[4], c[5]);
      Serial.print("REED: "); Serial.println(red);
      Serial.print("green: "); Serial.println(green);
      Serial.print("blue: "); Serial.println(blue);
      
      update_light();
    
      
          send_rgb_message();
      }
      
      
      
      
      
      //When receiving a V_STATUS command, switch the light between OFF
      //and the last received dimmer value
      
      
      if ( message.type == V_STATUS ) {
        Serial.println( "V_STATUS command received..." );
    
        int lstate = message.getInt();
        if (( lstate < 0 ) || ( lstate > 1 )) {
          Serial.println( "V_STATUS data invalid (should be 0/1)" );
          return;
        }
        last_state = lstate;
    
        //If last dimmer state is zero, set dimmer to 100
        if (( last_state == LIGHT_ON ) && ( last_dim == 0 )) {
          last_dim=100;
        }
    
        //Update constroller status
        send_status_message();
    
      } else if ( message.type == V_PERCENTAGE ) {
        Serial.println( "V_PERCENTAGE command received..." );
        
        int dim_value = constrain( message.getInt(), 0, 100 );
        
        if ( dim_value == 0 ) {
          last_state = LIGHT_OFF;
    
          //Update constroller with dimmer value & status
          send_dimmer_message();
          send_status_message();
     
           
        } else {
    
          
          last_state = LIGHT_ON;
          last_dim = dim_value;
          Serial.println(red);
          Serial.println(last_dim);
    
          int dimmerval = last_dim;
          //red = red /100 * dimmerval;
          //green = green /100 * dimmerval; 
          //blue = blue /100 * dimmerval;    
          Serial.println(red);
          Serial.println(dimmerval);
          //Driver.begin(); // begin
          //Driver.SetColor(red, green, blue); //Red. first node data
          //Driver.SetColor(red, green, blue); //Blue. second node data
          //Driver.end();
          
          //Update constroller with dimmer value
          send_dimmer_message();
        }
    
      } else {
        
        Serial.println( "Invalid command received..." );
        return;
      }
    
      //Here you set the actual light state/level
      update_light();
    }
    
    void update_light()
    {
      //For this example, just print the light status to console.
      if ( last_state == LIGHT_OFF ) {
        Serial.println( "Light state: OFF" );
    
          // colorWipe(strip.Color(0, 0, 0), 0); // Red
          //Driver.begin(); // begin
          //Driver.SetColor(0, 0, 0); //Red. first node data
          //Driver.SetColor(0, 0, 0); //Blue. second node data
          //Driver.end();
      } else {
        Serial.print( "Light state: ON, Level: " );
        Serial.println( last_dim );
    
        
    
          int reddim = red /100 * last_dim;
          int greendim = green /100 * last_dim; 
          int bluedim = blue /100 * last_dim;  
    
         //colorWipe(strip.Color(red, green, blue), 2); // Red
    
     
          int yada = NUM_LEDS * last_dim / 100;
          ;
          Serial.print("yadavalue: " );
          Serial.println (yada);
          
          int pixelfiller = NUM_LEDS - yada ;
    
                Serial.print("pixelfiller: ");
          Serial.println (pixelfiller);
    
    
         //strip.fill(red_ada, 0, yada);
         //strip.fill(black_ada, yada, pixelfiller);
         //strip.show();
     
    
         
         
          //Driver.begin(); // begin
          //Driver.SetColor(reddim, greendim, bluedim); //Red. first node data
          //Driver.SetColor(reddim, greendim, bluedim); //Red. first node data
          //Driver.end();
      }
    }
    
    void send_rgb_message()
    {
      send( rgbMsg.set(rgb));
    }
      
    void send_dimmer_message()
    {
      send( dimmerMsg.set( last_dim ) );
    }
    
    void send_status_message()
    {
      if ( last_state == LIGHT_OFF ) {
        send( lightMsg.set( (int16_t)0) );
      } else {
        send( lightMsg.set( (int16_t)1) );
      }
    }
    
    
    void getRGB(String hexvalue) {
      hexvalue.toUpperCase();
    
      char c[7];
      hexvalue.toCharArray(c, 8);
      int red = hexcolorToInt(c[1], c[2]);
      int green = hexcolorToInt(c[3], c[4]);
      int blue = hexcolorToInt(c[5], c[6]);
      Serial.print("REED: "); Serial.println(red);
      Serial.print("green: "); Serial.println(green);
      Serial.print("blue: "); Serial.println(blue);
      return red + green + blue;
    }
    
    int hexcolorToInt(char upper, char lower)
    {
      int uVal = (int)upper;
      int lVal = (int)lower;
      uVal = uVal > 64 ? uVal - 55 : uVal - 48;
      uVal = uVal << 4;
      lVal = lVal > 64 ? lVal - 55 : lVal - 48;
      //  Serial.println(uVal+lVal);
      return uVal + lVal;
    }
    
    // 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 Fire(int Cooling, int Sparking, int SpeedDelay) {
      static byte heat[NUM_LEDS];
      int cooldown;
      
      // Step 1.  Cool down every cell a little
      for( int i = 0; i < NUM_LEDS; i++) {
        cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
        
        if(cooldown>heat[i]) {
          heat[i]=0;
        } else {
          heat[i]=heat[i]-cooldown;
        }
      }
      
      // Step 2.  Heat from each cell drifts 'up' and diffuses a little
      for( int k= NUM_LEDS - 1; k >= 2; k--) {
        heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
      }
        
      // Step 3.  Randomly ignite new 'sparks' near the bottom
      if( random(255) < Sparking ) {
        int y = random(7);
        heat[y] = heat[y] + random(160,255);
        //heat[y] = random(160,255);
      }
    
      // Step 4.  Convert heat to LED colors
      for( int j = 0; j < NUM_LEDS; j++) {
        setPixelHeatColor(j, heat[j] );
      }
    
      showStrip();
      delay(SpeedDelay);
    }
    
    void setPixelHeatColor (int Pixel, byte temperature) {
      // Scale 'heat' down from 0-255 to 0-191
      byte t192 = round((temperature/255.0)*191);
     
      // calculate ramp up from
      byte heatramp = t192 & 0x3F; // 0..63
      heatramp <<= 2; // scale up to 0..252
     
      // figure out which third of the spectrum we're in:
      if( t192 > 0x80) {                     // hottest
        setPixel(Pixel, 255, 255, heatramp);
      } else if( t192 > 0x40 ) {             // middle
        setPixel(Pixel, 255, heatramp, 0);
      } else {                               // coolest
        setPixel(Pixel, heatramp, 0, 0);
      }
    }
    
    /*
    void Fire(int Cooling, int Sparking, int SpeedDelay) {
      static byte heat[NUM_LEDS];
      int cooldown;
      
      // Step 1.  Cool down every cell a little
      for( int i = 0; i < NUM_LEDS; i++) {
        cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
        
        if(cooldown>heat[i]) {
          heat[i]=0;
        } else {
          heat[i]=heat[i]-cooldown;
        }
      }
      
      // Step 2.  Heat from each cell drifts 'up' and diffuses a little
      for( int k= NUM_LEDS - 1; k >= 2; k--) {
        heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
      }
        
      // Step 3.  Randomly ignite new 'sparks' near the bottom
      if( random(255) < Sparking ) {
        int y = random(7);
        heat[y] = heat[y] + random(160,255);
        //heat[y] = random(160,255);
      }
    
      // Step 4.  Convert heat to LED colors
      for( int j = 0; j < NUM_LEDS; j++) {
        setPixelHeatColor(j, heat[j] );
      }
    
      showStrip();
      delay(SpeedDelay);
    }
    
    void setPixelHeatColor (int Pixel, byte temperature) {
      // Scale 'heat' down from 0-255 to 0-191
      byte t192 = round((temperature/255.0)*191);
     
      // calculate ramp up from
      byte heatramp = t192 & 0x3F; // 0..63
      heatramp <<= 2; // scale up to 0..252
     
      // figure out which third of the spectrum we're in:
      if( t192 > 0x80) {                     // hottest
        setPixel(Pixel, 255, 255, heatramp);
      } else if( t192 > 0x40 ) {             // middle
        setPixel(Pixel, 255, heatramp, 0);
      } else {                               // coolest
        setPixel(Pixel, heatramp, 0, 0);
      }
    }
    */
    
    void showStrip() {
     #ifdef ADAFRUIT_NEOPIXEL_H 
       // NeoPixel
       strip.show();
     #endif
     #ifndef ADAFRUIT_NEOPIXEL_H
       // FastLED
       FastLED.show();
     #endif
    }
    
    void setPixel(int Pixel, byte red, byte green, byte blue) {
     #ifdef ADAFRUIT_NEOPIXEL_H 
       // NeoPixel
       strip.setPixelColor(Pixel, strip.Color(red, green, blue));
     #endif
     #ifndef ADAFRUIT_NEOPIXEL_H 
       // FastLED
       leds[Pixel].r = red;
       leds[Pixel].g = green;
       leds[Pixel].b = blue;
     #endif
    }
    
    void setAll(byte red, byte green, byte blue) {
      for(int i = 0; i < NUM_LEDS; i++ ) {
        setPixel(i, red, green, blue); 
      }
      showStrip();
    }
    

    what is weird is that if i set the value of the NUM_LEDS to more than 201 it stops working. the flames just dont work anymore eventhough mysensors works fine. If it just take the part of the LEDs and exclude mysensors it works perfectly fine again with higher values like 350...

    #include <Adafruit_NeoPixel.h>
    #define PIN 2
    #define NUM_LEDS 350
    // Parameter 1 = number of pixels in strip
    // Parameter 2 = pin number (most are valid)
    // Parameter 3 = pixel type flags, add together as needed:
    //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
    //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
    //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
    //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     *
     * DESCRIPTION
     * Example sketch showing how to control physical relays.
     * This example will remember relay state after power failure.
     * http://www.mysensors.org/build/relay
     * 
     * 
     * 
     * Only sends a quick pulse via a reed relay. Useful to hack other devices with push 
     * buttons. In my case, a cheap IKEA dishwasher that didn't have a timer.
     */
    
    // security
    //#define MY_SIGNING_SIMPLE_PASSWD   "changeme"
    //#define MY_ENCRYPTION_SIMPLE_PASSWD "changeme"
    
    //#define MY_RF24_DATARATE RF24_250KBPS // Slower datarate offers more range. Only the + version of the radio supports 250kbps
    //#define MY_RF24_DATARATE RF24_1MBPS               
    //#define MY_RF24_DATARATE RF24_2MBPS
    
    
    #define MY_RF24_CE_PIN 10 
    #define MY_RF24_CS_PIN 9
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    #define MY_NODE_ID 76
    
    // Enable and select radio type attached 
    #define MY_RADIO_RF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    //#define MY_RF24_CE_PIN 49
    //#define MY_RF24_CS_PIN 53
    
    //#define MY_RF24_PA_LEVEL RF24_PA_MIN
    #define MY_RF24_PA_LEVEL RF24_PA_LOW
    
    
    // Enable repeater functionality for this node
    //#define MY_REPEATER_FEATURE
    
    #include <MySensors.h>
    
    // MySensors children
    #define DEVICE_STATUS_ID 0                          // The first 'child' of this device is a text field that contains status updates.
    #define RELAY_1_CHILD_ID 1 // MySensors child ID
    #define DONE_CHILD_ID 2 // MySensors child ID
    
    #define RELAY_1_PIN  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    #define PULSELENGTH 500 // How long the pulse should last (how long the button should be pressed).
    
    #define LOOPDURATION 600000
    #define ON_TOO_LONG 9 // If it's been on for X * 10 minutes, then it should send a message.
    #define RADIO_DELAY 150 // Keeps the bad Chinese radio happy / supplied with stable power.
    
    byte loopCounter = 0;
    boolean state = 0;
    byte retryCounter = 3;
    
    MyMessage charmsg(DEVICE_STATUS_ID, V_TEXT);        // Sets up the message format that we'll be sending to the MySensors gateway later. The first part is the ID of the specific sensor module on this node. The second part tells the gateway what kind of data to expect.
    MyMessage relaymsg(RELAY_1_CHILD_ID, V_STATUS);
    MyMessage donemsg(DONE_CHILD_ID, V_TRIPPED);
    
    
    
    void before()
    {
      //for (int pin=0; pin < NUMBER_OF_RELAYS; pin++) {
        // Then set relay pins in output mode
      //  pinMode(pin + RELAY_1_PIN, OUTPUT);
        // Set relay to last known state (using eeprom storage)
      //  digitalWrite(pin, LOW);
      //}
        pinMode(RELAY_1_PIN, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(RELAY_1_PIN, LOW);
     
    }
    
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(F("stepperzeug"), F("1.1")); wait(RADIO_DELAY);
      present(DEVICE_STATUS_ID, S_INFO, F("Status")); wait(RADIO_DELAY); 
      present(RELAY_1_CHILD_ID, S_BINARY, F("Start")); wait(RADIO_DELAY);
      present(DONE_CHILD_ID, S_MOTION, F("Done?")); wait(RADIO_DELAY);
    
      //send(relaymsg.setSensor(RELAY_1_CHILD_ID).set( RELAY_OFF )); wait(200);
      //for (int i=0; i<NUMBER_OF_RELAYS; i++) {
        // Register all sensors to gw (they will be created as child devices)
        //present(sensor, S_BINARY, F("Start")); wait(100);
        //send(relaymsg.setSensor(RELAY_1).set( RELAY_OFF )); wait(100);
      //}
    }
    
    
    void setup()
    {
      
      wait(1000);
      Serial.begin(115200);
      Serial.println(F("Hello world, I am a dish washer."));
        strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    
      if(isTransportReady()){
        Serial.println(F("Connected to gateway"));
        
    
      send(charmsg.setSensor(DEVICE_STATUS_ID).set( F("Dishwasher turned on"))); wait(RADIO_DELAY);  
      send(relaymsg.set(state?false:true), true); wait(RADIO_DELAY); // Send new state and request ack back
      send(donemsg.setSensor(DONE_CHILD_ID).set(0)); wait(RADIO_DELAY);
        
      }else{
        Serial.println(F("Not connected to gateway"));
      }  
    }
    
    
    void loop()
    {
    
    
    
    Fire(-500,15,0);
    
    }
    /*
    
    void messageRepeat(MyMessage &message, bool ack = true) {
      int repeat = 1;
      int repeats = 10;
      int repeatdelay = 0;
      boolean sendOK = false;
    
      Serial.print("Sending message of child ");
      Serial.println(message.sensor);
    
      while ((sendOK == false) and (repeat < repeats)) {
        if (send(message, ack)) {
          sendOK = true;
          Serial.print("Send OK");
        } else {
          sendOK = false;
          Serial.print("Send ERROR ");
          Serial.print(repeat);
          repeatdelay += RADIO_DELAY;
        }
    
        if (ack == true) {
          Serial.println(" With ack ");
        } else {
          Serial.println(" Without ack ");
        }
    
        repeat++;
        wait(repeatdelay);
      }
    }
    
    */
    
    
    void receive(const MyMessage &message)
    {
      // We only expect one type of message from controller. But we better check anyway.
    
      Serial.print("Incoming message for child: ");
      Serial.println(message.sensor);
    
      if (message.isAck() && message.sensor == RELAY_1_CHILD_ID) { // We got the ACK!
        Serial.println("- Received ACK for relay");
        retryCounter = 0;
      }
      else{
        // Change relay state
        Serial.println("-Gateway wants to change relay position");
        if (message.type==V_STATUS) {
          
          Serial.print ("-Received V_status:");
          Serial.println(message.getBool());
          
          if( message.sensor == RELAY_1_CHILD_ID ){
            boolean desiredState = message.getBool()?RELAY_ON:RELAY_OFF;
              if(desiredState == RELAY_ON){
              //digitalWrite(message.sensor-1+RELAY_1_PIN, RELAY_ON);
              //wait(PULSELENGTH);
              //digitalWrite(message.sensor-1+RELAY_1_PIN, RELAY_OFF);
              Serial.print ("-Switching relay on...");
              digitalWrite(RELAY_1_PIN, RELAY_ON);
              //wait(PULSELENGTH);
              //Serial.println ("Switching relay off.");
              //digitalWrite(RELAY_1_PIN, RELAY_OFF);
              send(relaymsg.set(RELAY_ON), true); wait(RADIO_DELAY); 
              //retryCounter = 3;
              }
              if(desiredState == RELAY_OFF){
              //digitalWrite(message.sensor-1+RELAY_1_PIN, RELAY_ON);
              //wait(PULSELENGTH);
              //digitalWrite(message.sensor-1+RELAY_1_PIN, RELAY_OFF);
              //Serial.print ("-Switching relay on...");
              //digitalWrite(RELAY_1_PIN, RELAY_ON);
              //wait(PULSELENGTH);
              Serial.println ("Switching relay off.");
              digitalWrite(RELAY_1_PIN, RELAY_OFF);
              send(relaymsg.set(RELAY_OFF), true); wait(RADIO_DELAY); 
              //retryCounter = 3;
              }
          }
          //digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
          // Store state in eeprom
          saveState(message.sensor, message.getBool());
          // Write some debug info
        }
      }
    }
    
    
    void Fire(int Cooling, int Sparking, int SpeedDelay) {
      static byte heat[NUM_LEDS];
      int cooldown;
      
      // Step 1.  Cool down every cell a little
      for( int i = 0; i < NUM_LEDS; i++) {
        cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
        
        if(cooldown>heat[i]) {
          heat[i]=0;
        } else {
          heat[i]=heat[i]-cooldown;
        }
      }
      
      // Step 2.  Heat from each cell drifts 'up' and diffuses a little
      for( int k= NUM_LEDS - 1; k >= 2; k--) {
        heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
      }
        
      // Step 3.  Randomly ignite new 'sparks' near the bottom
      if( random(255) < Sparking ) {
        int y = random(7);
        heat[y] = heat[y] + random(160,255);
        //heat[y] = random(160,255);
      }
    
      // Step 4.  Convert heat to LED colors
      for( int j = 0; j < NUM_LEDS; j++) {
        setPixelHeatColor(j, heat[j] );
      }
    
      showStrip();
      delay(SpeedDelay);
    }
    
    void setPixelHeatColor (int Pixel, byte temperature) {
      // Scale 'heat' down from 0-255 to 0-191
      byte t192 = round((temperature/255.0)*150);
     
      // calculate ramp up from
      byte heatramp = t192 & 0x3F; // 0..63
      heatramp <<= 0; // scale up to 0..252
     
      // figure out which third of the spectrum we're in:
      if( t192 > 0x80) {                     // hottest
        setPixel(Pixel, 255, 255, heatramp);
      } else if( t192 > 0x40 ) {             // middle
        setPixel(Pixel, 255, heatramp, 0);
      } else {                               // coolest
        setPixel(Pixel, heatramp, 0, 0);
      }
    }
    // *** REPLACE TO HERE ***
    
    void showStrip() {
     #ifdef ADAFRUIT_NEOPIXEL_H 
       // NeoPixel
       strip.show();
     #endif
     #ifndef ADAFRUIT_NEOPIXEL_H
       // FastLED
       FastLED.show();
     #endif
    }
    
    void setPixel(int Pixel, byte red, byte green, byte blue) {
     #ifdef ADAFRUIT_NEOPIXEL_H 
       // NeoPixel
       strip.setPixelColor(Pixel, strip.Color(red, green, blue));
     #endif
     #ifndef ADAFRUIT_NEOPIXEL_H 
       // FastLED
       leds[Pixel].r = red;
       leds[Pixel].g = green;
       leds[Pixel].b = blue;
     #endif
    }
    
    void setAll(byte red, byte green, byte blue) {
      for(int i = 0; i < NUM_LEDS; i++ ) {
        setPixel(i, red, green, blue); 
      }
      showStrip();
    }
    

    just adding mysensors makes it weird. I tried everything but nothing works so far. does anybody have an idea?



  • @zen85 could it be you have an overflow somewhere. You multiply num_leds by another value into an int, perhaps that should be a long



  • first i had the same thought. so i tried adding the flames to another really simple mysensors-relaysketch which have nothing to do with each other and the same thing happens... values over 201 brake the flames entirely as long as there is a mysensors-radio running. i tried with that code:

    #include <Adafruit_NeoPixel.h>
    #define PIN 2
    #define NUM_LEDS 350
    // Parameter 1 = number of pixels in strip
    // Parameter 2 = pin number (most are valid)
    // Parameter 3 = pixel type flags, add together as needed:
    //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
    //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
    //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
    //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     *
     * DESCRIPTION
     * Example sketch showing how to control physical relays.
     * This example will remember relay state after power failure.
     * http://www.mysensors.org/build/relay
     * 
     * 
     * 
     * Only sends a quick pulse via a reed relay. Useful to hack other devices with push 
     * buttons. In my case, a cheap IKEA dishwasher that didn't have a timer.
     */
    
    // security
    //#define MY_SIGNING_SIMPLE_PASSWD   "changeme"
    //#define MY_ENCRYPTION_SIMPLE_PASSWD "changeme"
    
    //#define MY_RF24_DATARATE RF24_250KBPS // Slower datarate offers more range. Only the + version of the radio supports 250kbps
    //#define MY_RF24_DATARATE RF24_1MBPS               
    //#define MY_RF24_DATARATE RF24_2MBPS
    
    
    #define MY_RF24_CE_PIN 10 
    #define MY_RF24_CS_PIN 9
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    #define MY_NODE_ID 76
    
    // Enable and select radio type attached 
    #define MY_RADIO_RF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    //#define MY_RF24_CE_PIN 49
    //#define MY_RF24_CS_PIN 53
    
    //#define MY_RF24_PA_LEVEL RF24_PA_MIN
    #define MY_RF24_PA_LEVEL RF24_PA_LOW
    
    
    // Enable repeater functionality for this node
    //#define MY_REPEATER_FEATURE
    
    #include <MySensors.h>
    
    // MySensors children
    #define DEVICE_STATUS_ID 0                          // The first 'child' of this device is a text field that contains status updates.
    #define RELAY_1_CHILD_ID 1 // MySensors child ID
    #define DONE_CHILD_ID 2 // MySensors child ID
    
    #define RELAY_1_PIN  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    #define PULSELENGTH 500 // How long the pulse should last (how long the button should be pressed).
    
    #define LOOPDURATION 600000
    #define ON_TOO_LONG 9 // If it's been on for X * 10 minutes, then it should send a message.
    #define RADIO_DELAY 150 // Keeps the bad Chinese radio happy / supplied with stable power.
    
    byte loopCounter = 0;
    boolean state = 0;
    byte retryCounter = 3;
    
    MyMessage charmsg(DEVICE_STATUS_ID, V_TEXT);        // Sets up the message format that we'll be sending to the MySensors gateway later. The first part is the ID of the specific sensor module on this node. The second part tells the gateway what kind of data to expect.
    MyMessage relaymsg(RELAY_1_CHILD_ID, V_STATUS);
    MyMessage donemsg(DONE_CHILD_ID, V_TRIPPED);
    
    
    
    void before()
    {
      //for (int pin=0; pin < NUMBER_OF_RELAYS; pin++) {
        // Then set relay pins in output mode
      //  pinMode(pin + RELAY_1_PIN, OUTPUT);
        // Set relay to last known state (using eeprom storage)
      //  digitalWrite(pin, LOW);
      //}
        pinMode(RELAY_1_PIN, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(RELAY_1_PIN, LOW);
     
    }
    
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(F("stepperzeug"), F("1.1")); wait(RADIO_DELAY);
      present(DEVICE_STATUS_ID, S_INFO, F("Status")); wait(RADIO_DELAY); 
      present(RELAY_1_CHILD_ID, S_BINARY, F("Start")); wait(RADIO_DELAY);
      present(DONE_CHILD_ID, S_MOTION, F("Done?")); wait(RADIO_DELAY);
    
      //send(relaymsg.setSensor(RELAY_1_CHILD_ID).set( RELAY_OFF )); wait(200);
      //for (int i=0; i<NUMBER_OF_RELAYS; i++) {
        // Register all sensors to gw (they will be created as child devices)
        //present(sensor, S_BINARY, F("Start")); wait(100);
        //send(relaymsg.setSensor(RELAY_1).set( RELAY_OFF )); wait(100);
      //}
    }
    
    
    void setup()
    {
      
      wait(1000);
      Serial.begin(115200);
      Serial.println(F("Hello world, I am a dish washer."));
        strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    
      if(isTransportReady()){
        Serial.println(F("Connected to gateway"));
        
    
      send(charmsg.setSensor(DEVICE_STATUS_ID).set( F("Dishwasher turned on"))); wait(RADIO_DELAY);  
      send(relaymsg.set(state?false:true), true); wait(RADIO_DELAY); // Send new state and request ack back
      send(donemsg.setSensor(DONE_CHILD_ID).set(0)); wait(RADIO_DELAY);
        
      }else{
        Serial.println(F("Not connected to gateway"));
      }  
    }
    
    
    void loop()
    {
    
    
    
    Fire(-500,15,0);
    
    }
    /*
    
    void messageRepeat(MyMessage &message, bool ack = true) {
      int repeat = 1;
      int repeats = 10;
      int repeatdelay = 0;
      boolean sendOK = false;
    
      Serial.print("Sending message of child ");
      Serial.println(message.sensor);
    
      while ((sendOK == false) and (repeat < repeats)) {
        if (send(message, ack)) {
          sendOK = true;
          Serial.print("Send OK");
        } else {
          sendOK = false;
          Serial.print("Send ERROR ");
          Serial.print(repeat);
          repeatdelay += RADIO_DELAY;
        }
    
        if (ack == true) {
          Serial.println(" With ack ");
        } else {
          Serial.println(" Without ack ");
        }
    
        repeat++;
        wait(repeatdelay);
      }
    }
    
    */
    
    
    void receive(const MyMessage &message)
    {
      // We only expect one type of message from controller. But we better check anyway.
    
      Serial.print("Incoming message for child: ");
      Serial.println(message.sensor);
    
      if (message.isAck() && message.sensor == RELAY_1_CHILD_ID) { // We got the ACK!
        Serial.println("- Received ACK for relay");
        retryCounter = 0;
      }
      else{
        // Change relay state
        Serial.println("-Gateway wants to change relay position");
        if (message.type==V_STATUS) {
          
          Serial.print ("-Received V_status:");
          Serial.println(message.getBool());
          
          if( message.sensor == RELAY_1_CHILD_ID ){
            boolean desiredState = message.getBool()?RELAY_ON:RELAY_OFF;
              if(desiredState == RELAY_ON){
              //digitalWrite(message.sensor-1+RELAY_1_PIN, RELAY_ON);
              //wait(PULSELENGTH);
              //digitalWrite(message.sensor-1+RELAY_1_PIN, RELAY_OFF);
              Serial.print ("-Switching relay on...");
              digitalWrite(RELAY_1_PIN, RELAY_ON);
              //wait(PULSELENGTH);
              //Serial.println ("Switching relay off.");
              //digitalWrite(RELAY_1_PIN, RELAY_OFF);
              send(relaymsg.set(RELAY_ON), true); wait(RADIO_DELAY); 
              //retryCounter = 3;
              }
              if(desiredState == RELAY_OFF){
              //digitalWrite(message.sensor-1+RELAY_1_PIN, RELAY_ON);
              //wait(PULSELENGTH);
              //digitalWrite(message.sensor-1+RELAY_1_PIN, RELAY_OFF);
              //Serial.print ("-Switching relay on...");
              //digitalWrite(RELAY_1_PIN, RELAY_ON);
              //wait(PULSELENGTH);
              Serial.println ("Switching relay off.");
              digitalWrite(RELAY_1_PIN, RELAY_OFF);
              send(relaymsg.set(RELAY_OFF), true); wait(RADIO_DELAY); 
              //retryCounter = 3;
              }
          }
          //digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
          // Store state in eeprom
          saveState(message.sensor, message.getBool());
          // Write some debug info
        }
      }
    }
    
    
    void Fire(int Cooling, int Sparking, int SpeedDelay) {
      static byte heat[NUM_LEDS];
      int cooldown;
      
      // Step 1.  Cool down every cell a little
      for( int i = 0; i < NUM_LEDS; i++) {
        cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
        
        if(cooldown>heat[i]) {
          heat[i]=0;
        } else {
          heat[i]=heat[i]-cooldown;
        }
      }
      
      // Step 2.  Heat from each cell drifts 'up' and diffuses a little
      for( int k= NUM_LEDS - 1; k >= 2; k--) {
        heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
      }
        
      // Step 3.  Randomly ignite new 'sparks' near the bottom
      if( random(255) < Sparking ) {
        int y = random(7);
        heat[y] = heat[y] + random(160,255);
        //heat[y] = random(160,255);
      }
    
      // Step 4.  Convert heat to LED colors
      for( int j = 0; j < NUM_LEDS; j++) {
        setPixelHeatColor(j, heat[j] );
      }
    
      showStrip();
      delay(SpeedDelay);
    }
    
    void setPixelHeatColor (int Pixel, byte temperature) {
      // Scale 'heat' down from 0-255 to 0-191
      byte t192 = round((temperature/255.0)*150);
     
      // calculate ramp up from
      byte heatramp = t192 & 0x3F; // 0..63
      heatramp <<= 0; // scale up to 0..252
     
      // figure out which third of the spectrum we're in:
      if( t192 > 0x80) {                     // hottest
        setPixel(Pixel, 255, 255, heatramp);
      } else if( t192 > 0x40 ) {             // middle
        setPixel(Pixel, 255, heatramp, 0);
      } else {                               // coolest
        setPixel(Pixel, heatramp, 0, 0);
      }
    }
    // *** REPLACE TO HERE ***
    
    void showStrip() {
     #ifdef ADAFRUIT_NEOPIXEL_H 
       // NeoPixel
       strip.show();
     #endif
     #ifndef ADAFRUIT_NEOPIXEL_H
       // FastLED
       FastLED.show();
     #endif
    }
    
    void setPixel(int Pixel, byte red, byte green, byte blue) {
     #ifdef ADAFRUIT_NEOPIXEL_H 
       // NeoPixel
       strip.setPixelColor(Pixel, strip.Color(red, green, blue));
     #endif
     #ifndef ADAFRUIT_NEOPIXEL_H 
       // FastLED
       leds[Pixel].r = red;
       leds[Pixel].g = green;
       leds[Pixel].b = blue;
     #endif
    }
    
    void setAll(byte red, byte green, byte blue) {
      for(int i = 0; i < NUM_LEDS; i++ ) {
        setPixel(i, red, green, blue); 
      }
      showStrip();
    }
    

    whereas:

    #include <Adafruit_NeoPixel.h>
    #define PIN 2
    #define NUM_LEDS 350
    // Parameter 1 = number of pixels in strip
    // Parameter 2 = pin number (most are valid)
    // Parameter 3 = pixel type flags, add together as needed:
    //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
    //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
    //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
    //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
    
    void setup() {
      strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    }
    
    // *** REPLACE FROM HERE ***
    void loop() {
      Fire(-500,15,0);
    }
    
    void Fire(int Cooling, int Sparking, int SpeedDelay) {
      static byte heat[NUM_LEDS];
      int cooldown;
      
      // Step 1.  Cool down every cell a little
      for( int i = 0; i < NUM_LEDS; i++) {
        cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
        
        if(cooldown>heat[i]) {
          heat[i]=0;
        } else {
          heat[i]=heat[i]-cooldown;
        }
      }
      
      // Step 2.  Heat from each cell drifts 'up' and diffuses a little
      for( int k= NUM_LEDS - 1; k >= 2; k--) {
        heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
      }
        
      // Step 3.  Randomly ignite new 'sparks' near the bottom
      if( random(255) < Sparking ) {
        int y = random(7);
        heat[y] = heat[y] + random(160,255);
        //heat[y] = random(160,255);
      }
    
      // Step 4.  Convert heat to LED colors
      for( int j = 0; j < NUM_LEDS; j++) {
        setPixelHeatColor(j, heat[j] );
      }
    
      showStrip();
      delay(SpeedDelay);
    }
    
    void setPixelHeatColor (int Pixel, byte temperature) {
      // Scale 'heat' down from 0-255 to 0-191
      byte t192 = round((temperature/255.0)*150);
     
      // calculate ramp up from
      byte heatramp = t192 & 0x3F; // 0..63
      heatramp <<= 0; // scale up to 0..252
     
      // figure out which third of the spectrum we're in:
      if( t192 > 0x80) {                     // hottest
        setPixel(Pixel, 255, 255, heatramp);
      } else if( t192 > 0x40 ) {             // middle
        setPixel(Pixel, 255, heatramp, 0);
      } else {                               // coolest
        setPixel(Pixel, heatramp, 0, 0);
      }
    }
    // *** REPLACE TO HERE ***
    
    void showStrip() {
     #ifdef ADAFRUIT_NEOPIXEL_H 
       // NeoPixel
       strip.show();
     #endif
     #ifndef ADAFRUIT_NEOPIXEL_H
       // FastLED
       FastLED.show();
     #endif
    }
    
    void setPixel(int Pixel, byte red, byte green, byte blue) {
     #ifdef ADAFRUIT_NEOPIXEL_H 
       // NeoPixel
       strip.setPixelColor(Pixel, strip.Color(red, green, blue));
     #endif
     #ifndef ADAFRUIT_NEOPIXEL_H 
       // FastLED
       leds[Pixel].r = red;
       leds[Pixel].g = green;
       leds[Pixel].b = blue;
     #endif
    }
    
    void setAll(byte red, byte green, byte blue) {
      for(int i = 0; i < NUM_LEDS; i++ ) {
        setPixel(i, red, green, blue); 
      }
      showStrip();
    }
    

    works perfectly fine....

    its really strange.



  • @zen85 I also see a delay being used. Can you change that to a wait()…?


  • Mod

    Are you getting a message regarding low memory when uplpading?

    Looks like you might be using an atmega328. It has a total of 2kB ram.

    201 pixels use 603 bytes, plus another 201 for the heat so 804 bytes. That could very well be at the limit.

    When verifying the sketch, you should get something similar to this:

    Global variables use 1278 bytes (62%) of dynamic memory, leaving 770 bytes for local variables. Maximum is 2048 bytes.
    


  • @mfalkvidd

    actually i am using a nano.

    it tells me:

    Sketch uses 18372 bytes (59%) of program storage space. Maximum is 30720 bytes.
    Global variables use 1070 bytes (52%) of dynamic memory, leaving 978 bytes for local variables. Maximum is 2048 bytes.
    

    but there is no warning...

    @electrik

    using wait(...) instead of delay(...) just gives me "wait can not be used as a function arduino" and nothing compiles... did you mean millis(...)?



  • @electrik

    i also tried to change it into long but there is no change in behaviour...



  • @zen85 that is strange. Are you using the latest drivers?
    See wait here
    https://www.mysensors.org/download/sensor_api_20



  • @electrik
    its indeed strange.
    i am using 2.3.1 - so this should be ok.... i replaced delay(wait) with wait(wait) which throws:
    "'wait' cannot be used as a function"

    my nano uses the "atmega328p (Old Bootloader)" as processor... could that be an issue but i dont see how...?



  • @zen85 said in NUM_LEDS value in LED-Strip Sketch can not be more than "201"?:

    @electrik
    its indeed strange.
    i am using 2.3.1 - so this should be ok.... i replaced delay(wait) with wait(wait) which throws:
    "'wait' cannot be used as a function"

    my nano uses the "atmega328p (Old Bootloader)" as processor... could that be an issue but i dont see how...?

    ok... i see why wait(wait) was a problem... i displaced the variable "wait" with another one and then it compiles... but it has no impact on the issue.

    i also checked out the limit again... it actually works up to 207 leds... more than that and it breaks...



  • oke.... apparently the storage for variables was too low on the nano.

    i replaced it with a mega and now it works.



  • I'm starting to run out of ideas... Is it just the flames that stop working, or is the normal dining still working (when you disable the flames code).
    It seems to me the mysensors task maybe takes to much time from the led strip library, which is quite time critical


  • Mod

    Seems like teh Arduino IDE is unable to calculate the memory usage for the Adafruit led strip object.
    When the Arduino IDE outputs
    Global variables use 1078 bytes (52%) of dynamic memory, leaving 970 bytes for local variables. Maximum is 2048 bytes
    it has not added the 603 bytes used by the Adafruit led strip object. So the real usage is 1 681 bytes which is 82%.

    Some general information on how Arduino memory works https://learn.adafruit.com/memories-of-an-arduino/optimizing-program-memory but there is not much you can do except switching to a mcu with more ram.



  • @electrik
    @mfalkvidd

    its exactly as you guys say. taking a mega solves my issue and thats fine. i work with arduinos for many years now but its the first time i ran out of storage so i did not have this on the radar. i also learned much about arduinos with that issue. i guess thats a huge thanks for steering me into the right direction.


  • Mod

    learning is the most fun part of Arduino (at least for me) 🙂

    Great work! If you have the time, you're very welcome to share a photo or video of your project. I have gotten a lot of inspiration from stuff other people have made.



  • @mfalkvidd
    i will definetly do that within the next days.


Log in to reply
 

Suggested Topics

72
Online

11.4k
Users

11.1k
Topics

112.7k
Posts