HSL to RGB tutorial + Updated Rotary Encoder Library

April 22nd, 2009

Background:

I am in the design process of a new project that uses a lot of RGB LEDs. In the project I want to allow the user to select various colours and I was looking for a fairly intuitive way to do this.

If one has ever worked with RGB LEDs you know you have to PWM the values of each channel (R, G or B). Therefore for Red, I would PWM (255,0,0), for Green - (0,255,0), etc.

Now since each LED has 3 channels, you have to control three outputs. Therefore if I wanted to allow the user to be able to control the colour of an LED, I would have to have him control three sensors. That is a lot of inputs for one output (3 inputs per output). For an application like this I would normally consider three potentiometer’s to control the LED

But I wanted to be able to control the LED with one sensor. Doing some research I found that the HSL colour scheme was exactly what I need. I stumbled across this Rotary Encoder on Seeedstudio and it fit my price range. The reason I chose an encoder is you can use it to act like a pot but it allows continuous rotation.

My solution was to use an HSL Color Schemer. If I set the luminance and saturation to a suitable value, I can then use the rotary encoder to cycle through the Hue spectrum. Now while this does not give me every single RGB combination, it does give me 360 combinations across all the RGB colour channels.

Integration:

The major stumbling block I had was the Rotary Encoder. The reason it was so cheap was because it was a Mechanical Encoder. Therefore I has some serious debounce factor to consider - either through software or hardware. I found a little Rotary Encoder library written by SunBox on the Arduino Forums. However, the way it worked was you had to set a max and a min and once either extreme was reached, it no longer counted forward or backward.

I added a restart function to the library. Setting restart to a value of 1, tells the library to start counting from the min value.

restart(1);

I’ve attached the library below:
Rotary Encoder Library

Note: the library currently counts up by 20 on every edge. I used this cause I had a 20 detent encoder and that means a full rotation goes just over the whole hue range. I will add a function that allows you to choose how much to count by on each edge

Here is some sample code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "RotaryEncoder.h"
 
RotaryEncoder rotary(3, 2, 4);
int Rpin=10;
int Gpin=9;
int Bpin=11;
float H,S,L,Rval,Gval,Bval;
 
void HSL(float H, float S, float L, float& Rval, float& Gval, float& Bval);
float Hue_2_RGB( float v1, float v2, float vH );
 
void setup()
{
  Serial.begin(9600);
 
  //set up encoder with rotary library
  rotary.minimum(0);
  rotary.maximum(360);
  rotary.position(320);
  rotary.restart(1);
  pinMode(12, OUTPUT); 
}
 
 
void loop()
{
  H=rotary.position();
  S=1;
  L=.5;
  Rval=0;
  Gval=0;
  Bval=0;
  HSL(float(rotary.position())/360,S,L,Rval,Gval,Bval);
 
  //common anode configuration
  //analogWrite(Rpin, 255-Rval);
  //analogWrite(Gpin, 255-Gval);
  //analogWrite(Bpin, 255-Bval);
  //digitalWrite(12,HIGH);
 
  //common cathode configuration
  analogWrite(Rpin, Rval);
  analogWrite(Gpin, Gval);
  analogWrite(Bpin, Bval);
  digitalWrite(12,LOW);
 
  //print statements for debug
  Serial.print("position:");
  Serial.print(H);
  Serial.print(" R:");
  Serial.print(Rval);
  Serial.print(" G:");
  Serial.print(Gval);
  Serial.print(" B:");
  Serial.println(Bval);
  delay(1000);
}
 
void HSL(float H, float S, float L, float& Rval, float& Gval, float& Bval)
{
  float var_1;
  float var_2;
  float Hu=H+.33;
  float Hd=H-.33;
  if ( S == 0 )                       //HSL from 0 to 1
  {
     Rval = L * 255;                      //RGB results from 0 to 255
     Gval = L * 255;
     Bval = L * 255;
  }
  else
  {
     if ( L < 0.5 ) 
       var_2 = L * ( 1 + S );
     else           
       var_2 = ( L + S ) - ( S * L );
 
     var_1 = 2 * L - var_2;
 
     Rval = round(255 * Hue_2_RGB( var_1, var_2, Hu ));
     Serial.print("Rval:");
     Serial.println(Hue_2_RGB( var_1, var_2, Hu ));
     Gval = round(255 * Hue_2_RGB( var_1, var_2, H ));
     Bval = round(255 * Hue_2_RGB( var_1, var_2, Hd ));
  }
 
}
float Hue_2_RGB( float v1, float v2, float vH )             //Function Hue_2_RGB
{
   if ( vH < 0 ) 
     vH += 1;
   if ( vH > 1 ) 
     vH -= 1;
   if ( ( 6 * vH ) < 1 ) 
     return ( v1 + ( v2 - v1 ) * 6 * vH );
   if ( ( 2 * vH ) < 1 ) 
     return ( v2 );
   if ( ( 3 * vH ) < 2 ) 
     return ( v1 + ( v2 - v1 ) * (.66-vH) * 6 );
   return ( v1 );
}

Hope this helps someone, I will be adding pictures soon. If you need any other modifications made to the library don’t hesitate to ask.

Darius Gai Arduino

Seeedstudio Issues Part II (Resolved!!)

April 21st, 2009

The issues have been resolved.
It did take some back and forth with Eric (the owner of seeedstudio) over email. Eric tried to help me through various options that would let me salvage the anode LEDs, but all the ideas we put together would cost me additional money and take up more space in my eventual design. Eric finally conceded that cathode LEDs would be the right way to go and then we went through arrangements for them to send me the cathode LEDs over. Initally they wanted me to pay for the new LEDs, but I stayed strong to my arguement that the mistake was their fault and Eric finally did concede.

Altogether the back and forth of emails took about 2 days, and the LEDs came in today (18 days later) at the cost of seeedstudio. Through out the process Eric was extremely polite, and replied promptly to my emails.

Thanks seeedstudio!!

Darius Gai Arduino

Seeedstudio Issues

March 31st, 2009

As of late I’ve been getting into bigger and bigger projects. Late last month I put in an order for a whole whack of parts from seeedstudio. The parts came in a week later and I tucked them away.

Last week my LED Driver ICs came in from Maxim, so today (now that PDEng is over with) I decided was a good time to start tinkering and working on a new project.

The main component of my order from seeedstudio was 50 RGB LEDs that I planned to interface with the LED Drivers. The LEDs I ordered were supposed to be common CATHODE, so I went about hooking all of them up on a breadboard to test them.

After 30 mins of tinkering I had nothing, not even a flicker. I kept looking over my wiring thinking I had messed up something obvious, but nothing came to the eye. When I used a normal red led to test, everything worked fine.

About an hour into the process, I was starting to give up, when I suddenly decided to just flip all the leads on the RGB Led around. Suprisingly it worked!

Now completely confused, I started going through my circuit again. Apparently, the LEDs I recieved were not common cathode, but common ANODE.  To make matters worse, they didn’t even fit the datasheet shown on the website (also shown below):

RGB LED datasheet

RGB LED datasheet

Instead they followed this pattern:

————–
|    |    |   |
|    |    |   |
G  B  +  R

This blows… common anode LEDs are useless to me for my application. To use my LED drivers I need common cathode LEDs

I just whipped out an email to seeedstudio, hopefully they’ll sort me out.

Darius Gai Arduino

Hacking a digital alarm clock

February 22nd, 2009

 

Philips AJ3540

Philips AJ3540

About 6 months ago, I purchased an digital alarm clock/radio from Walmart. The model i purchased was the Philips AJ3540 for about $40. I purchased it for the large display, which I did not see available for other clocks in the same price range.

The clock is not without its flaws, however. The sound of the alarm buzzer is deafening and the backlight on the display is just too bright, even on the lowest settings for both on their respective control knobs. 

This week I finally had enough and decided something needed to be done.

On opening up the alarm clock I saw that the clock was divided into 3 segments - the display, the controls and the “brains”. The brains section had some interesting components. The buzzer was actually a high wattage piezo buzzer, I haven’t ever seen a piezo buzzer that was this loud. Also the circuit used to convert the incoming ac to dc was interesting.

Anyway, down to business.

How do I reduce the sound of a piezo buzzer?

This was suprisingly easy. The incoming AC power is converted to 5v DC, so all I had to do was find the power rails and hook up a potentiometer to it. I then hooked up the wiper on the potentiometer to the buzzer, where it was previously connected straight to 5v. After setting the alarm to go off, I moved the wiper around till I found a volume I found suitable. 

Basicly that is really all you need to do. However I didn’t want to just leave the potentiometer there inside the alarm clock. The first idea I had was to cut a hole into the casing of the alarm clock and use the pot as my new volume control knob. However, I do not have a dremel handy for cutting a clean hole, so this would not do. Also I only have 1 potentiometer currently in my possession (I need to put an order in for parts!), so I didn’t want to give it up, especially since I use them quite regularry for testing.

After some thinking I suddenly remembered that the way I was using the pot was similar to a voltage divider. Which brings us to step 2 of our procedure.

What is the voltage I want to step down to?

This wasn’t as easy as I thought it would be. 

At first I hooked up my Arduino to the clock - share the ground and hook the wiper up to an Analog Pin through a 10K resistor. I then intended on displaying the data on my computer monitor serially. However, this wasn’t simple, as the circuit on the alarm clock was pulsing the buzzer faster (PWM) than the arduino could print values to the screen. At times like these, I wish I had an oscilloscope…

Anyway, there is always a way around difficulties! I calibrated the pot to the volume I wanted it and then removed it from the alarm clock. I then hooked it up to the arduino through the 5V power out. The reading I got out was 4.8V. This part still doesn’t make sense to me, as for a drop of .2V the volume decreased by quite a bit! Guess the buzzer doesn’t follow a linear curve (which would make sense as its based on frequency).

A little voltage divider math showed that my R2 should be equal to around 24 times my R1. Looking through my available resistors I used a 300 ohm resistor for R1 and a 5.1K and a 2K resistor in series for my R2. 

Soldered the resistors on and voila!! Your sound is now exactly how you want it!

I went on and did the same thing for my display backlight.

Hope this helps someone out! I planned on adding pictures but I my SD card on my laptop reader isn’t working :(

Darius Gai Arduino, Projects, personal

Learning Eagle

February 11th, 2009

I have been dabbling a lot with Eagle as of late. And today I started to make some inroads. I created my first part in Eagle and have started a library. The part I created was the AS1106 LED Driver from Austria Microsystems: http://www.austriamicrosystems.com/eng/Products/Lighting-Management/LED-Drivers/AS1106

It is a cheaper alternative of the MAX2219 LED driver from Maxim-IC. I recently embarked on created a game using the Arduino that incorporates tons of LEDs and depending on my final configuration (haven’t decided on this yet), it would require 2-3 of these LED Drivers.

I also plan on using this project to Learn Eagle and since my AS1106 chips came in yesterday I thought I’d start by creating a part for them. It wasn’t as bad as I thought it would be and the Sparkfun tutorials on Eagle are a good starting point.

 Next I want to create a small protoboard with a single piece of each component type. Once I make sure that the footprint of each one is right, I’ll finish up the board and then I am set to go!

Darius Gai Arduino, Projects

A bunch of good deals in unexpected places

January 25th, 2009

Since I’ve recently started prototyping at home, I’ve felt constrainted by the tools and components I had available. However, I don’t have the money or purchase said components for my little home workshop. Some basic components I’ve been in need of as of late were resistors, capacitors and transistors.

I’ve been scouring digikey, jameco as well as local electronic stores such as sayal and nutech. However, I wasn’t getting a good deal for the amount I wanted, around 10-20 through hole componets for the standard value resistors and capacitors. Sayal and Nutech did not have the variety and digikey did not have the quantity. Plus the prices weren’t as cheap.

The best deal I saw was for a 520 assorted resistor kit for about 32 dollars with a cabinet. However with 20 dollars for shipping from Jameco, it was becoming a little too pricey for me.

Then I suddenly though to check on Ebay. I was able to get a 520 resistor kit, a 100 capacitor kit and a 25 NPN transitor kit for 20 dollars including shipping. And on a trip to Canadian Tire, I saw a 61 drawer cabinet for 15 bux!

Thats a total price of ~40 dollars for all the components I needed. 

Moral: Shop around! Deals are available in the most unexpected places!

Darius Gai Uncategorized

Update: New wordpress theme

January 19th, 2009

Every coop I get the urge to blog about work and the various projects I work on. Come school time, life becomes more hectic, chaotic and less interesting as I spend more time studying and trying to maintain various ties with friends and family;  relationships which becomes very fragile due to the stressful nature of the Waterloo engineering program. 

But every 8 months, when a new coop term starts and the hunger to blog comes back, I find the design of the blog to be “el passe” and start searching for a new theme. So today I reintroduce the blog under the new theme - iNove. The simplistic design really appeals to me and seems to fit well with the theme of the blog. Enjoy!

Darius Gai Uncategorized

Project updates

January 18th, 2009

Its been a long time since I’ve posted on the board. A few project updates. The electronics prototype for the lazy bartender has been completed. However, due to a lack of tools and materials on my end, none of the mechanical work has been done. Hoping to work on that sometime this semester if I can get a mechanicaly inclined person involved

I’ve been playing a lot with the arduino as of late - http://www.arduino.cc. I have tinkered with microcontrollers before and really enjoyed the projects I did, but the arduino really helps to take it to next level. It takes away all the pains of the microcontroller - programming being the big one; and adds a slew of cool features, like a great IDE and a programming language based on Processing. All this is done for very low cost as the bootloader is pretty small. I really think this would be a great addition to what was a pretty “boring” high school curriculum. Talks with Chad Whittington - the computer hardware and robotics teacher at Grimsby Secondary School have been positive. Hopefully we’ll manage to make some inroads here. 

Another project I want to use the arduino for is a todo list for the kitchen. I’ve noticed that we aren’t efficient in our grocery shopping. We often make multiple trips to the grocery store as we forget various items. The goal of the project is to have a simple interface, where the user can add the item, and the item gets uploaded to a web server. When its time to go grocery shopping, the user just has to open up and application on their computer (web based or not) and print the list.

I started on the project last week. I’m using an LCD screen with a serial interface chip. This way I only take up 2 pins on my arduino instead of 7+ to control the LCD. For user input, I initially was going to user a keyboard and try to read the PS/2 interface. However, after some research I felt it would be easier to use a potentiometer as a letter selector (similar to the volume control knob on your car stereo); and a momentary push button to enter the selected letter. After the item was typed out, another push button would be used to send the item to the web server.The programming to display the correct letter on the LCD via the potentiometer is completed. The logic the arduino will use to send the word over the serial port to a computer is completed as well. On the computer, the logic to send the word to the webserver has been completed as well.

The following still has to be done:- being able to type full items into the LCD- add the ability for an “upload” button- data storage on web server - currently being stored to web file, might want to incorporate database. 

Darius Gai Uncategorized

Lazy Bartender v0.1

August 31st, 2008

Coop is over I finally have a chance to get back to the bartender project. Now that some progress has been made on the programming end, I feel its fit to start discussing the project on this blog.

The bartender project is the biggest hardware project I’ve undertaken to date. It was inspired by the Virtual Bartender by Digital Beverages. I read an article on the product a few months back on Wired (or maybe it was Popular Science…) and was enthralled by the idea. As a person who loves his alcohol (as evident in my participation as a developer on Urbandrinks.com), I too wanted one of these machines, but was immediately turned off by the price - $2,575!!!

And thus the lazy bartender was born. The goal was to make a simple version of the virtual bartender for under $300. The idea was to take out all the heavy hardware responsible for controlling the robot, and use a multimedia computer to control it instead. Now days everybody seems to have a computer in their living rooms or kitchens. Either as HTPCs (Windows Media Centre, MythTV) or a kitchen PC, these computers are becoming increasingly popular for extensive feature list and cheap price. We decided that we would build software that would run on top of these computers that would be responsible for controlling our lazy bartender.

So here is where we are at currently, out V0.1:

Hardware:
The hardware is currently very simple. A relay board is connected to the parallel port. Having worked with the parallel port before, I decided to use it again for its ease of use and reliability. The relay board has 4 relays on it, that can be turned on or off by the parallel port. Each relay is attached to a gravity based solenoid valve. In an order to save money and decrease the complexity of the project, we used gravity to push the drinks instead of a pump. Both the solenoids and the relay board use 12V.

Software:
Deciding the programming language was a much debated topic. I wanted to choose a language that would allow me to prototype quickly and worked cross platform. Initially I was thinking of using Python with PythonCard as a graphics library. However, I finally decided on Visual Basic 6 (didn’t have .NET on me). I absolutely hate Basic as a programming language, but you can’t argue with its ease of use.

The fact that Visual Basic 6 runs on Windows only pretty much crossed the language off the list during an earlier decision process. However, faced with the fact that I would have to create separate programs for Windows and Linux (Macs don’t even have a parallel port) since the parallel port operates differently in each system anyway, Visual Basic came back in to the foray due to the ease with which one can prototype a functional graphical program.

Hell, if this project really takes off, we’ll look into switching to a more “sophisticated” programming language.

So what can the bartender do now??
I can use my program to turn the solenoids on and off and pour my self a drink!! Pretty cool huh!!

Things to do for v1.0:

Hardware:
I need to design containers to hold the various alcohols and mixers. A lot of questions here since gravity is used. How do I design a container that won’t spill any liquid on to the electronics when opened?? I also need to procure or design a cabinet to house all my hardware.

Right now the user has to use the software provided to calibrate a shot. Essentially when the user clicks a button once the machines starts pouring. When the button is clicked a second time, the machines stops. The user can use this method and a shot glass to calibrate a shot. This technique (Bucket and Stopwatch technique), works but isn’t the most efficient. The user will have to do this for every type of alcohol and mixer because of their different viscosities. A flow meter of sorts would be a better solution. Due to the low cost of the project it might be better to pursue a hardware based design, like an indexer, or a modified toilet bowl float valve.

Software:
Right now the software can turn on and off the solenoid valves. It can also allow the user to calibrate the solenoid valves to pour a shot. For v1.0 a data storage has to be chosen - text files (currently used) or database (probably MySQL)?? There has to be a database of recipes. Once the user has been calibrated the solenoid valves to pour a shot, the software should be able to use this information to pout a drink as outlined by a recipe.

The software shouldn’t take too long. A good weekend should suffice. Its the hardware I am worried about. For some reason I can’t wrap my head around the design of a container. How do I design a container that will be easy to load and unload without any spillage? Right now I am envisioning something with Tupperware…

Anyway, all these developments are quite exciting, and working on this project has been a lot of fun!!

Darius Gai Lazy Bartender

Update to Livesoccertv.com Greasemonkey script

August 19th, 2008

I noticed a couple days ago that livesoccertv.com changed its url convention for the fixtures page. The script now accomodates for the url change.

More info available here:  http://userscripts.org/scripts/show/31551

Darius Gai Programming