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:

Arduino holidays

January 3rd, 2011 No comments

I got Arduino for Christmas! And I had over a week of vacation time!

First a bit of explanation. Arduino is an open-source hardware and software platform for prototyping electronic devices that interface with the real world. Simply, it’s a micro-controller board that’s easy to play with and program. It has a good mixture of digital and analog outputs and inputs.

I wanted to do some work with micro-controllers since high-school and never got around it. My thesis in technical high-school was supposed to be building a home-automation system using PIC chip but I never got to do that because I left the country. Now I got a chance and some time.

I received the project pack from MakerSHED that includes the Arduino Uno board, prototype shield (board that fits over the main board), breadboards for solder-less prototyping, and some parts and cables. I also asked Santa for Xbee kit from Sparkfun and I got it!

I started reading books and the website over the holidays and got to work. The kit comes with no documentation whatsoever, so the website, forums, and books are your friends. Thanks to my background in electronics I got straight to it without any issues.

The first project was to make a LED blink! I was done in few minutes. I started adding more LED’s, then buttons, then potentiometer to control the speed or brightness. All easy and great!

The second project was to try the Xbees. Those are small, low-cost and low-power devices that make wireless communication easier. Sparkfun’s kit contains an Arduino shield that connects one Xbee to Arduino’s serial port, and USB adapter that connects the second Xbee to the computer. This way one can implement protocols that allow larger computers to talk to Arduino boards, or two or more Arduino boards to communicate between each other. My first project here was to display messages sent over serial interface from the PC on a serial LCD display. More on that in a separate post.

All in all, Arduino is a great simple and powerful device.

Categories: Arduino Tags:

Falcon back in the box

December 2nd, 2010 No comments
20101202-001

I spend one day taking the Millennium Falcon apart and sorting all parts and fitting them in 80 bags. It should be easy the next time I want to build it.

Categories: Lego Tags:

Building Millennium Falcon – day 9

August 9th, 2010 No comments
lego10179progress09-01

It’s finished! Built! Done! And it’s awesome!

There are some leftover parts :)

Categories: Lego Tags:

Building Millennium Falcon – day 8

August 8th, 2010 No comments
lego10179progress08

Step 88, page 266. I’m nearing the end. The top-back of the ship is done. What bothers me a bit is that all those top plates are a bit loose. At the end they will be easily removable. But it looks great!

Categories: Lego Tags:

Building Millennium Falcon – day 7

August 7th, 2010 No comments
lego10179progress07

Step 81, page 227. Getting the sides and the cabin done.

Categories: Lego Tags:

Building Millennium Falcon – day 6

August 6th, 2010 No comments
lego10179progress06

Step 77, page 207. The bottom is done. I started working on the top of the ship.

Categories: Lego Tags:

Building Millennium Falcon – day 5

August 6th, 2010 No comments
lego10179progress05

Step 68, page 160. I started another step but did not finish it yet. The new elements added are under and inside the ship – the coolest is the moving entry platform. :)

Categories: Lego Tags: