Arduino Valentinstag: Romantisches Wandlicht

Irgendwie sollte doch jeden Tag Valentinstag sein, oder? Arduino Valentinstag: Den Menschen, die ihr Leben mit uns teilen gebührt besondere Aufmerksamkeit. Wie wäre es da mit einem romantischen Wandlicht?

Bei diesem Arduino-Projekt handelt es ich um ein Herz mit eingefrästen oder gedruckten Namen. Darunter befindet sich ein WS2812-LED-Leuchtstreifen, der nach außen leuchtet und dem Herz zu einen Glow-Effekt verhilft. Wie groß das Herz wird, oder wie viele LEDs du verwenden willst, kannst du natürlich selbst entscheiden. Achte aber darauf, dass die Elektronik darunter genügend Platz hat. Das Herz ist mit einem Button ausgestattet, mit dem sich unterschiedliche Animationen durchschalten lassen. Betrieben wird das alles per Netzteil.

Bauteile

  • 1x Arduino Uno*
  • 1x WS2812 LED Leuchtstreifen*
  • 1x USB-Netzteil und weißes USB Kabel
  • 1x Elektrolyt-Kondensator 500 – 1000 uF, > 10V
  • 1x Widerstand 470 Ohm (es geht auch ein Widerstandswert in der Nähe)

Schaltplan

Arduino Valentinstag Romantisches Herz

Die Schaltung besteht aus zwei Stromkreisen. Der eine Stromkreis verbindet die WS2812-LEDs mit dem GND und dem 5V+ des Arduino-Boards. Diese beiden Anschlüsse sind zusätzlich über einen Elektrolytkondensator verbunden. Richtiger Weise müsste man »nicht verbunden« sagen, da der Kondensator ja keine elektrische Verbindung herstellt. Er speichert Energie, die abgegeben wird, wenn die LEDs z.B. bei Farbwechseln besonders viel Energie benötigen (Stützkondensator). Der Daten-In-Anschluss des LED-Streifens ist über einen Widerstand (ca. 470 Ohm) mit dem digitalen Pin 6 des Arduino-Boards verbunden. Der zweite Stromkreis besteht aus einem Taster, der mit dem GND und dem digitalen Pin 2 des Arduinos verbunden ist.

Mehr Infos zu den WS2812-LEDs hab ich hier für dich: WS2812 – Der einfachste Weg, viele LEDs mit Arduino steuern.

Arduino Valentinstag: Bauanleitung

Ich habe mich für ein klassisches Herz mit eingravierten Namen entschieden, aber du kannst auch Fotos auf das Herz kleben. Es gibt unendliche Möglichkeiten, also lass deiner Fantasie freien Lauf. Ob du es aus Holz, Pappe, Papier oder anderen Materialien herstellst, ist ebenfalls komplett dir überlassen.

Arduino Valentinstag Romantisches Herz Schablonen

Wichtig ist, dass Platz für die Elektronik bleibt. Da die LEDs indirekt auf die hinterliegende Wand scheinen sollen, verstecke ich sie hinter dem Herz.

Arduino Valentinstag Romantisches Herz Bauanleitung

Den Button habe ich so platziert, dass er zwischen Herz und Wand sitzt und gedrückt wird, wenn man das Herz drückt.

Code

Das Arduino-Programm ist ein Beispiel-Code der Adafruit-Nanopixel-Bibliothek. Die muss übrigens in der Arduino-Software installiert werden. Öffne dafür in der Arduino IDE (Software) das Menü Sketch>Bibliotheken einbinden>Bibliotheken verwalten … und suche im Suchfeld nach NeoPixel. Installiere die Adafruit NeoPixel-Library von Adafruit in der aktuellen Version. Öffne nun das Beispiel unter Datei>Beispiele>Adafruit NeoPixel>ButtonCycler. Ändere die Pixelanzahl in der Zeile:

define PIXEL_COUNT 25  // Number of NeoPixels

Übertrage das Programm auf das Arduino-Board. Das war es auch schon :-)

Der Code spielt unterschiedliche Animationen ab. Am Anfang ist alles aus. Wird der Button gedrückt, ändert sich der Zähler der Variablen mode. Der Wert dieser Variablen entscheidet über die aktuelle Animation durch die Switch-Case-Abfrage.

Hier nochmal der gesamte Code der Vollständigkeit halber:

// A basic everyday NeoPixel strip test program.

// NEOPIXEL BEST PRACTICES for most reliable operation:
// - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections.
// - MINIMIZE WIRING LENGTH between microcontroller board and first pixel.
// - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR.
// - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS
//   connect GROUND (-) first, then +, then data.
// - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip,
//   a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED.
// (Skipping these may work OK on your workbench but can fail in the field)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    6

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 60

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


// setup() function -- runs once at startup --------------------------------

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop() {
  // Fill along the length of the strip in various colors...
  colorWipe(strip.Color(255,   0,   0), 50); // Red
  colorWipe(strip.Color(  0, 255,   0), 50); // Green
  colorWipe(strip.Color(  0,   0, 255), 50); // Blue

  // Do a theater marquee effect in various colors...
  theaterChase(strip.Color(127, 127, 127), 50); // White, half brightness
  theaterChase(strip.Color(127,   0,   0), 50); // Red, half brightness
  theaterChase(strip.Color(  0,   0, 127), 50); // Blue, half brightness

  rainbow(10);             // Flowing rainbow cycle along the whole strip
  theaterChaseRainbow(50); // Rainbow-enhanced theaterChase variant
}


// Some functions of our own for creating animated effects -----------------

// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}

// Theater-marquee-style chasing lights. Pass in a color (32-bit value,
// a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms)
// between frames.
void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this outer loop:
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

// Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames.
void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

Und hier noch eine einfache Version: Regenbogen oder Aus :-)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

#define BUTTON_PIN   2
#define PIXEL_PIN    6  // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 25  // Number of NeoPixels

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

boolean buttonState = HIGH;
boolean lastState = HIGH;
boolean myState = false;

void setup() {
  Serial.begin(115200);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin(); // Initialize NeoPixel strip object (REQUIRED)
  strip.show();  // Initialize all pixels to 'off'
}

void loop() {
  rainbow(100);
}

void colorWipe(uint32_t color, int wait) {
  for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}

void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 3 * 65536; firstPixelHue += 256) {

    buttonState = digitalRead(BUTTON_PIN);
    if ((buttonState == LOW) && (lastState == HIGH)) {
      myState = !myState;
      Serial.println(myState);
    }
    if (myState == true) {
      for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
        int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
        strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
      }

      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    } else {
       colorWipe(strip.Color(  0,   0,   0), 0);
    }
    lastState = buttonState;
  }
}
Anzeige: Böse Shirts für Menschen mit Humor

Findest Du die Möglichkeiten mit Arduino auch so faszinierend? Blickst Du auch gern hinter die Kulissen um zu verstehen, wie die Welt funktioniert? Dann empfehle ich Dir das Buch: Arduino: Kompendium: Elektronik, Programmierung und Projekte* – Damit wirst Du zum Arduino-Profi!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

 

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.