I had a problem identifying the LEDs. All of the available code uses the Arduino library “FastLED”, but this is complex and can use many types of LED. For the ones from the Whadda kit the examples that came with it specify WS2812B. I could not find online any information about the MCM LEDs, and MCM is no longer in business. I therefore made a breadboard with 1 Whadda and 2 MCM LEDs and run some simple tests, which showed they worked together OK.
However, when I wrote the main program on the actual project using code from the Octagon project, which also uses WS2812 LEDs, the palette-based functions did not work.
This code therefore uses simple arrays and assignment, which do work.
Omitted are fading and blending.
/* LEGO_Castle.ino using 8 MCM and 4 Whadda LEDs
This was supposed to use an old LEGO 'Mindstorms' set but
this did not have construction blocks so I got a kg of mixed
used blocks on Craigs' list for $20.
It also uses 4 'neopixel' 5 mm LEDs from a Whadda kit and
8 8mm bought long ago, which I did not have software or
information on then.
Major electronics are a Pololu A-Star P238 micro Arduino and
a doppler radar module with a 10-foot range.
The 3-ay Mode switch is for ON-OFF and adar enable
The 3-way Program swithch selects 3 display patterns.
The Speed potetiometer controls the display change period.
John Saunders 1/10/2025
*/
#include <FastLED.h>
FASTLED_USING_NAMESPACE
#define NUM_LEDS 12
#define BRIGHTNESS 64
#define LED_TYPE WS2812B //Most software is for this but
#define COLOR_ORDER GRB //there are incompatibilities.
#define DATA_PIN 3
#define RADAR_PIN A1
#define MODE_PIN 2
#define PROGRAM4_PIN 4
#define PROGRAM5_PIN 5
#define HOLDUP_TIME 60L //Seconds
#define SPEED_PIN A0
#define UPDATE_MULT 5 //For converting the pot voltage.
#define UPDATE_MAX 1060 //For converting the pot voltage.
CRGB leds[NUM_LEDS];
uint16_t run_mode, program_mode, interval, startPos, old_mode;
uint32_t timeout_limit, update_limit;
bool display_enable;
const uint16_t numSteps = 56;
//The method ColorFromPalette() does not woork here so this is a workaround
const CRGB Colors_List[10] {
CRGB::White, CRGB::Black, CRGB::Red, CRGB::Orange,
CRGB::YellowGreen, CRGB::Green, CRGB::Maroon, CRGB::Aqua,
CRGB::Teal, CRGB::Blue
};
const int LED_Order[12] {8, 9, 10, 11, 7, 6, 5, 4, 0, 1, 2, 3};
const uint8_t lED_maps[3][numSteps] = {
{ 1, 1, 2, 3, 1, 1, 3, 4, 1, 1, 4, 5, 1, 1, 5, 6, 1, 1, 6, 7, 1, 1, 7, 8, 1, 1, 8, 9,
1, 1, 2, 3, 1, 1, 3, 4, 1, 1, 4, 5, 1, 1, 5, 6, 1, 1, 6, 7, 1, 1, 7, 8, 1, 1, 8, 9
},
{ 0, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 0, 2, 3, 4, 5, 6, 7, 8, 9,
0, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 0, 2, 3, 4, 5, 6, 7, 8, 9
},
{ 2, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1 , 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1,
1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, 1, 1 , 1, 1, 8, 1, 1, 1, 1, 1, 1, 1
}
};
void setup() {
// Serial.begin(9600);
pinMode(MODE_PIN, INPUT_PULLUP);
pinMode(PROGRAM4_PIN, INPUT_PULLUP);
pinMode(PROGRAM5_PIN, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
run_mode = digitalRead(MODE_PIN);
if (run_mode == 0) {
display_enable = true;
}
else {
display_enable = false;
}
old_mode = 4;
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness( BRIGHTNESS );
startPos = 0;
interval = 100;
timeout_limit = ((uint32_t)1000 * HOLDUP_TIME) + millis();
update_limit = millis() + 200;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
}
}
void loop() {
uint16_t templatePos, colorPos, LED_Pos;
if (analogRead(RADAR_PIN) > 400) {
timeout_limit = ((uint32_t)1000 * HOLDUP_TIME) + millis();
display_enable = true;
}
if (display_enable) {
digitalWrite(LED_BUILTIN, HIGH);
if (millis() > update_limit) {
program_mode = 3 - digitalRead(PROGRAM4_PIN) - (2 * digitalRead(PROGRAM5_PIN));
if (program_mode != old_mode) {
old_mode = program_mode;
startPos = random(0, 12);
}
for (int i = 0; i < 12; i++) {
templatePos = startPos + i;
if (templatePos >= numSteps) {
templatePos = templatePos - numSteps;
}
colorPos = lED_maps[program_mode][templatePos];
LED_Pos = LED_Order[i];
leds[LED_Pos] = Colors_List[colorPos];
}
FastLED.show();
update_limit = (UPDATE_MULT * (UPDATE_MAX - analogRead(SPEED_PIN))) + millis();
startPos++;
if (startPos >= numSteps) {
startPos = startPos - numSteps;
}
}
else {
digitalWrite(LED_BUILTIN, LOW);
}
}
if ((run_mode == 1) && (millis() > timeout_limit)) { //AUTO Mode, controlled by radar
display_enable = false;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
}
FastLED.show();
}
delay(interval);
}