Wireless Outlet Remote Control…Control

In the near future, Scott and myself will be taking a crack at Adafruit’s Arduino-powered immersion cooker. I’ve looked at this tutorial a few times, and I have now amassed enough of the parts as a result of other projects to make this a not-very-expensive build.

There was one wrinkle, though. This project requires the control of a 120V outlet with an Arduino. The recommended Power Switch Tail is, at this time, difficult to come by. I’m not sure if it has been discontinued or not, but lead times and cost are significant on the sites that I’ve visited. I feel that I have the skill to throw together a relay and some cut-up extension cord, but if I burn my house down, it would kind of be a hard sell to the insurance company. So another solution to switch on and off an ‘analog’ crock pot was needed.

Some time ago, I picked up a set of three outlets that can be toggled on and off with a small RF remote. I thinks to myself, if I can toggle a button on the remote with a simple circuit, I have the answer to the 120V control wrinkle. Here’s what I came up with:

RemoteBuild_ClosedSideView

RemoteBuild_TestSetup

By soldering on two wires to either side of the button for outlet 3, I was able to bring those two points out to accessible female headers:

RemoteBuild_Prebuild

RemoteBuild_PCBunderside

RemoteBuild_OpenSideView

So now, if I were to short those two headers together, the circuit completes and the button is “pushed.” That’s the first step. Now I need a way to “short” that connection that can be controlled by a digital output pin. A small transistor works pretty well for this. I had a 2N3904 lying around. A 10K resistor and some prototype wire later, I had this circuit implemented:

Circuit

RemoteBuild_TestCircuit

I was really happy with this solution. The remote is still completely usable. When we decide to give the Adafruit project a go, all we need to do is plug in the remote. And for future projects, modifying the remote to allow control of the other two outlets wouldn’t be too difficult. 

I suspect there will be some slight code modification required for the final project, however. In the test circuit, the button was toggled by raising D13 high for a 300ms pulse. So there’s not a direct 1-to-1 relation between the control pin being high and the heat being on. I don’t think it will be too big a problem, just something to remember to do.

From a safety standpoint, this is probably the best option for the immersion cooker build. The mains power control is about as isolated from the control circuit as you can get. All the same, when this thing is running, it won’t be left unattended. After all, something that I built will be controlling something with a heating element. Common Sense is advised.

-Dan

Dial-A-Song: Part 2

For part two of the Dial-A-Song project, I’m going to go through the hookup of the phone’s keypad so that it can act as an input to the Raspberry Pi.

The first thing to do was remove the short ribbon cable that came on the keypad and replace it with something a little longer so I could more easily hook it up to the Pi. Here’s the old ribbon cable:

Dial Pad and Tone Generator

And now with the new, more colorful, cable:

Keypad Wiring

On the other end, I attached a 2×5 IDC female header (I didn’t have a 2×4, so there’s a couple wasted pins). This is what will eventually connect to the Pi interface board I’ll create, but for now I mocked up a breakout board (the green perf-board) so I could connect it to a breadboard along with Adafruit’s great “Cobbler” kit.

The keypad’s internal wiring is setup as shown below (which the red wire being pin 1 and increasing to the left, from the image above):

  5 6 7
4|1|2|3|
3|4|5|6|
2|7|8|9|
1|*|0|#|

Most matrix keypads are very similar so, the keypad pins should be connected to the Raspberry Pi GPIO as follows:

Pad | Pi
________
1   - 25
2   - 24
3   - 23
4   - 18
5   - 22
6   - 17
7   - 4

Now for the software. Originally, I was going to use a library designed for specifically this purpose. It did exactly what it said it would with the exception that it uses polling to detect the keypads. This works, but required a significant amount of the CPU resources to get any decent response time. Often around 80%. This was not acceptable.

So, I decided to try converting the library to use the interrupt capability of the RPi.GPIO library that comes pre-installed on Raspbian. It took a little fiddling because the Pi GPIO pins are really susceptible to noise making button debouncing a real issue. But in the end, it works quite well:

#!/usr/bin/python
 
import RPi.GPIO as GPIO
import time

class keypad():
    def __init__(self, callback):
        GPIO.setmode(GPIO.BCM)
        self._count = 0
        self._inInterrupt = False
        self._callback = callback

        # CONSTANTS 
        self.KEYPAD = [
            [1,2,3],
            [4,5,6],
            [7,8,9],
            ["*",0,"#"]
        ]

        #hook the rows (1,4,7,*) to these GPIO pins
        self.ROW         = [18,23,24,25]
        #hook the columns (1,2,3) to these GPIO pins
        self.COLUMN      = [4,17,22]

        self.__setInterruptMode()

    def __colInt(self, channel):
        time.sleep(0.05) #give it a moment to settle
        if GPIO.input(channel) > 0:
            return

        #remove interrupts temporarily
        for c in range(len(self.COLUMN)):
            GPIO.remove_event_detect(self.COLUMN)

        #get column number
        colVal = -1
        for c in range(len(self.COLUMN)):
            if channel == self.COLUMN:
                colVal = c

        #continue if valid column (it should always be)
        if colVal >=0 and colVal < len(self.COLUMN):

            #set rows as intputs
            for r in range(len(self.ROW)):
                GPIO.setup(self.ROW[r], GPIO.IN, pull_up_down=GPIO.PUD_UP)

            #set triggered column as low output
            GPIO.setup(channel, GPIO.OUT, initial=GPIO.LOW)

            # Scan rows for pushed key/button
            rowVal = -1
            for r in range(len(self.ROW)):
                tmpRead = GPIO.input(self.ROW[r])
                if tmpRead == 0:
                    rowVal = r
                    break

            #continue if row is valid (possible that it might not be if the key was very quickly released)
            if rowVal >= 0 and rowVal < len(self.ROW):
                #send key info right away
                self._callback(self.KEYPAD[rowVal][colVal])
                #This avoids nasty boucning errors when the key is released
                #By waiting for the rising edge before re-enabling interrupts it 
                #avoids interrupts fired due to bouncing on key release and 
                #any repeated interrupts that would otherwise fire.
                try:
                    GPIO.wait_for_edge(self.ROW[rowVal], GPIO.RISING)
                    self.__setInterruptMode()
                except RuntimeError:
                    pass
                
                return

            else:
                print "Invalid Row!"
        else:
            print "Invalid Col!"

        #re-enable interrupts
        self.__setInterruptMode()

    def __changeWrapper(self, channel):
        #if there is already another interrupt going on (multiple key press or something)
        #return right away to avoid collisions
        if self._inInterrupt:
            return;

        self._inInterrupt = True
        self.__colInt(channel) #handle the actual interrupt
        self._inInterrupt = False

    def __setInterruptMode(self):
        #set the first row as output low
        #only first one needed as it will ground to all columns
        for r in range(len(self.ROW)):
            GPIO.setup(self.ROW[r], GPIO.OUT, initial=GPIO.LOW)

        #set columns as inputs and attach interrupt handlers on rising edge
        for c in range(len(self.COLUMN)):
            GPIO.setup(self.COLUMN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            GPIO.add_event_detect(self.COLUMN, GPIO.FALLING, bouncetime=250, callback=self.__changeWrapper)
     

    def cleanup(self):
        GPIO.cleanup()
        print "Cleanup done!"

It's super simple to use as you can see from the code below. Instantiate the class with a callback function and that function gets called when there's a keypress on the pad. Just note that the callback will be running on the context of a different thread from the main thread. While it uses interrupts, RPi.GPIO cheats a little bit and the interrupts are actually running on background threads and so will the callback. Not usually a big problem but something to be aware of.

import time     
if __name__ == '__main__':
    def keypadCallback(value):
        print "Keypad: " + value

    key = keypad(keypadCallback)

    try:
        while True:
            time.sleep(1)

    except KeyboardInterrupt:
        key.cleanup()

You can grab the full library and find any updates to it on GitHub.
That's all for now. Check back soon for more progress on Dial-A-Song!

3D Modelling Software Review #1

Hey Igors, Miles here.

Yes, I’ve decided that fans of Maniacal Labs are hereby dubbed Igor, regardless of gender (I suppose female Igors might want to be referred to as Igorina, but I will allow them to petition for this at a later date [Fans of the great Sir Terry Pratchett, REJOICE!]).

The other maniacs and I have decided to do some reviews of modelling software that is available as freeware out there on the internet tubes. We’ll be using each of them to do a small project or two and giving our opinions on them, plus any silly puns we feel like adding in.

First into the gates is AutoDesk’s 123D Design application on an iPad. I believe it requires at least iOS 6 to run, making it unavailable on first generation iPads. I used a 3rd gen iPad for my project.

THE PROJECT

I am a huge fan of board games, but the boxes always frustrate me. As a whole, it seems that the manufacturers want a game to have a big, eye catching box to make it more noticeable, but when you open up a huge box, most of the space is taken up by a cheap vacuum formed plastic insert. Some of these games take up huge amounts of space, especially when you add in games with multiple expansions. Like Dominion. Have you heard of Dominion? It is a card based, deck building game with many additions to the base game. And I own all of them currently available. After getting tired of carting around several cubic feet of what was mostly empty boxes, I found a tutorial on how to fit all the different cards from the different expansions into one box. Originally, I did this, but the box was heavy and I worried about it breaking and making a huge mess. Later, I got a plastic photo storage box, and followed this tutorial, making the boxes out of heavy duty card stock. I’ve never been happy with the home made card stock boxes – it’s hard to get them out, the cards don’t fit well, cards easily get stuck in the bottom. 

So many cards

All of the dominion game that I currently own

Now you can see all the cards!

An open view of the box

Wouldn't it suck to drop this?

I have no idea how many cards are in this

So I decided to see about modelling a new box, to run 123D Design on my iPad through it’s paces.

THE PROCESS

The first thing I needed to do was measure the cards, to make sure I had enough width for them to fit correctly. Also, I needed to measure the small holder box, so it would fit into the large overall box. All in, the box would need to be 2.75″ square on the end and 6.25″ long with 1/8″ thick walls. I wanted some holes in the bottom to unstick fallen cards too.

Yes, I know the calipers are off in this photo.

Digital Calipers make measuring easy!

Orange is the company color.

The final product

THE REVIEW

THE GOOD:

The app was relatively easy to use. The icons for functions were easy to read and symbolized what  they did. Like, the align function showed two different rectangles side by side, each with one edge lined up with the other and a line emphasizing this.

Most of the functions are pretty self explanatory as to what they did. Between a little bit of trial and error and the help function, it’s pretty easy to figure things out.

The free version of the app requires you to register, and gives you some cloud storage space to upload your models. Mine can be found here.

Portability! You can model stuff while watching TV! Commuting! Sitting on the toilet! Wherever!

(I did not model this in the bathroom.)

THE BAD:

The camera is a bit on the clunky side. Especially when you move it with your fingers, using pinches and swipes. There’s also no way to easily orient it to a view (like front, back, left, etc.) In other Autodesk programs, there is a ViewCube that lets you do this, and it should have been included in this.

Metric. Only Metric. Everything I inserted came in at 5cm. Cubes? 5cm on a side. Cylinders? 5cm height and diameter. I couldn’t find a way to switch it into imperial units. This is only a problem in a few countries, but I live in one of them. Wouldn’t be much of a problem, what with Google conversions between inches and cm, but coupled with the next issue of… Wait for it…. Wait…

There’s no way to dimension anything. You can only scale things. From the aforementioned 5cm cube, I needed a 2.75″x2.75″x6.25″ rectangular prism. To do this, I had to scale little old Cubey up and down by percentages to get what I needed. For those interested, I had to scale height and width up by 39.7% and length up by 217.5%

Void forms are a tricky in this. Once you use the cut function, you cannot go back and change it. No take backs. This can be very frustrating when you want to move a hole in a model up half an inch, because you measured something wrong. Strike that. Not frustrating, infuriating.

ALL IN ALL

The iPad app seems to be more of a support tool for the desktop version. It seems to rely on the portability of it to make up for some of the strangeness of the controls. I think it would be best used in a meeting or similar to show a model to someone else, instead of building something from scratch.

When I review the desktop application, I’ll see how easy it is to change stuff between the two clients.

To quote Chris Hardwick: Quemments? (Question + Comment = Quemment)

Dial-A-Song: Part 1

Earlier this week, we got the great news that we have been accepted to the North Carolina Maker Faire. We’re absolutely ecstatic to get to share some of our projects with the public but it’s also been a great push to get some other projects done. I’ve had this particular project bouncing around my head for a couple of years now. I call it Dial-A-Song.

Much of the inspiration came from They Might Be Giants, who used to leave recordings of their songs on their answering machine, which could be listened to by calling (718) 387-6962. So, I wanted to combine a little of that with a phone tree menu to give the feel of calling in to a phone service to listen to music of your choice. Yes, it’s a little ridiculous, but why else would I be building it.

As a way of documenting the project and an extra push to keep working on it, I’m going to be writing up a build log in several parts as the build progresses.

So, first, the desired specs:

  • Completely enclosed in an old phone
  • Music plays over the headset speaker.
  • Raspberry Pi as the brains
  • Automatically index all music
  • Choose 10 random songs when the phone is picked up and make them available via the menu
  • Text to speech for the menu
  • Network capable for remote control

In part 1, I’ll deal with the phone itself. I really wanted to use an old pay-phone, but good condition models were well over $200, much more than I wanted to spend. So I went for the next best thing:

The Red Phone

Who doesn’t want a big red phone on their desk? Only important calls come over a red phone. I found this one on eBay for about $20 and it’s fully functional… now let’s gut it.

I started by removing the two large, flathead screws on the bottom metal plate. Once out, the entire top casing simply lifts off. As you can see from the interior picture, there’s really not much to these old phones. One PCB on the bottom, another beneath the dial pad, and the ringer assembly, which had to go. I would have loved to keep the ringer intact and actually use it but it takes up too much space and older phones like this run on a higher voltage than I would be working with. They typically run at 48V DC when idle, but a 90V 20Hz AC current is required to actually make the ringer work. So, out it came.

The main board had to go next, as it is really of no use. The only things from the phone I plan on using are the dial pad, the handset and the phone line input (for power and network). I was surprised to see how little was actually on the main board and that it was mostly there just to hook up all the other components of the phone… with removable spade connectors no less. This was definitely a hand-assembled product. The truly don’t make things like this anymore! The only active components on this board are likely for the ringer since it’s the only thing using AC current, making the small transformer and diodes a give-away to their purpose. No matter… to the parts bin it goes.

Dial Pad and Tone Generator

Next to come off is the dial pad assembly. Here’s where the electronics actually get a little interesting. The IC chip on the left is the HM9102C tone generator, responsible for generating the DTMF tones that make a “touch tone” phone system work. The IC reads the dial pad key presses and generates the corresponding tone that gets sent over the phone line. Each row on the dial pad represents a low frequency tone and each column a high frequency. So when a key is pressed, the chip creates a single tone from the two frequencies represented by the row and column of that key, hence the term “dual-tone, multi-frequency” or DTMF. But I don’t need this either – I’m just going to fake the tone sounds in software since they aren’t needed – so off to the parts bin with this board as well.

The dial pad, however, I do need. Fortunately, a little probing with a multimeter shows that it’s wired up like any other matrix keypad ever made. Even better, there’s already a python library for the Raspberry Pi that handles all the heavy lifting of reading the key presses. More on hooking this up in a future post.

Hang Up Relay

Next is the hang-up mechanism. It’s actually much more complex than I was expecting, as it includes 3 separate internal relays. The first (left most) has two switch contacts, one is open when the mechanism is down and the other when it is up. The middle relay opens the circuit when the mechanism is down whereas the right-most relay closes the circuit. Each obviously has a specific purpose, such as connecting the phone line to the handset speaker and mic. But I’m not sure which is which. Fortunately, I only need one of them and don’t really care which direction it goes. I just need to detect a state change via one of the Raspberry Pi GPIO pins and handle it accordingly in the software.

Phone Handset

Finally, for this post anyways, is the handset itself. I was a little surprised to see that it had a built in volume control (the wheel in the middle of the handle)… I’ll have to see if there is some way to actually make this work. Unfortunately, I won’t be able to use the volume circuit as is, or the speaker, because they are both designed to run on 48V DC. Whereas I plan to just connect it all to the 1/8″ audio jack on the Raspberry Pi. The major problem with the speaker is that, as a quick check with my multimeter showed, it has an impedance of over 100 ohms! It makes sense given the voltage it is supposed to run at but that is huge compared to the typical 4-8 ohms of modern speakers. So, instead, I’ll keep the wiring but replace the speaker with one from an old pair of headphones. Likely with both the right and left signals going to the same speaker.

That’s all for now. As this project continues I will post new articles following the progress. Stay tuned!