How to Instantiate an Object from Another Class and Have Other Functions Modify it?

As long as you don't post all the code so we can try to compile it and examine it then I don't see a way forward.
Good luck.

The reason for posting a complete code that compiles and demonstrates the problem is that it makes it easier for the people trying to help you ... For FREE!!! That way, they can take your code drop it right in the IDE and see what you're seeing. They can also modify it right there, test it, and make suggestions.

Again, try to make things easier for people trying to help you ... For FREE!!!

@esp32-c3user
What you are being asked to do is to post a compilable sketch that is the least necessary to duplicate the problem you are seeing.

@gfvalvo hit return before me. :grinning_face:

At least you're more polite about it than most people have been here, thank you. If people explained it like you did without the disrespect, things would've gone a lot more smoothly. I don't know why someone posting a snippet gives people the right to act like the first person did.

Main sketch:

/*
A test for the ESP32-C3 to make ensure the custom LED library works on it.
Sketch specifically uses the ESP32-C3-DevKitM-1.
6-16-2026
 */

#include "ESPC3_LED.h" // Custom LED class I wrote to save code space.
#include <Adafruit_NeoPixel.h> 

// ======== LED STUFF: ======= \\

enum LEDPins: byte {LED = 8}; // ESP32-C3 only has 1 built-in RGB LED that is attached to GPIO 8.

// |||============ COLOR MODES: ===========||| \\

enum ColorModes: byte {LIMITED_COLOR = 1, FREE_COLOR = 2};  

// |||============ BLINK MODES: ===========||| \\

enum BlinkModes: byte {STARTUP, SD_FAILED, RTC_FAILED, DEEP_SLEEP, SCANNING, CONNECTING_BLE, CONNECTION_SUCCESSFUL, CONNECTION_LOST, MANUAL_DISCONNECT, RECEIVED_ALL_DATA, SENSOR_ERROR, RECEIVING_DATA, SAVING_DATA, FILE_ERROR, SENDING_DATA};

ESPC3_LED lightObj(LED); // Creates LED object with the correct pins selected & configured. 

void setup() 
{
  
  //lightObj.blinkPattern(FREE_COLOR, STARTUP, 300, lightObj.led); //Simple blink test using green before trying out different colors.
}

void loop() 
{
  lightObj.blinkPattern(FREE_COLOR, STARTUP, 300, lightObj.led); //Simple blink test using green before trying out different colors.

  
}

Header:

#ifndef ESPC3_LED_h
#define ESPC3_LED_h

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

class ESPC3_LED
{
  public:

    Adafruit_NeoPixel led;
    
    ESPC3_LED(byte pin);
    
    void blinkLED(const byte mode, byte red, byte green, byte blue, unsigned int blinkLength, Adafruit_NeoPixel &led);
    void blinkPattern(const byte mode, const byte blinkMode, unsigned int blinkLength, Adafruit_NeoPixel &led);
    void turnOffLED(const byte mode, Adafruit_NeoPixel &LED_Obj);    



    // ======== COLOR MODES: ======= \\

    enum ColorModes: byte {LIMITED_COLOR = 1, FREE_COLOR = 2}; 
    enum Colors: byte {OFF = 0, RED = 1, GREEN = 2, BLUE = 3}; 

    // ======== BLINK MODES: ======= \\

    enum BlinkModes: byte {STARTUP, SD_FAILED, RTC_FAILED, DEEP_SLEEP, SCANNING, CONNECTING_BLE, CONNECTION_SUCCESSFUL, CONNECTION_LOST, MANUAL_DISCONNECT, RECEIVED_ALL_DATA, SENSOR_ERROR, RECEIVING_DATA, SAVING_DATA, FILE_ERROR, SENDING_DATA};

    // ======== BLINK TIMER: ======= \\
    
    unsigned long blinkTimer; // In ms.
 
 private:
    
    byte LED;

    inline static unsigned long timeDifference;
    inline static bool lightSwitch;
    inline static bool isSwitchFlipped;    

    void updateLED(const byte mode, byte red, byte green, byte blue, unsigned int blinkLength, unsigned int blinkNumber, Adafruit_NeoPixel &led);

};
#endif

.cpp file:

#include "Arduino.h"
#include "ESPC3_LED.h"
#include "Adafruit_NeoPixel.h"

ESPC3_LED::ESPC3_LED(byte pin)
{

  LED = pin;

  Adafruit_NeoPixel led(1, 8, NEO_GRB + NEO_KHZ800);
  
  led.begin();
  led.show();
  led.setPixelColor(0, led.Color(0, 0, 100));
  led.show();

  timeDifference = 0;
  lightSwitch = false;
}

void ESPC3_LED::turnOffLED(const byte mode, Adafruit_NeoPixel &led)
{
  switch (mode)
  {
    case LIMITED_COLOR:
      led.show();
      led.setPixelColor(0, led.Color(0, 0, 0));
      break;

    case FREE_COLOR:
      led.setPixelColor(0, led.Color(0, 0, 0));
      led.show();
      break;
  }
}

void ESPC3_LED::blinkLED(const byte mode, const byte red, const byte green, const byte blue, unsigned int blinkLength, Adafruit_NeoPixel &led)
{
  if ((millis() - timeDifference) > blinkLength)
  { 
    switch (mode)
      {
        case LIMITED_COLOR:
            turnOffLED(mode, led);
            
            if (!lightSwitch)
            {
              //Serial.println("Light switch is off!");
              turnOffLED(mode, led);
    
              if (red == RED)
              {
                //Serial.println("Red activated!");
                led.setPixelColor(0, led.Color(255, 0, 0));
                led.show();
                lightSwitch = true;
                isSwitchFlipped = true;
                
                timeDifference = millis();
                return;
              }
              else if (green == GREEN)
              {
                //Serial.println("Startup 6.");
                led.setPixelColor(0, led.Color(0, 255, 0));
                led.show();
                lightSwitch = true;
                isSwitchFlipped = true;
                timeDifference = millis();
                return;
              }
              else if (blue == BLUE)
              {
                //Serial.println("Blue");
                led.setPixelColor(0, led.Color(0, 0, 255));
                led.show();
                lightSwitch = true;
                timeDifference = millis();
                isSwitchFlipped = true;
                return;
              }
            }
            else
            {
              turnOffLED(mode, led);
              lightSwitch = false;
              timeDifference = millis();
              
              return;
            }
          break;
    
        case FREE_COLOR:
            if (!lightSwitch)
            {
              led.setPixelColor(0, led.Color(red, green, blue));
              led.show();
              lightSwitch = true;
              isSwitchFlipped = true;
              timeDifference = millis();
            }
            else
            {
              turnOffLED(mode, led);
              lightSwitch = false;
              timeDifference = millis();
            }
    
          break;
    }    
  }
  else
  {
    //Serial.println("Timer not ready!");
  }
  
}

/* -------------------- blinkPattern ------------------- */
/*
  Action: Blinks an RGB LED with a set pattern/color depending on the mode & blink passed into the function.
  Parameters: The LED mode between 1 or 2 (limited color or free color mode), the blink mode as a constant byte (modes found at top of program), and the length between each blink.
  Returns: None.
  Precondition: An RGB LED must be properly connected to the board with the correct pins configured.
*/

void ESPC3_LED::blinkPattern(const byte mode, const byte blinkMode, unsigned int blinkLength, Adafruit_NeoPixel &led)
{
  switch (mode)
  {
    case LIMITED_COLOR:
      switch (blinkMode)
      {
        case STARTUP:
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 3, led);
          break;

        case SD_FAILED:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 3, led);
          break;

        case RTC_FAILED:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          break;

        case DEEP_SLEEP:
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 3, led);
          break;
          
        case SCANNING:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          break;

        case CONNECTING_BLE:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          break;
          
        case CONNECTION_SUCCESSFUL:
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          break;
          
        case CONNECTION_LOST:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 2, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 2, led);
          break;
          
        case MANUAL_DISCONNECT:
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          break;

        case RECEIVED_ALL_DATA:
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          break;
          
        case SENSOR_ERROR:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 2, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          break;
          
        case RECEIVING_DATA:
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          break;
          
        case SAVING_DATA:
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 2, led);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 2, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          break;

        case FILE_ERROR:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 2, led); // doesn't get called for some reason
          break;

        case SENDING_DATA:
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 2, led);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1, led);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1, led);
          break;
      }
      break;
///*      
    case FREE_COLOR:
      switch (blinkMode)
      {
        case STARTUP:
          updateLED(FREE_COLOR, OFF, (255 / 25), OFF, blinkLength, 3, led);
          break;
        case SD_FAILED:
          updateLED(FREE_COLOR, (255 / 25), OFF, OFF, blinkLength, 3, led);
          break;

        case RTC_FAILED:
          updateLED(FREE_COLOR, (255 / 25), (100 / 25), OFF, blinkLength, 3, led);
          break;

        case DEEP_SLEEP:
          updateLED(FREE_COLOR, OFF, OFF, (255 / 25), blinkLength, 3, led);
          break;

        case SCANNING:
          updateLED(FREE_COLOR, (255 / 25), (255 / 25), (255 / 25), blinkLength, 3, led);
          break;

        case CONNECTING_BLE:
          updateLED(FREE_COLOR, (255 / 25), (255 / 25), OFF, blinkLength, 3, led);
          break;

        case CONNECTION_SUCCESSFUL:
          updateLED(FREE_COLOR, OFF, (255 / 25), 5, blinkLength, 3, led);
          break;

        case CONNECTION_LOST:
          updateLED(FREE_COLOR, (255 / 25), (153 / 25), (255 / 25), blinkLength, 3, led);
          break;

        case MANUAL_DISCONNECT:
          updateLED(FREE_COLOR, (100 / 25), OFF, (255 / 25), blinkLength, 3, led);
          break;

        case RECEIVED_ALL_DATA:
          updateLED(FREE_COLOR, (204 / 25), (255 / 25), (25 / 25), blinkLength, 3, led);
          break;

        case SENSOR_ERROR:
          updateLED(FREE_COLOR, (255 / 25), OFF, (255 / 25), blinkLength, 3, led);
          break;

        case RECEIVING_DATA:
          updateLED(FREE_COLOR,(100 / 25), (204 / 25), (255 / 25), blinkLength, 3, led);
          break;
          
        case SAVING_DATA:
          updateLED(FREE_COLOR,(255 / 25), (255 / 25), (25 / 25), blinkLength, 3, led);
          break;    

        case FILE_ERROR:
          updateLED(FREE_COLOR,(221 / 25), (194 / 25), (255 / 25), blinkLength, 3, led);
          break;

        case SENDING_DATA:
          updateLED(FREE_COLOR,(174 / 40), (255 / 15), (158 / 45), blinkLength, 3, led);
      }//*/
  }
}

/* -------------------- updateLED ------------------- */
/*
  Action: Keeps the program in a loop until a set time, then the connected LED is flipped to the opposite state. 
  This repeats until the loop reaches the inputted counter number.
  Parameters: The LED mode (LIMITED_COLOR & FREE_COLOR), the RGB values 
  (use enum constants if using limited color (RED, GREEN, & BLUE), the length between each blink, and how many times the LED will blink.
  Returns: None.
  Precondition: An RGB LED must be properly connected to the board with the correct pins configured.
*/

void ESPC3_LED::updateLED(const byte mode, byte red, byte green, byte blue, unsigned int blinkLength, unsigned int blinkNumber, Adafruit_NeoPixel &led)
{
  unsigned int blinkCounter = 0;
  while (blinkCounter < blinkNumber)
  {
      blinkLED(mode, red, green, blue, blinkLength,led);
      if (isSwitchFlipped)
      {
        blinkCounter++;
        isSwitchFlipped = false;
        if (blinkCounter == blinkNumber)
        {  
          while ((millis() - timeDifference) < blinkLength)
          {
            //Basically delay without blocking, just to ensure the LED gets its last blink in before turning off.
          }
          turnOffLED(mode, led);
        }
      }   
  }
}

You are 100% out of line. The first time you visited the forum you should have read the pinned post re How to get the most from the forum. Asking for ALL the code is a post I make maybe 10 times a day. You are one of the few who reacted to that in an unprofessional way.
BTW, your code does NOT compile. I am done.

I'm sorry, but not taking someone's disrespect is not "unprofessional." van_der_decken very much could've explained it like how EmilyJane did and this could've been avoided. All I needed was this simple explanation instead of, "Post the code or I refuse to help you":

I just checked and I messed up a line in loop();. I just fixed it, and I hope it compiles now. That was entirely my bad.

I don't know why I'm doing this considering the way you treated 2 others here for asking for your code. Here is the Adafruit library you are using. May I suggest clicking on the link below and select "examples". Maybe one will help you.

He at least owes an apology to @van_der_decken, I think I ask for the full code as per the new people post a dozen times a day, 99.9% post it.

I really do not know C++ but I see some weird stuff. BTW, I re-arranged his code per your suggestion, he did not.

If you could please point to me how asking others not to be rude is somehow "unprofessional" and having attitude, I'd be grateful because I genuinely do not understand how not wanting to be treated like that fits the above criteria. I understand being frustrated with support questions, I've been there, but it's not an excuse to take it out on people who've done nothing to you. I appreciate the people who have taken their time to offer solutions like you have, thank you for that. Or people like EmilyJane who gave a clear and simple explanation.

I have looked at the examples provided by the library, but none of them quite do what I've done with instantiating a NeoPixel Object inside of a .cpp file and trying to get it to work.

What is it the examples in the library won't do?

You can declare multiple instances like most other Adafruit libraries.

Nobody was rude to you.

This is something I genuinely didn't think of. So I instantiated a different LED object for each class that called the setPixelColor() and show(), tried, it, and the LED is blinking! Progress! Though one thing I don't quite get is that between blinks of the same color (same blinkPattern()) command, it very briefly flashes white between blinks, and I don't know why. This is what the updated .cpp file looks like:

#include "Arduino.h"
#include "ESPC3_LED.h"
#include "Adafruit_NeoPixel.h"

ESPC3_LED::ESPC3_LED(byte pin)
{

  LED = pin;

  timeDifference = 0;
  lightSwitch = false;
}

void ESPC3_LED::turnOffLED(const byte mode)
{
  Adafruit_NeoPixel led_OL(1, LED, NEO_GRB + NEO_KHZ800);
  led_OL.begin();
  //led_OL.show();
  switch (mode)
  {
    case LIMITED_COLOR:
      led_OL.setPixelColor(0, led_OL.Color(0, 0, 0));
      led_OL.show();
      break;

    case FREE_COLOR:
      led_OL.setPixelColor(0, led_OL.Color(0, 0, 0));
      led_OL.show();
      break;
  }
}

void ESPC3_LED::blinkLED(const byte mode, const byte red, const byte green, const byte blue, unsigned int blinkLength)
{
  Adafruit_NeoPixel led_BL(1, LED, NEO_GRB + NEO_KHZ800);
  led_BL.begin();
  //led_BL.show();
  
  if ((millis() - timeDifference) > blinkLength)
  { 
    switch (mode)
      {
        case LIMITED_COLOR:
            turnOffLED(mode);
            
            if (!lightSwitch)
            {
              //Serial.println("Light switch is off!");
              turnOffLED(mode);
    
              if (red == RED)
              {
                //Serial.println("Red activated!");
                led_BL.setPixelColor(0, led_BL.Color(255, 0, 0));
                led_BL.show();
                lightSwitch = true;
                isSwitchFlipped = true;
                
                timeDifference = millis();
                return;
              }
              else if (green == GREEN)
              {
                //Serial.println("Startup 6.");
                led_BL.setPixelColor(0, led_BL.Color(0, 255, 0));
                led_BL.show();
                lightSwitch = true;
                isSwitchFlipped = true;
                timeDifference = millis();
                return;
              }
              else if (blue == BLUE)
              {
                //Serial.println("Blue");
                led_BL.setPixelColor(0, led_BL.Color(0, 0, 255));
                led_BL.show();
                lightSwitch = true;
                timeDifference = millis();
                isSwitchFlipped = true;
                return;
              }
            }
            else
            {
              turnOffLED(mode);
              lightSwitch = false;
              timeDifference = millis();
              
              return;
            }
          break;
    
        case FREE_COLOR:
            if (!lightSwitch)
            {
              led_BL.setPixelColor(0, led_BL.Color(red, green, blue));
              led_BL.show();
              lightSwitch = true;
              isSwitchFlipped = true;
              timeDifference = millis();
            }
            else
            {
              turnOffLED(mode);
              lightSwitch = false;
              timeDifference = millis();
            }
    
          break;
    }    
  }
  else
  {
    //Serial.println("Timer not ready!");
  }
  
}

/* -------------------- blinkPattern ------------------- */
/*
  Action: Blinks an RGB LED with a set pattern/color depending on the mode & blink passed into the function.
  Parameters: The LED mode between 1 or 2 (limited color or free color mode), the blink mode as a constant byte (modes found at top of program), and the length between each blink.
  Returns: None.
  Precondition: An RGB LED must be properly connected to the board with the correct pins configured.
*/

void ESPC3_LED::blinkPattern(const byte mode, const byte blinkMode, unsigned int blinkLength)
{
  
  switch (mode)
  {
    case LIMITED_COLOR:
      switch (blinkMode)
      {
        case STARTUP:
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 3);
          break;

        case SD_FAILED:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 3);
          break;

        case RTC_FAILED:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          break;

        case DEEP_SLEEP:
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 3);
          break;
          
        case SCANNING:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          break;

        case CONNECTING_BLE:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          break;
          
        case CONNECTION_SUCCESSFUL:
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          break;
          
        case CONNECTION_LOST:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 2);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 2);
          break;
          
        case MANUAL_DISCONNECT:
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          break;

        case RECEIVED_ALL_DATA:
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          break;
          
        case SENSOR_ERROR:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 2);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          break;
          
        case RECEIVING_DATA:
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          break;
          
        case SAVING_DATA:
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 2);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 2);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          break;

        case FILE_ERROR:
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 2); // doesn't get called for some reason
          break;

        case SENDING_DATA:
          updateLED(LIMITED_COLOR, OFF, GREEN, OFF, blinkLength, 2);
          updateLED(LIMITED_COLOR, OFF, OFF, BLUE, blinkLength, 1);
          updateLED(LIMITED_COLOR, RED, OFF, OFF, blinkLength, 1);
          break;
      }
      break;
///*      
    case FREE_COLOR:
      switch (blinkMode)
      {
        case STARTUP:
          updateLED(FREE_COLOR, OFF, (255 / 25), OFF, blinkLength, 3);
          break;
        case SD_FAILED:
          updateLED(FREE_COLOR, (255 / 25), OFF, OFF, blinkLength, 3);
          break;

        case RTC_FAILED:
          updateLED(FREE_COLOR, (255 / 25), (100 / 25), OFF, blinkLength, 3);
          break;

        case DEEP_SLEEP:
          updateLED(FREE_COLOR, OFF, OFF, (255 / 25), blinkLength, 3);
          break;

        case SCANNING:
          updateLED(FREE_COLOR, (255 / 25), (255 / 25), (255 / 25), blinkLength, 3);
          break;

        case CONNECTING_BLE:
          updateLED(FREE_COLOR, (255 / 25), (255 / 25), OFF, blinkLength, 3);
          break;

        case CONNECTION_SUCCESSFUL:
          updateLED(FREE_COLOR, OFF, (255 / 25), 5, blinkLength, 3);
          break;

        case CONNECTION_LOST:
          updateLED(FREE_COLOR, (255 / 25), (153 / 25), (255 / 25), blinkLength, 3);
          break;

        case MANUAL_DISCONNECT:
          updateLED(FREE_COLOR, (100 / 25), OFF, (255 / 25), blinkLength, 3);
          break;

        case RECEIVED_ALL_DATA:
          updateLED(FREE_COLOR, (204 / 25), (255 / 25), (25 / 25), blinkLength, 3);
          break;

        case SENSOR_ERROR:
          updateLED(FREE_COLOR, (255 / 25), OFF, (255 / 25), blinkLength, 3);
          break;

        case RECEIVING_DATA:
          updateLED(FREE_COLOR,(100 / 25), (204 / 25), (255 / 25), blinkLength, 3);
          break;
          
        case SAVING_DATA:
          updateLED(FREE_COLOR,(255 / 25), (255 / 25), (25 / 25), blinkLength, 3);
          break;    

        case FILE_ERROR:
          updateLED(FREE_COLOR,(221 / 25), (194 / 25), (255 / 25), blinkLength, 3);
          break;

        case SENDING_DATA:
          updateLED(FREE_COLOR,(174 / 40), (255 / 15), (158 / 45), blinkLength, 3);
      }//*/
  }
}

/* -------------------- updateLED ------------------- */
/*
  Action: Keeps the program in a loop until a set time, then the connected LED is flipped to the opposite state. 
  This repeats until the loop reaches the inputted counter number.
  Parameters: The LED mode (LIMITED_COLOR & FREE_COLOR), the RGB values 
  (use enum constants if using limited color (RED, GREEN, & BLUE), the length between each blink, and how many times the LED will blink.
  Returns: None.
  Precondition: An RGB LED must be properly connected to the board with the correct pins configured.
*/

void ESPC3_LED::updateLED(const byte mode, byte red, byte green, byte blue, unsigned int blinkLength, unsigned int blinkNumber)
{

  
  unsigned int blinkCounter = 0;
  while (blinkCounter < blinkNumber)
  {
      blinkLED(mode, red, green, blue, blinkLength);
      if (isSwitchFlipped)
      {
        blinkCounter++;
        isSwitchFlipped = false;
        if (blinkCounter == blinkNumber)
        {  
          while ((millis() - timeDifference) < blinkLength)
          {
            //Basically delay without blocking, just to ensure the LED gets its last blink in before turning off.
          }
          turnOffLED(mode);
        }
      }   
  }
}

@SurferTim this has helped me a lot, thank you so much! I don't have anymore time this week, so I'll have to work on this next week, but this has definitely been a huge step in the right direction.

Here is something to think about. This is from the library examples "simple.ino"
I started 2 instances of the Neopixel library. pixels1 (pin6) and pixels2 (pin7)

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// Released under the GPLv3 license to match the rest of the
// Adafruit NeoPixel library

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN1        6 // On Trinket or Gemma, suggest changing this to 1
#define PIN2        7 // On Trinket or Gemma, suggest changing this to 1

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 16 // Popular NeoPixel ring size

Adafruit_NeoPixel pixels1(NUMPIXELS, PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels2(NUMPIXELS, PIN2, NEO_GRB + NEO_KHZ800);

#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  pixels1.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  pixels2.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
}

void loop() {
  pixels1.clear(); // Set all pixel colors to 'off'
  pixels2.clear(); // Set all pixel colors to 'off'
  
  // The first NeoPixel in a strand is #0, second is 1, all the way up
  // to the count of pixels minus one.
  for(int i=0; i<NUMPIXELS; i++) { // For each pixel...

    // pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
    // Here we're using a moderately bright green color:
    pixels1.setPixelColor(i, pixels1.Color(0, 150, 0));

    pixels1.show();   // Send the updated pixel colors to the hardware.

    delay(DELAYVAL); // Pause before next pass through loop
  }
}

That is a dubious proposition at best. But, as a learning exercise ....

You threw together a large amount of code without knowing what you're doing with C++ classes. And, your code's OOP style is poor.

So, as a learning exercise .... here's a shorter, simpler example (compiles but not tested as I don't have a NeoPixel setup handy):

Main .ino:

#include "SingleBlinker.h"

SingleBlinker blinker(8);

void setup() {
  blinker.begin();
}

void loop() {
  blinker.processBlink();
}

SingleBlinker.h:

#ifndef SINGLE_BLINKER
#define SINGLE_BLINKER

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

class SingleBlinker {
  public:
    SingleBlinker(uint8_t pin) : led(1, pin, NEO_GRB + NEO_KHZ800) {}

    void begin();
    void setBlink(uint32_t period, uint32_t col);
    void processBlink();

  private:
    bool state;
    uint32_t blinkPeriod;
    uint32_t color;
    uint32_t lastMillis;
    Adafruit_NeoPixel led;
};

#endif

SingleBlinker.cpp:

#include "SingleBlinker.h"

void SingleBlinker::begin() {
  led.begin();
  setBlink(100, 0xFFFFFF);
}

void SingleBlinker::setBlink(uint32_t period, uint32_t col) {
  lastMillis = millis();
  blinkPeriod = period;
  color = col;
  state = true;
  led.setPixelColor(0, color);
  led.show();
}

void SingleBlinker::processBlink() {
  uint32_t currentMillis {millis()};
  if ((currentMillis - lastMillis) > blinkPeriod / 2) {
    lastMillis = currentMillis;
    if (state) {
      led.setPixelColor(0, 0);
    } else {
      led.setPixelColor(0, color);
    }
    led.show();
    state = !state;
  }
}

@esp32-c3user
I don't think this can be called progress, quite the opposite. You're continuing in the same, incorrect direction as in your first code.
Instead of using a led object as a class member, you're creating a local object in each method. This is very inefficient in terms of memory usage and sketch size.
And the reason I say this is a step in the wrong direction is because your first code didn't work for precisely this reason. You created a local led object in a ESPC3_LED constructor and used it to turn on the LED. And in the turnOffLED() method, you used a class member led that has no relation to the previous one and is also uninitialized.
Apparently, you should read up on variable scopes; you lack even the most basic knowledge of C++.

To illustrate, here is the constructor of your class:

The line
Adafruit_NeoPixel led(1, 8, NEO_GRB + NEO_KHZ800);

is a creation of a new local object led rather than instantiation of the class member led.