Lego Smart Brick selber bauen – warum der berühmte Stein gar nicht so smart ist
Welt, seid mir gegrüßt. Ich bin der Held der ESPs, im Herzen von Altena – an einem fantastischen Tag. Und schaut mal, was ich euch mitgebracht habe…
Heute bauen wir den Lego Smart Brick nach. Oder genauer gesagt: Wir schauen uns an, was dieser berühmte Stein eigentlich wirklich macht.
Denn wenn man sich moderne Lego-Sets anschaut, könnte man fast glauben, irgendwo im Plastikstein wohnt ein kleines Raumschiff-Gehirn. Sensoren, Geräusche, Farben erkennen, Bewegung registrieren – das wirkt alles ziemlich magisch, wenn auch mit eher überschaubarer Sprachausgabe.
Die Wahrheit ist allerdings deutlich simpler.
Schnellnavigation
- Die Idee hinter unserem Smart Brick
- Die Hardware unseres Smart Brick
- Bewegungssensor und Soundmodul
- Pinbelegung
- Der Code
- Warum der Lego Smart Brick technisch weniger smart ist als gedacht
- Der wahre Respekt gehört der Miniaturisierung
- Was Lego versäumt hat
- Was man daraus noch machen könnte
Die Idee hinter unserem Smart Brick
Unser Ziel war nicht, einen perfekten Nachbau zu entwickeln.
Das Ziel war eigentlich viel interessanter: verstehen, was der Smart Brick überhaupt macht.
Dafür bauen wir eine minimalistische Version mit handelsüblichen Maker-Modulen.
Der Aufbau besteht aus fünf Bausteinen:
- Mikrocontroller (ESP32)
- RFID-Leser
- Farbsensor
- Bewegungssensor
- MP3-Player
Der Mikrocontroller übernimmt dabei im Kern nur eine einzige Aufgabe: Er sammelt Sensordaten und löst daraufhin Aktionen aus.
Zum Beispiel:
- Bewegung erkannt → spiele
0001.mp3 - RFID-Tag erkannt → spiele
0002.mp3 - Farbe Rot erkannt → spiele
0004.mp3
Nicht mehr. Nicht weniger.
Der Stein denkt also nicht wirklich – er reagiert nur.
Die Hardware unseres Smart Brick

Für den Nachbau haben wir folgende Komponenten verwendet:
Mikrocontroller
Herzstück ist ein ESP32 DevKit.
Der Controller ist leistungsfähig, günstig und hat genügend Schnittstellen, um mehrere Sensoren gleichzeitig zu bedienen. Für so ein Projekt ist das ziemlich komfortabel.
ESP32 DevKit Board (bezahlter Link)
RFID-Leser
Der RFID-Leser erkennt kleine Tags oder Karten.
Damit kann unser Smart Brick verschiedene Objekte identifizieren. In der Praxis heißt das: Tag erkannt, passenden Sound abspielen.
RFID RC522 Modul (bezahlter Link)
Farbsensor
Der TCS3200 misst reflektiertes Licht und bestimmt daraus die dominante Farbe.
Für unseren Nachbau reicht das völlig aus, denn wir wollen nicht jede Nuance unterscheiden, sondern nur auf einfache Grundfarben reagieren.
TCS3200 Farbsensor (bezahlter Link)
Bewegungssensor und Soundmodul
Bewegungssensor
Für Bewegung verwenden wir einen ADXL345 Beschleunigungssensor.
Der Sensor erkennt Lageänderungen, Kippen oder Schütteln. Das passt ziemlich gut zu einem Brick, der auf Bewegung reagieren soll, ohne dass man direkt einen klassischen PIR-Sensor braucht.
ADXL345 Beschleunigungssensor (bezahlter Link)
Soundmodul
Damit der Brick Geräusche abspielen kann, kommt ein DFPlayer Mini zum Einsatz.
Das Modul spielt MP3-Dateien direkt von einer microSD-Karte ab. Genau das macht es für solche Bastelprojekte herrlich pragmatisch: Datei drauf, Track abspielen, fertig.
DFPlayer Mini MP3 Modul (bezahlter Link)
Pinbelegung
Damit alle Module miteinander sprechen können, müssen sie korrekt angeschlossen werden.
| Modul | Pin | ESP32 |
|---|---|---|
| RC522 | SDA | GPIO5 |
| RC522 | SCK | GPIO18 |
| RC522 | MOSI | GPIO23 |
| RC522 | MISO | GPIO19 |
| RC522 | RST | GPIO27 |
| ADXL345 | SDA | GPIO21 |
| ADXL345 | SCL | GPIO22 |
| DFPlayer | RX | GPIO17 |
| DFPlayer | TX | GPIO16 |
| TCS3200 | S0 | GPIO32 |
| TCS3200 | S1 | GPIO33 |
| TCS3200 | S2 | GPIO25 |
| TCS3200 | S3 | GPIO26 |
| TCS3200 | OUT | GPIO14 |
Damit nutzt unser kleiner Stein gleich mehrere Kommunikationsprotokolle gleichzeitig:
- SPI
- I²C
- UART
- Frequenzmessung
Für einen simplen „Smart Brick“ ist das schon eine erstaunliche Sensorparty in einem ziemlich kleinen Aufbau.
Der Code
Der Code verbindet alle Sensoren miteinander. Je nach Ereignis wird ein bestimmter Sound abgespielt.
#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <HardwareSerial.h>
#include <DFRobotDFPlayerMini.h>
// =========================
// RFID RC522
// =========================
#define RFID_SS_PIN 5
#define RFID_RST_PIN 27
MFRC522 mfrc522(RFID_SS_PIN, RFID_RST_PIN);
// =========================
// ADXL345
// =========================
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
// =========================
// DFPlayer
// =========================
HardwareSerial mySerial(2); // UART2
DFRobotDFPlayerMini dfPlayer;
// =========================
// TCS3200
// =========================
#define TCS_S0 32
#define TCS_S1 33
#define TCS_S2 25
#define TCS_S3 26
#define TCS_OUT 14
// =========================
// Einstellungen
// =========================
const String RFID_TAG_1 = "3AED0685";
const String RFID_TAG_2 = "49770785";
const float movementThreshold = 3.0;
const unsigned long motionCooldown = 1500;
const unsigned long colorReadInterval = 250;
const unsigned long playCooldown = 1200;
// Farb-Erkennung
const float colorDominanceRatio = 1.25;
const int stableColorReadsNeeded = 3;
// =========================
// Zustände
// =========================
float lastX = 0;
float lastY = 0;
float lastZ = 0;
bool accelInitialized = false;
unsigned long lastMotionTrigger = 0;
unsigned long lastColorRead = 0;
unsigned long lastPlayTime = 0;
String lastStableColor = "";
String colorCandidate = "";
int colorCandidateCount = 0;
// =========================
// Hilfsfunktionen
// =========================
void playTrack(uint8_t track, const String& reason)
{
unsigned long now = millis();
if (now - lastPlayTime < playCooldown)
{
return;
}
dfPlayer.play(track);
Serial.print("Track ");
Serial.print(track);
Serial.print(" gestartet durch: ");
Serial.println(reason);
lastPlayTime = now;
}
String readUID()
{
String uidString = "";
for (byte i = 0; i < mfrc522.uid.size; i++)
{
if (mfrc522.uid.uidByte[i] < 0x10)
{
uidString += "0";
}
uidString += String(mfrc522.uid.uidByte[i], HEX);
}
uidString.toUpperCase();
return uidString;
}
unsigned long readColorFrequency(bool s2, bool s3)
{
digitalWrite(TCS_S2, s2);
digitalWrite(TCS_S3, s3);
delay(5);
return pulseIn(TCS_OUT, LOW, 50000);
}
String detectBasicColor(unsigned long red, unsigned long green, unsigned long blue)
{
if (red == 0 || green == 0 || blue == 0)
{
return "";
}
unsigned long smallest = red;
String color = "ROT";
unsigned long secondSmallest = min(green, blue);
if (green < smallest)
{
smallest = green;
color = "GRUEN";
secondSmallest = min(red, blue);
}
if (blue < smallest)
{
smallest = blue;
color = "BLAU";
secondSmallest = min(red, green);
}
if ((float)secondSmallest / (float)smallest < colorDominanceRatio)
{
return "";
}
return color;
}
void handleRFID()
{
if (!mfrc522.PICC_IsNewCardPresent())
{
return;
}
if (!mfrc522.PICC_ReadCardSerial())
{
return;
}
String uid = readUID();
Serial.print("RFID erkannt: ");
Serial.println(uid);
if (uid == RFID_TAG_1)
{
playTrack(2, "RFID Tag 1");
}
else if (uid == RFID_TAG_2)
{
playTrack(3, "RFID Tag 2");
}
else
{
Serial.println("Unbekannter RFID-Tag");
}
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
void handleMovement()
{
sensors_event_t event;
accel.getEvent(&event);
if (!accelInitialized)
{
lastX = event.acceleration.x;
lastY = event.acceleration.y;
lastZ = event.acceleration.z;
accelInitialized = true;
return;
}
float dx = fabs(event.acceleration.x - lastX);
float dy = fabs(event.acceleration.y - lastY);
float dz = fabs(event.acceleration.z - lastZ);
float totalChange = dx + dy + dz;
if (totalChange > movementThreshold && millis() - lastMotionTrigger > motionCooldown)
{
Serial.print("Bewegung erkannt: ");
Serial.println(totalChange);
playTrack(1, "Bewegung");
lastMotionTrigger = millis();
}
lastX = event.acceleration.x;
lastY = event.acceleration.y;
lastZ = event.acceleration.z;
}
void handleColor()
{
if (millis() - lastColorRead < colorReadInterval)
{
return;
}
lastColorRead = millis();
unsigned long red = readColorFrequency(LOW, LOW);
unsigned long blue = readColorFrequency(LOW, HIGH);
unsigned long green = readColorFrequency(HIGH, HIGH);
Serial.print("Farbe Rohwerte - Rot: ");
Serial.print(red);
Serial.print(" Gruen: ");
Serial.print(green);
Serial.print(" Blau: ");
Serial.println(blue);
String detectedColor = detectBasicColor(red, green, blue);
if (detectedColor == "")
{
colorCandidate = "";
colorCandidateCount = 0;
return;
}
if (detectedColor == lastStableColor)
{
colorCandidate = "";
colorCandidateCount = 0;
return;
}
if (detectedColor == colorCandidate)
{
colorCandidateCount++;
}
else
{
colorCandidate = detectedColor;
colorCandidateCount = 1;
}
if (colorCandidateCount >= stableColorReadsNeeded)
{
lastStableColor = detectedColor;
Serial.print("Neue stabile Farbe erkannt: ");
Serial.println(detectedColor);
if (detectedColor == "ROT")
{
playTrack(4, "Farbe Rot");
}
else if (detectedColor == "GRUEN")
{
playTrack(5, "Farbe Gruen");
}
else if (detectedColor == "BLAU")
{
playTrack(6, "Farbe Blau");
}
colorCandidate = "";
colorCandidateCount = 0;
}
}
// =========================
// Setup
// =========================
void setup()
{
Serial.begin(115200);
delay(1000);
Serial.println("Smart-Brick startet...");
// RFID
SPI.begin();
mfrc522.PCD_Init();
Serial.println("RFID bereit");
// ADXL345
Wire.begin(21, 22);
if (!accel.begin())
{
Serial.println("ADXL345 nicht gefunden. Verkabelung pruefen.");
while (true) { }
}
accel.setRange(ADXL345_RANGE_16_G);
Serial.println("ADXL345 bereit");
// DFPlayer
mySerial.begin(9600, SERIAL_8N1, 16, 17);
if (!dfPlayer.begin(mySerial))
{
Serial.println("DFPlayer nicht gefunden. Verkabelung pruefen.");
while (true) { }
}
dfPlayer.volume(20);
Serial.println("DFPlayer bereit");
// TCS3200
pinMode(TCS_S0, OUTPUT);
pinMode(TCS_S1, OUTPUT);
pinMode(TCS_S2, OUTPUT);
pinMode(TCS_S3, OUTPUT);
pinMode(TCS_OUT, INPUT);
digitalWrite(TCS_S0, HIGH);
digitalWrite(TCS_S1, LOW);
Serial.println("TCS3200 bereit");
Serial.println("Smart-Brick bereit");
}
// =========================
// Loop
// =========================
void loop()
{
handleRFID();
handleMovement();
handleColor();
}
Der eigentliche Trick ist nicht der Code selbst. Die eigentliche Herausforderung liegt darin, Sensorwerte sinnvoll zu filtern.
Der Farbsensor liefert zum Beispiel permanent neue Werte. Damit nicht bei jeder winzigen Änderung sofort ein Sound losplärrt, reagiert unser Code nur dann, wenn:
- eine Farbe klar dominiert
- und diese Erkennung mehrfach stabil hintereinander auftritt
Erst dann wird eine Aktion ausgelöst. Sonst würde der Brick akustisch so nervös reagieren wie ein Eichhörnchen auf Espresso.
Zwei RFID-Tags als Beispiel
Für unseren Test haben wir zwei RFID-Tags verwendet, die zuvor per Script ausgelesen wurden. Je nachdem, welcher Tag erkannt wird, spielt der Brick einen anderen Sound ab. Genau so simpel – und genau darum geht es hier auch.
Warum der Lego Smart Brick technisch weniger smart ist als gedacht
Wenn man sich den Aufbau anschaut, merkt man schnell: Der Smart Brick ist eigentlich nur ein Sensor-Hub.
Er sammelt Informationen aus der Umgebung:
- Bewegung
- Farbe
- Identität eines Objekts
Und reagiert darauf mit einfachen Aktionen.
Das klingt deutlich weniger spektakulär als „smarter Stein“ – ist technisch gesehen aber ziemlich exakt das, was passiert. Kein kleines Plastik-Orakel, sondern ein Ereignis-Auslöser mit Lautsprecher.
Und dann kommt noch ein Punkt dazu, der viele Fans etwas ernüchtert: die eigentliche Audioqualität. Die Figuren sprechen nicht wirklich – sie murmeln eher vor sich hin. Statt klarer Sprachausgabe gibt es ein ziemlich kryptisches „Mumble-Mumble“, begleitet von Geräuschen, die klingen, als hätte man sie durch einen Joghurtbecher aufgenommen. Das liegt vermutlich an der Kombination aus winzigem Lautsprecher und sehr stark komprimierten Soundeffekten. Der bekannte Lego-YouTuber Held der Steine hat das in mehreren Videos ebenfalls kritisch kommentiert und zeigt sehr anschaulich, wie seltsam diese Geräusche teilweise wirken.
Wer noch tiefer sehen möchte, was in diesem Stein tatsächlich steckt, dem sei außerdem das Video „Der Brain der Steine | Lego Smart Play mit Smart Brick im Teardown und ZERLEGT!“ vom YouTuber Zerobrain empfohlen. Dort wird der Smart Brick komplett auseinandergenommen und man bekommt einen ziemlich guten Eindruck davon, wie simpel die Technik im Inneren eigentlich aufgebaut ist – und warum viele Bastler danach sofort Lust bekommen, so etwas selbst zu bauen.
Hinzu kommt der Preis der Sets. Die interaktiven Lego-Systeme gehören inzwischen zu den teuersten Produktlinien überhaupt. Für den Preis eines einzigen größeren Sets bekommt man bereits genug Maker-Hardware, um mehrere eigene Smart-Brick-Experimente zu bauen – inklusive besserem Sound, mehr Sensoren und deutlich mehr Freiheit beim Programmieren.
Wer trotzdem sich eines der Lego Sets gönnen will, findet auf Amazon eine ganze Reihe, z.B. Darth Vaders TIE Fighter (bezahlter Link) oder das Set AT-ST Angriff auf Endor (bezahlter Link).
Alternativen mit sehr viel Licht sind Sets von FunWhole (bezahlter Link) oder das DJ Deck von PANTASY (bezahlter Link). welches sogar einen Bluetooth-Speaker enthält.
Der wahre Respekt gehört der Miniaturisierung
Jetzt kommt der Teil, bei dem man Lego wirklich Respekt zollen muss.
Unser Aufbau liegt aktuell gemütlich auf dem Tisch: ein paar Module, etwas Kabelsalat, ein Controllerboard. Alles entspannt, alles gut zugänglich, alles maximal unromantisch.
Der echte Lego Smart Brick steckt jedoch in einem 2×4 Stein.
Und darin befinden sich:
- Controller
- Sensorik
- Lautsprecher
- Akku
- Ladeelektronik
Das ist tatsächlich eine beeindruckende Ingenieursleistung.
Vor allem wenn man bedenkt, dass unser Prototyp aktuell ungefähr so viel Platz braucht wie ein mittelgroßes Sandwich. Vielleicht mit Beilage.
Und genau da liegt der faire Punkt: Der Stein ist funktional nicht wirklich smart, aber die Miniaturisierung ist verdammt stark.
Was Lego versäumt hat
Was Lego aus meiner Sicht hätte besser machen können, ist eigentlich ziemlich naheliegend. Statt unbedingt alles in einen winzigen 2×4-Stein zu quetschen, wäre ein etwas größerer Brick mit besserem Lautsprecher vermutlich die deutlich bessere Entscheidung gewesen. Dann wären auch echte Sprachsamples möglich gewesen, statt diese merkwürdigen Gemurmel-Sounds. Zur Sprachfrage: Statt für jede Region eigene Varianten zu bauen, hätte eine einfache englische Sprachausgabe völlig gereicht – Kinder kommen damit erstaunlich gut klar und der Produktionsaufwand wäre deutlich geringer. Und schließlich bleibt noch der Preis. Lego produziert in gigantischen Stückzahlen, wodurch die Elektronik eigentlich relativ günstig sein müsste. Genau deshalb wirkt es für viele Fans etwas seltsam, dass die interaktiven Sets trotzdem so extrem teuer sind.
Was man daraus noch machen könnte
Mit unserem Aufbau könnte man zum Beispiel:
- eigene Lego-Interaktionen bauen
- Lernspielzeuge entwickeln
- Geräuschmodule für Modelle erstellen
- kleine IoT-Spielzeuge bauen
Oder man geht den nächsten nerdigen Schritt: ein komplett eigener Smart Brick – nur deutlich leistungsfähiger.
Denn wenn man ehrlich ist: Mit einem ESP32 im Inneren könnte so ein Stein deutlich mehr als nur „Sound abspielen“.
Und genau darin liegt der eigentliche Reiz dieses Projekts. Der originale Brick zeigt, was auf engstem Raum möglich ist. Unser Nachbau zeigt, dass man funktional mit überschaubarem Aufwand schon ziemlich weit kommt – und dass da noch reichlich Luft nach oben ist.
Mehr Microcontroller Kram
Mehr nerdige Projekte aus derselben Ecke findest du übrigens auch hier auf Prokrastinerd. Wenn dich Sensoren, Displays und ESP-Basteleien interessieren, wirf einen Blick auf Zebra-Scent: Der Smart Home Aroma Diffusor, Nerd-Display – die MQTT LED Matrix fürs Smart Home und WaterMeV2 – Smarter Feuchtigkeitssensor mit ESP8266 & OLED-Display Noch mehr zum Thema Anzeigen und Displays findest du außerdem in OLED, LCD, E-Ink & Co.
GrayTheZebra ist Entwickler und Betreiber von prokrastinerd.de mit Fokus auf Smart Home ohne Cloud, ESP32 und MQTT-basierte Systeme. Alle Projekte basieren auf praktischer Umsetzung und eigener Hardwareentwicklung.
Autorprofil und Hintergrund:
Über GrayTheZebra

