In de vorige post zagen we de hardwarekant van mijn model van de Lichtzeitpegel. In deze post gaan we de softwarekant verkennen, om er vervolgens achter te komen dat we nog lang niet klaar zijn met de hardware…

NeoPixel

Vorige keer hadden we de strandtest al gedaan om te bevestigen dat de schakeling werkt. Nu gaan we een simpel looplicht maken om de NeoPixel library te leren kennen.

Onderstaande code is alles om mee te beginnen:

#include <Adafruit_NeoPixel.h>

#define LED_PIN    6            // Which pin on the Arduino is connected to the strip?
#define LED_COUNT  60           // How many LEDs are on the strip?
#define HUE_STEP   65536 / 90   // Full rainbow cycle in 90 frames

// Declare the strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
int hue = 0;

void setup() {
  strip.begin();                // Initialize library
  strip.show();                 // Initialize LEDs
  strip.setBrightness(50);      // Set default brightness at about 1/5
}

void loop() {
  for (int i = 0; i < LED_COUNT; i++) {
    strip.clear();              // Clear LED color in controller RAM
    for (int j = 0; j <= 9; j++) {
      strip.setPixelColor(
        (i - j + LED_COUNT) % LED_COUNT, // Makes for a fluid run-off at the end
        strip.ColorHSV(hue, 255, 255 - j * (255 / 9))
      );
    }
    strip.show();               // Update LEDs according to controller RAM
    delay(10);
    hue += HUE_STEP;
  }
}

En dat levert dan iets dergelijks op als dit:


Regenboog looplicht

Logische klok

LED index – 0-based Kleur Omschrijving
56 – 59 Geel Geen functie
54 – 55 Wit Tien uren
53 Geel Scheidingslamp
44 – 52 Wit Uren
43 Geel Scheidingslamp
42 Rood Luchtbaken
37 – 41 Wit Tien minuten
36 Geel Scheidingslamp
27 – 35 Wit Minuten
26 Rood Luchtbaken
25 Geel Scheidingslamp
20 – 24 Wit Tien seconden
19 Geel Scheidingslamp
10 – 18 Wit Seconden
0 – 9 Geel Geen functie

Werkende Lichtzeitpegel van 19:59:55 tot 20:00:02

Er zijn online niet heel veel details te vinden van de werking van de klok. Op de Duitstalige Wikipedia-pagina van de Lichtzeitpegel staat wel een tabel met de verdeling van de lampen. Het origineel heeft er 62, maar omdat ik maar 60 LEDs in de strip heb, heb ik de eerste en laatste lamp zonder functie laten vervallen. Ik hoop dat iemand me kan vergeven.

De gele lampen zijn niet geheel zonder functie. Aan het eind van elke minuut gaan alle scheidingslampen een seconde lang aan. Aan het eind van elk uur gaan alle scheidingslampen bovendien een hele minuut lang aan. Het effect bij de volle minuut is ook te zien in een video op YouTube. De precieze werking van het hele uur is daar echter niet zichtbaar. Ik gok dat ik daarvoor echt zelf naar Düsseldorf zal moeten.

Code

Opvallend genoeg is het algoritme eenvoudiger te lezen dan de tijd aflezen van een klok op een zendmast.

void updateTime(const ZonedDateTime& dt)
{
  for (int i = 0; i < NUMPIXELS; i++) theLEDs[i] = 0; // Reset
  for (int i = 0; i < dt.second() % 10; i++) theLEDs[10 + i] = 1; // Single seconds
  for (int i = 0; i < dt.second() / 10; i++) theLEDs[20 + i] = 1; // Ten seconds
  for (int i = 0; i < dt.minute() % 10; i++) theLEDs[27 + i] = 1; // Single minutes
  for (int i = 0; i < dt.minute() / 10; i++) theLEDs[37 + i] = 1; // Ten minutes
  for (int i = 0; i < dt.hour() % 10; i++) theLEDs[44 + i] = 1; // Single hours
  for (int i = 0; i < dt.hour() / 10; i++) theLEDs[54 + i] = 1; // Ten hours
  /* Whole Minute and Whole Hour effect */
  if (dt.second() == 59 || dt.minute() == 59) {
    for (int i = 0; i < 10; i++) theLEDs[i] = 2;
    theLEDs[19] = 2;
    theLEDs[25] = 2;
    theLEDs[36] = 2;
    theLEDs[43] = 2;
    theLEDs[53] = 2;
    for (int i = 56; i < 60; i++) theLEDs[i] = 2;
  }
}

Nu de tijd getoond kan worden op de strip, hebben we natuurlijk de tijd zelf nog nodig.

Een Arduino komt niet met een eigen klok en een losse RTC (Real Time Clock) module heb ik (nog) niet. Voorlopig zet ik de tijd handmatig tijdens compilatie en kan de tijd bijgesteld worden via de seriële interface. En dat moet regelmatig gebeuren, want de millis()functie die Arduino biedt om het aantal milliseconden sinds het starten te bepalen is niet erg precies. Na een nacht heb je al een afwijking van zo’n 7 seconden te pakken.

Daarnaast is onmogelijk om de helderheid van de LEDs te bepalen voor zowel een zonnige dag als een donkere nacht. Er moet dus een dimmer in komen die afhangt van het omgevingslicht.

Twee onderwerpen voor een volgende post; wordt vervolgd!