LEGO Castle Program

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 Program Includes and  Defines

/* 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

  }

};

LEGO Castle Program Setup

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;

  }

}

LEGO Castle Program Loop

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);

}