Scaling up Neopixels and InfraRed

So here's the previous project.

So, I'm going up from 3 pixels on a diddy, single strip to the 256 Pixels on the matt in the picture; I'm using the same code; the bench power unit is putting out 5v, 10amp; and its an Arduino Uno running the show. I've tested each of the components individually with different programs to ensure that they are all working properly because I have encountered a problem and I'm now wondering about feasibility.

I've read in other parts of the internets that the Uno will have no problems running up to 512 NeoPixels but when I send in the Infra Red signal it appears as it like the IR Receiver just blocks up (giving me a constant lit LED on receiver and I continue to see the loop outputting my serial monitor debugging messages), and the super interesting problem is that this is a problem inherent to using the roll of NeoPixels. Using a strip of Neopixels and putting data into the same amount of Pixels I don't have a crash.

The goal of the build is to go up to all 256 Pixels and ideally the personal challenge is to stay on the one Arduino.

Has anyone got any ideas as to what the cause of this may be? I'm tempted to lean towards memory usage but that doesn't explain the differing strips having differing performance.

2 things are missing. Code and schematics.

Well, the code was in the link to the previous thing but here we go -

//Always comment your code like it will be maintained by a violent psychopath who knows where you live.
#include <IRLibAll.h>                                                                       //Infra Red Library
#include <Adafruit_NeoPixel.h>                                                              //Adafruit NeoPixel Library

//======== Constants =============
const int LEDpin = 3;                                                                       //IO pin for the LED strip
const int LEDcount = 5;                                                                     //Number of LED's in the strip
const int IRreceiver = 2;                                                                   //IO pin for the IRreceiver
IRrecvPCI myReceiver(IRreceiver);                                                           //Instantiate the Infra Red receiver 
IRdecode myDecoder;                                                                         //Instatiate a Decoder object (Veriable to hold the recieved data from the button press)
enum  pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, color_WIPE, SCANNER, FADE };            //Limit the results 'pattern' will accept with an enumeration

//======== Variables =============

//=====Classes and Functions =====

class neoPatterns : public Adafruit_NeoPixel                                              //A class to govern the operation of the Neopixel patterns outside of the Main loop
{
  private:
    int steps;
    uint32_t color;
           
  public:

    pattern activePattern;                                                                  //Tracks the pattern that is currently active on the strip
    unsigned long interval;                                                                 //Milliseconds between updates
    unsigned long lastUpdate;                                                               //Records the millisecond of the last update

    uint32_t color1, color2;                                                              //Variables for recording active colors
    uint16_t totalSteps;                                                                    //How many steps of the pattern have been called
    uint16_t index;                                                                         //What step within the pattern we are on

    void (*onComplete)();                                                                   //onComplete callback function - still wondering how much i need this?
    
    neoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())             //Class constructor to...
    :Adafruit_NeoPixel(pixels, pin, type)                                                   //initialise the Neopixel strip
    {
      onComplete = callback;      
    }

  void update()                                                                             //Function that manages updating the pattern
  {
    Serial.println("update function");                                                                //debugging line for the Serial Monitor
    if((millis() - lastUpdate) > interval)                                                  //Is it time to update?
      {
      lastUpdate = millis();                                                                //Updates 'lastUpdate' to the current milli's value
      switch(activePattern)                                                                 //Switch statement to track which pattern needs its update function
        {
          case RAINBOW_CYCLE:                                                               //If rainbowCycle...
          rainbowCycleUpdate();                                                             //update rainbowCycle
          break;
  
          case THEATER_CHASE:                                                               //If theatreChase...
          theaterChaseUpdate();                                                             //update theatreChase
          break;
  
          case color_WIPE:                                                                 //if colorWipe
          colorWipeUpdate();                                                                //update colorWipe
          break;
  
          case SCANNER:                                                                     //if scanner
          scannerUpdate();                                                                  //update scanner
          break;
  
          case FADE:                                                                        //if fade
          fadeUpdate();                                                                     //update fade
          break;
  
          default:
          break;
        }
      }
  }

  void increment()                                                                          //Function for incrementing values to drive strand tests
  {
    index++;                                                                                //increment index variable
      if (index >= totalSteps)                                                              //if index is greater than or equal to totalsteps...
      {
        index = 0;                                                                          //..reset index to 0 and...
        if (onComplete != NULL)                                                             //... if onComplete has no value...
          {
            onComplete();                                                                   //...call the onComplete callback
          }
      }
  }  

  void rainbowCycle(uint8_t interval)                                                                //Rainbow Cycle strand test pattern
  {
    activePattern = RAINBOW_CYCLE;                                                          //Set current active pattern to Rainbow Cycle...
    interval = interval;                                                                    //reset interval to interval
    totalSteps = 255;                                                                       //set total step variable to 255
    index = 0;                                                                              //set index variable to 0
  }

  void rainbowCycleUpdate()                                                                 //update for Rainbow Cycle
  {
    for(int i=0; i< numPixels(); i++)                                                       //create a variable called 'i' which is equal to 0 and do loops, whilst the number of pixels in the strip is greater than i, incremeting i every loop.
    {
      setPixelColor(i, wheel(((i * 256 / numPixels()) + index) & 255));                     //set the pixel color to ...
    }
    show();                                                                          //update the orders to the Neopixel strand
    increment();                                                                            //Run the increment function
  }

  void colorWipe (uint32_t color, uint8_t interval)                                       //color wipe funtion
  {
    activePattern = color_WIPE;                                                            //update the current active pattern to color Wipe
    interval = interval;                                                                    //reset the interval variable
    totalSteps = 255;                                                                       //set the total steps variable to 255
    color1 = color;                                                                       //set color to color 1
    index = 0;                                                                              //reset the index variable to 0
  }

  void colorWipeUpdate()                                                                    //Color wipe update function
  {
    setPixelColor(index, color1);                                                           //change the pixel color to color1
    show();                                                                          //update the strand
    increment();                                                                            //run the increment function
  }

  void theaterChase(uint32_t color1, uint32_t color2, uint8_t interval)                   //Theatre Chase funtion
  {
    activePattern = THEATER_CHASE;                                                          //change the current active pattern to Theatre Chase 
    interval = interval;                                                                    //reset the interval variable 
    totalSteps = numPixels();                                                               //update the total steps variable to be equivilent to the number of pixels
    color1 = color1;                                                                      //Reset color1
    color2 = color2;                                                                      //Reset color2
    index = 0;                                                                              //Set index variable to 0
  }    

  void theaterChaseUpdate()                                                                 //Theatre Chase update function
  {
    for(int i=0; i< numPixels(); i++)                                                       //take the i variable and reset it to 0 and do loops, whilst the number of pixels in the strip is greater than i, incremeting i every loop.
      {
        if ((i + index) % 3 == 0)                                                           //if the total of I and index divide equally by 3...
          {
            setPixelColor(i, color1);                                                       //...set the pixelcolor to color 1...
          }
        else                                                                                //...otherwise... 
          {
            setPixelColor(i, color2);                                                       //set the pixel color to color 2
          }
      }
    show();                                                                          //update the neopixel strand
    increment();                                                                            //run the increment function
  }

  void scanner(uint32_t color1, uint8_t interval)                                          //Scanner function
  {
    activePattern = SCANNER;                                                                //update the active pattern to Scanner
    interval = interval;                                                                    //reset the interval variable
    totalSteps = (numPixels() - 1) * 2;                                             //set the total steps variable to by equal to twice that of the number of pixels on the strand less one 
    color1 = color1;                                                                      //reset the color1 variable 
    index = 0;                                                                              //set the index variable to 0
  }

  void scannerUpdate()                                                                      //Scanner update function
  {
    for (int i = 0; i < numPixels(); i++)                                                   //take the i variable and reset it to 0 and do loops, whilst the number of pixels in the strip is greater than i, incremeting i every loop.
    {
      if (i == index)                                                                       //if the i variable is equivilant to the index variable...
      {
        setPixelColor(i, color1);                                                          //set the pixel color to color1
      }
      else if (i == totalSteps - index)                                                     //if the i variable is equivilant to totalsteps less the value of index...
      {
        setPixelColor(i, color1);                                                           //set the pixel color to color1...
      }
      else                                                                                  //otherwise...
      {
        setPixelColor(i, DimColor(getPixelColor(i)));                                       //dim the current pixel value
      }
    }
    show();                                                                          //update the strand
    increment();                                                                            //run the increment function
  }  

  void fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval)           //Fade function
  {
    activePattern = FADE;                                                                   //set the current active pattern to fade
    interval = interval;                                                                    //reset the interval variable
    totalSteps = steps;                                                                     //create a new steps variable and set it to be eqivilant to totalSteps 
    color1 = color1;                                                                      //reset color1
    color2 = color2;                                                                      //reset color2
    index = 0;                                                                              //set index to 0
  }

  void fadeUpdate()                                                                                       //Fade update function
  {
    uint8_t red = ((Red(color1) * (totalSteps - index)) + (Red(color2) * index)) / totalSteps;          
    uint8_t green = ((Green(color1) * (totalSteps - index)) + (Green(color2) * index)) / totalSteps;
    uint8_t blue = ((Blue(color1) * (totalSteps - index)) + (Blue(color2) * index)) / totalSteps;
    colorSet(Color(red, green, blue));
    show();                                                                                        //update the strand
    increment();                                                                                          //run the increment function
  }

  uint8_t Red(uint32_t color)                                                              //Red color function
  {
    return (color >> 16) & 0xFF;    
  }

  uint8_t Green(uint32_t color)                                                            //Green color function
  {
    return (color >> 8) & 0xFF;
  }

  uint8_t Blue(uint32_t color)                                                             //Blue color function
  {
    return color & 0xFF;
  }

  uint32_t DimColor(uint32_t color)                                                        //color dimming function
  {
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }   
  
  uint32_t wheel(byte wheelPos)                                                             //color wheeling function for the rainbow color functions
  {
    wheelPos = 255 - wheelPos;
    if(wheelPos < 85)
    {
      return Color(255 - wheelPos * 3, 0, wheelPos * 3);
    }
    else if(wheelPos < 170)
    {
      wheelPos -= 85;
      return Color(0, wheelPos * 3, 255 - wheelPos * 3);
    }
    else
    {
      wheelPos -= 170;
      return Color(wheelPos * 3, 255 - wheelPos * 3, 0);    
    }
  }
 
  void colorSet(uint32_t color)                                                           //color set function sets all colors to the same synchronus color
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);    
    }
    show();    
  }

  void IRSelector()                                                                           //Infra Red selection function - takes action based on IR code received        
  {
    if (myDecoder.protocolNum == NEC) {                                                       //ignore any code that is not recieved from a NEC remote control 
      switch(myDecoder.value)                                                                   //Switch statement that makes a decision based upon the value recieved from the Infra Red decoder
      {
        case 0xFFA25D: Serial.println("Untethered button, please select from 0-8"); break;      //=====================================================================
        case 0xFFE21D: Serial.println("Untethered button, please select from 0-8"); break;
        case 0xFF629D: Serial.println("Untethered button, please select from 0-8"); break;
        case 0xFF22DD: Serial.println("Untethered button, please select from 0-8"); break;
        case 0xFF02FD: Serial.println("Untethered button, please select from 0-8"); break;      // ------------- UNASSIGNED BUTTON SELECTIONS -------------------------
        case 0xFFC23D: Serial.println("Untethered button, please select from 0-8"); break;
        case 0xFFE01F: Serial.println("Untethered button, please select from 0-8"); break;
        case 0xFFA857: Serial.println("Untethered button, please select from 0-8"); break;
        case 0xFF906F: Serial.println("Untethered button, please select from 0-8"); break;
        case 0xFF9867: Serial.println("Untethered button, please select from 0-8"); break;
        case 0xFFB04F: Serial.println("Untethered button, please select from 0-8"); break;      //=====================================================================
        
        case 0xFF6897:      //"0 - All black (off)"    
          colorWipe(color, interval);     
          Serial.println("0 - Black/off");    
          break;
        case 0xFF30CF:      //"1 - All red"
          colorWipe(color, interval);    
          Serial.println("1 - All red");    
          break;
        case 0xFF18E7:      //"2 - All green" 
          colorWipe(color, interval);         
          Serial.println("2 - All green");    
          break;
        case 0xFF7A85:      //"3 - All blue"
          colorWipe(color, interval);    
          Serial.println("3 - All blue");    
          break;
        case 0xFF10EF:      //"4 - All white"
          colorWipe(color, interval); 
          Serial.println("4 - All white");    
          break;
        case 0xFF38C7:       //"5 - Rainbow Cycle"
          rainbowCycle(interval);                      
          Serial.println("5");    
          break;
        case 0xFF5AA5:       //"6 - Theater Chase"
          theaterChase(color1, color2, interval);                                 
          Serial.println("6");    
          break;
        case 0xFF42BD:       //"7 - Scanner"
          scanner(color1, interval);                                 
          Serial.println("7");    
          break;
        case 0xFF4AB5:      //"8 - Fader"
          fade(color1, color2, steps, interval);                      
          Serial.println("8");    
          break;
        
        case 0xFF52AD: Serial.println("Untethered button, please select from 0-8");    break;      //button 9 - unassigned
        case 0xFFFFFFFF: Serial.println("Please release button and reselect");         break;      //consistant repeat code

        default: 
        Serial.print(" other button   ");                                                          
        Serial.println(myDecoder.value);

      }//End of Switch
    }
  }//End of IRSelector method
}; // End of neoPatterns class

void strandComplete();                                                                         
neoPatterns strand(LEDcount, LEDpin, NEO_RGBW + NEO_KHZ800, &strandComplete);               //Neopattern object to define the strand

void setup(){   /*----( SETUP: RUNS ONCE )----*/
  Serial.begin(9600);                                                                          //engage the serial monitor
  Serial.println("IR Receiver Button Decode");                                                 //print out to the monitor
  myReceiver.enableIRIn();                                                                     //Start the receiver
  strand.begin();                                                                              //start the Neopixel strip
}/*--(end setup )---*/

void loop(){   /*----( LOOP: RUNS CONSTANTLY )----*/
  if (myReceiver.getResults())                                                                 //check to see if we have received an IR signal?
  {
    myDecoder.decode();                                                                        //Decode the recieved signal
    strand.IRSelector();                                                                       //Run the IR selection function
    myReceiver.enableIRIn();                                                                   //reset the receiver for a new code
  }
  strand.update();
  Serial.println("LoopdeLoop");                                                                //debugging line for the Serial Monitor
}/* --(end main loop )-- */

void strandComplete()
{
    // Random color change for next scan
    strand.color1 = strand.wheel(random(255));
}

... and if the picture of the build wasn't enough I'm yet to find somewhere that I can draw good schematics on for free so if you recommend somewhere I'll go knock that up? :slight_smile:

Which is part of why you should not have started a new thread. Ask the moderators to combine the threads.

a7

Pencil and paper + camera = good schematic.

Ok, I'll take Alto's advice and move it over to the other string. I only moved here and started a new string because it was a new problem on a new project and I figured it was more of a prototyping question :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.