Teensy 4.1 WS2812B LED Problem

Status
Not open for further replies.
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>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
//FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(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 = 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;
}
}
 
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);
	}
}
 
I modified the DemoReel100 to use the same initialization that is used in the Teensy WS2812SERIAL demo, and it works.
 
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, 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, bitIsSet);
}
int val = analogRead(analogPin);
return val;
}
 
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
 
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
 
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, 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, 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) {
 
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
 
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);
^
 
Please paste your code between code wrappers. It is very difficult to help debug code otherwise.

See picture:

CodeNoCode.png
 
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.
 
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:
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.
 
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:)
 
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:
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:

CC 4 Piezos Working.jpg
 
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
 
Status
Not open for further replies.
Back
Top