Interactieve LED-matrix deurdisplay met PIR-bewegingsensor – Arduino vakantiegroet
Onderdelen en benodigdheden
| Arduino UNO (hoofdcontroller LED-matrices) | 1 |
| Arduino Nano (voor 2e PIR + LED-strip) | 1 |
| PIR-bewegingsensor (HC-SR501 of gelijk) | 2 |
| Relaismodule 5V | 1 |
| RGB LED-strip 12V (met verlengkabel) | 1 |
| 3x 8x8 NeoPixel-paneel (WS2812B) = 24×8 matrix | 3 |
| 5V 30A voeding (voor LED-matrices) | 1 |
| PC-voedingskabel | 1 |
| Draadjes | 1 set |
Benodigde tools
- Solderbout
- Draadstripper
Over dit project
Dit project combineert 3 WS2812B 8×8 RGB LED-matrices (totaal 24×8 = 192 LEDs) en een PIR-bewegingsensor om bezoekers te begroeten met de tekst "Happy Holidays & Happy New Year!" wanneer ze dichtbij de deur komen. Bij geen detectie toont het een screensaver-achtige reeks effecten (regenboog, glitter, confetti, sinus, BPM, juggle, cylon).
Een tweede PIR-sensor (op de trap) activeert via een relais een 12V RGB LED-strip en de feestverlichting. Na een paar traptreden activeert de tweede sensor (bij de deur) de tekst op de matrices.
De code is een combinatie van:
- FastLED
DemoReel100voorbeeld (idle-effecten) - PIR-sensorcode
- NeoPixel/Adafruit_NeoMatrix setup
Code
Arduino Holiday (voor UNO met 3 matrices + PIR)
#include <FastLED.h>
FASTLED_USING_NAMESPACE
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
#define PSTR
#endif
#define PIN 6
#define DATA_PIN 6
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 192
CRGB leds[NUM_LEDS];
const uint8_t kMatrixWidth = 24;
const uint8_t kMatrixHeight = 8;
const bool kMatrixSerpentineLayout = true;
#define BRIGHTNESS 50
#define FRAMES_PER_SECOND 120
static uint16_t x, y, z;
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(24, 8, PIN,
NEO_MATRIX_TOP + NEO_MATRIX_RIGHT + NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
NEO_GRB + NEO_KHZ800);
const uint16_t colors[] = {
matrix.Color(255,0,0), matrix.Color(0,255,0), matrix.Color(0,0,255),
matrix.Color(0,255,255), matrix.Color(255,0,255), matrix.Color(255,255,0),
matrix.Color(255,255,255)
};
uint16_t speed = 20, scale = 30;
uint8_t noise[24][24];
CRGBPalette16 currentPalette(PartyColors_p);
uint8_t colorLoop = 1;
int pirSensorPin = 5;
int pirState = true;
int val = 0;
int minimummSecsLowForInactive = 5000;
long unsigned int timeLow;
boolean takeLowTime;
int calibrationTime = 30;
int a = 24;
int pass = 0;
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm, cylon };
uint8_t gCurrentPatternNumber = 0;
uint8_t gHue = 0;
void setup() {
delay(3000);
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
matrix.setTextWrap(false);
matrix.setBrightness(40);
matrix.setTextColor(colors[0]);
pinMode(pirSensorPin, INPUT);
LEDS.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
x = random16(); y = random16(); z = random16();
}
void fadeall() {
for (int i = 0; i < NUM_LEDS; i++) leds[i].nscale8(250);
}
void loop() {
val = digitalRead(pirSensorPin);
if (val == HIGH) {
// Beweging gedetecteerd → scrollende tekst
matrix.fillScreen(0);
matrix.setCursor(a, 0);
matrix.print(F("Happy Holidays & Happy New Year!"));
if (--a < -200) {
a = matrix.width();
if (++pass >= 6) pass = 0;
matrix.setTextColor(colors[pass]);
}
matrix.show();
delay(100);
if (pirState) { pirState = false; }
takeLowTime = true;
} else {
// Geen beweging → screensaver effecten
gPatterns[gCurrentPatternNumber]();
FastLED.show();
FastLED.delay(1000 / FRAMES_PER_SECOND);
EVERY_N_MILLISECONDS(20) { gHue++; }
EVERY_N_SECONDS(10) { nextPattern(); }
}
}
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
void nextPattern() {
gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE(gPatterns);
}
void rainbow() { fill_rainbow(leds, NUM_LEDS, gHue, 7); }
void rainbowWithGlitter() { rainbow(); addGlitter(80); }
void addGlitter(fract8 chance) { if (random8() < chance) leds[random16(NUM_LEDS)] += CRGB::White; }
void confetti() {
fadeToBlackBy(leds, NUM_LEDS, 10);
int pos = random16(NUM_LEDS);
leds[pos] += CHSV(gHue + random8(64), 200, 255);
}
void sinelon() {
fadeToBlackBy(leds, NUM_LEDS, 20);
int pos = beatsin16(13, 0, NUM_LEDS - 1);
leds[pos] += CHSV(gHue, 255, 192);
}
void bpm() {
uint8_t BeatsPerMinute = 62;
CRGBPalette16 palette = PartyColors_p;
uint8_t beat = beatsin8(BeatsPerMinute, 64, 255);
for (int i = 0; i < NUM_LEDS; i++)
leds[i] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10));
}
void juggle() {
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;
}
}
void cylon() {
static uint8_t hue = 0;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(hue++, 255, 255);
FastLED.show(); fadeall(); delay(10);
}
for (int i = NUM_LEDS - 1; i >= 0; i--) {
leds[i] = CHSV(hue++, 255, 255);
FastLED.show(); fadeall(); delay(10);
}
}
Schema
Zie schema: 3 matrices in serie op pin 6 (UNO), PIR op pin 5. Nano: PIR → relais → 12V LED-strip (apart voeding).
Productieproces
- Bouw Je Eigen LUMAZOID: Een DIY Arduino Muziek Visualizer
- DHT11 Temperatuur- & Vochtigheidsensor Project met LED-indicatoren en Piezo-luidspreker
- Riviergezondheidsmonitor: Arduino-gebaseerd Waterkwaliteitssysteem
- Een eenvoudige obstakelsensor bouwen met Arduino – IR LED & Fotodiodo Tutorial
- Find Me: Slimme Item Locator met Arduino en Bluetooth
- Bouw een Slimme Arduino Vierpotige Robot: Stap-voor-Stap Handleiding
- Slimme beweegactiverde waterpistool gebouwd met Arduino Nano
- Realtime afstandsmeting met Arduino Sonar & Processing visualisatie
- Zelfbouw Arduino Nano Oscilloscoop (10 Hz – 50 kHz) met 128×64 LCD
- Arduino Flip Clock met 8×8 LED Matrix – DIY Real-Time Clock Project
- Een 8×8 LED-matrix beheersen met Arduino Uno: Stap-voor-stap handleiding