InfaRed selected switch statement with Neopixels

Ok, so I'm having some problems putting the finishing touches on the latest project. The Idea is to have an Infrared receiver mounted on a single Arduino Uno, taking ques from a remote to select preprogramed patterns on a Neopixel strip (selection from the Neopixel Strand test)

Here is some code...

//Always comment your code like a violent psychopath will be maintaining it and they know where you live
#include <Adafruit_NeoPixel.h>                            //Neopixel Library
#include <IRLibAll.h>                                     //IR reciever Library

IRrecvLoop myReceiver(2);                                     //IR receiver on IO pin 2
IRdecode myDecoder;                                       //Decoder object
unsigned long oldCode = 00000000;                         //Comparison variable to evaluate the execution of the 'Check' function later
Adafruit_NeoPixel strip (3,3,NEO_RGBW + NEO_KHZ800);      //Creates the Pixel strip as an object in the code

void setup() {
  strip.begin();                      //Initialise the Neopixel strip
  strip.show();                       //Initialise all pixels to 'off'
  myReceiver.enableIRIn();            // Start the IR receiver
}

void loop() {
  check();                            //Run the check function
  delay(20);                          //Delay before running the loop again by 20 milliseconds giving time to recieve signals
}

void check() {                                    //check Function: Checks for an IR signal before nominating which of the test displays to run
    if (oldCode = myDecoder.value){                    //Evaluates if the IR code recieved from the remote matches 'oldCode' and if it does....
    return;                                       //Terminates the check Function returning its values
    }                                                  
      if (myReceiver.getResults()) {
        myDecoder.decode();
        if (myDecoder.protocolNum == NEC) {  
          switch(myDecoder.value) {                                                                 //Activate this switch statement based on the value 'myDecoder' holds
            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;
            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:
              colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off  "0"     
              Serial.println("0 - Black/off");    
              break;
            case 0xFF30CF:
              colorWipe(strip.Color(255,   0,   0), 50);    // Red  "1"
              Serial.println("1 - All red");    
              break;
            case 0xFF18E7:
              colorWipe(strip.Color(  0, 255,   0), 50);    // Green  "2"      
              Serial.println("2 - All green");    
              break;
            case 0xFF7A85: 
              colorWipe(strip.Color(  0,   0, 255), 50);    // Blue  "3"
              Serial.println("3 - All blue");    
              break;
            case 0xFF10EF:
              theaterChase(strip.Color(127, 127, 127), 50); // White  "4"
              Serial.println("4 - All white");    
              break;
            case 0xFF38C7:
              theaterChase(strip.Color(127,   0,   0), 50); // Red  "5"
              Serial.println("5");    
              break;
            case 0xFF5AA5:
              theaterChase(strip.Color(  0,   0, 127), 50); // Blue   "6"
              Serial.println("6");    
              break;
            case 0xFF42BD:
              rainbow(10);                                  //      "7"
              Serial.println("7");    
              break;
            case 0xFF4AB5:
              theaterChaseRainbow(50);                      //      "8"
              Serial.println("8");    
              break;

            case 0xFF52AD: Serial.println("Untethered button, please select from 0-8");    break;
            case 0xFFFFFFFF: Serial.println("Please release button and reselect");         break;                          
        }
      }
    oldCode = myDecoder.value;                       //make the new button state equal the old buttonstate preventing the button from activating if statement
  }
}

void colorWipe(uint32_t color, int wait) {        //Colour wipe test
  while(true) {
    for(int i=0; i<strip.numPixels(); i++) {      // For each pixel in strip...
      strip.setPixelColor(i, color);              //  Set pixel's color (in RAM)
      strip.show();                               //  Update strip to match
      check();   
      delay(wait);                                //  Pause for a moment
  }
  }
}

void theaterChase(uint32_t color, int wait) {     //Theatre Chase test
  while(true) {
  for(int a=0; a<10; a++) {                       // Repeat 10 times...
    for(int b=0; b<3; b++) {                      //  'b' counts from 0 to 2...
      strip.clear();                              //   Set all pixels in RAM to 0 (off)
      for(int c=b; c<strip.numPixels(); c += 3) { // 'c' counts up from 'b' to end of strip in steps of 3...
        strip.setPixelColor(c, color);            // Set pixel 'c' to value 'color'
        check();                                  //Run the check function
      }
      strip.show();                               // Update strip with new contents
      delay(wait);                                // Pause for a moment
    }
  }
  }
}
void rainbow(int wait) {                                                            //Rainbow test function
  while(true) {                                                                     //while this function is active
  for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {      //Sets differing colours for the rainbow 
    for(int i=0; i<strip.numPixels(); i++) {                                        //For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());              //balances the colour pattern along the length of the strip
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));              //run the colour pattern along the strip
      check();                                                                      //run the check function
    }
    strip.show();                                                                   //Update strip with new contents
    delay(wait);                                                                    //Pause for a moment
  }
  }
}

void theaterChaseRainbow(int wait) {
  while(true) {
  int firstPixelHue = 0;                                                            //First pixel starts at red
  for(int a=0; a<30; a++) {                                                         //Repeat 30 times...
    for(int b=0; b<3; b++) {                                                        //'b' counts from 0 to 2...
      strip.clear();                                                                //Set all pixels to off
      for(int c=b; c<strip.numPixels(); c += 3) {                                   //'c' counts up from 'b' to end of strip in increments of 3, hue of pixel 'c' is offset by an amount to make one full revolution of the color wheel (range 65536) along the length of the strip (strip.numPixels() steps):
        int hue = firstPixelHue + c * 65536L / strip.numPixels();                   //create the hue variable and balance the rainbow colouring across the strip
        uint32_t color = strip.gamma32(strip.ColorHSV(hue));                        // hue -> RGB
        strip.setPixelColor(c, color);                                              // Set pixel 'c' to value 'color'
        check();                                                                    //Run the check function
      }
      strip.show();                         // Update strip with new contents
      delay(wait);                          // Pause for a moment
      firstPixelHue += 65536 / 90;          // One cycle of color wheel over 90 frames
    }
  }
  }
}

... and here is a picture of the build...

the IR sensor plugs into IO pin 2 on the Arduino, 5V and GND on the Breadboard; The Neopixel Strip plugs into IO pin 3 and GND on the Arduino and 5V on the board.

The Problems

I have tried to write a loop that uses a class call to decide what is going on ("check"), I have also written another version where the switch statement is place in the loop instead. The problem from what I understand is that the IR input cannot receive whilst the loop is running (as it cannot interrupt) yet the test patterns will not play unless the loop is running. I have looked at solutions that involve using two Arduino's with either one running IR and the Neopixel respectively but unfortunately this will not match up with my brief - I need to have it running on one Arduino.

Any Ninja's out there have any ideas?

Not a Ninja, but I can say you need to rewrite the strip effects to use a non-blocking code style.

Then other things can happen at what seems to be the same time.

See

non blocking pixel effects

and read that entire thread for ideas.

google

arduino two things at once

for many many sites that will go into the details as well.

HTH

a7

You could put the IR reception in an intelligent subsystem,
and get the codes via serial, which is not as time restrictive.

https://de.aliexpress.com/item/4000092880585.html

If you do not write the effects patterns in a non- blocking manner, or go to a good deal of a different kind of trouble within the code for each effect, the response to a request to change patterns will necessarily not occur until a pattern has finished.

I did not look at all Your effect functions do not finish, do not return control to your loop() function, so you would never get a chance to hear and react to a request to change…

a7

Wanted to stop by and say thank you for quick responses! Reading; rebuilding; returning :slight_smile:
jHouse

Hello again!

I've read and rewritten but there are still a number of errors in the bug report, however, I did want to drop in and give some sort of update to the string for progress' sake.

//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 = 3;                                                                     //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
{
  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 colour1, colour2;                                                              //Variables for recording active colours
    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
  {
    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 COLOUR_WIPE:                                                                 //if colourWipe
          colorWipeUpdate();                                                                //update colourWipe
          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)                                                                //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 colour to ...
    }
    strand.show();                                                                          //update the orders to the Neopixel strand
    increment();                                                                            //Run the increment function
  }

  void colourWipe (uint32_t colour, uint8_t interval)                                       //colour wipe funtion
  {
    activePattern = COLOUR_WIPE;                                                            //update the current active pattern to Colour Wipe
    interval = interval;                                                                    //reset the interval variable
    totalSteps = 255;                                                                       //set the total steps variable to 255
    colour1 = colour;                                                                       //set colour to colour 1
    index = 0;                                                                              //reset the index variable to 0
  }

  void colorWipeUpdate()                                                                    //Color wipe update function
  {
    setPixelColor(Index, Color1);                                                           //change the pixel colour to colour1
    strand.show();                                                                          //update the strand
    increment();                                                                            //run the increment function
  }

  void theaterChase(uint32_t colour1, uint32_t colour2, 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
    colour1 = colour1;                                                                      //Reset colour1
    colour2 = colour2;                                                                      //Reset colour2
    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 pixelcolour to colour 1...
          }
        else                                                                                //...otherwise... 
          {
            setPixelColor(i, Color2);                                                       //set the pixel colour to colour 2
          }
      }
    strand.show();                                                                          //update the neopixel strand
    increment();                                                                            //run the increment function
  }

  void scanner(uint32_t colour1, uint8_t interval)                                          //Scanner function
  {
    activePattern = SCANNER;                                                                //update the active pattern to Scanner
    interval = interval;                                                                    //reset the interval variable
    totalSteps = (strand->numPixels() - 1) * 2;                                             //set the total steps variable to by equal to twice that of the number of pixels on the strand less one 
    colour1 = colour1;                                                                      //reset the colour1 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, colour1);                                                          //set the pixel colour to colour1
      }
      else if (i == totalSteps - index)                                                     //if the i variable is equivilant to totalsteps less the value of index...
      {
        setPixelColor(i, colour1)                                                           //set the pixel colour to colour1...
      }
      else                                                                                  //otherwise...
      {
        setPixelColor(i, DimColor(getPixelColor(i)));                                       //dim the current pixel value
      }
    }
    strand.show();                                                                          //update the strand
    increment();                                                                            //run the increment function
  }  

  void fade(uint32_t colour1, uint32_t colour2, 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 
    colour1 = colour1;                                                                      //reset colour1
    colour2 = colour2;                                                                      //reset colour2
    index = 0;                                                                              //set index to 0
  }

  void fadeUpdate()                                                                                       //Fade update function
  {
    uint8_t red = ((Red(colour1) * (totalSteps - Index)) + (Red(colour2) * index)) / totalSteps;          
    uint8_t green = ((Green(colour1) * (totalSteps - index)) + (Green(colour2) * index)) / totalSteps;
    uint8_t blue = ((Blue(colour1) * (totalSteps - index)) + (Blue(colour2) * index)) / totalSteps;
    ColorSet(Color(red, green, blue));
    strand.show();                                                                                        //update the strand
    increment();                                                                                          //run the increment function
  }

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

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

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

  uint32_t DimColor(uint32_t colour)                                                        //Colour dimming function
  {
    uint32_t dimColor = Colour(Red(colour) >> 1, Green(colour) >> 1, Blue(color) >> 1);
    return dimColor;
  }   
  
  uint32_t wheel(byte wheelPos)                                                             //Colour wheeling function for the rainbow colour 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 colour(wheelPos * 3, 255 - wheelPos * 3, 0)    
    }
  }
 
  void colourSet(uint32_t colour)                                                           //Colour set function sets all colours to the same synchronus colour
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, colour)    
    }
    strand.show();    
  }
}; // End of neoPatterns

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(strand.Color(0, 0, 0));     
      Serial.println("0 - Black/off");    
      break;
    case 0xFF30CF:      //"1 - All red"
      colorWipe(strand.Color(255, 0, 0));    
      Serial.println("1 - All red");    
      break;
    case 0xFF18E7:      //"2 - All green" 
      colorWipe(strand.Color(0, 255, 0));         
      Serial.println("2 - All green");    
      break;
    case 0xFF7A85:      //"3 - All blue"
      colorWipe(strand.Color(0, 0, 255));    
      Serial.println("3 - All blue");    
      break;
    case 0xFF10EF:      //"4 - All white"
      colorWipe(strand.Color(255, 255, 255)); 
      Serial.println("4 - All white");    
      break;
    case 0xFF38C7:       //"5 - Rainbow Cycle"
      rainbowCycle();                      
      Serial.println("5");    
      break;
    case 0xFF5AA5:       //"6 - Theater Chase"
      theaterChase();                                 
      Serial.println("6");    
      break;
    case 0xFF42BD:       //"7 - Scanner"
      scanner();                                 
      Serial.println("7");    
      break;
    case 0xFF4AB5:      //"8 - Fader"
      fader();                      
      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

void strandComplete();                                                                         

neopatterns strand(LEDcount, LEDpin, NEO_RGBW + NEO_KHZ800, &Ring1Complete);                   //Neopattern object to control 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
    IRSelector();                                                                              //Run the IR selection function
    myReceiver.enableIRIn();                                                                   //reset the receiver for a new code
  }
  strand.update();                                                                             //Run the update function on the Neopixel Strand
}/* --(end main loop )-- */

If anyone has any pointers on the bug fixes or advice on what I've done badly they would be welcome otherwise I'll be back with a solution eventually :slight_smile:

Describe the bugs

Never mind. A glance at the code suggests you know what you are doing. I should have seen that, sry. But still, crank up the warnings…

The perils of peephole views.

Here's what is not applicable, again, sry: jumpy conclusion.

This is an error in your thinking, but would only be warned about.

You've used the same symbol onComplete in two different ways.

Here's what the code says

If onComplete is an existing function, that is to say its address is non-zero, call the onComplete() function.

That is almost certainly not what you meant.

Go to the IDE and use preferences to turn up verbosity and make all warnings be issued.

Then scrutinize the output during verify or upload, read and heed the red ink, errors as well as warnings what you might not have been previously getting.

That's just through the small window.

Oh, I see some comments. oncomplete is a different symbol, spelling counts. But from a style/aesthetics point of view, using two symbols that differ only in their use of capital letters is a bad idea.

a7

Thank you, thank you - back in the lab!

:slight_smile:

Just stopping in with a more advanced reply for @alto777 before I drop the next post which I'm hoping to be the penultimate.

I took your advice and dialled up the compiler's error checking to max and I'm down to a couple of warnings which I'm happy with and thanks to you for the help.

In regards to the onComplete if statement, obviously, large chunks or this code has been taken from the Arduino educational pages (specifically here) and I'm still struggling with the comprehension with the onComplete function. As far as I can tell it is a library call or from somewhere else as I cant identify what it calls from my code but it is definitely doing something. Currently I intend to comment it out come final tweaks to see how badly it crashes things.

Anyways, to the current status...

So I'm getting close to the end of my bug hunt as I've removed all of my errors and I'm down to warnings, the last two of which are really getting to me as they seem to be conflictions my code has with the libraries I'm using. Here is my compiler report - current full code at the bottom.

In file included from C:\Users\DCLX Server\Documents\Arduino\libraries\IRLib2/IRLibAll.h:35:0,
                 from C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino:2:
C:\Users\DCLX Server\Documents\Arduino\libraries\IRLibProtocols/IRLib_P12_CYKM.h: In member function 'void IRdecodeCYKM::doMouseKeyboard(uint16_t)':
C:\Users\DCLX Server\Documents\Arduino\libraries\IRLibProtocols/IRLib_P12_CYKM.h:251:35: warning: unused parameter 'code' [-Wunused-parameter]
     void doMouseKeyboard(uint16_t code) {
                                   ^~~~
C:\Users\DCLX Server\Documents\Arduino\libraries\IRLibProtocols/IRLib_P12_CYKM.h: In member function 'void IRdecodeCYKM::doMods(bool)':
C:\Users\DCLX Server\Documents\Arduino\libraries\IRLibProtocols/IRLib_P12_CYKM.h:270:22: warning: unused parameter 'Press' [-Wunused-parameter]
     void doMods(bool Press){
                      ^~~~~
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino: In member function 'void neoPatterns::rainbowCycleUpdate()':
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino:97:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     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.
                  ~^~~~~~~~~~~~~
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino: In member function 'void neoPatterns::theaterChaseUpdate()':
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino:133:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     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.
                  ~^~~~~~~~~~~~~
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino: In member function 'void neoPatterns::scannerUpdate()':
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino:159:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     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.
                     ~~^~~~~~~~~~~~~
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino:161:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       if (i == index)                                                                       //if the i variable is equivilant to the index variable...
           ~~^~~~~~~~
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino:165:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       else if (i == totalSteps - index)                                                     //if the i variable is equivilant to totalsteps less the value of index...
                ~~^~~~~~~~~~~~~~~~~~~~~
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino: In member function 'void neoPatterns::colorSet(uint32_t)':
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino:240:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 0; i < numPixels(); i++)

I have two problems here...

C:\Users\DCLX Server\Documents\Arduino\libraries\IRLibProtocols/IRLib_P12_CYKM.h: In member function 'void IRdecodeCYKM::doMouseKeyboard(uint16_t)':
C:\Users\DCLX Server\Documents\Arduino\libraries\IRLibProtocols/IRLib_P12_CYKM.h:251:35: warning: unused parameter 'code' [-Wunused-parameter]
     void doMouseKeyboard(uint16_t code

... indicates that I have an unused variable. A problem which I have two of and...

C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino: In member function 'void neoPatterns::rainbowCycleUpdate()':
C:\Users\DCLX Server\Desktop\Johns_Stuff\Arduino_Projects\Neopixel_StopperWithIRremote\IRremoteStopperV2.4\IRremoteStopperV2.4.ino:97:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0; i< numPixels(); i++

...six instances of comparisons between signed and unsigned integers.

My problem is that according to the line locator in the compiler report, the unused variables are to do with a "Serial" call and the mix matched comparisons all include "numPixels" from the Adafruit Library.

I'm just short of a perfect piece of code so if anyone has any pointers, ideas or advice it would be most welcome.

Full code >>>

//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 = 3;                                                                     //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
  {
    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();                                                                             //Run the update function on the Neopixel strand
}/* --(end main loop )-- */

Cracked it! Went to lunch, came back and read things anew, found my missing function! The final code is...

//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 = 3;                                                                     //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
  {
    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();                                                                             //Run the update function on the Neopixel strand
}/* --(end main loop )-- */

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

Nice. Some warnings can be just that, and a human eye can let it slide.Other warnings can catch you up to a real problem.

The onComplete mechanism is using a call back function - that's a way of handing someone the ability to do something for you when they want to. They can use the call back function, that you wrote, so what ends up getting done is whatever you want.

Here presumably something that is to be done when something else finishes.

If there is no call back function assigned at the moment, that variable is set to NULL or zero, as a signal and testable indication of whether or not it is valid to call.

Which is exactly

if (onComplete)    //  if onComplete is not zero...
{
  onComplete();    //...it's a valid function address, call it
}

HTH

a7

1 Like

Thanks for the help and encouragement :slight_smile:

Moved from a new string to the correct place...

As requested on the intermission string here is my schematic (please be gentle, first one I have ever done ever being a code guy not a wires dude)

... and here's a repost of the start of the string I misplaced...

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.

... and some code...

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

If you mean to say the code doesn't change...

that's more than interesting, as it seems impossible.

Since Neopixels operate open loop, the performance of a program should not change if you had pixels, strips or rings or whatever, or if you just disconnected them altogether.

So I think your focus may be on the wrong thing.

Why happens with no pixels attached?

a7

With no Pixel's attached it bounces between the Update function and the loop and receives most button presses from the remote coupled with a mix of button holds ("Please release button and reselect", but not on all buttons and although undesirable, this could be correct behaviour).

I'm pretty sold on the idea that the updates and the IR signals are conflicting and need better synchronising, but this morning I've noticed another anomaly which is the program is using more Pixels than recommended by the LEDcount variable which is just wrong. I think I have to go back into the code and find out what stupid mistake I have made before I bring it out in public again :wink:

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