Error: 'FastLED' does not name a type

Help! I cannot get my code to compile for the life of me. FastLED seems to work fine in a simple file, but as soon as I incorporate into a larger project with separate files I'm getting this error.
In staff.h I have:

#ifndef _STAFF_H
#define _STAFF_H
#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_DotStar.h>
#include <FastLED.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_MPU6050.h>
#include <Wire.h>
#include "config.h"
#include "flashstorage.h"
#include "bmpimage.h"


class POVstaff {
    public:
        void begin();
        void setPixel(uint16_t i, uint32_t c);
        void clear();
        void show();
        CRGB leds[NUM_PIXELS];

        /* quickly blink each 8th LED red, for "I am alive" indication */ 
        void blink();

        /* returns supply voltage (higher of battery or USB) in mV */
        uint16_t batteryVoltage();

        /* Is the staff connected to USB power?         */
        bool USBconnected() { return (batteryVoltage()>VOLTAGE_MAX+100); }

        /* Shows battery voltage by lighting the LEDs on staff for 2 seconds */
        void showVoltage();
        
        /* Shows one line. line should be pointer to array which holds  pixel colors, in BGR order.
         *  size shoudl be size of array (number of pixels, not number of bytes)
         */
        void showLine(byte * line, uint16_t size);
        
        /* Set active image. The image must have been loaded to memory */        
        void setImage(BMPimage * image);
        
        /* Show next line of active image */
        void showNextLine();
        
        uint32_t timeSinceUpdate();
        
        float rotationSpeed(); //returns total rotation speed, in (deg/s)

        float rotationSpeedAxial();
        
        bool atRest();
        
        float getCurrent(BMPimage image); //returns average current in mA

    private:
        BMPimage * currentImage=NULL;
        int16_t currentLine=-1;
        uint32_t lastUpdate=0; //time in microseconds
        //sensor objects
        Adafruit_Sensor *accel, *gyro;


};
//extern CRGB leds[NUM_PIXELS_TOT];
//extern CRGB leds[NUM_PIXELS_TOT];
//extern CRGB leds[NUM_PIXELS_TOT];
extern POVstaff staff;
extern Adafruit_MPU6050 _mpu;

#endif

and in staff.cpp I have

#include "staff.h"

void POVstaff::begin(){
    pinMode(PIN_VSENSE, INPUT);
#ifdef PIN_CLOCK
    pinMode(PIN_CLOCK, OUTPUT);
    pinMode(PIN_DATA, OUTPUT);
    pinMode(MOSI, OUTPUT);
    pinMode(SCK, OUTPUT);
#endif
    //Serial.println("Starting...");
    FastLED.clear();
    FastLED.show();

    //init external flash
    flash.begin();
    // Open file system on the flash
    if ( !fatfs.begin(&flash) ) {
        Serial.begin(9600);
        Serial.println("Error: filesystem doesn't not exist. Please try SdFat_format example to make one.");
        while(1) yield();
    }
    //initialize the IMU, using I2C address 0x69
    if (!_mpu.begin(0x69)) {
        Serial.begin(9600);
        Serial.println("Failed to find MPU6050 chip");
    }

    //configure  IMU
    _mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
    _mpu.setGyroRange(MPU6050_RANGE_2000_DEG);
    _mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
    accel = _mpu.getAccelerometerSensor();
    gyro = _mpu.getGyroSensor();

    //Serial.println("POVstaff initilaized");
}

uint16_t POVstaff::batteryVoltage(){
    //because of voltage divider, VREF corresponds to read value of  1023/2=512
    //since battery is connected to VHI through a diode, we need to add back 100mV lost on the diode.
    return ((analogRead(PIN_VSENSE)*VREF)/512  + 100) ;
}

void POVstaff::showVoltage(){
    uint16_t level=0;
    uint8_t i, value;
    uint32_t c;
    FastLED.clear();
    //how many pixels should be lighted?
    if (batteryVoltage()<=VOLTAGE_MIN) {
        level=1;
    } else {
        level = ((uint32_t)NUM_PIXELS*(batteryVoltage()-VOLTAGE_MIN))/(VOLTAGE_MAX-VOLTAGE_MIN);
    }
    if (level>NUM_PIXELS) level=NUM_PIXELS;
    //Serial.println(level);
    //fill strip with gradient color
    for (i=0; i< level; i++){
       leds[i].r = 255-255*i/NUM_PIXELS;
       leds[i].g = 255*i/NUM_PIXELS;
    }
    FastLED.show();
    //Serial.println("Showing level");
    delay(2000); //keep for 2 seconds
    FastLED.clear();
    FastLED.show();
    lastUpdate=micros();
    //Serial.println("Showing levle done");
}

void POVstaff::clear(){
    FastLED.clear();
    FastLED.show();
    lastUpdate=micros();
}

void POVstaff::show(){
    FastLED.show();
    lastUpdate=micros();
}

void POVstaff::setPixel(uint16_t i, uint32_t c){
    leds[i] = c;
}

void POVstaff::showLine(byte * line, uint16_t size){
    uint16_t i,pos;
    uint8_t r,g,b;
    for (i=0; i<NUM_PIXELS; i++) {
        if (i<size) {
            pos=3*i;
            //using bgr order
            b=line[pos++];
            g=line[pos++];
            r=line[pos];
            leds[i].setRGB(r,g,b);
        } else {
           leds[i] = CRGB::Black;
        }
    }
    FastLED.show();
    lastUpdate=micros();
}

void POVstaff::blink(){
    uint16_t i;
    uint8_t line[3*NUM_PIXELS];
    for (i=0; i<3*NUM_PIXELS;  i++) line[i]=0;
    FastLED.clear();
    for (i=0; 8*i<NUM_PIXELS; i++) {
        line[24*i+2]=255;//set pixel with index 8i red. Recall that the color order is BGR
    }
    showLine(line,  3*NUM_PIXELS);
    delay(500);
    FastLED.clear(); FastLED.show();
    delay(500);
    showLine(line,  3*NUM_PIXELS);
    delay(500);
    FastLED.clear();        FastLED.show();
}

void POVstaff::setImage(BMPimage * image){
    if (image->isLoaded()) {
        currentImage = image;
        currentLine=-1;
        lastUpdate = micros();
    } else {
        Serial.println("Image not loaded in memory yet");
    }
}

void POVstaff::showNextLine(){
    if (currentImage) {
        //move to next line
        currentLine++;
        if (currentLine == currentImage->height()) {currentLine=0;}
        showLine(currentImage->line(currentLine), currentImage->width());
    }
}

uint32_t POVstaff::timeSinceUpdate(){
    return (micros()-lastUpdate);
}

float POVstaff::rotationSpeedAxial(){
    /*IMU.readGyroscope(x, y, z);
    return sqrtf(x*x+y*y+z*z);*/
    sensors_event_t g;
    gyro->getEvent(&g);
    return (RAD_TO_DEG*sqrtf(g.gyro.x*g.gyro.x +g.gyro.y*g.gyro.y+g.gyro.z*g.gyro.z));
}

float POVstaff::rotationSpeed(){
    /*IMU.readGyroscope(x, y, z);
    return sqrtf(x*x+y*y+z*z);*/
    sensors_event_t g;
    gyro->getEvent(&g);
    return (RAD_TO_DEG*sqrtf(g.gyro.x*g.gyro.x +g.gyro.y*g.gyro.y+g.gyro.z*g.gyro.z));
}

bool POVstaff::atRest(){
    sensors_event_t a;
    accel->getEvent(&a);
    return ( (fabs(a.acceleration.x)<3.0) && (rotationSpeed()<30.0)); //x-component of accel< 3m/s^2 and rotation speed < 30 deg/s
}



float POVstaff::getCurrent(BMPimage image){
    float currentTotal=0.0;
    float currentLine=0.0;
    int height=image.height();
    int width=image.width();
    uint8_t b,g,r;//levels
    byte * pos;
    if (! image.isLoaded()){
        return 0.0;
    }
    for (int i=0; i<height; i++){
        //compute total current for line i
        currentLine=0.0;
        for (int j=0; j<width; j++){
            pos=image.line(i); //pointer to start of i-th line
            b=*pos; pos++;
            g=*pos; pos++;
            r=*pos; pos++;
            currentLine+=b*CURRENT_B+g*CURRENT_G+r*CURRENT_R;
        }
        //now, remember to divide by 255
        currentLine/=255.0;
        currentTotal+=currentLine;
    }
    return currentTotal;
}

  FastLED.addLeds<APA102,MOSI,SCK,BGR,DATA_RATE_KHZ(3000)>(leds, NUM_PIXELS);
 // LEDS.addLeds<APA102,13,12,BGR,DATA_RATE_KHZ(3000)>(leds, NUM_PIXELS);

POVstaff staff;
Adafruit_MPU6050 _mpu

And in my main file I have:

#include "staff.h"
/*
 * Gloabl variables
 */
int         mode;        //staff operating mode. Possible values are
                         // MODE_SHOW (default when not connected to USB), MODE_UPLOAD, MODE_DEBUG
uint32_t    lastCheck=0; //time in ms since last check of "staff at rest"
float       speed=0;        //current rotation speed, in deg/s
//setting this true will force the staff, if connected to USB, go into MODE_DEBUG mode
//otherwise, when connected to USB, the staff will go into upload mode.
bool         FORCE_DEBUG = false;
BMPimageList imageList; // list of all image files (can store up to MAX_FILES entries)
                        // initially empty, will be populated by reading from file imagelist.txt during setup()
BMPimage *   currentImg;  // pointer to current image
uint32_t     imageStart=0; //when did we start showing current image? (in ms)
bool         paused;           //indicates that the show must be paused
uint32_t     timePaused=0; //when did we pause the show? (in ms)


void setup() {

    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    staff.begin();
    //SPI.setClockDivider(1); //Just for testing fast LEDS

    //set up mode - depending on whether we are connected to USB
    if (!staff.USBconnected()) {
        // we are not connected to USB
        // then we do not have a choice
        mode=MODE_SHOW;
    } else {
        //we are connected to USB
        if (FORCE_DEBUG) {
            mode=MODE_DEBUG;
        } else {
            mode=MODE_UPLOAD;
        }
    }
    //mode=MODE_DEBUG;
    //now let us do appropriate setup depending on the mode
    if (mode==MODE_UPLOAD) {
        // start mass storage protocol
        msc_init();
        Serial.begin(9600);
        delay(1000);
        Serial.println("Mass storage device started ");
        Serial.print("JEDEC ID: "); Serial.println(flash.getJEDECID(), HEX);
        Serial.print("Flash size: "); Serial.println(flash.size());
    } else {
        //we are running the show or debug
        staff.showVoltage();
        if (mode==MODE_DEBUG) {
            Serial.begin(9600);
            delay(2000);
            Serial.println("Starting in debug mode...");
        }
        // read the  image list
        imageList.addFromFile("imagelist.txt");
        if (mode==MODE_DEBUG) {
            imageList.print();
            Serial.print("Voltage: ");     Serial.print(staff.batteryVoltage()); Serial.println(" mV");
        }


        //load first image
        currentImg=imageList.first();
        currentImg->load();
        staff.setImage(currentImg);
        //wait until we start rotating the staff
        paused=true;
    }

}

void loop(){
    if (mode==MODE_UPLOAD){
        //do nothing
        delay(10);
    } else {
        if (millis()-lastCheck>200){
            //more than 0.2 seconds since last update
            lastCheck=millis();
            // update speed and if necessary pause/restart the show or load next image
            // setting all global varaibles
            updateState();
        }
        //show new line if necessary
        checkNextLine();
    }
}
/* ************************************************************
 *     Utility functions
 * ************************************************************
 */

//if necessary, show next line
void checkNextLine(){
    float rotAngle=speed*staff.timeSinceUpdate()*0.000001; //how much have we turned since last update, in degrees?
    if ( (!paused) && (rotAngle>DEG_PER_LINE) ) {
        if (mode==MODE_DEBUG) {delay(50);Serial.println("showing next line");}
        staff.showNextLine();
    }
}

//move to next image in list
void nextImage(){
    char name[MAX_FILENAME];
    staff.clear();
    currentImg->unload();        //unload  from RAM
    currentImg=imageList.next(); //move to next image in list
    currentImg->load();          //load to RAM
    staff.setImage(currentImg);
    if (mode==MODE_DEBUG) {
        currentImg->getFilename(name);
        Serial.print("Moving to next image: "); Serial.println(name);
    }
}

// update speed and check if we need to pause/restart the show,
// or move to next image
void updateState(){
    //update speed, using low-pass filter
    speed=0.6*speed+0.4*staff.rotationSpeed();
    //now, let us determine our next actions
    if (paused) {
        //check if we have started rotating - then we need to restart the show
        if (speed>150) {
            paused=false;
            imageStart=millis();
            if (mode==MODE_DEBUG){Serial.println("Restaring show after pause");}
        } else {
            //if we have been paused for more than 30 seconds, blink to remind the user
            if ((millis()-timePaused>30000)  && (!staff.USBconnected())) {
                staff.blink();
                //reset paused time
                timePaused=millis();
            }
        }
        return;
    }
    //if we are here, the show was not  paused
    // have the staff been stopped in horizontal position?
    bool staffStopped = (speed<50) &&(staff.atRest());
    if (staffStopped) {
        paused=true;
        timePaused=millis();
        //load next image into staff
        nextImage();
        return;
    }
    //have we been showing current image too long?
    bool imageExpired = (imageList.currentDuration()>0) && (millis()-imageStart>1000*imageList.currentDuration());
    if (imageExpired) {
        nextImage();
        imageStart=millis();
    }
    return;
}

Error message is:

staff.cpp:197:3: error: 'FastLED' does not name a type
197 | FastLED.addLeds<APA102,MOSI,SCK,BGR,DATA_RATE_KHZ(3000)>(leds, NUM_PIXELS);
| ^~~~~~~
exit status 1
'FastLED' does not name a type

Post your Code (and make sure You included the library .h)

The compiler is telling you that it does not know what FastLED is.
You have to include FastLED.h, so the compiler knows what it is.

I'm a new user and it won't let me post anymore code than that or upload anything...

Did you include the .h ?

yes I included the .h

do yourself a favour and please read How to get the best out of this forum and modify your first post accordingly (including code tags).

—-

What’s #ifndef _STAFF_H
The library include is dépendant on this. Seems weird

Sorry working on making it easier to read right now. Thanks for your help.

I have included everything as far as I can tell...

I'm not sure what that is, seems irrelevant. _staff_h doesn't appear anywhere else in the code. I'm modifying someone else code.

That’s to avoid double imports

1 Like

Yes I see that now. So any idea what could be causing this? When I run this simple sketch everything works fine...

#include <FastLED.h>

// How many leds in your strip?
#define NUM_LEDS 429   
 
// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 13
#define CLOCK_PIN 12

// Define the array of leds
CRGB leds[NUM_LEDS];
CRGB leds2[NUM_LEDS];

void setup() { 

  Serial.begin(57600);
  Serial.println("resetting");

//  LEDS.addLeds<APA102,MOSI,SCK,BGR,DATA_RATE_MHZ(5)>(leds,NUM_LEDS);
//  LEDS.addLeds<APA102,13,12,BGR,DATA_RATE_MHZ(5)>(leds,NUM_LEDS);

//  LEDS.addLeds<APA102,MOSI,SCK,BGR>(leds,NUM_LEDS);
//  LEDS.addLeds<APA102,13,12,BGR>(leds2,NUM_LEDS);

  FastLED.addLeds<APA102,MOSI,SCK,BGR,DATA_RATE_KHZ(3000)>(leds, NUM_LEDS);
  FastLED.addLeds<APA102,13,12,BGR,DATA_RATE_KHZ(3000)>(leds, NUM_LEDS);

  
//  LEDS.setBrightness(1);
}


void loop() {
  for ( int i = 0; i < NUM_LEDS; i++){
    leds[(i)%NUM_LEDS] = CRGB::Red;
 //   leds2[(i)%NUM_LEDS] = CRGB::Blue;
    FastLED.show();
    leds[i] = CRGB::Black;
//    leds2[i] = CRGB::Black;

  }
}

You want the fastled.h? If so here it is:

#ifndef __INC_FASTSPI_LED2_H
#define __INC_FASTSPI_LED2_H

///@file FastLED.h
/// central include file for FastLED, defines the CFastLED class/object

#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
#define FASTLED_HAS_PRAGMA_MESSAGE
#endif

#define FASTLED_VERSION 3004000
#ifndef FASTLED_INTERNAL
#  ifdef FASTLED_HAS_PRAGMA_MESSAGE
#    pragma message "FastLED version 3.004.000"
#  else
#    warning FastLED version 3.004.000  (Not really a warning, just telling you here.)
#  endif
#endif

#ifndef __PROG_TYPES_COMPAT__
#define __PROG_TYPES_COMPAT__
#endif

#ifdef SmartMatrix_h
#include <SmartMatrix.h>
#endif

#ifdef DmxSimple_h
#include <DmxSimple.h>
#endif

#ifdef DmxSerial_h
#include <DMXSerial.h>
#endif

#include <stdint.h>

#include "cpp_compat.h"

#include "fastled_config.h"
#include "led_sysdefs.h"

// Utility functions
#include "fastled_delay.h"
#include "bitswap.h"

#include "controller.h"
#include "fastpin.h"
#include "fastspi_types.h"
#include "dmx.h"

#include "platforms.h"
#include "fastled_progmem.h"

#include "lib8tion.h"
#include "pixeltypes.h"
#include "hsv2rgb.h"
#include "colorutils.h"
#include "pixelset.h"
#include "colorpalettes.h"

#include "noise.h"
#include "power_mgt.h"

#include "fastspi.h"
#include "chipsets.h"

FASTLED_NAMESPACE_BEGIN

/// definitions for the spi chipset constants
enum ESPIChipsets {
    LPD6803,
	LPD8806,
	WS2801,
	WS2803,
	SM16716,
	P9813,
	APA102,
	SK9822,
	DOTSTAR
};

enum ESM { SMART_MATRIX };
enum OWS2811 { OCTOWS2811,OCTOWS2811_400, OCTOWS2813};
enum SWS2812 { WS2812SERIAL };

#ifdef HAS_PIXIE
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class PIXIE : public PixieController<DATA_PIN, RGB_ORDER> {};
#endif

#ifdef FASTLED_HAS_CLOCKLESS
template<uint8_t DATA_PIN> class NEOPIXEL : public WS2812Controller800Khz<DATA_PIN, GRB> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SM16703 : public SM16703Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1829 : public TM1829Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1812 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1809 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1804 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1803 : public TM1803Controller400Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1903 : public UCS1903Controller400Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1903B : public UCS1903BController800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1904 : public UCS1904Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS2903 : public UCS2903Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2812 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2852 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2812B : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GS1903 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SK6812 : public SK6812Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SK6822 : public SK6822Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class APA106 : public SK6822Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class PL9823 : public PL9823Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2811 : public WS2811Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2813 : public WS2813Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class APA104 : public WS2811Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2811_400 : public WS2811Controller400Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GE8822 : public GE8822Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GW6205 : public GW6205Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GW6205_400 : public GW6205Controller400Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class LPD1886 : public LPD1886Controller1250Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class LPD1886_8BIT : public LPD1886Controller1250Khz_8bit<DATA_PIN, RGB_ORDER> {};
#ifdef DmxSimple_h
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class DMXSIMPLE : public DMXSimpleController<DATA_PIN, RGB_ORDER> {};
#endif
#ifdef DmxSerial_h
template<EOrder RGB_ORDER> class DMXSERIAL : public DMXSerialController<RGB_ORDER> {};
#endif
#endif

enum EBlockChipsets {
#ifdef PORTA_FIRST_PIN
	WS2811_PORTA,
	WS2813_PORTA,
	WS2811_400_PORTA,
	TM1803_PORTA,
	UCS1903_PORTA,
#endif
#ifdef PORTB_FIRST_PIN
	WS2811_PORTB,
	WS2813_PORTB,
	WS2811_400_PORTB,
	TM1803_PORTB,
	UCS1903_PORTB,
#endif
#ifdef PORTC_FIRST_PIN
	WS2811_PORTC,
	WS2813_PORTC,
	WS2811_400_PORTC,
	TM1803_PORTC,
	UCS1903_PORTC,
#endif
#ifdef PORTD_FIRST_PIN
	WS2811_PORTD,
	WS2813_PORTD,
	WS2811_400_PORTD,
	TM1803_PORTD,
	UCS1903_PORTD,
#endif
#ifdef HAS_PORTDC
	WS2811_PORTDC,
	WS2813_PORTDC,
	WS2811_400_PORTDC,
	TM1803_PORTDC,
	UCS1903_PORTDC,
#endif
};

#if defined(LIB8_ATTINY)
#define NUM_CONTROLLERS 2
#else
#define NUM_CONTROLLERS 8
#endif

typedef uint8_t (*power_func)(uint8_t scale, uint32_t data);

/// High level controller interface for FastLED.  This class manages controllers, global settings and trackings
/// such as brightness, and refresh rates, and provides access functions for driving led data to controllers
/// via the show/showColor/clear methods.
/// @nosubgrouping
class CFastLED {
	// int m_nControllers;
	uint8_t  m_Scale; 				///< The current global brightness scale setting
	uint16_t m_nFPS;					///< Tracking for current FPS value
	uint32_t m_nMinMicros;		///< minimum µs between frames, used for capping frame rates.
	uint32_t m_nPowerData;		///< max power use parameter
	power_func m_pPowerFunc;	///< function for overriding brightness when using FastLED.show();

public:
	CFastLED();


	/// Add a CLEDController instance to the world.  Exposed to the public to allow people to implement their own
	/// CLEDController objects or instances.  There are two ways to call this method (as well as the other addLeds)
	/// variations.  The first is with 3 arguments, in which case the arguments are the controller, a pointer to
	/// led data, and the number of leds used by this controller.  The second is with 4 arguments, in which case
	/// the first two arguments are the same, the third argument is an offset into the CRGB data where this controller's
	/// CRGB data begins, and the fourth argument is the number of leds for this controller object.
	/// @param pLed - the led controller being added
	/// @param data - base point to an array of CRGB data structures
	/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
	/// @param nLedsIfOffset - number of leds (4 argument version)
	/// @returns a reference to the added controller
	static CLEDController &addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0);

	/// @name Adding SPI based controllers
  //@{
	/// Add an SPI based  CLEDController instance to the world.
	/// There are two ways to call this method (as well as the other addLeds)
	/// variations.  The first is with 2 arguments, in which case the arguments are  a pointer to
	/// led data, and the number of leds used by this controller.  The second is with 3 arguments, in which case
	/// the first  argument is the same, the second argument is an offset into the CRGB data where this controller's
	/// CRGB data begins, and the third argument is the number of leds for this controller object.
	///
	/// This method also takes a 1 to 5 template parameters for identifying the specific chipset, data and clock pins,
	/// RGB ordering, and SPI data rate
	/// @param data - base point to an array of CRGB data structures
	/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
	/// @param nLedsIfOffset - number of leds (4 argument version)
	/// @tparam CHIPSET - the chipset type
	/// @tparam DATA_PIN - the optional data pin for the leds (if omitted, will default to the first hardware SPI MOSI pin)
	/// @tparam CLOCK_PIN - the optional clock pin for the leds (if omitted, will default to the first hardware SPI clock pin)
	/// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
	/// @tparam SPI_DATA_RATE - the data rate to drive the SPI clock at, defined using DATA_RATE_MHZ or DATA_RATE_KHZ macros
	/// @returns a reference to the added controller
	template<ESPIChipsets CHIPSET,  uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER, uint32_t SPI_DATA_RATE > CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		switch(CHIPSET) {
			case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case DOTSTAR:
			case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
		}
	}

	template<ESPIChipsets CHIPSET,  uint8_t DATA_PIN, uint8_t CLOCK_PIN > static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		switch(CHIPSET) {
			case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case DOTSTAR:
			case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
		}
	}

	template<ESPIChipsets CHIPSET,  uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER > static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		switch(CHIPSET) {
			case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case DOTSTAR:
			case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
			case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
		}
	}

#ifdef SPI_DATA
	template<ESPIChipsets CHIPSET> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB>(data, nLedsOrOffset, nLedsIfOffset);
	}

	template<ESPIChipsets CHIPSET, EOrder RGB_ORDER> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER>(data, nLedsOrOffset, nLedsIfOffset);
	}

	template<ESPIChipsets CHIPSET, EOrder RGB_ORDER, uint32_t SPI_DATA_RATE> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER, SPI_DATA_RATE>(data, nLedsOrOffset, nLedsIfOffset);
	}

#endif
	//@}

#ifdef FASTLED_HAS_CLOCKLESS
	/// @name Adding 3-wire led controllers
	//@{
	/// Add a clockless (aka 3wire, also DMX) based CLEDController instance to the world.
	/// There are two ways to call this method (as well as the other addLeds)
	/// variations.  The first is with 2 arguments, in which case the arguments are  a pointer to
	/// led data, and the number of leds used by this controller.  The second is with 3 arguments, in which case
	/// the first  argument is the same, the second argument is an offset into the CRGB data where this controller's
	/// CRGB data begins, and the third argument is the number of leds for this controller object.
	///
	/// This method also takes a 2 to 3 template parameters for identifying the specific chipset, data pin, and rgb ordering
	/// RGB ordering, and SPI data rate
	/// @param data - base point to an array of CRGB data structures
	/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
	/// @param nLedsIfOffset - number of leds (4 argument version)
	/// @tparam CHIPSET - the chipset type (required)
	/// @tparam DATA_PIN - the optional data pin for the leds (required)
	/// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
	/// @returns a reference to the added controller
	template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		static CHIPSET<DATA_PIN, RGB_ORDER> c;
		return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
	}

	template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		static CHIPSET<DATA_PIN, RGB> c;
		return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
	}

	template<template<uint8_t DATA_PIN> class CHIPSET, uint8_t DATA_PIN>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		static CHIPSET<DATA_PIN> c;
		return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
	}

#if defined(__FASTLED_HAS_FIBCC) && (__FASTLED_HAS_FIBCC == 1)
	template<uint8_t NUM_LANES, template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB>
	static CLEDController &addLeds(struct CRGB *data, int nLeds) {
		static __FIBCC<CHIPSET, DATA_PIN, NUM_LANES, RGB_ORDER> c;
		return addLeds(&c, data, nLeds);
	}
#endif

	#ifdef FASTSPI_USE_DMX_SIMPLE
	template<EClocklessChipsets CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
	{
		switch(CHIPSET) {
			case DMX: { static DMXController<DATA_PIN> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
		}
	}
	#endif
	//@}
#endif

	/// @name Adding 3rd party library controllers
	//@{
	/// Add a 3rd party library based CLEDController instance to the world.
	/// There are two ways to call this method (as well as the other addLeds)
	/// variations.  The first is with 2 arguments, in which case the arguments are  a pointer to
	/// led data, and the number of leds used by this controller.  The second is with 3 arguments, in which case
	/// the first  argument is the same, the second argument is an offset into the CRGB data where this controller's
	/// CRGB data begins, and the third argument is the number of leds for this controller object. This class includes the SmartMatrix
	/// and OctoWS2811 based controllers
	///
	/// This method also takes a 1 to 2 template parameters for identifying the specific chipset and rgb ordering
	/// RGB ordering, and SPI data rate
	/// @param data - base point to an array of CRGB data structures
	/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
	/// @param nLedsIfOffset - number of leds (4 argument version)
	/// @tparam CHIPSET - the chipset type (required)
	/// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
	/// @returns a reference to the added controller
	template<template<EOrder RGB_ORDER> class CHIPSET, EOrder RGB_ORDER>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		static CHIPSET<RGB_ORDER> c;
		return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
	}

	template<template<EOrder RGB_ORDER> class CHIPSET>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		static CHIPSET<RGB> c;
		return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
	}

#ifdef USE_OCTOWS2811
	template<OWS2811 CHIPSET, EOrder RGB_ORDER>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
	{
		switch(CHIPSET) {
			case OCTOWS2811: { static COctoWS2811Controller<RGB_ORDER,WS2811_800kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
			case OCTOWS2811_400: { static COctoWS2811Controller<RGB_ORDER,WS2811_400kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
#ifdef WS2813_800kHz
      case OCTOWS2813: { static COctoWS2811Controller<RGB_ORDER,WS2813_800kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
#endif
		}
	}

	template<OWS2811 CHIPSET>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
	{
		return addLeds<CHIPSET,GRB>(data,nLedsOrOffset,nLedsIfOffset);
	}

#endif

#ifdef USE_WS2812SERIAL
	template<SWS2812 CHIPSET, int DATA_PIN, EOrder RGB_ORDER>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
	{
		static CWS2812SerialController<DATA_PIN,RGB_ORDER> controller;
		return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset);
	}
#endif

#ifdef SmartMatrix_h
	template<ESM CHIPSET>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
	{
		switch(CHIPSET) {
			case SMART_MATRIX: { static CSmartMatrixController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
		}
	}
#endif
	//@}


#ifdef FASTLED_HAS_BLOCKLESS

	/// @name adding parallel output controllers
  //@{
	/// Add a block based CLEDController instance to the world.
	/// There are two ways to call this method (as well as the other addLeds)
	/// variations.  The first is with 2 arguments, in which case the arguments are  a pointer to
	/// led data, and the number of leds used by this controller.  The second is with 3 arguments, in which case
	/// the first  argument is the same, the second argument is an offset into the CRGB data where this controller's
	/// CRGB data begins, and the third argument is the number of leds for this controller object.
	///
	/// This method also takes a 2 to 3 template parameters for identifying the specific chipset and rgb ordering
	/// RGB ordering, and SPI data rate
	/// @param data - base point to an array of CRGB data structures
	/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
	/// @param nLedsIfOffset - number of leds (4 argument version)
	/// @tparam CHIPSET - the chipset/port type (required)
	/// @tparam NUM_LANES - how many parallel lanes of output to write
	/// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
	/// @returns a reference to the added controller
	template<EBlockChipsets CHIPSET, int NUM_LANES, EOrder RGB_ORDER>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		switch(CHIPSET) {
		#ifdef PORTA_FIRST_PIN
				case WS2811_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case WS2811_400_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
        case WS2813_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
				case TM1803_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case UCS1903_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
		#endif
		#ifdef PORTB_FIRST_PIN
				case WS2811_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case WS2811_400_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
        case WS2813_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
				case TM1803_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case UCS1903_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
		#endif
		#ifdef PORTC_FIRST_PIN
				case WS2811_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case WS2811_400_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
        case WS2813_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
				case TM1803_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case UCS1903_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
		#endif
		#ifdef PORTD_FIRST_PIN
				case WS2811_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case WS2811_400_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
        case WS2813_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
				case TM1803_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case UCS1903_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
		#endif
		#ifdef HAS_PORTDC
				case WS2811_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case WS2811_400_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
        case WS2813_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
				case TM1803_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
				case UCS1903_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
		#endif
		}
	}

	template<EBlockChipsets CHIPSET, int NUM_LANES>
	static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
		return addLeds<CHIPSET,NUM_LANES,GRB>(data,nLedsOrOffset,nLedsIfOffset);
	}
	//@}
#endif

	/// Set the global brightness scaling
	/// @param scale a 0-255 value for how much to scale all leds before writing them out
	void setBrightness(uint8_t scale) { m_Scale = scale; }

	/// Get the current global brightness setting
	/// @returns the current global brightness value
	uint8_t getBrightness() { return m_Scale; }

	/// Set the maximum power to be used, given in volts and milliamps.
	/// @param volts - how many volts the leds are being driven at (usually 5)
	/// @param milliamps - the maximum milliamps of power draw you want
	inline void setMaxPowerInVoltsAndMilliamps(uint8_t volts, uint32_t milliamps) { setMaxPowerInMilliWatts(volts * milliamps); }

	/// Set the maximum power to be used, given in milliwatts
	/// @param milliwatts - the max power draw desired, in milliwatts
	inline void setMaxPowerInMilliWatts(uint32_t milliwatts) { m_pPowerFunc = &calculate_max_brightness_for_power_mW; m_nPowerData = milliwatts; }

	/// Update all our controllers with the current led colors, using the passed in brightness
	/// @param scale temporarily override the scale
	void show(uint8_t scale);

	/// Update all our controllers with the current led colors
	void show() { show(m_Scale); }

	/// clear the leds, wiping the local array of data, optionally black out the leds as well
	/// @param writeData whether or not to write out to the leds as well
	void clear(bool writeData = false);

	/// clear out the local data array
	void clearData();

	/// Set all leds on all controllers to the given color/scale
	/// @param color what color to set the leds to
	/// @param scale what brightness scale to show at
	void showColor(const struct CRGB & color, uint8_t scale);

	/// Set all leds on all controllers to the given color
	/// @param color what color to set the leds to
	void showColor(const struct CRGB & color) { showColor(color, m_Scale); }

	/// Delay for the given number of milliseconds.  Provided to allow the library to be used on platforms
	/// that don't have a delay function (to allow code to be more portable).  Note: this will call show
 	/// constantly to drive the dithering engine (and will call show at least once).
	/// @param ms the number of milliseconds to pause for
	void delay(unsigned long ms);

	/// Set a global color temperature.  Sets the color temperature for all added led strips, overriding whatever
	/// previous color temperature those controllers may have had
	/// @param temp A CRGB structure describing the color temperature
	void setTemperature(const struct CRGB & temp);

	/// Set a global color correction.  Sets the color correction for all added led strips,
	/// overriding whatever previous color correction those controllers may have had.
	/// @param correction A CRGB structure describin the color correction.
	void setCorrection(const struct CRGB & correction);

	/// Set the dithering mode.  Sets the dithering mode for all added led strips, overriding
	/// whatever previous dithering option those controllers may have had.
	/// @param ditherMode - what type of dithering to use, either BINARY_DITHER or DISABLE_DITHER
	void setDither(uint8_t ditherMode = BINARY_DITHER);

	/// Set the maximum refresh rate.  This is global for all leds.  Attempts to
	/// call show faster than this rate will simply wait.  Note that the refresh rate
	/// defaults to the slowest refresh rate of all the leds added through addLeds.  If
	/// you wish to set/override this rate, be sure to call setMaxRefreshRate _after_
	/// adding all of your leds.
	/// @param refresh - maximum refresh rate in hz
	/// @param constrain - constrain refresh rate to the slowest speed yet set
	void setMaxRefreshRate(uint16_t refresh, bool constrain=false);

	/// for debugging, will keep track of time between calls to countFPS, and every
	/// nFrames calls, it will update an internal counter for the current FPS.
	/// @todo make this a rolling counter
	/// @param nFrames - how many frames to time for determining FPS
	void countFPS(int nFrames=25);

	/// Get the number of frames/second being written out
	/// @returns the most recently computed FPS value
	uint16_t getFPS() { return m_nFPS; }

	/// Get how many controllers have been registered
	/// @returns the number of controllers (strips) that have been added with addLeds
	int count();

	/// Get a reference to a registered controller
	/// @returns a reference to the Nth controller
	CLEDController & operator[](int x);

	/// Get the number of leds in the first controller
	/// @returns the number of LEDs in the first controller
	int size() { return (*this)[0].size(); }

	/// Get a pointer to led data for the first controller
	/// @returns pointer to the CRGB buffer for the first controller
	CRGB *leds() { return (*this)[0].leds(); }
};

#define FastSPI_LED FastLED
#define FastSPI_LED2 FastLED
#ifndef LEDS
#define LEDS FastLED
#endif

extern CFastLED FastLED;

// Warnings for undefined things
#ifndef HAS_HARDWARE_PIN_SUPPORT
#warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info."
#define NO_HARDWARE_PIN_SUPPORT
#endif


FASTLED_NAMESPACE_END

#endif

You don't have the FastLED.addLeds function call inside an executable function.

omg. Thank you. Should I just place it inside POVstaff.begin()

Try it.

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