Wednesday, December 9, 2009

Telephone Interface (updated 12/30/09)

This project describes an Arduino/MCU interface to a telephone land-line. It's only been tested on a US version of the telephone system, but hopefully it will apply to the phone system in other countries.

The basic idea was to allow the MCU to make calls by transmitting DTMF tones, and to receive and decode DTMF tones (keystrokes) made on the phone that was called.

There are other possibilities however. Using the complete interface, it should be possible for the MCU to answer calls, and to transmit "room sounds" picked up by a microphone to the other phone.

If you're only interested in sending and receiving DTMF tones and not interfacing to a phone line, you can skip the next dozen or so paragraphs. The schematics and code samples will still apply. 

It all begins with the interface to the actual telephone line. Unfortunately this is trickiest part!

There are two reasons for this:
  1. Phone lines require a 600 Ohm "balanced line". You can't just slap any old circuit between your "TIP" and "Ring".
  2. It's illegal!

Lets start with #2. Here I'm speaking from a US and Canadian perspective, but I'm sure it's similar in many countries. In the US, it's FCC Part 68 that makes it illegal to connect any unapproved device across your phone lines. So what can they do? Well, I'm sure it's much worse than tearing off that tag on your mattress.  I've read that if you create a problem that must be investigated by the phone company, and it's due to a little circuit you whipped together - your financially liable to cover the cost of the phone companies time. And it's relatively easy to do horrible things to your phone line during the process of creating an interface, and that leads to point #1.

When you Google "phone interface" you'll be drinking from a fire hose of circuits, methods, and projects. I spent a lot of time researching them, and did indeed come up with an interface that "worked". However, what I ended up with, struck me as being sensitive to component values, and somewhat "fragile". By this I mean, for example, that the correct "polarity" for TIP and RING was required. Given that the line should be "balanced" I felt like I disturbed the balance of the force. In short, after all of my experience with electronics, I felt like I was over my head with the interface I came up with. Ironic considering you're dealing with a system that has been around for so long.

For those who want to ignore points 1 & 2 above, here are some of the best resources I found, as well as the schematic for the "working" interface I was using. Big disclaimer here! I do not recommend building your own unapproved interface. Furthermore, I am not responsible for anything you do with any information I am providing. Everything here you use at your own risk.

Some of the telephone interface links I found helpful are:
Just looking at the variety of this information should give you an idea what your up against when rolling your own POTS interface. The interface that I tried is here.

Not a very encouraging beginning is it?

Enter the "Direct Access ArrangementDAA. This little module is an FCC Part 68 approved interface. Does it make everything OK? I don't think so - it really just makes it a lot easier for you to get your device FCC approved. Will it give you peace of mind? You bet. After switching to a DAA, the TIP and RING polarity did not matter, and everything seems to be much more solid - calls go through 100% of the time. The DAA also saves you from buying an isolation transformer, relay, transistor, and a large capacitor.

The problem is getting your hands on one without having to special order 54 of them from Mouser, etc. After a lot of searching, the best deal I found, for my use, was for a Cermetek CH1817-LM (discontinued) still some left on eBay - here. It will cost you $15-$18 shipped.

Note: If your interested in capturing caller ID, I don't think this is the DAA for you. However, while searching I did see some that will output CID. I also ran across the Holtek HT9032C which looks like an interesting CID chip, but they seem to be hard to find.

Sorry if the above was long and detailed. I wrote it in the interest of saving you a lot of time. However, as always, YMMV.

Once connected to the phone line, I wanted to do several things:
  • Have the Nex10 dial my cell when an event ("macro") was triggered.
  • Leave a message - a series of beeps.
  • Optionally be able to listen in on the room noise from the called phone. (work in progress)
  • Capture any key presses I made from my cell. (Not sure how I want to use this yet.)
Note that currently all the communication is initiated by the Nex10. In fact, it is possible to use the RI (ring indicator) on the DAA to answer calls with the Nex10. (No plans yet for this.)

To do the things above, I used 2 chips from Holtek - an HT9200B DTMF generator to dial the call, and a HT9170B DTMF receiver to read the key presses once connected. Both are less than 70¢ each at Futurlec.

I wired both chips per the datasheets and ran the HT9240B in serial mode. Here is my schematic and an Arduino example sketch for the project at that point.

I could have stopped there, but even with serial mode, the interface to the MCU required 8 pins + power. I also want the Nex10 to accept "plug-in modules" - so an I2C interface seemed like the way to go.

I picked the PCF8574 I2C GPIO chip to go between the MCU and the DTMF chips. It's also available at Futurlec and is also wired per the datasheet. (Note: the PCA8574 is a newer version and runs at the faster I2C speed but was not carried by Futurlec.)

Both the DTMF receiver and the I2C GPIO have a nice feature that sets an interrupt line when new data is received. I wanted to use the INT line on the GPIO. However, because the DTMF receiver latches it's output, there was no easy way to read multiple presses of the same key. So, I am currently using the interrupt on the DTMF receiver (DV). Either way an external interrupt is triggered when new tones are received. This saves me from having to poll for changes.

Using the I2C GPIO with the interrupt line saves 5 pins on the MCU. Here is the current schematic and Eagle files. And here is the current example sketch for the completed project using the DAA, DTMF, and GPIO.

The short movie below describes the state of the project before adding the GPIO. (Looks the same now - only less wires to the Arduino.)


Monday, October 19, 2009

Building a Case for the Nex10

Sounds like something a lawyer would say.

Building this case took a solid weekend.

The wood is walnut. I know this wood well because 25 years ago it was a tree on our land in Arkansas. We had to cut down some walnuts to make room for the house and we hauled them to the mill and had them cut into boards. For me, it's a nice mix of the past and present.

I planned a board down to 5/16", cut it up, and mitered the ends. Then I glued up a box.

The board was wide enough to make 2 boxes. I also made the acrylic front using acetone to chemically wield two black strips that hold the 8x32 matrix in place. The IR sensor is glued over a small hole drilled in the top black strip.

I got a few gaps in the wield which show up as shinny spots on the black strips. Next time a little more acetone and better clamping. I used tripoli abrasive on a buffing wheel to finish the edges.

To make the box stronger, and more interesting, I added ebony splines in the corners. I do this with a jig I made for my router table. Its kind of a sled that holds the box at 45° (photo).

After cutting off the excess ebony (photo), I rounded all the corners with the router.

On the inside of the box there's a platform that holds the board in position to line up the SD socket with a slot in the side of the case (photo). I used the router to cut the slot, and a little sanding drum to make the recess in the case for fingers to get at the card (photo).

A back cover of clear acrylic was made to fit into a rabbet cut around the back of the box. A power jack and an RJ14 jack for the PSC05 was added to the back. There's also a hole for the USB cable when I'm developing (photo). (Later I added a wood dowel with a hole that fits over the stem of the reset button to bring it out to the back of the case (photo).

The box was finished with a light coat of tung oil varnish. (photo)

Finally, the obligatory video . . .

Friday, October 16, 2009

Nex10 Functionality

Almost all of the functionality of the "X10 Book" is included in this project and new features have been added.

What's missing is the ability to drive relays and LED's. My thinking is to include such things as optional "add-ons". So a "relay pack" could be designed for lawn sprinklers. I'm currently working on a phone dialer (see above), and I'm considering other ad-on modules like a Bluetooth PC interface. But I've gotten ahead of myself.

One of the biggest advantages over the X10 Book is the ability to read in configuration files that are put on the SD card. So far there are 4:
  1. TIMEDATE.TXT - enter the time and date on a single line, put the card in the Nex10, restart, and the time and date are set. (Then the file is deleted from the card.)
  2. SETUP.TXT - this file is loaded into the external EEPROM and deleted after loading. It has several sections where you can define;
    Messages - like names of the weekdays, full moon names, etc.
    Reminders - yearly reminders like birthdays, scheduled salary reviews, etc.
    X10 Events - timers to send X10 commands at certain times.
    X10 Profiles - Friendly names for House / Unit codes so instead of "A-5" "Desk Lamp" is displayed. Other parameters in each Profile control beep type, display and logging options.
    X10 Macros - (work in progress) "IF A-5 ON - Send G-2 and G-3 OFF" is a simple example. They should be pretty powerful - stay tuned.
  3. PARAMS.TXT - This file contains user defined parameters such as the date and time format, the house code for the remote temp sensor, high / low temp alarms, various delay times, etc.I've pretty much replaced all "hard coded" settings with these parameters.
  4. FONTS.TXT - Since we're using an LED display, a set of fonts must be defined. All characters from ASCII 32 to 127 are included. Additionally about 20 or so "sprites" like the moon phases are defined. This file is loaded to the ATmega644P EEPROM instead of the external EEPROM. It is deleted after it is read in.
So what's it do? We'll you should have some idea from the above, but here's the list in all it's gory detail . . .

Clock Features:
  • Time - set by writing it to a file on the SD card, automatically adjusts for DST. The clock has a battery backup.
  • Day of the week is displayed with a user defined message for each day.
  • The current phase of the moon is displayed as an animated sprite. The number of days to the next full moon, and name of the full moon, is displayed as a scrolling message.
  • The times for sunrise and sunset are displayed.
  • Yearly reminders will display a day in advance and on the day.
X10 Features:
  • All X10 signals that come across the powerline are displayed and optionally logged. If a "profile" was set up for the house and unit code, a friendly name will display - i.e. "Desk Lamp". The profile also has options for 3 levels of "beep", no display, and no logging.
  • Logs are written to the SD card as a text file readable by a PC. A new log file is automatically created each month.
  • The current status of all 255 devices is kept. The status table can be written to the SD card or cleared using the TV remote. The table will be used for one type of "macro" command.
  • A TV remote may be used to manually send X10 commands.
  • X10 commands can be set up to be automatically sent at certain times during the day.
  • X10 Macros are defined in a section of the setup file. Current types supported are; "if cmnd-then cmnds" (up to 5 thens), "if cmnd and time > x or < y then cmnd, if cmnd - display time, temp, etc. I am working on more types like "if temperature".
  • Nex10 will receive the temperature from a remote wireless sensor on a dedicated House Code. (See this.) The time and temperature is logged to a separate file on the SD card. The current temperature and the low and high temperature for the day is displayed in the display loop.
  • Alarms may be set to provide an audible warning if, for example, the the garage door has not closed in a certain time.
  • There's a good chance I forgot something.
Most of the time, the device is just listening for X10 commands coming from the PSC05. Once every 5 minutes or so, it goes into it's display routine and shows all the things listed above under clock features. The display routine can also be activated via the remote, or from a macro.

Credit and thanks to Bill Westfield, Andrew Hedges, and Bill Ho for the ht1632 code that writes to the Sure matrix, Bill Greiman for the fantastic SD card library fat16lib, B. Hagman for a slick non-blocking Tone library, and Mike Rice for a great little sunrise / sunset time calc. library.

Sunday, October 11, 2009

Nex10 Begins

I'm far enough along that I can be posting about this thing.

To the left is a PCB board I designed to be the platform for the "Nex10" - the next level of the "X10 Book".

The goal is to create an X10 controller that is user configurable without the need to change the software. The Nex10 is configured through text files copied to it's SD card. More on the functionality later. This post is about the hardware!

A larger picture of the board is here.

In order to support reads and writes of the SD card, I went with a larger microcontroller - the ATmega644P. This has twice the program space of the ATmega328 used in the X10 Book. The board also has an external EEPROM, RTC (real time clock), piezo, and IR detector. It also has a difficult to solder FTDI chip that allows it to be programmed via USB. I see this as totally optional. I just wanted one to make my development easier. Besides, it's pretty cool!

Other little goodies include a resettable fuse, ISP header, and jumpers for power, auto-reset, and ARef. It runs on regulated 5V and has a voltage regulator that supplies 3.3V for the SD card. It uses a 16MHz crystal or resonator.

I used CadSoft's Eagle to create the schematic and lay out the board and BatchPCB to fabricate it. This is Rev. 1, and amazingly everything worked. If I decide to make a Rev. 2 there are a few changes I'd make, but basically I'm pretty happy. (Eagle files here.)

This board will drive an 8x32 LED Matrix from Sure Electronics. This display is very easy to read, cheap, and uses SPI so no additional hardware is needed on the board.

There is nothing about the board that is dedicated to Nex10 application - it can be used for just about any microcontroller project.

If you'd like a board very similar to this one (with a serial interface), a fellow maker, Florin, sells an easy to solder kit. You can read about it here.

Thursday, September 17, 2009

Is the Garage Door Closed?

After the second time my neighbor had to tell me that I left my garage door open, I thought I'd throw a little technology at my senility.

I could have gone the route of using a PSC01 "PowerFlash" but I had a few problems with that:

  • It requires a "normally closed" reed switch (which opens when the door is closed and next to the magnet. 
  • It only sends the X10 command one time. 
  • It would plug into the same outlet as the door opener - not a good time or place to send X10 signals on the power line. 
  • I wanted to make my own. :-) 
So this ugly little board above was my solution. It consists of an ATmega168 (running on it's internal oscillator), and a CM17A "Firecracker" (removed from it's jacket). It's wire-tied to it's wall wart.

When the normally open reed switch closes - because the door is open - it causes a pin based interrupt in the ATmega168. The CM17A then sends a preset House + Unit + ON wirelessly to a TM751 receiver and it's put on the power line and picked up by the X10 Book (see below). The command is sent 3 times with a delay in between to make sure the signal gets through. When the door closes, an OFF signal is sent 3 times.

(get Arduino sketch)

On the X10 Book side, a timer is started when the first door open signal arrives. After a preset time, the X10 Book beeps every few seconds until it receives a door closed signal.

If the door is open late at night, the X10 Book will also turn on lights near the garage. (I could have it wake me up, but I'd be too tired and too scared to want that!)

Friday, May 22, 2009

X10 Wireless Temperature Transmitter

This is a battery operated Arduino project that uses the CM17A to wirelessly transmit the temperature to the power line. From there, it is picked up by the X10 Book, (see below) and displayed and logged. (It can also be used to trigger macros.)

The PSC05/TW523 will not receive X10 "extended" codes. Therefore I had to get tricky with how I sent the temperature and how I received it. This means that the technique requires you to have control over the receiving end as well.

The idea is simple. An entire House Code is dedicated to the temperature. Each digit is sent as a Unit Code representing that digit (i.e. Unit Code"3" is sent if the digit is 3). The Command is used to indicate the digit position. So for the least significant digit, I used "OFF" for the next digit I used "ON". BRIGHT and DIM can also be used for more positions or to represent + and -. So with 4 types of commands (and 4 separate transmissions) you can transmit variables up to "9999" or "+/-999".

[detail . . .]
Since Unit Codes really have a range of 1-16 you could use this to transmit even larger values - with 2 transmissions you could transmit and digit up to 255. However I choose not to do this because the CM17A is transmitting to the same (TM751) receiver that I use to receive form a motion sensor. The motion sensor uses Unit Codes 1 and 2. So in actuality I offset the digits by 5, leaving the first 5 Unit Codes. (Two for the motion sensor and 3 reserved.) I'm sure there are other methods you can use to transmit values, but this works fine for me.

So much for theory!
Since the CM17A is wireless, it's a nice idea to make the whole thing battery operated. There are techniques to use with the Arduino to conserve battery power. I used one that combines "sleep" mode with the "watchdog timer" There is a good example of this here. The idea is to have the Arduino in low power sleep mode, wake it up every now and then, and have it read and transmit the temperature before going back to sleep. The example cited has a maximum sleep time only 8 seconds, but on waking, a variable can simply be incremented and skip sending until say 10 wakeups have occurred. Mine sends the temperature about every 2 min. (The less often you send, the longer your battery lasts.)

I used the DS1621 temperature sensor. It's I2C and simple to connect. You will find examples of how to use it on the Arduino Forum.
I put everything in a waterproof box. A word about the picture. You can see the DS1621 temperature sensor on the "spring" ribbon cable. The green square on the right is the CM17A with it's jackets removed and covered with heat shrink tubing. The Arduino (ATmemg128) board is a custom board I made that includes a boost circuit so it only needs 2 AA batteries. You can use any Arduino and use 3 AA batteries instead.

On the temperature receiver side (the X10 Book in my case) I look for commands from the dedicated temperature House Code. When I get one, I determine which digit position it represents by the command code, convert the Unit Code into a digit, and store it in a global for that digit position. It's OK if a digit is somehow missed, it's likely to be picked up from the next transmission. When I want to log or display the temperature (periodically or using the TV Remote) I simply multiply the values in the various digit positions to get the current temperature.

Here's a short video . . .

Thursday, May 21, 2009

The X10 Book

The X10 Book is the must useful project I've made with the Arduino. Again, I've already posted a lot of details on this elsewhere, so here I'll write about it from a different perspective (I hope).

The project is based on the Arduino interface to the PSC05/TW523 (see below) and an experiment on encasing electronic gizmos in a book.

It provides me with all the X10 functionality I had with with ActiveHome and a lot more. (I now use my CM15A only as a whole house transceiver.)

At the risk of repeating myself, for those who haven't read the links, here is a partial list of what it does:
  • Displays each X10 command that comes across the power line on a scrolling display. If it's a "known" house / unit code, it displays a friendly name like "Basement Light - On".
  • Stores a list of timed events like "turn on this light at 8PM, off at 10PM, on again at 11PM, etc.".
  • Checks X10 commands on the line, and trigger a "macro" if required - i.e "if garage Door open more than 10 min. display a warning, and trigger the sounder".
  • For defined X10 commands, light an LED and/or open or close a (10A) relay.
  • For selected commands, log the command and the time to an SD memory card that can be pulled and read by a PC.
  • Accept "special" X10 commands that provide variable data, such as temperature, from another X10 project I created (see next post). Note, these are not X10 "extended" commands.
So your saying "that's cool, good for you, but what about me?". Here is where I hope to be able to help by explaining the build process and offering a few tips. Since it's likely I don't know you, I'll imagine someone who is interested in X10, but has little or no experience with Arduino, some electronics, and an interest in programming. You are also patient, and motivated to help yourself. (Yuck, this is going to be long!)

The key things to remember, are that you don't have build all this functionality, you don't have to build it all at once, and you can build other functionality. You also don't have to build it the same way. For example you can use an LCD display instead of a scrolling LED matrix - much easier. If you use an LED matrix, there are several ways to drive it (i.e. MAX7221 vs "595's").

Another suggestion is to make the project in steps. Learn about and complete and test each step before going on to the next. This is where I think I can help the most. Below is the sequence of steps that I suggest you take to create an X10 controller with the Arduino.
  •  Get comfortable with the Arduino. Read the tutorials, join the forum, ask questions there, do some basic projects that interest you. (Get an Arduino with an ATmega328, you will need the room.)
  • Make a simple clock. I suggest a real time clock (RTC) based on the DS1307 chip. (IMO it's the simplest.)
  • For the clock, you will need a display. If you want a display on your controller, consider what you want there when considering your options. You have lots of options, but consider not biting off more that you can chew, you can always beef it up later. (i.e. A single color LED matrix is much simpler than a 2 color matrix.)
  • If you want a TV remote, figure out how to build that. I suggest a Sony protocol with a universal remote. For mine, I picked an interface that was interrupt driven rather than "blocking".
  • If you are going to display a lot of text, and to hold timed events, etc. get familiar with the I2C EEPROM.
  • This can be done earlier, but add the X10 stuff from here and here.
  • Recently, others have created some nice libraries that let you write to an SD card if you want a log.
  • Along the way, you have learned a great deal about electronics. Here is the schematic / wiring diagram for the X10 Book.
I'll add more to this list in future edits.

Sending and Receiving with the PSC05 / TW523

For a long time, the Arduino community had a library (written by Tom Igoe) that would interface the Arduino to the PSC05/TW523 so that it could send X10 commands. (available here) Since I was already wirelessly sending commands via the CM17A, I never took much interest in it.

But then I thought if you could also receive commands with the PSC05/TW523, you could pretty much make your own X10 controller and replace the ActiveHome SW and the CM11A/CM15A hardware.

Again the web provided a lot of the great detail on the protocol that enabled me to write an Arduino driver to receive commands with the PSC05/TW523. I created an example sketch and wrote a lot of background and posted it on the Arduino Playground here. Since the receive driver can coexist with the send library, the Arduino now has a complete interface with the PSC05/TW523 that allows you to send and receive X10 commands.

[3/30/2010] Thanks to Creatrope, a beta of the combined X10 send / receive library is now available - you'll find it here. [1/5/11] Creatrope site down. You can use the separate X10 transmit & receice libs or check out ThomasM's library here

The Playground article should tell you all you need to know about how to use this software, so I won't go into it here. Just to say that the Arduino is always looking for any X10 signal on the powerline at every zero crossing of the AC. When it gets one, it sets a flag, and fills out globals for the House Code, Unit Code, and Command that are used by your program.

With this complete, I was able to make my own X10 controller called the "X10 Book" that I will write about in my next post. 

Edit Nov. 2, 09: Based on a comment by Phil, here's a link to an Ap Note from Microchip that describes how to use a PIC to essentially replace the PSC05. It would be great to port it to ATmega chips. Thanks Phil!

Edit Feb. 23, 09: I've received some very good feedback from Johannes related to changing the send and receive software to have reliable communications using 50Hz line frequency. (He uses an "XM10" X10 module instead of the PSC05 / TW523 for 220V 50Hz.) It's simply a matter of changing 4 #defines - 2 in the X10.lib (for sending) and 2 in my code (for receiving).

In the source for your X10.lib, in X10constants.h change:
#define BIT_DELAY from 1778 to 2133
#define BIT_LENGTH from 800 to 900

In my example for the X10 Receive function, in PSC05.h change:
#define OFFSET_DELAY from 500 to 800
#define HALF_CYCLE_DELAY from 8334 to 10000

Thanks Johannes! I'm sure others will find this helpful.

Wednesday, May 20, 2009

The CM17A and Arduino

My first X10 project was to create an interface between the Arduino and the CM17A (aka "Firecracker"). The CM17A is a dongle that wirelessly (RF) sends X10 commands to X10 RF receivers. The receivers then send signals down the house wiring to control lights and appliances.

After many hours of Googling, I could not find any examples of an interface other than some written in assembler. However, I did find lots of good information about the protocol that is used to talk to the CM17A. With that I was able to write a small program ("sketch") that demonstrates how to have the Arduino talk to the CM17A. I wrote up an article with the explanation and example and posted it on the Arduino Playground here. It should tell you all you need to know.
I made a short video of a simple example where a TV remote is used to have the CM17A send X10 commands to a light.

Don't let the custom boards and led matrix scare you. There are much simpler ways to use the CM17A with Arduino. In a future post I will describe how it can be used to send the temperature to a home made X10 Controller.

What is Arduino? / What is X10?

It's likely that most people reading this will know a lot about either Arduino or X10. (If you know about both - you're in good shape. If you don't know about either - I'm surprised you're here!) In any case, I won't go into detail about either. You can learn about Arduino here, and Google will give you lots of info on X10.

In short, the Arduino is an inexpensive (~$30) microcomputer that you program in C/C++ that has input and output pins that connect to real world devices. I choose the Arduino because of it's popularity, price and wonderful support.  It's likely another type of microcomputer can be used for these projects, but I'm only comfortable discussing the Arduino and the C language.

X10 is a home automation system that typically sends signals down your power line to remotely control lights and appliances. There are many types of modules one can get to do various things. While X10 is old technology, it still has some key advantages regarding remote control. Primarily, it is the cheapest and safest way I know of to control things that plug into the power line. 

So what are the advantages when you combine the Arduino and X10? Here is a diagram where I tried to show X10 and Arduino working together.

From an X10 user's perspective, the X10 world now becomes your oyster. You are no longer bound by a PC and the limited functionality and cost of commercial software. You can create entirely new functionality while replacing your ActiveHome SW and your CM11A / CM15A interface device.

From an Arduino user's perspective, you gain an option for wireless remote control at a much lower cost per controlled device than say XBee and roll your own triacs. It's also a hell of a lot safer than mucking around with line voltage. The modules are UL approved and cost as little as $6 on Ebay  (link just an example).

Obviously, all of the above is just my opinion and points can be argued. You can fault X10 for not being reliable. Personally I solved most of my issues with a XPCR coupler /filter / amplifier. For those in 220V land, X10 charges an arm and a leg extra for the 200V models. See this website for a cheap way to convert most 115V modules.

OK, enough background.

Code Examples

In the posts above, I have provided links to the source I wrote for all examples.

If you are interested in example code for other areas of these projects, you can contact me at:

Well, here we go!

Much of what I post here, at least in the beginning, I have already posted in other locations. For example:
As I describe each project I'll include material from these links in addition to new material. As to how well I'll describe each project, that depends on you. Until I get questions, I won't go overboard. However, if I do get questions I will add the detail that covers them.

Welcome! - and I hope you find this interesting and helpful.

BroHogan (aka John)