Arduino Nativity Set LED Light Controller – Led fading effects
Now it’s time for some code.. :)
With Arduino it’s easy writing a simple sketch for dimming LEDs via PWN.. also for guy with (very) limited programming skills like me.
The learning material is very helpful and rich of examples.
We need to manage 3 independent led channels and a create a kind of “program” for lights effects.
Requirements for this first version:
- the total duration of the program/sequence should be configurable
- led brightness should be dimmable and max brightness configurable
- each led channel should have an independent fade-in phase, a constant light phase and a fade-out phase with scheduled start and stop times
Timing
The sequence is divided in 1024 steps, each one lasting for a number of milliseconds calculated dividing the total duratation (in ms) by 1024.
Of course we need to have only ONE delay at the end of the main loop.
..
float delayvalue = 0;
int cycledelay = 0;
int programduration = 30; // light program duration in seconds
…
void setup() {
…
delayvalue = ((float(programduration) * 1000) / 1024); // main delay in ms calculated on program duration
cycledelay = int(delayvalue);
}
…
void loop() {
…
delay(cycledelay);
}
In this example the program will last about 30 seconds.
Now we need to have a Fading (In and Out) lasting for the duration of the entire phase.
analogWrite function have only 255 values and we may want to have a longer lasting FadeIn/Out phase.
So we need to calculated the Fading step related to the duration of the phase.
It’s also useful to be able to control the maximum brightness we want to reach for creating for example weak illumination effects.
…
int brightnessCH1 = 0; // how bright the LED is
int brightnessCapCH1 = 0; // the maximum value of brigther (0-255)
float fadeAddCH1 = 0.0; // how many points to fade the LED by. Leave 0 if should be autocalculated
float fadeSubCH1 = 0.0; // how many points to fade the LED by. Leave 0 if should be autocalculated
float brightfloatCH1 = 0.0; // brightness in float
…
// Parameters, edit these for creating your custom show
…
int fadePcCH1 = 20; // the maximum percent of Fade for CH1
int CH1FadeInStart = 1; // start time of FadeIn phase for CH1
int CH1FadeInStop = 256; // stop time of FadeIn phase for CH1
int CH1FadeOutStart = 257; //start time of FadeOut phase for CH1
int CH1FadeOutStop = 512; //stop time of FadeOut phase for CH1
…
void setup() {
…
pinMode(3, OUTPUT);
…
}
…
void loop() {
cycleValue = cycleValue + 1;
// CHANNEL1
// Lets calculate the fadeStep related to duration of FadeIn and the cap percent
if (fadeAddCH1 == 0) {
fadeAddCH1 = ((255 * (float(fadePcCH1) / 100)) / (float(CH1FadeInStop) – float(CH1FadeInStart)));
//Serial.print(“fadeAddCH1: “);
//Serial.println(fadeAddCH1);
}
…
// Lets calculate the fadeStep related to duration of FadeOut and the cap percent
if (fadeSubCH1 == 0) {
// fadeSubCH1 = ((float(CH1FadeOutStop) – float(CH1FadeOutStart)) / 255) * (float(fadePcCH1) / 100);
fadeSubCH1 = ((255 * (float(fadePcCH1) / 100)) / (float(CH1FadeOutStop) – float(CH1FadeOutStart)));
//Serial.print(“fadeSubCH1: “);
//Serial.println(fadeSubCH1);
}
…
// FadeIn phase
if (cycleValue >= CH1FadeInStart && cycleValue < CH1FadeInStop) {
brightfloatCH1 = brightfloatCH1 + fadeAddCH1;
brightnessCH1 = int(brightfloatCH1);
}
...
// control Max brightness
brightnessCapCH1 = int(fadeAddCH1 * 255);
constrain(brightnessCH1, 0, brightnessCapCH1);
//Serial.print("brightnessCH1: ");
//Serial.println(brightnessCH1);
...
// FadeOut phase. Some extra cycles are useful to be sure to bring to 0 variables
if (cycleValue >= CH1FadeOutStart && cycleValue < (CH1FadeOutStop + 20)) {
brightfloatCH1 = brightfloatCH1 - fadeSubCH1;
brightnessCH1 = int(brightfloatCH1);
}
// brightness must be positive
if (brightnessCH1 < 0) {
brightnessCH1 = 0;
brightfloatCH1 = 0.0;
}
...
analogWrite(3, brightnessCH1);
if (cycleValue == 1024 ) {
cycleValue = 0;
}
// The delay must be only one
delay(cycledelay);
}
In this example Leds conntected to Channel 1 (PWN Pin 3);
- will have a maximum brightness of the 20 percent
- the FadeIn phase will start at step 1 and will end at step 256 (reaching the max brightness of the 20%)
- the FadeOut phase will start at step 257 (no constant phase) and will end at step 512 (reaching a zero value)
The code can be optimized a lot with for cycles and arrays instead of variables.. but it works and it’s easier to read.
This is the download link for the full sketch.
Have fun and please leave a comment if something is unclear.. :)
Arduino Nativity Set LED Light Controller – Hardware
My job as IT consultant leave empty the (human) need of creating something “physical”, something made with your brain but also with your hands.. so a few months ago I started playing with Arduino and a bunch of electonics components.
The most amazing part of Physical Computing for a “software” grown-up kid like me (C64 generation..) is that you really create “things”, without simply configuring a “limited” device.
It’s really a new world!
A few days ago my 10 years old brother asked me to add some “cool” light effects to the nativity set that he is building year after year with “some” help of our father.. :)
The set is built mainly with wood and paperboard, so we have to keep low the risk of fire avoiding incandescent light bulbs.
Why not using LEDs? They are cheap, available in multiple colors and very brigth.
And why not using an Arduino for creating a sequence program with some dimming effect?
This nativity set needs al least 3 independent “channels” for lights: manger, village houses and street lamps.
Basic requirements for the 0.1alpha version of this project are:
- having a night/day cycle with a given duration
- controlling 3 independent channel with 10-15 high brightness LEDs each one
- managing dimming effects as fade-in and fade-out
Arduino can “simulate” the dimming of led with PWM via the AnalogWrite function.
Arduino Uno has 6 PWN Digital pins but each each one has a maximum output current of 40 mA.
Each LED needs 20 mA, so we need to “amplify” the output of PWN Pin current with a NPN transistor.
The best choice if using a ULN2003A Seven Darlington Arrays which is very useful for driving loads like some LEDs.
Each of the seven driver has a maximum output current of 500mA.. enough for more of 20 standard LEDs.
This is my first Fritzing design.. :)
After some test with a breadboard (not usable in the set) I made my first Arduino custom shield.
For this first “milestone” we need:
- An Arduino 2009 or UNO
- a pad board / stripboard with 0.1 inch spacing and a tool for cutting it (I used a Dremel with no. 409 Cut-Off Wheel)
- 1 DIP-16 ULN2003A
- a DIP-16 socket (not strictly needed)
- some screw terminal block connector with 0.1 inch spacing
- male-male headers with 0.1 spacing
- some copper wire and a soldering iron
Excluding the Arduino, less than 5 euros of components.
I was a bit disappointed when I discovered that spacing between digital pins blocks is not 0.1 inch compatible..
For the moment i needed only 3 PWM pins plus +5V and GND pins.. so i used only 1 block of 8 male header and one block of 2 male header..
This is the final result.
Warning: Soldering (and photography) skills below zero.. :)
In the next post I will describe the first sketch that will manage LEDs.
See you soon!
Setting up a Linux home server based on a low cost and low power hardware (Pc Engines Alix) – Sharing USB disk with Samba – Part4
Now we will install SAMBA, the well known suite of programs for file and printer sharing.
We will provide a basic configuration for home users, with a share for files downloaded for example with Bittorent and home dir for each user.
Let’s install needed packages:
homeserver:~# apt-get install samba samba-common smbclient smbfs
We will configure the service later, leave the default value at the first question and answer “No” to the second.
Our configuration will be very easy, first of all remove the default configuration generated by debconf:
homeserver:~# mv /etc/samba/smb.conf /etc/samba/smb.conf.orig
Now we will create the directory that we will use for sharing downloaded files and we will add write permission to all (remember that we mount the USB disk as /data)
homeserver:~# mkdir /data/download
homeserver:~# chmod a+w /data/download
Now let’s create a private directory for the first of our users:
homeserver:~# mkdir /data/users_shares/
Now we need to edit the configuration file for Samba /etc/samba/smb.conf.
The file was renamed a few steps above and so now it’s empty, insert the following content:
[global]
workgroup = HOME
netbios name = FILESERVER
server string = Home Fileserver %v
map to guest = Bad User
log file = /var/log/samba/log.%m
max log size = 50
socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
preferred master = No
local master = No
dns proxy = No
security = User
# Sharing for downloaded files
[download]
path = /data/download
valid users = family
read only = No
create mask = 0777
directory mask = 0777
#Home shares for users
[homes]
path = /data/users_shares/%S
comment = Home Directories
browseable = no
valid users = %S
create mask = 0700
directory mask = 0700
Now we need to restart the Samba service to apply the new configuration.
homeserver:~# /etc/init.d/samba restart
Pay attention that the valid user required for the “download” share is “family”, so we need to create it:
homeserver:~# useradd -c “Family User” family
homeserver:~# smbpasswd -a family
New SMB password:
Retype new SMB password:
startsmbfilepwent_internal: file /etc/samba/smbpasswd did not exist. File successfully created.
Added user family.
We can now create the first user (in our example “user1″) with his own samba password:
homeserver:~# mkdir /data/users_shares/
homeserver:~# adduser
The wizard will prompt you for password and basic informations.
For example we created “user1″ and the directory “/data/users_shares/user1″
Now we need to se SMB password for the user:
homeserver:~# smbpasswd -a
New SMB password:
Retype new SMB password:
Added user
You home server is now sharing the external USB disk!
From a Windows machine in your home network you can now map shares of your home server.
This is for example the command to view available shares via Windows command prompt (cmd.exe):
C:\Users\username> net view \\IP_Home_Server
And this is the command to map the network drive “download”:
C:\Users\username> net use * \\IP_Home_Server\download
In the next post we will install Bittorrent with a Web User Interface.
Setting up a Linux home server based on a low cost and low power hardware (Pc Engines Alix) – External USB disk mounted at boot – Part3
The Compact Flash we created is used only for the operating system and the binaries of the applications, we need some space for saving our data.
Most of PC Engines boards, like the Alix 2D2 we are using, have 2 USB 2.0 ports, perfect for managing an external USB disk!
If available a 2.5 inch external disk (for example an used notebook disk with an external case) is preferable because it’s lower power hungry and noisy respect a 3.5 disk.
This new post will describe how to format and mount an external USB disk at each boot to make available all the space we need for our data.
First of all, let’s power on our disk and plug it into a free USB port.
Now we need to identify the special device assigned to the new disk, partition and format: follow instructions in the first part of this howto.
Please remember that you want to work on the newly added USB disk, and not on the CF (hda1)
Fdisk will permanently delete all data contained in the disk, please pay attention.
Once the partition is created you can format it with ext3 filesystem with the following command:
homeserver:~# mkfs.ext3 /dev/sda1
We will use this new ext3 partition to store all downloaded and personal data.
We need a script to mount the disk at each boot of the operating system.
Let’s create a file mount_usb.sh in the directory /etc/init.d:
homeserver:~# touch /etc/init.d/mount_usb.sh
Edit it with "nano" and add the following content:
#! /bin/sh
mount -o defaults /dev/sda1 /data
We need to make this file executable and create the mount point
homeserver:~# chmod 755 /etc/init.d/mount_usb.sh
homeserver:~# mkdir /data
We can now try the script and see if the disk is correctly mounted with the command “df”:
homeserver:~# /etc/init.d/mount_usb.sh
homeserver:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hda1 3.7G 337M 3.2G 10% /
tmpfs 125M 0 125M 0% /lib/init/rw
udev 10M 24K 10M 1% /dev
tmpfs 125M 4.0K 125M 1% /dev/shm
tmpfs 125M 0 125M 0% /tmp
tmpfs 125M 0 125M 0% /var/tmp
tmpfs 125M 24K 125M 1% /var/run
tmpfs 125M 100K 125M 1% /var/log
tmpfs 125M 0 125M 0% /var/lock
/dev/sda1 29G 173M 27G 1% /data
Everything is working correctly, we can now configure the automatic execution of this scripts at each boot.
homeserver:~# update-rc.d -f mount_usb.sh start 89 2 3 4 5 .
Now the mount_usb script is executed at boot time at each runlevel (remember the dot at the end of the command!).
But we also need to unmount the external disk when the system is powered off
Create a file umount_usb.sh always in the directory /etc/init.d:
homeserver:~# touch /etc/init.d/umount_usb.sh
homeserver:~# chmod 755 /etc/init.d/umount_usb.sh
edit it with nano and add the following content:
#! /bin/sh
umount /dev/sda1
Now we need to configure the execution the the umount_usb.sh script when the system powers off.
homeserver:~# update-rc.d -f umount_usb.sh stop 89 0 1 6 .
Now we have a lot of free space for our needs!
Categories
- Arduino (2)
- AskoziaPBX (6)
- cisco (1)
- Debian Lenny (6)
- general (1)
- Home server (6)
- Linux (6)
- m0n0wall (1)
- switching (1)
- voice (1)
- Voyage Linux (6)


