Crescent and star lantern on an Arduino Uno
Ten LEDs of a WS2812B ring glow as a warm crescent moon beside a twinkling LED star, and a light sensor lights the lantern at dusk, for Eid in any year. The whole build, an Arduino Uno and 5 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Beginner Runs in your browser. Free, and no account needed.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Crescent and star lantern: a crescent moon of warm LEDs and a twinkling
// star, for a window or a table at Eid, lit by itself at dusk.
//
// light sensor module AO -> A0, VCC -> 5 V, GND -> GND
// crescent 16 WS2812B LEDs in a ring, DIN <- 330 ohms <- pin 6
// star pin 5 -> 220 ohms -> white LED -> GND
//
// Eid al-Fitr comes at the end of Ramadan, and Eid al-Adha about ten weeks
// later. Both follow the Islamic lunar calendar, which is about eleven days
// shorter than the solar year, so they move earlier each year and the start
// of each month waits on the new crescent moon. That is why the crescent and
// star are on so many Eid lanterns and cards, and why this sketch makes no
// claim about dates: it is a lantern for every year.
//
// The crescent is part of a ring: ten LEDs lit in a curve, brightest in the
// middle and fading toward the horns, with the other six dark. The star is
// one LED on a PWM pin that twinkles, a quick bright flash now and then over
// a soft glow.
//
// The light module's reading rises as the room gets darker, so the lantern
// lights when it goes above DARK_ABOVE and goes out in daylight.
//
// Things to try. Drag the light sensor's slider down. Make the moon fuller by
// lighting more of the ring with ARC.
#include <Adafruit_NeoPixel.h>
const int STAR_PIN = 5;
const int LEDS = 16;
const int ARC = 10; // LEDs in the crescent
const int DARK_ABOVE = 700; // A0 reading: on above this
const int LIGHT_BELOW = 600; // and off below this
Adafruit_NeoPixel moon(LEDS, 6, NEO_GRB + NEO_KHZ800);
bool lit = false;
int star = 0;
void drawMoon(int glow) {
moon.clear();
for (int i = 0; i < ARC; i++) {
// Brightest in the middle of the arc, dimmer toward the horns.
int fromMiddle = abs(2 * i - (ARC - 1));
int v = glow - fromMiddle * glow / (2 * ARC);
moon.setPixelColor(i, v, v * 3 / 4, v / 4);
}
moon.show();
}
void setup() {
Serial.begin(9600);
pinMode(STAR_PIN, OUTPUT);
moon.begin();
moon.setBrightness(170);
moon.show();
Serial.println("Eid Mubarak! The lantern lights at dusk");
}
void loop() {
int light = analogRead(A0);
if (!lit && light > DARK_ABOVE) {
lit = true;
// Fade the crescent in.
for (int g = 0; g <= 255; g += 5) {
drawMoon(g);
delay(20);
}
Serial.println("Dusk: the crescent and star are lit");
} else if (lit && light < LIGHT_BELOW) {
lit = false;
moon.clear();
moon.show();
analogWrite(STAR_PIN, 0);
Serial.println("Daylight: lantern off");
}
if (!lit) return;
// The star: a soft glow with a bright twinkle now and then.
if (random(0, 60) == 0) star = 255;
analogWrite(STAR_PIN, star < 60 ? 60 : star);
if (star > 60) star -= 12;
delay(20);
}
Parts list
7 parts, plus the jumper wires. Every one is in the editor's parts bin.
How it is wired
7 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Arduino Uno R3 pin 6; Resistor, 330 Ω pin 1
- Arduino Uno R3 pin 5; Resistor, 220 Ω pin 1
- Arduino Uno R3 pin 5V; Photoresistor sensor module pin VCC; Addressable RGB LEDs pin VDD
- Ground: Arduino Uno R3 pin GND; Photoresistor sensor module pin GND; Addressable RGB LEDs pin VSS; LED, white pin C
- Arduino Uno R3 pin A0; Photoresistor sensor module pin AO
- Resistor, 330 Ω pin 2; Addressable RGB LEDs pin DIN
- Resistor, 220 Ω pin 2; LED, white pin A
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.