Under cabinet lights with BlinkM MaxM

January 14th, 2012 No comments

The lights in my kitchen are somehow inconvenient. There are two entrances and the light switch is only at one of them, on the outside wall. Whenever I walk in from the living room and want to do something quickly I have to walk around to turn on the light. To solve this, I got an idea to build a under-cabinet light controlled by a motion sensor.

My first idea was to get an LED strip (like this one) and build a controller with ATTiny, PIR sensor, and a transistor to drive the LED’s. But one day I saw a BlinkM MaxM. It can drive RGB LED’s (12V, 2A) and can be programmed with color sequences. It also has 4 inputs so connecting PIR sensor is possible. It is perfect for my kitchen lights, except that it’s RGB. So I got:

I used 20 sections of the LED strip (60 RGB LED’s). Each color draws 1.2A which is below the maximum MaxM can drive. PIR sensor is powered from the MaxM board and the data pin is connected to input number 3.
I programmed BlinkM with an Arduino. Here is the BlinkM script:
// set fade speed
{0, {'f', 2, 0, 0}},
// go to white when movement detected
{0, {'I', 3, 50, 4}},
// loop black
{60, {'n', 0, 0, 0}},
{0, {'j', -1, 0, 0}},
// fade to white and stay on
{60, {'c', 0xff, 0xff, 0xff}},
// 1 minute (7 * 255 * 0.03333ms)
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
// 1 minute
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
// 1 minute
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
{255, {'n', 0xff, 0xff, 0xff}},
// loop black
{60, {'c', 0, 0, 0}},
{0, {'j', -1, 0, 0}},

 

The light fades in when I walk in and fades out after 3 minutes of inactivity in the kitchen. When I keep moving in the kitchen, PIR sensor keeps triggering and the 3 minutes renew, so the light stays on as long as I’m in the kitchen.

001-20120114

There are a few problems with the setup, which I’ll have to address:

  • RGB strip produces a reddish color. To get a warm white I’ll have to experiment with different settings.
  • BlinkM fades are not linear. I might re-write the script in assembly and re-programm the BlinkM.
Update, Jan 27, 2012:
I just changed the power supply from 9V to 12V. The red is gone and I have a bright cool white color, that is much better.
Categories: BlinkM, DIY Tags:

iCufflinks on ATTiny85

December 31st, 2011 No comments

After playing with Arduino for a while I decided to go hardcore and experiment with bare ATTiny microprocessors. I ordered a couple of ATTiny85, ATMega328, and a AVRISP mkII programmer. I started with a simpler ATTiny85, a breadboard, couple of resistors, and power supply. What better project to start with as a blinking LED? But blinking is boring. I wanted pulsating. iCufflinks pulsating.

iCufflinks are cufflinks that pulsate to mimmic Apple laptop’s LED sleeping light pattern made by Adafruit. The design and software are open source. iCufflinks are based on ATTiny10 microprocessor which is way simpler than ATTiny85 I have. So I ported the assembly code and made it work on a breadboard. I never read almost entire data sheet for a microprocessor, but without that I would not be able to make the port. I was surprised to see that the instruction sets of similar microprocessors can be so different.

Blog post on programming ATTiny85 from Yet Another Hacker’s Blog was very helpful on connecting the programmer to the chip.

I also used Atmel AVR Studio 5 running in VMWare Fusion to program the ATTiny.

My fork is in my Github.

 

Why did I do this? BlinkM is running on ATTiny85 :)

Categories: ATTiny, DIY Tags:

Animoto from Utah

September 27th, 2011 No comments

A friend of mine started working for Animoto and I decided to give their service a try. Here is a short slideshow video of some photos I took during my recent business trip to Utah.

More photos on my Photoblog.

 

Create your own video slideshow at animoto.com.

Categories: Photography, Utah Tags:

SaveTV script updates

September 4th, 2011 No comments

I got a code contribution from Andreas Horn a week ago to the save.tv download script. He made some speed and error checking improvements, as well as added a code to use the cut lists. He’s using the script on his QNAP TS-210 NAS-System. Good to know that it’s working on anything other than computers.

Thank you for your contribution Andreas!

I finally got to implementing a change I always wanted to add – timeout for the wget command in save_tv.py and for the mplayer in tv_polonia.py. And I fixed removing save.tv shows from the website after they are downloaded.

The code is already on github.

Categories: Save TV Tags:

Lego 8129 AT-AT Walker™

July 20th, 2011 No comments
20110720-001

The AT-AT is easier to build than the Falcon, but still took two evenings. The build is movable, but somehow fragile. When moving legs I have to hold them tightly to prevent some pieces from becoming detached.

This one will hopefully find a permanent place on my shelf, because it’s not too big :)

Categories: Lego Tags:

The story of atomic radio clock

February 20th, 2011 2 comments

This is a story why I’m not gonna add atomic radio synchronization to my Arduino clock project.

I started working on a clock based on Arduino and Chronodot that would synchronize with the WWVB radio signal and got the prototype working. But, yeah, there is a but.

The WWVB radio station that sends the time signal is in Fort Collins, Colorado. Its signal reaches New York without any problems but the interference in the city introduces errors in the time code sent by the station. Only at night it’s possible to read the time and set the clock.

So here is what I have:

  • Arduino
  • Chronodot (I2C)
  • Two 4-digit 7-segment LED displays
  • MAX7219 LED matrix driver (SPI)
  • CMMR-6P-60 receiver module (digikey: 561-1014-ND)
  • 100mm ferrite antenna (digikey: 561-1001-ND)
  • LCD and SD-card (and Ethernet) shield for debugging

I wrote a library to decode WWVB signal that can be found in my git repository. It’s an initial working copy but does not have any examples yet.

The Chronodot and display part of the clock project were easy. I had the prototype running in no time. Also, connecting CMMR-6 module to Arduino was not a big problem. I will have another post on that – it might jump-start a lot of folks doing the same thing.

The stairs began with getting rid of interference. I could get a signal when I run the clock from a 9V battery, but the battery cannot drive all debugging displays and logging that I have connected for a long time, so naturally I started using a 9V power supply. I quickly noticed that the 5V regulator on the Arduino got too hot; so hot, in fact, that I was unable to touch it, as well as the ethernet port just above it. I switched to iPhone charger that outputs a nice 5V DC on the USB port and I used a USB cable. All worked great without overheating.

Once the power situation has been cleared I left the clock running overnight to collect some data and see it the signal synchronizes the Chronodot. I got nothing over the first night. Well, a bad reception night, bad weather (we had a snow storm in the US at that time). But I got no data for the next few nights. That made me thinking that the reception is bad in New York City. Period. But I noticed that the signal appeared when I was touching the LCD screen. Soon I discovered that the signal was perfect when I was touching the ground wire. That leads me to believe that the switching power supply introduces some kind of interference and prevents the receiver from getting any usable signal.

How do I quickly ground an electronics circuit? I run a wire from the ground to the shield of the cable-TV connection. Signal appeared! I got multiple synchronizations over a single night for the first time after two weeks of prototyping and programming!

In the end I will not proceed with WWVB synchronization just because it’s too difficult to shield from all the interference and properly grounding the project. Additionally, the positioning of the ferrite antenna in relation to the transmitter in Colorado is very important. I don’t want to be forced to place the clock in the room in accordance to the radio transmitter.

My idea of clock synchronization is by employing XBee radios (which I use for lighting project already). The clock will listen for time signal commands and set the clock. The time reference can be sent by a PC from either local clock or by querying an NTP server. I’m also thinking about building a GPS receiver with an XBee radio that will sit at my window and send the time periodically to my PC and the clock. This way the project is more versatile and I get to build more fun devices :)

Update (2011-02-20):
I did some more testing last night and got very little signal. So grounding helped, but I guess there are good and bad reception days.

Categories: Arduino, DIY Tags:

Chronodot library for Arduino

January 16th, 2011 1 comment

I wrote a library to talk to Chronodot real time clock based on DS3231 chip by Maxim. It is also possible to talk to the chip using Time library but it does not fully support the chip’s abilities and replicates the clock internally in Arduino, only updating the time from DS1307.

The library is in my git repository.

At this moment, it has functions to read and set date and time returning both decimal and BCD representation. It also controls SQW pin output. The next step is to implement setting and using both alarms that the chip supports. Take a look at the .h file and included example sketch for more info.

Categories: Arduino, Chronodot Tags:

Chronodot SQW and Arduino interrupts

January 11th, 2011 11 comments

My Arduino clock is being built, but I have to share a cool feature of Chronodot. It has a INT/SQW output, merked SQW on the board. It’s programable to be either a square-wave generator or an alarm interrupt line. The chip has two alarms that can be set, and if one of them goes off, the INT/SQW line becomes active. It’s all documented in the datasheet. Let me concentrate on the sqare-wave generator.

My first clock’s main loop looked like this:

void loop() {
  displayTime();
  delay(1000);
}

I display the time and wait one second, then display the time, and so on, forever. But that one second wait is not very accurate and my displayTime() function reads the time from the RTC sometime in the middle of its second. This can be solved by the SQW and interrupts.

I set the Chronodot to generate 1Hz sqare-wave on its SQW output. That is one beat per second, and it’s gonna be accurate because I’m working with an accurate RTC. I feed that sqare wave into one of the Arduino digital inputs pins and register an interrupt function, that will be triggered every time the wave is at its falling edge (changing from high to low). Here is the setup code:

#define INTERRUPT_PIN 3
 
void setup() {
  Wire.begin();
 
  set1Hz();
 
  // register interrupt function to 1Hz line
  pinMode(INTERRUPT_PIN, INPUT);
  attachInterrupt(1, oneHzInterruptHandler, FALLING);
}
 
void set1Hz() {
  // Frequency is stored in register 0x0e in bit 3 and 4
  Wire.beginTransmission(CHRONODOT_ID);
  Wire.send(0x0e);
  Wire.endTransmission();
  Wire.requestFrom(CHRONODOT_ID, 1);
  uint8_t register0E = Wire.receive();
 
  // clear bits 3 and 4 for 1Hz
  register0E &= ~(1 << 3);
  register0E &= ~(1 << 4);
 
  // put the value of the register back
  Wire.beginTransmission(CHRONODOT_ID);
  Wire.send(0x0e);
  Wire.send(register0E);
  Wire.endTransmission();
}

Right there, I configured the Chronodot’s generator to 1Hz and registered the handler. The frequency is stored in bit 3 and 4 of register 0x0E.

One word about interrupt handlers. They have to be quick. They should only set a flag or do a quick calculation. My handler sets a global flag that tells the main loop to display the time.

boolean displayNow = false;
 
void loop() {
  if (displayNow == true) {
    displayTime();
    displayNow = false;
  }
}
 
void oneHzInterruptHandler(void) {
  displayNow = true;
}

That’s all. The clock is ticking more accurately now.

Categories: Arduino, Chronodot Tags:

Connecting Chronodot and setting the time

January 9th, 2011 10 comments

I want to build a clock, a precise one. For this purpose I got a Chronodot – extremely accurate and temperature compensated and battery backed real time clock module, based on the DS3231. The sample code on the website only shows how to read the time from the clock using Wire library. There is no info how to connect the thing to the Arduino. There is no code to show how to set the time. After reading the documentation and searching on-line I figured it out.

20110109-001

Chronodot uses I²C bus to talk to the outside world. Arduino accepts I²C connections on two analog intput pins. On most boards, SDA (data line) is on pin A4, and SCL (clock line) is on pin A5. Those are analog lines, not digital. So, connect pin A4 to Chronodot’s pin labeled SDA, and Arduino’s pin A5 to Chronodot’s pin SCL. Of course, +5V goes to VCC and GND to GND.

Based on the Time library and the DS3231 datasheet I wrote a library to talk to Chronodot, and a sketch with a Python script to set the time. Both are available in my git repository: Chronodot library, ChronodotSet sketch.

Load the ChronodotSet.pde into your Arduino and leave the unit connected to the PC. The set.py Python script will set the date and time over serial connection to either local PC time, time from a string, or time from NTP server (depends on Python serial library pySerial and NTP library for NTP functions). The time is rounded to the nearest second.

Without any options it sets the time to the local PC time and reads back the time reported by Arduino 5 times.

$ ./set.py  -h
Usage: set.py [options]

Options:
  -h, --help            show this help message and exit
  -d DEVICE, --device=DEVICE
  -s STRING, --string=STRING
  -n, --ntp
  --noreadback

$ ./set.py
Setting time from local time
Time has been set to 2011-01-16 18:31:38.503983
Reading time back
2011-01-16 18:31:38
2011-01-16 18:31:39
2011-01-16 18:31:40
2011-01-16 18:31:41
2011-01-16 18:31:42

$ ./set.py --device /dev/tty.usbmodem411 --string "2010-02-28 23:59:57"
Setting time from string 2010-02-28 23:59:57
Time has been set to 2010-02-28 23:59:57
Reading time back
2010-02-28 23:59:57
2010-02-28 23:59:58
2010-02-28 23:59:59
2010-02-29 00:00:00
2010-02-29 00:00:01

$ ./set.py --ntp --noreadback
Setting time from NTP server
Time has been set to 2011-01-16 18:33:39

Have fun. I’m getting to work on 7-segment displays.

Categories: Arduino, Chronodot Tags:

Arduino Remote RGB Light

January 8th, 2011 No comments

Playing with my Arduino project pack I noticed RGB LED’s. Those contain three LED’s in one package (red, green, and blue). You can create any color by applying different voltages to separate LED’s. Since Arduino has PWM outputs I decided to give it a try and produce different colors by varying different outputs for each color.

RGB LED’s come in two types – common anode and common cathode. The difference is how you drive them.

Common cathode (CC) ones, like the name implies, have a common cathode for all three colors. The cathode connects to the ground and anodes for each color go to the Arduino PWM output pin with a limiting resistor in series. The higher the voltage you apply the brighter the LED will get.

Common anode (CA) LED’s must have the common pin connected to +5v, and each cathode to the PWM pin with a limiting resistor in series. The LED gets brighter when the voltage from the PWM output gets lower. The RGB LED’s in my pack are all common anode – I have to reverse the common sense thinking when I code for those.

When connecting the RGB LED, choose the PWM pins – not all pins are capable of analog output. I chose 9, 10, and 11 on my Arduino UNO. Here is a sample program to set some colors with CA LED.

int redPin = 9;
int grnPin = 10;
int bluPin = 11;
 
void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(grnPin, OUTPUT);
  pinMode(bluPin, OUTPUT);
}
 
void loop() {
  // red
  analogWrite(redPin, 0);
  analogWrite(grnPin, 255);
  analogWrite(bluPin, 255);
  delay(1000);
 
  // green
  analogWrite(redPin, 255);
  analogWrite(grnPin, 0);
  analogWrite(bluPin, 255);
  delay(1000);
 
  // blue
  analogWrite(redPin, 255);
  analogWrite(grnPin, 255);
  analogWrite(bluPin, 0);
  delay(1000);
}

Great! I got some colors displayed. Boring! Let’s get it to the next level. Maybe a remotely controlled color lamp with XBee’s.

I found a site with a nice sample program to crossfade pre-defined colors. I decided to take that and write a library I to drive RGB LED’s to set and crossfade colors. The original code works with CC LED’s so I have to revert the logic. My final library works with both CC and CA LED’s. It is GPL’ed, so feel free to use it. Here is sample usage.

#include <RGBLED.h>
#include <RGBColor.h>
 
/*
 * red pin 9; green pin 10, blue pin 11
 * hold 0ms, wait 2ms, common anode
*/
RGBLED rgbLED = RGBLED(9, 10, 11, 0, 2, 1);
 
RGBColor black = RGBColor(0, 0, 0);
RGBColor white = RGBColor(100, 100, 100);
RGBColor red   = RGBColor(100, 0, 0);
RGBColor green = RGBColor(0, 100, 0);
RGBColor blue  = RGBColor(0, 0, 100);
 
void setup() {
  rgbLED.setIntensity(100);
  rgbLED.setColor(black);
}
 
void loop() {
  rgbLED.crossfade(white);
 
  rgbLED.crossfade(red);
 
  rgbLED.crossfade(green);
 
  rgbLED.setCrossfadeHold(1);
  rgbLED.setCrossfadeWait(0);
  rgbLED.crossfade(blue);
  rgbLED.setCrossfadeHold(0);
  rgbLED.setCrossfadeWait(2);
}

This way it’s much simpler to drive RGB LED’s. But back to my remote light. I needed a protocol to send commands to the lamp. I started reading a brand new book: Building Wireless Sensor Networks: with ZigBee, XBee, Arduino, and Processing. It explains the details behind XBee radios and how to use them alone and with micro-controllers. It also brings the entire protocol a bit closer. I borrowed some ideas from there.

My protocol is based on simple packets that start with byte 250, followed by the data size byte, and the payload – command byte and parameters. For example, to set the red color I send the following bytes over the XBee: 250 4 20 100 0 0. To crossfade three colors you send: 250 10 30 100 0 0 0 100 0 0 0 100. Let’s break it down:

  • 250 – start the packet
  • 10 – we are sending 10 bytes of payload
  • 30 – command for crossfade
  • 100 0 0 – the first color (red)
  • 0 100 0 – the second color (green)
  • 0 0 100 – the third color (blue)

The lamp’s hardware:

20110108-001

The code can be found in my git repository. There is also a python library and sample scripts to send commands to the lamp.

There is an option to debug the incoming packets by showing them on the LCD display. I use Matrix Orbital LK202-24-USB and the SoftMatrixOrbital library I wrote.

Categories: Arduino Tags: