Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 17 of 17

Thread: Teensy 4.1 WS2812B LED Problem

  1. #1

    Teensy 4.1 WS2812B LED Problem

    Hi all........I'm doing a project using 72 LEDs but can't get the LEDs to respond correctly. When I run the Fastled Demo Reel 100 code (Fastled Library 3.3.3) it seems like it's running through the routines but the LEDs are all white & not changing colour. I'm using a 470 ohm resistor on the data pin & have tried different pins but no change. I wired up a Teensy 2.0 and ran the program & they work fine so it's not the wiring or code. Any ideas?

    #include <FastLED.h>

    FASTLED_USING_NAMESPACE

    // FastLED "100-lines-of-code" demo reel, showing just a few
    // of the kinds of animation patterns you can quickly and easily
    // compose using FastLED.
    //
    // This example also shows one easy way to define multiple
    // animations patterns and have them automatically rotate.
    //
    // -Mark Kriegsman, December 2014

    #if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
    #warning "Requires FastLED 3.1 or later; check github for latest code."
    #endif

    #define DATA_PIN 7
    //#define CLK_PIN 4
    #define LED_TYPE WS2812B
    #define COLOR_ORDER BRG
    #define NUM_LEDS 72
    CRGB leds[NUM_LEDS];

    #define BRIGHTNESS 96
    #define FRAMES_PER_SECOND 120

    void setup() {
    delay(3000); // 3 second delay for recovery

    // tell FastLED about the LED strip configuration
    FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(led s, NUM_LEDS).setCorrection(TypicalLEDStrip);
    //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_OR DER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

    // set master brightness control
    FastLED.setBrightness(BRIGHTNESS);
    }


    // List of patterns to cycle through. Each is defined as a separate function below.
    typedef void (*SimplePatternList[])();
    SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };

    uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
    uint8_t gHue = 0; // rotating "base color" used by many of the patterns

    void loop()
    {
    // Call the current pattern function once, updating the 'leds' array
    gPatterns[gCurrentPatternNumber]();

    // send the 'leds' array out to the actual LED strip
    FastLED.show();
    // insert a delay to keep the framerate modest
    FastLED.delay(1000/FRAMES_PER_SECOND);

    // do some periodic updates
    EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
    EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically
    }

    #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

    void nextPattern()
    {
    // add one to the current pattern number, and wrap around at the end
    gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
    }

    void rainbow()
    {
    // FastLED's built-in rainbow generator
    fill_rainbow( leds, NUM_LEDS, gHue, 7);
    }

    void rainbowWithGlitter()
    {
    // built-in FastLED rainbow, plus some random sparkly glitter
    rainbow();
    addGlitter(80);
    }

    void addGlitter( fract8 chanceOfGlitter)
    {
    if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
    }
    }

    void confetti()
    {
    // random colored speckles that blink in and fade smoothly
    fadeToBlackBy( leds, NUM_LEDS, 10);
    int pos = random16(NUM_LEDS);
    leds[pos] += CHSV( gHue + random8(64), 200, 255);
    }

    void sinelon()
    {
    // a colored dot sweeping back and forth, with fading trails
    fadeToBlackBy( leds, NUM_LEDS, 20);
    int pos = beatsin16( 13, 0, NUM_LEDS-1 );
    leds[pos] += CHSV( gHue, 255, 192);
    }

    void bpm()
    {
    // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
    uint8_t BeatsPerMinute = 62;
    CRGBPalette16 palette = PartyColors_p;
    uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
    for( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
    }
    }

    void juggle() {
    // eight colored dots, weaving in and out of sync with each other
    fadeToBlackBy( leds, NUM_LEDS, 20);
    byte dothue = 0;
    for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
    }
    }

  2. #2
    Member LitterBug's Avatar
    Join Date
    Nov 2020
    Location
    Earth
    Posts
    24
    I get similar results. Works fine with one of my APA102 strips on the T4.1

    Probably a timing issue with the standard FastLED WS2812 library running on the Teensy 4.x.

    Have you checked on the FastLED support forum?


    EDIT: I tested with the Teensy FastLED_Cylon demo, and that demo works. (running on pin 14)

    Code:
    // FastLED Cylon Example, using Non-Blocking WS2812Serial
    
    #include <WS2812Serial.h>
    #define USE_WS2812SERIAL
    #include <FastLED.h>
    
    // How many leds in your strip?
    #define NUM_LEDS 64
    
    // Usable pins:
    //   Teensy LC:   1, 4, 5, 24
    //   Teensy 3.2:  1, 5, 8, 10, 31   (overclock to 120 MHz for pin 8)
    //   Teensy 3.5:  1, 5, 8, 10, 26, 32, 33, 48
    //   Teensy 3.6:  1, 5, 8, 10, 26, 32, 33
    //   Teensy 4.0:  1, 8, 14, 17, 20, 24, 29, 39
    #define DATA_PIN 14
    
    // Define the array of leds
    CRGB leds[NUM_LEDS];
    
    void setup() {
    	Serial.begin(57600);
    	Serial.println("resetting");
    	LEDS.addLeds<WS2812SERIAL,DATA_PIN,RGB>(leds,NUM_LEDS);
    	LEDS.setBrightness(84);
    }
    
    void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }
    
    void loop() {
    	static uint8_t hue = 0;
    	Serial.print("x");
    	// First slide the led in one direction
    	for(int i = 0; i < NUM_LEDS; i++) {
    		// Set the i'th led to red
    		leds[i] = CHSV(hue++, 255, 255);
    		// Show the leds
    		FastLED.show();
    		// now that we've shown the leds, reset the i'th led to black
    		// leds[i] = CRGB::Black;
    		fadeall();
    		// Wait a little bit before we loop around and do it again
    		delay(20);
    	}
    	Serial.print("x");
    
    	// Now go in the other direction.
    	for(int i = (NUM_LEDS)-1; i >= 0; i--) {
    		// Set the i'th led to red
    		leds[i] = CHSV(hue++, 255, 255);
    		// Show the leds
    		FastLED.show();
    		// now that we've shown the leds, reset the i'th led to black
    		// leds[i] = CRGB::Black;
    		fadeall();
    		// Wait a little bit before we loop around and do it again
    		delay(20);
    	}
    }

  3. #3
    Member LitterBug's Avatar
    Join Date
    Nov 2020
    Location
    Earth
    Posts
    24
    I modified the DemoReel100 to use the same initialization that is used in the Teensy WS2812SERIAL demo, and it works.

  4. #4
    Quote Originally Posted by LitterBug View Post
    I modified the DemoReel100 to use the same initialization that is used in the Teensy WS2812SERIAL demo, and it works.
    Thanks for the post. I'm more a musician than a coder. Would you mind posting the Demo 100 code showing where you did the mod?

    The code I'm trying to get to work is a MIDI controller with 72 'wheels' & switches that need to change colour to reflect position. Here it is:

    // ====== LEDs ======
    #include "FastLED.h"
    const int ledDataPin = 5;
    const int numLeds = 96;
    CRGB leds[numLeds];

    // ====== MUXs ======
    // The number of mux boards used and their ADC pins
    const int muxCount = 5;
    const int muxInputPins[] = {A0, A1, A2, A3, A4};

    // The pins that select which mux channel is connected
    const int muxControlPinCount = 4;
    const int muxControlPins[] = {4, 3, 2, 1};

    // Define the mux control pins
    const int channelsPerMux = 16;

    #include "input.h"
    MusicInput inputGroups[muxCount][channelsPerMux] = {};

    // ====== MIDI ======
    // The number of milliseconds between successive sends of the CC data
    const int ccdelay = 10;

    // Set the MUX to MIDI CC channel mapping
    // (position is MUX input, value is MIDI CC channel)
    int ccChannelMap[muxCount][channelsPerMux] = {
    12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, // MUX 1
    28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, // MUX 2
    44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, // MUX 3
    60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, // MUX 4
    76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, // MUX 5
    };

    // ====== Button ======
    #include <Bounce2.h>
    Bounce allSendButton = Bounce();
    const int allSendPin = 0;

    // ====== Program ======
    unsigned long lastUpdateTime = 0;

    void setup()
    {
    delay(1000);
    Serial.begin(115200);
    Serial.println("Claude Controller Mini");

    allSendButton.attach(allSendPin, INPUT_PULLUP);
    allSendButton.interval(20);

    FastLED.addLeds<WS2812B, ledDataPin>(leds, numLeds);
    setupMux();

    allSendButton.update();
    if (allSendButton.read() == LOW)
    {
    // Calibrate and then stop
    doCalibration();
    }
    else
    {
    // Load calibration and continue
    loadCalibration();
    }
    Serial.println("CCnum,val,hue");
    }

    void setupMux() {
    // Set MUX control pins as OUTPUTS
    for (int i = 0; i < muxControlPinCount; i++) {
    pinMode(muxControlPins[i], OUTPUT);
    }

    // Configure CC numbers and default types
    for (int mux = 0; mux < muxCount; mux++) {
    for (int ch = 0; ch < channelsPerMux; ch++) {
    // Default type of POT
    inputGroups[mux][ch].setType(EChannelType::POT);

    // Number inputs from definition
    inputGroups[mux][ch].setCCNum(ccChannelMap[mux][ch]);
    }
    }

    // Set some channels to switches
    // MUX 1 = CH 0 to CH 15
    inputGroups[0][0].setType(EChannelType:ISABLED);
    // MUX 2 = CH16 to CH31
    inputGroups[1][7].setType(EChannelType::SWITCH);
    inputGroups[1][8].setType(EChannelType::SWITCH);
    inputGroups[1][9].setType(EChannelType::SWITCH);
    inputGroups[1][13].setType(EChannelType::SWITCH);
    inputGroups[1][14].setType(EChannelType::SWITCH);
    inputGroups[1][15].setType(EChannelType::SWITCH);
    // MUX 3 = CH 32 to CH 47
    inputGroups[2][0].setType(EChannelType::SWITCH);
    inputGroups[2][4].setType(EChannelType::SWITCH);
    inputGroups[2][7].setType(EChannelType::SWITCH);
    inputGroups[2][11].setType(EChannelType::SWITCH);
    inputGroups[2][14].setType(EChannelType::SWITCH);
    inputGroups[2][15].setType(EChannelType::SWITCH);
    // MUX 4 = CH 48 to CH 63
    // MUX 5 = CH 64 to CH 79
    inputGroups[4][6].setType(EChannelType::SWITCH);

    inputGroups[4][8].setType(EChannelType:ISABLED);
    inputGroups[4][9].setType(EChannelType:ISABLED);
    inputGroups[4][10].setType(EChannelType:ISABLED);
    inputGroups[4][11].setType(EChannelType:ISABLED);
    inputGroups[4][12].setType(EChannelType:ISABLED);
    inputGroups[4][13].setType(EChannelType:ISABLED);
    inputGroups[4][14].setType(EChannelType:ISABLED);
    inputGroups[4][15].setType(EChannelType:ISABLED);
    }

    void loop()
    {
    // Handle all send button
    allSendButton.update();
    if (allSendButton.fell()) {
    Serial.println("All send pressed");
    // Blake: I have temporarily disabled the all send button to help
    // debug first CC button sending all send.
    // for (int ch = 0; ch < channelsPerMux; ch++) {
    // for (int mux = 0; mux < muxCount; mux++) {
    // inputGroups[mux][ch].sendNext();
    // }
    // }
    }

    // Read the MUXs and send MIDI/LED if changed, every 'ccdelay' milliseconds
    unsigned long timeNow = millis();
    if (timeNow >= lastUpdateTime + ccdelay)
    {
    lastUpdateTime = timeNow;

    // Loop through each channel and each mux
    for (int ch = 0; ch < channelsPerMux; ch++)
    {
    for (int mux = 0; mux < muxCount; mux++) {
    // Read from ADC
    int rawValue = readMux(ch, muxInputPins[mux]);
    inputGroups[mux][ch].updateValue(rawValue);

    // Write to MIDI and LEDs
    if (inputGroups[mux][ch].toSend()) {
    int ccNum = inputGroups[mux][ch].getCCNum();
    int val = inputGroups[mux][ch].getValue();
    usbMIDI.sendControlChange(ccNum, val, 4);
    Serial.print("cc=");
    Serial.print(ccNum);
    Serial.print(",val=");
    Serial.print(val);

    int ledIndex = ch + mux * channelsPerMux;
    int hue = map(val, 0, MIDI_MAX, 150, 0);
    leds[ledIndex] = CHSV(hue, 255, 255);
    Serial.print(",hue=");
    Serial.print(hue);

    Serial.println();
    }
    }
    }

    // Push the values in 'leds[]' out to the physical LEDs
    FastLED.show();
    }
    }

    // === Reading the MUXs ===

    int readMux(int channel, int analogPin)
    {
    for (int i = 0; i < muxControlPinCount; i++)
    {
    // Bit shift a 1 up to the control bit.
    // AND it with channel and write HIGH if nonzero.
    bool bitIsSet = (channel & (1 << i)) > 0;
    digitalWrite(muxControlPins[i], bitIsSet);
    }
    int val = analogRead(analogPin);
    return val;
    }

  5. #5
    Member LitterBug's Avatar
    Join Date
    Nov 2020
    Location
    Earth
    Posts
    24
    When you paste code to the forum, it makes it easier to work with if you have it wrapped in code tags (use the # button above the text box) so we can make sure that we are not grabbing more than just the code, or that emoticons don't change the context of the code.

    There are two key places to modify the code. The changes affect the initialization of the FastLED library.

    1st is the includes at the very start of the program.
    Code:
    #include <WS2812Serial.h>
    #define USE_WS2812SERIAL
    #include <FastLED.h>
    The 2nd spot, is the actual initialization.
    Code:
    // FastLED.addLeds<WS2812B, ledDataPin>(leds, numLeds);
    LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
    LEDS.setBrightness(84);
    Regards,
    LB

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,447
    Yes, USE_WS2812SERIAL is the best solution, though it does limit you to specific pins and use a little more memory.

    The other thing to try is this, before you include FastLED.h

    #define FASTLED_ALLOW_INTERRUPTS 0

  7. #7
    Thanks for your great help. I did the changes and got it to work on both the Cylon & the Demo Reel 10. (yay!) Unfortunately I couldn't get it to compile on my project. I put the LEDs on pin 8 which was one listed as ok (unless there's a difference between the Teensy 4.0 & 4.1).
    I know it's a bit of an ask but can you see anything that might help? This is the line it doesn't like:

    FastLED.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);

    Here's the code:

    // ====== LEDs ======
    #include <WS2812Serial.h>
    #define USE_WS2812SERIAL
    #include "FastLED.h"
    const int ledDataPin = 8;
    const int numLeds = 96;
    CRGB leds[numLeds];

    // ====== MUXs ======
    // The number of mux boards used and their ADC pins
    const int muxCount = 5;
    const int muxInputPins[] = {A0, A1, A2, A3, A4};

    // The pins that select which mux channel is connected
    const int muxControlPinCount = 4;
    const int muxControlPins[] = {4, 3, 2, 1};

    // Define the mux control pins
    const int channelsPerMux = 16;

    #include "input.h"
    MusicInput inputGroups[muxCount][channelsPerMux] = {};

    // ====== MIDI ======
    // The number of milliseconds between successive sends of the CC data
    const int ccdelay = 10;

    // Set the MUX to MIDI CC channel mapping
    // (position is MUX input, value is MIDI CC channel)
    int ccChannelMap[muxCount][channelsPerMux] = {
    12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, // MUX 1
    28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, // MUX 2
    44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, // MUX 3
    60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, // MUX 4
    76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, // MUX 5
    };

    // ====== Button ======
    #include <Bounce2.h>
    Bounce allSendButton = Bounce();
    const int allSendPin = 0;

    // ====== Program ======
    unsigned long lastUpdateTime = 0;

    void setup()
    {
    delay(1000);
    Serial.begin(115200);
    Serial.println("Claude Controller Mini");

    allSendButton.attach(allSendPin, INPUT_PULLUP);
    allSendButton.interval(20);

    FastLED.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
    setupMux();

    allSendButton.update();
    if (allSendButton.read() == LOW)
    {
    // Calibrate and then stop
    doCalibration();
    }
    else
    {
    // Load calibration and continue
    loadCalibration();
    }
    Serial.println("CCnum,val,hue");
    }

    void setupMux() {
    // Set MUX control pins as OUTPUTS
    for (int i = 0; i < muxControlPinCount; i++) {
    pinMode(muxControlPins[i], OUTPUT);
    }

    // Configure CC numbers and default types
    for (int mux = 0; mux < muxCount; mux++) {
    for (int ch = 0; ch < channelsPerMux; ch++) {
    // Default type of POT
    inputGroups[mux][ch].setType(EChannelType::POT);

    // Number inputs from definition
    inputGroups[mux][ch].setCCNum(ccChannelMap[mux][ch]);
    }
    }

    // Set some channels to switches
    // MUX 1 = CH 0 to CH 15
    inputGroups[0][0].setType(EChannelType:ISABLED);
    // MUX 2 = CH16 to CH31
    inputGroups[1][7].setType(EChannelType::SWITCH);
    inputGroups[1][8].setType(EChannelType::SWITCH);
    inputGroups[1][9].setType(EChannelType::SWITCH);
    inputGroups[1][13].setType(EChannelType::SWITCH);
    inputGroups[1][14].setType(EChannelType::SWITCH);
    inputGroups[1][15].setType(EChannelType::SWITCH);
    // MUX 3 = CH 32 to CH 47
    inputGroups[2][0].setType(EChannelType::SWITCH);
    inputGroups[2][4].setType(EChannelType::SWITCH);
    inputGroups[2][7].setType(EChannelType::SWITCH);
    inputGroups[2][11].setType(EChannelType::SWITCH);
    inputGroups[2][14].setType(EChannelType::SWITCH);
    inputGroups[2][15].setType(EChannelType::SWITCH);
    // MUX 4 = CH 48 to CH 63
    // MUX 5 = CH 64 to CH 79
    inputGroups[4][6].setType(EChannelType::SWITCH);

    inputGroups[4][8].setType(EChannelType:ISABLED);
    inputGroups[4][9].setType(EChannelType:ISABLED);
    inputGroups[4][10].setType(EChannelType:ISABLED);
    inputGroups[4][11].setType(EChannelType:ISABLED);
    inputGroups[4][12].setType(EChannelType:ISABLED);
    inputGroups[4][13].setType(EChannelType:ISABLED);
    inputGroups[4][14].setType(EChannelType:ISABLED);
    inputGroups[4][15].setType(EChannelType:ISABLED);
    }

    void loop()
    {
    // Handle all send button
    allSendButton.update();
    if (allSendButton.fell()) {
    Serial.println("All send pressed");
    // Blake: I have temporarily disabled the all send button to help
    // debug first CC button sending all send.
    // for (int ch = 0; ch < channelsPerMux; ch++) {
    // for (int mux = 0; mux < muxCount; mux++) {
    // inputGroups[mux][ch].sendNext();
    // }
    // }
    }

    // Read the MUXs and send MIDI/LED if changed, every 'ccdelay' milliseconds
    unsigned long timeNow = millis();
    if (timeNow >= lastUpdateTime + ccdelay)
    {
    lastUpdateTime = timeNow;

    // Loop through each channel and each mux
    for (int ch = 0; ch < channelsPerMux; ch++)
    {
    for (int mux = 0; mux < muxCount; mux++) {
    // Read from ADC
    int rawValue = readMux(ch, muxInputPins[mux]);
    inputGroups[mux][ch].updateValue(rawValue);

    // Write to MIDI and LEDs
    if (inputGroups[mux][ch].toSend()) {
    int ccNum = inputGroups[mux][ch].getCCNum();
    int val = inputGroups[mux][ch].getValue();
    usbMIDI.sendControlChange(ccNum, val, 4);
    Serial.print("cc=");
    Serial.print(ccNum);
    Serial.print(",val=");
    Serial.print(val);

    int ledIndex = ch + mux * channelsPerMux;
    int hue = map(val, 0, MIDI_MAX, 150, 0);
    leds[ledIndex] = CHSV(hue, 255, 255);
    Serial.print(",hue=");
    Serial.print(hue);

    Serial.println();
    }
    }
    }

    // Push the values in 'leds[]' out to the physical LEDs
    FastLED.show();
    }
    }

    // === Reading the MUXs ===

    int readMux(int channel, int analogPin)
    {
    for (int i = 0; i < muxControlPinCount; i++)
    {
    // Bit shift a 1 up to the control bit.
    // AND it with channel and write HIGH if nonzero.
    bool bitIsSet = (channel & (1 << i)) > 0;
    digitalWrite(muxControlPins[i], bitIsSet);
    }
    int val = analogRead(analogPin);
    return val;
    }


    I thought I'd better post the first few lines of the reason it won't compile:


    In file included from /Users/claudewoodward/Downloads/claude-controller-mini-main/claude_controller_mini_code2/claude_controller_mini_201120/claude_controller_mini_201120.ino:4:0:
    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:14:21: note: #pragma message: FastLED version 3.003.003
    # pragma message "FastLED version 3.003.003"
    ^
    claude_controller_mini_201120: In function 'void setup()':
    claude_controller_mini_201120:55: error: no matching function for call to 'CFastLED::addLeds(CRGB [96], const int&)'
    FastLED.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
    ^
    In file included from /Users/claudewoodward/Downloads/claude-controller-mini-main/claude_controller_mini_code2/claude_controller_mini_201120/claude_controller_mini_201120.ino:4:0:
    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:223:130: note: candidate: template<ESPIChipsets CHIPSET, unsigned char DATA_PIN, unsigned char CLOCK_PIN, EOrder RGB_ORDER, long unsigned int SPI_DATA_RATE> CLEDController& CFastLED::addLeds(CRGB*, int, int)
    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) {

  8. #8
    Member LitterBug's Avatar
    Join Date
    Nov 2020
    Location
    Earth
    Posts
    24
    If you are using the WS2812SERIAL library, you need to swap the FastLED.addLeds command with LEDS.addLeds

    Code:
    // FastLED.addLeds<WS2812B, ledDataPin>(leds, numLeds);
    LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
    LB

  9. #9
    I just had a go but sadly didn't work:

    claude_controller_mini_201120: In function 'void setup()':
    claude_controller_mini_201120:56: error: no matching function for call to 'CFastLED::addLeds(CRGB [96], const int&)'
    LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
    ^

  10. #10
    Member LitterBug's Avatar
    Join Date
    Nov 2020
    Location
    Earth
    Posts
    24
    Please paste your code between code wrappers. It is very difficult to help debug code otherwise.

    See picture:

    Click image for larger version. 

Name:	CodeNoCode.png 
Views:	13 
Size:	28.2 KB 
ID:	22604

  11. #11
    Sorry about that.

    Here's the code with the amended line you suggested:

    Code:
    // ====== LEDs ======
    #include <WS2812Serial.h>
    #define USE_WS2812SERIAL
    #include "FastLED.h"
    const int ledDataPin = 8;
    const int numLeds = 96;
    CRGB leds[numLeds];
    
    // ====== MUXs ======
    // The number of mux boards used and their ADC pins
    const int muxCount = 5;
    const int muxInputPins[] = {A0, A1, A2, A3, A4};
    
    // The pins that select which mux channel is connected
    const int muxControlPinCount = 4;
    const int muxControlPins[] = {4, 3, 2, 1};
    
    // Define the mux control pins
    const int channelsPerMux = 16;
    
    #include "input.h"
    MusicInput inputGroups[muxCount][channelsPerMux] = {};
    
    // ====== MIDI ======
    // The number of milliseconds between successive sends of the CC data
    const int ccdelay = 10;
    
    // Set the MUX to MIDI CC channel mapping
    // (position is MUX input, value is MIDI CC channel)
    int ccChannelMap[muxCount][channelsPerMux] = {
      12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,  // MUX 1
      28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,  // MUX 2
      44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,  // MUX 3
      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,  // MUX 4
      76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,  // MUX 5
    };
    
    // ====== Button ======
    #include <Bounce2.h>
    Bounce allSendButton = Bounce(); 
    const int allSendPin = 0;
    
    // ====== Program ======
    unsigned long lastUpdateTime = 0;
    
    void setup()
    {
      delay(1000);
      Serial.begin(115200);
      Serial.println("Claude Controller Mini");
    
      allSendButton.attach(allSendPin, INPUT_PULLUP);
      allSendButton.interval(20);
      
      //FastLED.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
     LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
      setupMux();
    
      allSendButton.update();
      if (allSendButton.read() == LOW)
      {
        // Calibrate and then stop
        doCalibration();
      }
      else
      {
        // Load calibration and continue
        loadCalibration();
      }
      Serial.println("CCnum,val,hue");
    }
    
    void setupMux() {
      // Set MUX control pins as OUTPUTS
      for (int i = 0; i < muxControlPinCount; i++) {
        pinMode(muxControlPins[i], OUTPUT);
      }
    
      // Configure CC numbers and default types
      for (int mux = 0; mux < muxCount; mux++) {
        for (int ch = 0; ch < channelsPerMux; ch++) {
          // Default type of POT
          inputGroups[mux][ch].setType(EChannelType::POT);
    
          // Number inputs from definition
          inputGroups[mux][ch].setCCNum(ccChannelMap[mux][ch]);
        }
      }
    
      // Set some channels to switches
      //  MUX 1 = CH 0 to CH 15
      inputGroups[0][0].setType(EChannelType::DISABLED);
      //  MUX 2 = CH16 to CH31
      inputGroups[1][7].setType(EChannelType::SWITCH);
      inputGroups[1][8].setType(EChannelType::SWITCH);
      inputGroups[1][9].setType(EChannelType::SWITCH);
      inputGroups[1][13].setType(EChannelType::SWITCH);
      inputGroups[1][14].setType(EChannelType::SWITCH);
      inputGroups[1][15].setType(EChannelType::SWITCH);
      //  MUX 3 = CH 32 to CH 47
      inputGroups[2][0].setType(EChannelType::SWITCH);
      inputGroups[2][4].setType(EChannelType::SWITCH);
      inputGroups[2][7].setType(EChannelType::SWITCH);
      inputGroups[2][11].setType(EChannelType::SWITCH);
      inputGroups[2][14].setType(EChannelType::SWITCH);
      inputGroups[2][15].setType(EChannelType::SWITCH);
      //  MUX 4 = CH 48 to CH 63
      //  MUX 5 = CH 64 to CH 79
      inputGroups[4][6].setType(EChannelType::SWITCH);
    
      inputGroups[4][8].setType(EChannelType::DISABLED);
      inputGroups[4][9].setType(EChannelType::DISABLED);
      inputGroups[4][10].setType(EChannelType::DISABLED);
      inputGroups[4][11].setType(EChannelType::DISABLED);
      inputGroups[4][12].setType(EChannelType::DISABLED);
      inputGroups[4][13].setType(EChannelType::DISABLED);
      inputGroups[4][14].setType(EChannelType::DISABLED);
      inputGroups[4][15].setType(EChannelType::DISABLED);
    }
    
    void loop()
    {
      // Handle all send button
      allSendButton.update();
      if (allSendButton.fell()) {
        Serial.println("All send pressed");
    //    Blake: I have temporarily disabled the all send button to help 
    //           debug first CC button sending all send.
    //    for (int ch = 0; ch < channelsPerMux; ch++) {
    //      for (int mux = 0; mux < muxCount; mux++) {
    //        inputGroups[mux][ch].sendNext();
    //      }
    //    }
      }
      
      // Read the MUXs and send MIDI/LED if changed, every 'ccdelay' milliseconds
      unsigned long timeNow = millis();
      if (timeNow >= lastUpdateTime + ccdelay)
      {
        lastUpdateTime = timeNow;
    
        // Loop through each channel and each mux
        for (int ch = 0; ch < channelsPerMux; ch++)
        {
          for (int mux = 0; mux < muxCount; mux++) {
            // Read from ADC
            int rawValue = readMux(ch, muxInputPins[mux]);
            inputGroups[mux][ch].updateValue(rawValue);
    
            // Write to MIDI and LEDs
            if (inputGroups[mux][ch].toSend()) {
              int ccNum = inputGroups[mux][ch].getCCNum();
              int val = inputGroups[mux][ch].getValue();
              usbMIDI.sendControlChange(ccNum, val, 4);
              Serial.print("cc=");
              Serial.print(ccNum);
              Serial.print(",val=");
              Serial.print(val);
    
              int ledIndex = ch + mux * channelsPerMux;
              int hue = map(val, 0, MIDI_MAX, 150, 0);
              leds[ledIndex] = CHSV(hue, 255, 255);
              Serial.print(",hue=");
              Serial.print(hue);
    
              Serial.println();
            }
          }
        }
        
        // Push the values in 'leds[]' out to the physical LEDs
        FastLED.show();
      }
    }
    
    // === Reading the MUXs ===
    
    int readMux(int channel, int analogPin)
    {
      for (int i = 0; i < muxControlPinCount; i++)
      {
        // Bit shift a 1 up to the control bit.
        // AND it with channel and write HIGH if nonzero.
        bool bitIsSet = (channel & (1 << i)) > 0;
        digitalWrite(muxControlPins[i], bitIsSet);
      }
      int val = analogRead(analogPin);
      return val;
    }
    And here's the first part of why it said it didn't compile:

    Code:
    n file included from /Users/claudewoodward/Downloads/claude-controller-mini-main/claude_controller_mini_code2/claude_controller_mini_201120/claude_controller_mini_201120.ino:4:0:
    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:14:21: note: #pragma message: FastLED version 3.003.003
     #    pragma message "FastLED version 3.003.003"
                         ^
    claude_controller_mini_201120: In function 'void setup()':
    claude_controller_mini_201120:56: error: no matching function for call to 'CFastLED::addLeds(CRGB [96], const int&)'
      LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
                                                          ^
    In file included from /Users/claudewoodward/Downloads/claude-controller-mini-main/claude_controller_mini_code2/claude_controller_mini_201120/claude_controller_mini_201120.ino:4:0:
    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:223:130: note: candidate: template<ESPIChipsets CHIPSET, unsigned char DATA_PIN, unsigned char CLOCK_PIN, EOrder RGB_ORDER, long unsigned int SPI_DATA_RATE> CLEDController& CFastLED::addLeds(CRGB*, int, int)
      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) {
                                                                                                                                      ^
    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:223:130: note:   template argument deduction/substitution failed:
    claude_controller_mini_201120:56: error: could not convert template argument 'WS2812SERIAL' to 'ESPIChipsets'
      LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
                                                          ^
    Hope that helps.

  12. #12
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    168
    Quote Originally Posted by sonicmanipulator View Post
    Sorry about that.

    Here's the code with the amended line you suggested:

    Code:
    CRGB leds[numLeds];
    
    void setup()
    {
    < portions snipped out>
     LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
    < portions snipped out>
    }
    @sonicmanipulator:

    I don't have any specific experience with WS2812SERIAL, but these comments are from my experience with the FastLED library in general. Here's something to try and/or check:

    As part of the library initialization (at least for FastLED, non-serial), the first parameter after the opening "<" should reflect the type of LEDs that you are using (commonly WS2812B, so try that...if that's not what you have, try inserting the constant for whatever type you do have).


    You might try changing the following line:

    Code:
     LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
    To this:

    Code:
     LEDS.addLeds<WS2812B, ledDataPin>(leds, numLeds);
    Hope that helps !!

    Good luck & have fun !!

    Mark J Culross
    KD5RXT
    Last edited by kd5rxt-mark; 11-25-2020 at 03:40 AM.

  13. #13
    Member LitterBug's Avatar
    Join Date
    Nov 2020
    Location
    Earth
    Posts
    24
    Quote Originally Posted by sonicmanipulator View Post
    Sorry about that.

    Here's the code with the amended line you suggested:

    Code:
    // ====== LEDs ======
    #include <WS2812Serial.h>
    #define USE_WS2812SERIAL
    #include "FastLED.h"
    const int ledDataPin = 8;
    const int numLeds = 96;
    CRGB leds[numLeds];
    
    // ====== MUXs ======
    // The number of mux boards used and their ADC pins
    const int muxCount = 5;
    const int muxInputPins[] = {A0, A1, A2, A3, A4};
    
    // The pins that select which mux channel is connected
    const int muxControlPinCount = 4;
    const int muxControlPins[] = {4, 3, 2, 1};
    
    // Define the mux control pins
    const int channelsPerMux = 16;
    
    #include "input.h"
    MusicInput inputGroups[muxCount][channelsPerMux] = {};
    
    // ====== MIDI ======
    // The number of milliseconds between successive sends of the CC data
    const int ccdelay = 10;
    
    // Set the MUX to MIDI CC channel mapping
    // (position is MUX input, value is MIDI CC channel)
    int ccChannelMap[muxCount][channelsPerMux] = {
      12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,  // MUX 1
      28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,  // MUX 2
      44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,  // MUX 3
      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,  // MUX 4
      76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,  // MUX 5
    };
    
    // ====== Button ======
    #include <Bounce2.h>
    Bounce allSendButton = Bounce(); 
    const int allSendPin = 0;
    
    // ====== Program ======
    unsigned long lastUpdateTime = 0;
    
    void setup()
    {
      delay(1000);
      Serial.begin(115200);
      Serial.println("Claude Controller Mini");
    
      allSendButton.attach(allSendPin, INPUT_PULLUP);
      allSendButton.interval(20);
      
      //FastLED.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
     LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
      setupMux();
    
      allSendButton.update();
      if (allSendButton.read() == LOW)
      {
        // Calibrate and then stop
        doCalibration();
      }
      else
      {
        // Load calibration and continue
        loadCalibration();
      }
      Serial.println("CCnum,val,hue");
    }
    
    void setupMux() {
      // Set MUX control pins as OUTPUTS
      for (int i = 0; i < muxControlPinCount; i++) {
        pinMode(muxControlPins[i], OUTPUT);
      }
    
      // Configure CC numbers and default types
      for (int mux = 0; mux < muxCount; mux++) {
        for (int ch = 0; ch < channelsPerMux; ch++) {
          // Default type of POT
          inputGroups[mux][ch].setType(EChannelType::POT);
    
          // Number inputs from definition
          inputGroups[mux][ch].setCCNum(ccChannelMap[mux][ch]);
        }
      }
    
      // Set some channels to switches
      //  MUX 1 = CH 0 to CH 15
      inputGroups[0][0].setType(EChannelType::DISABLED);
      //  MUX 2 = CH16 to CH31
      inputGroups[1][7].setType(EChannelType::SWITCH);
      inputGroups[1][8].setType(EChannelType::SWITCH);
      inputGroups[1][9].setType(EChannelType::SWITCH);
      inputGroups[1][13].setType(EChannelType::SWITCH);
      inputGroups[1][14].setType(EChannelType::SWITCH);
      inputGroups[1][15].setType(EChannelType::SWITCH);
      //  MUX 3 = CH 32 to CH 47
      inputGroups[2][0].setType(EChannelType::SWITCH);
      inputGroups[2][4].setType(EChannelType::SWITCH);
      inputGroups[2][7].setType(EChannelType::SWITCH);
      inputGroups[2][11].setType(EChannelType::SWITCH);
      inputGroups[2][14].setType(EChannelType::SWITCH);
      inputGroups[2][15].setType(EChannelType::SWITCH);
      //  MUX 4 = CH 48 to CH 63
      //  MUX 5 = CH 64 to CH 79
      inputGroups[4][6].setType(EChannelType::SWITCH);
    
      inputGroups[4][8].setType(EChannelType::DISABLED);
      inputGroups[4][9].setType(EChannelType::DISABLED);
      inputGroups[4][10].setType(EChannelType::DISABLED);
      inputGroups[4][11].setType(EChannelType::DISABLED);
      inputGroups[4][12].setType(EChannelType::DISABLED);
      inputGroups[4][13].setType(EChannelType::DISABLED);
      inputGroups[4][14].setType(EChannelType::DISABLED);
      inputGroups[4][15].setType(EChannelType::DISABLED);
    }
    
    void loop()
    {
      // Handle all send button
      allSendButton.update();
      if (allSendButton.fell()) {
        Serial.println("All send pressed");
    //    Blake: I have temporarily disabled the all send button to help 
    //           debug first CC button sending all send.
    //    for (int ch = 0; ch < channelsPerMux; ch++) {
    //      for (int mux = 0; mux < muxCount; mux++) {
    //        inputGroups[mux][ch].sendNext();
    //      }
    //    }
      }
      
      // Read the MUXs and send MIDI/LED if changed, every 'ccdelay' milliseconds
      unsigned long timeNow = millis();
      if (timeNow >= lastUpdateTime + ccdelay)
      {
        lastUpdateTime = timeNow;
    
        // Loop through each channel and each mux
        for (int ch = 0; ch < channelsPerMux; ch++)
        {
          for (int mux = 0; mux < muxCount; mux++) {
            // Read from ADC
            int rawValue = readMux(ch, muxInputPins[mux]);
            inputGroups[mux][ch].updateValue(rawValue);
    
            // Write to MIDI and LEDs
            if (inputGroups[mux][ch].toSend()) {
              int ccNum = inputGroups[mux][ch].getCCNum();
              int val = inputGroups[mux][ch].getValue();
              usbMIDI.sendControlChange(ccNum, val, 4);
              Serial.print("cc=");
              Serial.print(ccNum);
              Serial.print(",val=");
              Serial.print(val);
    
              int ledIndex = ch + mux * channelsPerMux;
              int hue = map(val, 0, MIDI_MAX, 150, 0);
              leds[ledIndex] = CHSV(hue, 255, 255);
              Serial.print(",hue=");
              Serial.print(hue);
    
              Serial.println();
            }
          }
        }
        
        // Push the values in 'leds[]' out to the physical LEDs
        FastLED.show();
      }
    }
    
    // === Reading the MUXs ===
    
    int readMux(int channel, int analogPin)
    {
      for (int i = 0; i < muxControlPinCount; i++)
      {
        // Bit shift a 1 up to the control bit.
        // AND it with channel and write HIGH if nonzero.
        bool bitIsSet = (channel & (1 << i)) > 0;
        digitalWrite(muxControlPins[i], bitIsSet);
      }
      int val = analogRead(analogPin);
      return val;
    }
    And here's the first part of why it said it didn't compile:

    Code:
    n file included from /Users/claudewoodward/Downloads/claude-controller-mini-main/claude_controller_mini_code2/claude_controller_mini_201120/claude_controller_mini_201120.ino:4:0:
    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:14:21: note: #pragma message: FastLED version 3.003.003
     #    pragma message "FastLED version 3.003.003"
                         ^
    claude_controller_mini_201120: In function 'void setup()':
    claude_controller_mini_201120:56: error: no matching function for call to 'CFastLED::addLeds(CRGB [96], const int&)'
      LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
                                                          ^
    In file included from /Users/claudewoodward/Downloads/claude-controller-mini-main/claude_controller_mini_code2/claude_controller_mini_201120/claude_controller_mini_201120.ino:4:0:
    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:223:130: note: candidate: template<ESPIChipsets CHIPSET, unsigned char DATA_PIN, unsigned char CLOCK_PIN, EOrder RGB_ORDER, long unsigned int SPI_DATA_RATE> CLEDController& CFastLED::addLeds(CRGB*, int, int)
      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) {
                                                                                                                                      ^
    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:223:130: note:   template argument deduction/substitution failed:
    claude_controller_mini_201120:56: error: could not convert template argument 'WS2812SERIAL' to 'ESPIChipsets'
      LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
                                                          ^
    Hope that helps.
    Can you please provide everything in the error box? There can be other clues that we are not seeing.

  14. #14
    When I changed the line Mark suggested - LEDS.addLeds<WS2812B, ledDataPin>(leds, numLeds); - it compiled ok but the LEDs didn't work.

    When I changed it back to - LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds); the error message was:

    /Users/claudewoodward/Documents/Arduino/libraries/FastLED/FastLED.h:391:25: note: template argument deduction/substitution failed:
    /Users/claudewoodward/Downloads/claude-controller-mini-main/claude_controller_mini_code2/claude_controller_mini_201120/claude_controller_mini_201120.ino:56:54: note: couldn't deduce template parameter 'RGB_ORDER'
    LEDS.addLeds<WS2812SERIAL, ledDataPin>(leds, numLeds);
    ^
    Multiple libraries were found for "FastLED.h"
    Used: /Users/claudewoodward/Documents/Arduino/libraries/FastLED
    Not used: /private/var/folders/0c/rl8qxzxj6t97dx0bsxb_gf7r0000gn/T/AppTranslocation/2F268634-8600-493D-A5D9-2C336C699550/d/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/FastLED
    Multiple libraries were found for "Bounce2.h"
    Used: /private/var/folders/0c/rl8qxzxj6t97dx0bsxb_gf7r0000gn/T/AppTranslocation/2F268634-8600-493D-A5D9-2C336C699550/d/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/Bounce2
    Not used: /Users/claudewoodward/Documents/Arduino/libraries/Bounce2-master
    no matching function for call to 'CFastLED::addLeds(CRGB [96], const int&)'

    I wired up another Teensy 4.1 just connected to a LED strip and ran the amended Demo 100 program & it worked fine but when I tried to run it on my project Teensy 4.1 I got nothing so there may be a hardware issue.
    I can get the wheels to send MIDI data so I know the Teensy is ok.

    Let me know if you see anything obvious. I'm going to my local hack space tonight so might have some joy there.

    Thanks so much for your help & I hope I can get it sorted before my brain explodes(:

  15. #15
    Member LitterBug's Avatar
    Join Date
    Nov 2020
    Location
    Earth
    Posts
    24
    I tried to complile it on mine, but I am missing the library for the #include<input.h> . Do you know what library that you installed for that?


    EDIT:
    You need to add the LED color order to the initialization command. the "BGR" is currently missing. (or what ever order works correctly for your strips)

    Code:
     LEDS.addLeds<WS2812SERIAL, ledDataPin, BGR>(leds, numLeds);
    Last edited by LitterBug; 11-25-2020 at 03:52 PM.

  16. #16
    The <input.h> was written especially for this project (Claude Controller MIDI controller) for the various functions of the wheels & switches. Thanks for the LED order update.

    The good news is thanks to your help & Blake from the Artifactory (who wrote the code) here in Perth Australia, we were able to port over the changes from the modified Demo Reel 100 & now IT WORKS!! Also after rewiring the led strips I had accidentally wired one with earth & volts backwards (major oops).

    Anyway thanks for all your help guys. The only thing I need to do now is get the to send MIDI notes. If anyone knows a good drum pad program out there you could point me to, I'd appreciate it. I've tried doing piezo triggering a few times but found it difficult to get good sensitivity without false triggering.

    Here's a pic:

    Click image for larger version. 

Name:	CC 4 Piezos Working.jpg 
Views:	10 
Size:	117.5 KB 
ID:	22630

  17. #17
    Member LitterBug's Avatar
    Join Date
    Nov 2020
    Location
    Earth
    Posts
    24
    Glad to be of help. I can't believe I looked at that statement so many times and missed that the color ordering field was missing. Ahh well, Glad I could be of help. Great to see pictures of projects others are working on!

    Cheers!
    and HAPPY THANKSGIVING!

    Regards,
    Karl Litterer
    AKA LitterBug

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •