DIY RGB Leuchtschrift mit Arduino
In dieser Anleitung zeigen wir, wie du eine dekorative RGB Leuchtschrift selbst herstellen und mit einem Arduino steuern kannst.
Benötigte Komponenten
- Filament in beliebigen Farben
- Lötzinn
- WS2812B LED Streifen
- yourDroid UNO R3 Entwicklungsboard
- Dupont / Jumper Kabel Buchse Stecker
- Kabel
- Netzteil
- USB-Kabel
Benötigtes Werkzeug
- 3D-Drucker
- Heißkleber
- Lötstation
- Seitenschneider
- Abisolierzange
- Dritte Hand / Löthilfe
Zunächst müssen die Buchstaben auf dem 3D-Drucker in beliebiger Größe gedruckt werden. Hierfür haben wir diese kostenlose Vorlage von Thingiverse verwendet. Zwingend benötigt werden dabei die einzelnen Buchstaben sowie die dazugehörigen Abdeckungen, also zum Beispiel die Dateien Letter_R.stl und Letter_R_lens.stl für den Buchstaben R
Der LED Streifen wird, je nach für den einzelnen Buchstaben benötigter Länge, entlang des Lötpads in Stücke geschnitten. An die Lötpads des ersten Streifens werden drei Dupontkabel mit Stecker angelötet, die später an den Arduino angeschlossen werden. An die andere Seite, die später zum nächsten Buchstaben führt kommt ein normales Kabel, dass dann wieder an den LED-Streifen angelötet wird.
Schritt 3
Der LED-Streifen wird nun mit etwas Heißkleber seitlich im Buchstaben fixiert, die LED nach innen gerichtet und die Kabel durch die vorhandenen Löcher geführt. Beim nächsten Buchstaben wird das oben beschriebene Wiederholt, bis alle Buchstaben mit LED-Streifen bestückt sind.
Schritt 4
Nun werden die Abdeckkappen auf in die Buchstaben gesteckt.
Schritt 5
Die an den ersten Buchstaben angelöteten Dupontkabel werden nun mit dem Arduino verbunden.
“5V“ vom LED-Streifen kommt an den 5 Volt Anschluss des Arduino.
“G“ wird an GND angeschlossen und “D“ stecken wir an Pin 6 des Arduino.
Der Arduino wird an den USB-Anschluss des Computers angeschlossen und wir starten die Programmierumgebung “Arduino IDE“
Für unser Beispiel benötigen wir zunächst die Bibliothek “Adafruit Neopixel“, die wir über “Werkzeuge“ > “Bibliotheken verwalten...“ hinzufügen.
Anschließend fügen wir folgenden Code in den Sketch ein und editieren noch den Wert hinter “#define LED_COUNT“. Dort wird die Anzahl der in der Leuchtschrift verbauten LED eingetragen. Anschließend laden wir den Code auf den Arduino
Codes anzeigen / einklappen
1. Hauptcode: RFID-Zeiterfassung
#include "MFRC522.h"
#include "SPI.h"
#include "SdFat.h"
#include "RTClib.h"
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
// Name des RTC-Moduls
RTC_DS3231 rtc;
// Adressierung des OLED-Displays
#define I2C_ADDRESS 0x3C
// Buttons definieren
#define greenButton 2
#define redButton 3
// RFID Anschlüsse definieren
#define SDA 7
#define RST 9
// Name des OLED-Displays
SSD1306AsciiWire oled;
// Bezeichnung der SD-Karte
SdFat SD;
// Bezeichnung der CSV-Datei
File Zeiterfassung;
// RFID-Empfänger benennen und Pins zuordnen
MFRC522 mfrc522(SDA, RST);
// Pin der SD-Karte
int DatenPin = 10;
// Pin des Buzzer
int buzzer = 4;
// Wert zum Auslesen der Aktivität
int ButtonValue = 0;
// Variable zum Verfolgen der RFID-Aktivität
bool rfidGelesen = false;
// Trennzeichen für die CSV-Datei
const String TrennZeichen = ",";
String Mitarbeiter;
void setup() {
Serial.begin(9600);
SPI.begin();
// OLED mit 128x64 Pixeln starten
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
// Schriftart festlegen
oled.setFont(Arial14);
oled.println(F(" kommen gehen"));
oled.println(F(" "));
oled.println(F(" Zur Zeiterfassung"));
oled.println(F(" Taste druecken!"));
// Initialisierung des RFID-Empfängers
mfrc522.PCD_Init();
// Buttons als Input deklarieren
pinMode(greenButton, INPUT_PULLUP);
pinMode(redButton, INPUT_PULLUP);
// Buzzer als Output deklarieren
pinMode(buzzer, OUTPUT);
// RTC-Modul starten
if (!rtc.begin()) {
Serial.println(F("RTC Initialisierung fehlgeschlagen!"));
while (1);
} else if (rtc.lostPower()) {
// Setze die Uhrzeit nur, wenn die RTC ihre Zeit verloren hat
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println(F("RTC Uhrzeit auf Kompilierzeit eingestellt!"));
} else {
Serial.println(F("RTC bereit und Uhrzeit korrekt!"));
}
// SD-Karte starten
if (!SD.begin(DatenPin)) {
Serial.println(F("Initialisierung der SD-Karte fehlgeschlagen!"));
} else {
Serial.println(F("SD-Karte gestartet!"));
}
// rtc.now() -> aktuelle Zeit holen
DateTime aktuell = rtc.now();
// Format des Datums festlegen
char Datum[] = "DD.MM.YYYY";
// Datum in String umwandeln und anzeigen
Serial.print(aktuell.toString(Datum));
// Format der Zeitangabe festlegen
char Zeit[] = "hh:mm:ss";
// Zeitangabe in String umwandeln und anzeigen
Serial.print(aktuell.toString(Zeit));
}
void loop() {
// Wenn grüner Button gedrückt wird
if (digitalRead(greenButton) == LOW) {
oled.clear();
oled.println(F(" kommen"));
oled.println(F(" "));
oled.println(F(" Karte an das"));
oled.println(F(" Lesegeraet halten!"));
ButtonValue = 1; // Setze ButtonValue auf 1
digitalWrite(buzzer, HIGH); // Ton an
delay(100);
digitalWrite(buzzer, LOW); // Ton aus
delay(1000);
rfidGelesen = true; // Erlaube das Lesen des RFID-Chips
}
// Wenn roter Button gedrückt wird
if (digitalRead(redButton) == LOW) {
oled.clear();
oled.println(F(" gehen"));
oled.println(F(" "));
oled.println(F(" Karte an das"));
oled.println(F(" Lesegeraet halten!"));
ButtonValue = 2; // Setze ButtonValue auf 2
digitalWrite(buzzer, HIGH); // Ton an
delay(100);
digitalWrite(buzzer, LOW); // Ton aus
delay(1000);
rfidGelesen = true; // Erlaube das Lesen des RFID-Chips
}
// Wenn RFID-Chip noch nicht gelesen wurde und einer der Buttons gedrückt wurde
if (rfidGelesen == false) {
return; // Warte auf Button-Druck
}
// vom RFID ermittelter Wert der Karte als Folge von Dezimalzahlen
String WertDEZ;
// String Mitarbeiter löschen, damit falsche Karte erkannt wird
Mitarbeiter = "";
// Wenn keine Karte in Reichweite ist
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Wenn kein RFID-Sender ausgewählt wurde
if (!mfrc522.PICC_ReadCardSerial()) {
return;
}
Serial.println(F("Karte entdeckt!"));
digitalWrite(buzzer, HIGH); // Ton an
delay(100);
digitalWrite(buzzer, LOW); // Ton aus
delay(1000);
// Dezimal-Werte in String WertDEZ schreiben
for (byte i = 0; i < mfrc522.uid.size; i++) {
WertDEZ = WertDEZ + String(mfrc522.uid.uidByte[i], DEC) + " ";
}
// dezimalen Wert anzeigen
Serial.println("Wert in dezimal: " + WertDEZ);
// Leerzeichen am Ende entfernen
WertDEZ.trim();
/*
Karten abfragen und Namen der Mitarbeiter*innen zuordnen
*/
if (WertDEZ == "227 211 219 29") Mitarbeiter = " Max Mustermann";
if (WertDEZ == "147 50 48 28") Mitarbeiter = " Maxi Musterfrau";
// Namen abfragen
if (Mitarbeiter == " Max Mustermann" || Mitarbeiter == " Maxi Musterfrau") {
// Daten in die Datei schreiben
DatenSchreiben();
}
// bei falscher Karte
else {
Serial.println(F("Falsche Karte!"));
oled.clear();
oled.print(F(" Falsche Karte!"));
delay(2000);
oled.clear();
oled.println(F(" kommen gehen"));
oled.println(F(" "));
oled.println(F(" Zur Zeiterfassung"));
oled.println(F(" Taste druecken!"));
ButtonValue = 0;
rfidGelesen = false;
}
// Pause, damit die Daten nicht mehrfach geschrieben werden
delay(2000);
}
void DatenSchreiben() {
// Meldungen im Seriellen Monitor
Serial.println(F("Schreibe Daten in Zeiterfassung.csv ... "));
// Name der Mitarbeiter*in
Serial.println("Mitarbeiter*in: " + Mitarbeiter);
Serial.println(F("-----------------------------"));
// rtc.now() -> aktuelle Zeit holen
DateTime aktuell = rtc.now();
char Datum[] = "DD.MM.YYYY ";
// Datum in String umwandeln und anzeigen
Serial.print(aktuell.toString(Datum));
// Format der Zeitangabe festlegen
char Zeit[] = "hh:mm:ss";
// Zeitangabe in String umwandeln und anzeigen
Serial.println(aktuell.toString(Zeit));
// Ausgabe OLED
oled.clear();
oled.println(Mitarbeiter);
oled.println(aktuell.toString(Datum));
oled.println(aktuell.toString(Zeit));
delay(2000);
oled.clear();
oled.print(F(" Gespeichert!"));
delay(2000);
// Reset für den nächsten Durchlauf
rfidGelesen = false;
/*
FILE_WRITE - Datei zum Schreiben öffnen
*/
Zeiterfassung = SD.open("Zeiterfassung.csv", FILE_WRITE);
if (Zeiterfassung) {
// Überschrift nach jedem Datensatz wiederholen
Zeiterfassung.print(F("Mitarbeiter*in:"));
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(F("Datum:"));
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(F("Zeit"));
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(F("Aktion"));
Zeiterfassung.println();
// Daten in die Datei schreiben
Zeiterfassung.print(Mitarbeiter);
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(Datum);
Zeiterfassung.print(TrennZeichen);
Zeiterfassung.print(Zeit);
Zeiterfassung.print(TrennZeichen);
if (ButtonValue == 1) {
Zeiterfassung.print(F("kommen"));
} else if (ButtonValue == 2) {
Zeiterfassung.print(F("gehen"));
}
Zeiterfassung.println();
Zeiterfassung.println();
}
// Datei schließen
Zeiterfassung.close();
Serial.println(F("Speichern abgeschlossen."));
Serial.println();
delay(200);
// Reset für den nächsten Durchlauf
ButtonValue = 0;
oled.clear();
oled.println(F(" kommen gehen"));
oled.println(F(" "));
oled.println(F(" Zur Zeiterfassung"));
oled.println(F(" Taste druecken!"));
}
2. RTC-Modul separat einrichten & testen
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
Serial.begin(9600);
Wire.begin();
if (!rtc.begin()) {
Serial.println("RTC konnte nicht gefunden werden!");
while (1);
}
// RTC auf das Kompilierdatum und -zeit einstellen
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println("RTC erfolgreich auf das Kompilierdatum und -zeit eingestellt!");
}
void loop() {
// Hier können weitere Anweisungen eingefügt werden
}
3. NeoPixel LED-Steuerung (Regenbogeneffekte)
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define LED_PIN 6 // Der Pin an den "D" vom LED Streifen angeschlossen ist
#define LED_COUNT 80 // Anzahl der in der Leuchtschrift verbauten LED
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
strip.begin();
strip.show();
strip.setBrightness(80); // Helligkeit 0 - 100
}
void loop() {
rainbow(10);
theaterChaseRainbow(50);
}
void colorWipe(uint32_t color, int wait) {
for(int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, color);
strip.show();
delay(wait);
}
}
void theaterChase(uint32_t color, int wait) {
for(int a=0; a<10; a++) {
for(int b=0; b<3; b++) {
strip.clear();
for(int c=b; c < strip.numPixels(); c += 3) {
strip.setPixelColor(c, color);
}
strip.show();
delay(wait);
}
}
}
void rainbow(int wait) {
for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
for(int i=0; i < strip.numPixels(); i++) {
int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
}
strip.show();
delay(wait);
}
}
void theaterChaseRainbow(int wait) {
int firstPixelHue = 0;
for(int a=0; a<30; a++) {
for(int b=0; b<3; b++) {
strip.clear();
for(int c=b; c < strip.numPixels(); c += 3) {
int hue = firstPixelHue + c * 65536L / strip.numPixels();
uint32_t color = strip.gamma32(strip.ColorHSV(hue));
strip.setPixelColor(c, color);
}
strip.show();
delay(wait);
firstPixelHue += 65536 / 90;
}
}
}