Light House Beacon Software
August 1, 2016
Back in late summer 2013 I started construction on a copper light house (article in progress). A light house isn’t a light house unless it has a light, right? I started with a solar path light thinking that would be a good starting point – and it would have been if I was making a light house lamp.
Turns out there are a few people doing this kind of thing but I couldn’t, at the time, find a free or open option. The one I did find was a product for model train layouts and was quite expensive.
What was I going to do to make a proper light house beacon? Pull out the Arduino and write some code, of course!
I started with the idea I needed to light an LED and make the brightness change over time. Lighting an LED via Arduino is pretty easy: connect it between an Output pin and ground then set the pin high or low. To vary the brightness, the output pin needs to be capable of pulse width modulation (PWM). PWM allows us the ability to determine how long the pin is set high over a given duration (the duty cycle). For example, if power is output over only half of the period, the LED Is half as bright as If power was output over the whole duration.
Check out this site to learn more about how PWM works on the Arduino. It has many other uses besides dimming an LED.
Here is my early version Arduino sketch:
//Arduino Model Lighthouse Beacon V2
//Copyright 2013 - Present
//eccentricworkshop.com
int led = 9; // the pin that the LED is attached to. It needs to be a PWM pin to fade properly
int brightness = 5; // set the initial LED brightness to the minimum illumination
int fadeAmount = 1; // how to step the LED fade
void setup() { // the setup routine runs once when you press reset
pinMode(led, OUTPUT); // declare the LED pin to be an output
}
void loop() { // the loop routine runs over and over again forever
analogWrite(led, brightness); // set the brightness of pin 9
brightness = brightness + fadeAmount; // add the fade step amount to the current brightness value to increase
// stop fading at 50% and pulse to full brightness
if (brightness == 100) { // about half way to maximum brightness
analogWrite(led, 255); // pulse the LED to maximum brightness
}
// reverse the direction of the fading at the ends of the fade:
if (brightness == 5 || brightness == 100) { // 5 is the minimum brightness we want so the LED is still illuminated
delay(150); // pause for 1.5 seconds at the end of the cycle then reverse it
fadeAmount = -fadeAmount; // subtract the face step amount from the current brightness value to fade to darkness
}
delay(30); // wait for 30 milliseconds to see the dimming effect
}
This video shows the PWM signal on the oscilloscope and the corresponding LED.
https://youtube.com/watch?v=cQQYkAnYjDc
Hopefully this demonstrates what PWM does and what the signal looks like. One interesting thing shown on the scope is as the duty cycle increases, the voltage drops. This is because the LED has a greater draw as the brightness increases.
Once the proof of concept was working, I needed to figure out how to downsize and cheapen it up a bit. This led me to the PICAXE platform. I found it is relatively cheap and easy to work with. The chips (08M2s) are about $3 each and don’t require (too much) special hardware to program. PICAXE also uses a BASIC like language or can even be programmed using a flowchart method. Score tow points for PICAXE.
Here is my PICAXE code:
'PICAXE Model Lighthouse Beacon V4.1
'Copyright 2013 - Present
'eccentricworkshop.com
symbol CdS = C.1 'define CdS pin as C.1
symbol LED = C.2 'define LED pin as C.2
symbol SW1 = pin3 'define SW1 pin as C.3
symbol voltage = w1 'variable to hold the CdS voltage value
symbol brightness = w0 'variable to hold the brightness value
symbol fadeAmount = w3 'variable to hold the fade step size
symbol stepDelay = w5 'variable to hold the delay value between steps
brightness = 1 'initiate LED brightness
fadeAmount = 1 'initiate step size for fading
stepDelay = 10 'initiate delay time for each step
disabletime 'disable internal time counter
pause 2000 'pause on startup to load
start:
'this is the loop for the test mode with the light on
do while SW1 = 1
pwmout LED, off 'turn off PWM so LED can go high
high LED 'make LED pin high to turn it on
disablebod 'turn off brown-out detection to enter a lower power mode
sleep 10 'go into low power state (*2.3s = 23s)
enablebod 'turn on brown-out detection
loop
low LED 'housekeeping line, make sure the light doesn't stay on once we exit the above loop
readadc CdS, voltage 'read voltage across CdS
if voltage > 130 then 'check room darkness, above about 100 is too bright
disablebod 'turn off brown-out detection to enter a lower power mode
sleep 52 'go into low power state for (*2.3s = 1.99m)
enablebod 'turn on brown-out detection
goto start: 'start over to re-check
endif
'set initial brightness, pwmout PIN, period (0-255), duty cycle (0-1023)
pwmout LED,199,brightness
'change brightness by the fade step size on each step through
brightness = brightness + fadeAmount
'stop fading and pulse to full brightness
if brightness >= 300 then
pwmout LED,199,800 'pulse the LED
brightness = 300 'set to 300 to exit the loop
pause 150 `quick pause at the bright flash
endif
'step up the fade direction when at the low end
if brightness = 5 then
fadeAmount = 1
pause 1000 `pause in the dark/dim state for effect
endif
'step down the fade direction when at the high end
if brightness = 300 then
fadeAmount = -1
endif
pause stepDelay 'pause for the delay set at the top. this gives the proper fade effect
goto start: 'do it again, forever
Switching to the PICAXE let me incorporate a few more features also – also possible on the Arduino, I just didn’t do it. I added in a CdS cell to detect the ambient light. This disables the light house if it is too bright. There is also a switch to put it into a ‘debug’ mode which lights up the light. The brown out detection and sleep code puts the PICAXE into a lower power state so it can remain switched on and not drain the battery as fast. I haven’t measured so I have no idea how much this actually extends the battery life.
PWM on the PICAXE is a little more controllable as you must define the period and the duty cycle whereas the Arduino only needs the duty cycle defined. The period is how much time for the on/off sequence and the duty cycle is how much of that time is on. Check out this site to learn more about PWM on the PICAXE. In my code above, the period is 199 and the duty cycle varies between 5 and 300 with a pulse to 800. The period must be between 0 and 255 and the duty cycle must be between 0 and 1023.
Voltage across the CdS is read into a variable and analyzed – any value above about 100 is too bright for the light house to be visible so it automatically shuts the light off, goes into a low power state, and checks again in about 2 minutes.
You can see in the code we can vary the stepDelay or fadeAmount to produce many different lighting patterns. Increasing or decreasing the stepDelay will lengthen or shorten the flash sequence. Changing the fadeAmount within the if statements will also change the sequence speed but can also affect how the light looks if the steps are too large.
The CdS and LED are on remote wires to be run to the outside of the light house, the circuit is built on a 1 inch square of perf board, and the power switch and battery are able to be mounted near by. This is the large version for my 18 inch tall light house. The smaller versions, for the 4 inch tall and 10 inch light houses, are the same circuit with different battery packs. The mid size is running on 3 AAA batteries and the smallest is running off a single higher voltage battery.