Capacitive Touch Testing with bcard

While I think a little bit more about why I can’t seem to get V-USB to work with hdctrlr, I’ve gone back to working on my PCB business card, bcard.

The ATTiny10 is basically impossible to do meaningful development on, so I decided to make a breakout version of my business cards that use an Atmega168 instead. That way, I can get data over serial, etc. to develop a decent sketch of a program that I will then implement in assembly on the Attiny. Of course, when I get to that point, I could always disassemble the Atmega program and use that as a template for the Attiny program, but I’m far too much of a masochist to do something like that; I’ll be rewriting it from scratch in order to get as much power savings as physically possible.

Anyways, here’s a quick photo of the capacitive breakout board that I made:

The basic idea of this style of capacitive touch sensing is that there is a parallel RC circuit like this:

First, I set the CTRL pin to be an output so that it can charge up the capacitor (which is the interlocking bars in the image above). Then, I change CTRL to be an input pin, so that it has infinite impedance. This means that the circuit just looks like a resistor and capacitor in parallel, connected to ground. So, the capacitor will discharge through the resistor while the input pin monitors the voltage. We don’t even need CTRL to be an ADC; all it has to do is look for when the input goes from 1 to 0.

So what happens when we put our finger on the pad? Well, this is where it gets fun. When this happens, you’re changing the dielectric constant of the capacitor on the board, increasing the time constant (i.e. increasing the time it takes to discharge). This looks somewhat similar to a design by Michael Ciuffo, a friend of mine, but his sensor is being actuated on the change in resistance when you put your finger on a sensor whereas I’m looking at the change in capacitance. So, with his design, when you put your finger on the pad, the time constant decreases, whereas with mine, the time constant increases.

Screw it, let’s do it in pictures. I like pictures.  (In this example, I model the change in the dielectric constant as an added capacitor).

And how does it look in real life? Well here’s two photos of my scope measuring the CTRL pin for a sensor. The first shows the normal waveform (I charge up the cap with the CTRL pin and wait a while, then let it fall) and the second shows what happens when you put your finger on the sensor.

I based this design on inspiration from this site.

So, how do you get useful information with a microcontroller? It’s really just a few lines of code. Let’s say that you’re using PB0 as your CTRL pin.

[cc lang=”c”]
uint8_t counter = 0; // we’ll count how long it takes the pin to drop back to 0 here

DDRB |= (1<<PB0); // set CTRL to drive a voltage
PORTB |= (1<<PB0); // apply logic 1 to charge the cap
_delay_ms(PIN_ON_DELAY); // charge for a little while (this can be really small)
DDRB &= ~(1<<PB0); // set CTRL to input mode
PORTB &= ~(1<<PB0); // get rid of driving voltage

while ( PINB&(1<<PB0) && counter <= 255 ) {
// each time, we check to see if PB0 has gone back down to logic 0. If it hasn’t, then we increment counter (up until the point where it could overflow)
counter++;
}
[/cc]

That’s it! Drive the pins, stop driving them, and see how long it takes for them to change back.

So here’s a video of some live plotting of data I took (see video description for the moment on details).

In this example, I let counter be a 16-bit value instead of just an 8-bit one so that I would have more resolution, but in practice, just using an 8-bit counter is sufficient.

To measure a press versus a not-press, I start by establishing a baseline — basically when the micro first starts up, it takes a bunch of samples (I assume that the user doesn’t start by pressing the pads). It then starts performing readings. If the reading is significantly off baseline, then it registers it as a press. If it’s not significantly off, then it updates the baseline by averaging in the new value. This allows the sensor to react to minor changes in the environment around it.

With respect to bcard, I actually have two sensors (you can see that there are two sensing pins). So, I wrote a short algorithm that looks for a press on the first one and then a press on the second one to indicate that someone swiped their finger over the pads. I should have a full code implementation done fairly soon.

I really have stopped liking my current bcard design so I’m probably going to do a complete redesign and rerouting of it soon. I really want it to look aesthetically pleasing and I’m definitely not there yet. I think I’m going to make the swipey thing vertical instead of horizontal. I may also adjust the placement of the LEDs.

Testing the scroll wheel through serial

In this experiment, I send a command (either “< " or ">“) to indicate which way to scroll using the initial signal processing algorithm I designed. It guesses at which phase leg the motor is currently closest to and compares it against the previous phase leg and then decides whether that means it should scroll left or right. All this code is available on my git repo.

I then wrote a simple python program that uses PyGame to send either a left or right scroll command based on the input it receives over serial.

I currently am missing some parts to complete the V-USB setup, but when my Digikey order comes in, I should be able to finish it.

Hard Drive Scroll Wheel

With all of the failures I’ve had with bcard lately (I’ll write about them at some point), and with the design of my plasma speakers progressing rather slowly because I’m trying to develop a Class D power supply that can be audio modulated and accept a varying load (each speaker will be powered by a chain of Class D and Class E amplifiers), and because I’m moving soon, I’m not implementing any kind of room automation system until I’m somewhere more permanent.

So I grabbed a dead hard drive, opened it up, took out the controller board, and turned it into a little turntable.

Hard drive disks are typically spun by a standard brushless DC motor with 3 or 4 terminals. This one happened to have 4, so it was a motor in the wye configuration. I measured the resistance between each terminal and found the common one. Then I tacked on a few wires so that I could plug the device into my breadboard.

The black pin was common and each of the colored pins was an end of the motor, so the motor can be drawn like this:

When spinning a BLDC a wye-configured BLDC motor, you will see a back EMF voltage between the common terminal and each of the end terminals in turn. So, for example, with this motor, if I spin it clockwise (against the direction of the spindle), I can see a voltage on the yellow, blue, and green pins in that order. If I spin it counter-clockwise, then the order is yellow, then green, then blue.

This means that by measuring the voltage of each pin and watching the relative phase of the changes, we can actually get the rotational speed of the motor! Then, we can turn that into a scroll wheel or something useful. My friend Scott had done this a while back by hooking the hard drive motor up to an op-amp and then to an Arduino, which spat out serial data. He then wrote a program that emulated mouse events based on the data it received from the Arduino.

I wanted to produce a much more direct version: using V-USB to actually make a mouse device that the computer would recognize without any special software. However, first, I wanted to get an idea of what the data actually looks like when I spin the motor.

So I wired up a wonderfully messy breadboard.

The actual design is very simple: the common terminal of the drive is connected to ground and each of the motor terminals is connected to an opamp in the non-inverting configuration with a 10K/220ohm amplification ratio. The outputs of each of those 3 amplifiers go into 3 ADC ports on an Atmega168. So the schematic looks like this:

The Atmega simply reads each ADC value, and then sends a packet of data over serial that starts with “:” and has the 3 ADC samples (I’m going to call them yellow, blue, and green). Then, it waits 50ms and does it again.

Next, I borrowed the code from the second example on this page. It performs live plotting with Python! I modified the code to grab data from the serial port and interpret the packet. Eli’s code only works for a single line plot, so I also modified it to support an arbitrary number of data inputs. Finally, I boosted the refresh time to 50ms so that it would about match the speed that the Atmega was sending packets.

Here’s a slow scroll:

And here’s a fast one:

Now comes the fun part: signal processing. For the first design, it’s obviously easiest to have a state machine that looks at the progression of phases and watches for the signal crossing a certain threshold. Scott’s design amped the hell out of the signal so that it would appear as a digital input. By using a threshold crossing, I’d be creating a similar design. With a little low-pass filtering, I can also guard against false scrolling. I plan to get that working in serial first, and then I’ll implement the V-USB library to create a mouse device. In the future, I can work on nicer signal conditioning algorithms that provide more sensitivity at lower speeds (by looking at the derivative of the signals perhaps) and faster scrolling at higher speeds.

This weekend, if my design works reliably well, I’ll create a small PCB and hopefully enclose it nicely.

My work so far is located here.

Yet another slight redesign of bcard

I think this is the design that’s going to work. I found side-mounted LEDs on Digikey that are pretty cheap as well as a very minimalistic battery clip that is surface-mounted.

The etch was very clean:

I also bought some DIY solder mask off of eBay. Seeedstudio used to sell it too, but stopped carrying it. We’ll see how it works; I have high hopes for it though. If I can get it to work, then the solder paste reflow technique may work really well for this design.

2nd prototype of bcard: a little better, but not much

I redesigned bcard. Here’s what it looks like now:

After discovering that it’s basically impossible to vertically embed SMD LEDs into a board, I decided to try to see if it would be possible to use 3mm LEDs instead. So I switched those footprints. I also made the majority of the traces 20 mils thick to improve etching. Next, I moved to a 2-sensor design, so that theoretically you swipe your finger across a newly designed capacitive touch sensor and the lights will pulse. I like the design of the new sensor better; it fills up the space much more nicely. I had to reroute the entire board to make this new design work.

I kind of like the swirling pattern of the traces as they approach the micro. I originally intended to rotate the design so they wouldn’t swirl, but after looking at it, I kind of liked the design.

Anyways, I went to MITERS to etch it today. There were some good results and some bad ones.

First off, I completely forgot to include the outline of the battery holder cavity on the board outline, so I had to eyeball that.

The photo above shows my attempt to solder down the SMD components. I couldn’t find the really fine tip that I usually use and I was working with thick solder, so the result was very messy. I think that for production, I’m going to need to use the hot plate method.

If I use the hotplate method, that’d be a good time to try DIY soldermask. I’ve found it online; I think it might be fun to try.

Here’s a shot of the new battery holder, which uses copper foil. Copper foil does not work as a battery holder. I’m pretty convinced that I will not be able to make a reliable button cell battery holder, as much as I wanted to. So I’m probably going to buy one and add it to the board because I have no other choice. 🙁

The LEDs were a shitshow too. I’ve given up trying to embed LEDs into a board. It sounds easy, but it’s extremely difficult to do reliably. I’m going to have to figure out what else to do to make the board cool. This might mean major redesigns. Hopefully it won’t.

All in all, though, this is a completely usable prototype and I will attempt to do the programming for the touch sensing on it. Implementing the swipe motion probably won’t be too difficult; it’s a very simple state change. Hopefully I can take advantage of power saving features. I have some wires coming off of the microcontroller for programming as well as tabs for VCC and GND.

So, this failure wasn’t quite as bad as the last… I’m going to focus on programming the damn thing for a while. Then I’ll get back to figuring out how to resolve the remaining issues. Moral of the story, though: it’s basically impossible to do repeatable custom stuff on a PCB. My embedded battery holder idea was great in theory, but almost impossible to implement in reality. Embedded LEDs just won’t work right. Even if I could embed them, they aren’t lighting the card up enough.

Added MAX232 Breakout Board

Here’s a simple MAX232 breakout board for a breadboard, à la the FTDI-based board I made a few days ago. I haven’t etched it yet, but I would be surprised if it didn’t work.

The schematics and layout are available on ubbcom’s GitHub repo.

ubbcom Works!

Got it working very quickly after a couple of redesigns.

My first etch came out pretty iffy, as you can easily see:

So, I redesigned the board a bit and transferred it.

Ah crap, forgot to mirror my transfer. Let’s try that again:

Nice. The only sketchy trace was the one that connects to the RXD line, but I tested it and electrically, it’s okay. So, I assembled the board and planned to find a broken USB cable and solder it onto the 4 holes at the top of the board.

Unfortunately I couldn’t find a USB cable, so… I made my own by taking a random piece of 4-conductor wire and soldering a PCB USB connector to it.:

Yeah, that didn’t work so well. My computer recognized that a device was plugged in, but failed to talk to it. I think it might have had something to do with the fact that the cables weren’t stranded. Or, I may have killed the FTDI chip because I applied a fair amount of heat when I soldered it.

So, it was back to the drawing board. I designed a new board with a built-in USB connector so that I could just connect it to my computer by plugging it in directly or by using a USB extension cable.

I’ve discussed the MITERS etching process before. It’s pretty great. Basically, the steps are:

  1. Print out the board design onto glossy paper with a laser printer.
  2. Sand down the board you want to etch a little bit to roughen up the surface.
  3. Clean the surface with acetone.
  4. Put the printed design and the board together and stick it through the laminator.
  5. Remove the paper quickly under water. I discovered the technique is to scrub the paper away rather than to peel it; the transfer comes out usually nearly perfectly.
  6. Throw it in ferric chloride and swish it around for 10 minutes.
  7. Wash with acetone.

I wired RXD and TXD together and tested it out. It worked!

Afterward, I put some male headers onto the device and stuck it in a breadboard to create the demo video above.
I’m pretty sure the entire device can operate with just the FT232RL alone. The rest of the components on the board range from somewhat important (ferrite bead, filter caps) to purely asthetic (debug LEDs). I bet you could get rid of it all and it’ll work fine. It’s more expensive than a typical MAX232 design (which probably totals about $2.50), but it doesn’t require RS232, which is kind of a plus. I’ll probably make a cute little MAX232 breakout board in the future as well, though.

ubbcom: Etching Really Small Things

It’s almost time for me to graduate, so I decided to take a little time this weekend to do something other than freak out about making sure I have everything taken care of.

I was staring at a breadboard on my desk and it occurred to me that I’m always ripping up my MAX232 chip and associated components to save space for one project while putting it back so that I can use serial communication for the next project. So, I thought, why not make a decent breakout board that uses one of the FT232RL USB Serial drivers that I have lying around?

The design is very simple; it’s basically the same schematic as Sparkfun’s FT232RL breakout board. However, unlike that board, it’s designed so that it sits in the middle of the breadboard, using only 2 rows (and 4 pins). It also allwos one to use USB to power the breadboard.

First, I wanted to test to see if I could actually etch an SSOP28. They have an extremely fine pitch, so I knew it would be quite difficult to etch them. Using MITERS’s lamination method, I tried it out and had some decent success. I only have a picture of the final etch, but I’m convinced that with a little refinement (not to mention fixing the blatant bugs in the design), this design is totally etchable with minimal manual intervention. I had to clean up a few toner-transferred traces with a knife, but overall, the transfer process went well; the laminator applies a perfect, even amount of heat to the board and toner as it passes through and only takes a few seconds. For a design with such a small pitch, one of the issues is that the toner smooshed and covered a slightly larger area than it should have.

After I cleaned up the traces, I etched the board with very good results. It took a while (probably 15 minutes) to clear out the tiny little spaces between the SSOP traces, but it definitely worked in the end.

I’m going to re-route the board and etch a prototype that should theoretically work, hopefully, maybe, if the stars are aligned.

ubbcom’s github repo is here.

ACRIS at the Cambridge Science Festival!

I demoed ACRIS at the Cambridge Science Festival’s Mini Maker Faire. Charles and Shane were also there demoing their spectacular skills.

One of the organizers, Chris Connors, took a few photos. Here’s me:

I got a few ideas from talking to people concerning color temperature adjustment. ACRIS might become a lightbulb replacement one day. 🙂

Receiving IRC Messages as Text Messages

Bah, I’m a nerd. I’ve been using IRC for… like… ever. More recently, I decided to integrate all of my IM accounts into my IRC client (Weechat! — the superior alternative to irssi) with Bitlbee. So, now everything goes through my IRC client — Google Talk, AIM, Twitter, etc. Awesome.

But sometimes, I’m away and someone sends me something important over IRC or one of my IM clients and in my continuing effort to be omnipresent on the internet, I’d like those messages sent to my phone. I could just use a Jabber client for my phone, which would give me two-way communication, but what I really wanted was a one-way “paging” system.

So I built irc2sms. This is a very simple ZeroMQ-powered script that will take messages received when away and forward them via SMS to a mobile phone using Google Voice. It’s absurdly dependency-heavy, requiring Weechat, the zmq_notify plugin, Ruby, the ZMQ Ruby Gem, Python2, the ZMQ bindings for Python, PyYAML, and pygooglevoice.

But, configuration is very simple: make a ~/.gvoice by just running Python and importing googlevoice. Then, edit it, and run irc2sms.py -h to find out the command-line options.

Yay niche use cases!