Panteltje's col_pic page
Panteltje's col_pic page
Here you find the source code for a Linux PC side program to select a color, and send the selected color via a serial port,
and the asm listing for a PIC 16F648A program to drive a red, green, and blue LED so it displays the color selected on the PC.
col_pic is an X11 program, intended to work with the PIC based hardware running col.hex, to drive 3 LEDs, red, green, and blue, to create a controlled color lighting.
It sends color commands via a serial port.
col_pic-0.7.4 also has UDP support for use with the ethernet based color controller ecolor_pic.
Click here to download col_pic-0.7.4.tgz.
Click here for the lsm info file.
The asm and hex file for a PIC 16F648A, plus wiring instructions for the PIC are included in the col_pic tgz archive, but here is a later better version available separately:
Do not forget to ground pin 10 RB4/PGM to prevent low voltage programming mode.
For this version F should be set to 237 and C to 65 to get the clock speed approx right, fine tune with F.
For changes see the asm source.
Click here to download col-0.7.4.asm.
Click here to download col-0.7.4.hex.
Here is the diagram, simple, almost any NPN transistor will work in the output, the base resistors can be 4k7, you could use low voltage Vgs on MOSFETS too.
Here is the little thing build into a box.
The black thing on the left is a connector with the LDR mounted in it, the grey cable goes to the LED strips via a 5 pol 180 degees DIN connector, and the black cable is the +12V input for a battery or DC adaptor.
It is possible to use the col.hex with a simple terminal program, and / or to change color over time from a script for example.
Here is a simple terminal program (Linux) that by default will work with col.hex, and also can be called from a script:
Click here to download ptlrc-0.3.tgz.
NEW: xpequ now supports col_pic making music driven disco lights!
Here an example how to call ptlrc from a script, it sets red to 30, green to 20, blue to 10, and display the status of the registers in the PIC, then returns:
echo -e "R30\nG20\nB10\ns" | ptlrc -i
You can use crontab to change colors on certain times during the day:
Make a copy of the current crontab:
crontab -l > ~/crtab
Edit crtab like this:
49 15 * * * /bin/echo -en "R255\nG255\nB255\ns" | /usr/local/bin/ptlrc -i 1>/dev/zero 2>/dev/zero
50 15 * * * /bin/echo -en "R255\nG55\nB5\ns" | /usr/local/bin/ptlrc -i 1>/dev/zero 2>/dev/zero
51 15 * * * /bin/echo -en "R5\nG55\nB255\ns" | /usr/local/bin/ptlrc -i 1>/dev/zero 2>/dev/zero
This will set red, green, and blue to maximum at 15:49, to 255, 55, 5 at 15:50, and to 5, 55, 255 at 15:51.
Make the new entry active:
You can list crontab with:
crond must be running for this to work.
So now you can even simulate a rising sun in your bedroom to wake you up, have special sphere light in the evening too, all automagically.
Col.hex now has a 24 hour clock, and 5 programable timers.
There also is a fast mode, where the clock runs at very high speed, 24 hours in a few seconds, that can be used with the timers for flashing light effects.
Commands recognised by col.hex:
BnnnLF set blue PWM
CnnnENTER set clock calibration, range 0-255, saved in EEPROM
c prints clock speed.
D set clock prescaler1 and clock speed defaults, deselect fast mode.
FnnnENTER set clock prescaler, range 0-255, default 255, saved in EEPROM
f print clock prescaler.
GnnnLF set green PWM
HnnENTER set hour, range 0-23
L load values from EEPROM
MnnENTER set minute, range 0-59.
PnENTER program timer number n, n is range 0-4. will ask for hour, minute, red, green, blue, timers saved in EEPROM.
p display timers, sorted, timer_nr, hour, minute, red, green, blue
RnnnLF set red PWM
S save settings in EPROM
s sends back R, G, B in the form of 3 integers.
t prints time
X set fast mode.
x reset fast mode
ENTER stands for code 10 (LF) or code 13(CR).
Programming the PIC 16F648A:
You need a hex programmer, use the file col.hex
Assembling col.asm (if you are into that),
col.asm was assembled with gpasm-0.13.5 beta
Connecting the PIC 16F648A
The following values give approximately white for my LEDs with all 3 colors at 255, use trimpots in blue and red, green as reference:
Red LED pin 18 via a 220 Ohm resistor to +5V.
Green LED pin 17 via a 100 Ohm resistor to +5V.
Blue LED pin 16 via a 1000 Ohm resistor to +5V.
Ground to pin 5.
Ground to pin 10.
+5V to pin 14.
RX data (via for example a MAX232 chip) to pin 7.
TX data (via for example a MAX232 chip) to pin 8.
That is all.
This is what it looks like on the PC:
Gamma correction and driving RGB color LEDs with PWM from a color table.
When we have a PWM system driving red, green, and blue LEDs,
and use a color table to select the color, as I do for example here,
then that color table *normally* is used to set the DAC in the graphics card.
That DAC creates a voltage that is send to the CRT, and the CRT
has a function of brightness versus drive voltage of y = x ^2.2.
In LCD monitors this function is created in the firmware to be compatible to
So, it is safe to assume that in color tables, as in for example in Linux in
/usr/lib/X11/rgb.txt, the gamma is already corrected to the opposite curve:
y = x^(1/2.2), so that it looks correct on a CRT or LCD monitor.
So, to use these tables, we need to mimic a CRT curve, and correct the 0-255
values with y = x^(2.2).
That is why the gamma correction button, you can specify other values for gamma too.
Click here to view col_pic_the_movie on youtube