Posts Tagged ‘hacking’

Raspberry Pi + Linux Interrupt Latency: 10μs

March 1, 2013

I decided I wanted to use a capacitive relative humidity sensor in a project with a Raspberry Pi, but that meant timing the charing or discharging of the sensor in an RC circuit. These things don’t have much capacitance, and the data sheet suggests it might not give good results under 1kHz. That makes it look like it’ll need microsecond timing at least to provide usable data.

I first tried making two consecutive calls to clock_gettime() and found that it takes between 2 to 5μs to complete one call on an otherwise idle Raspberry Pi. This wasn’t good enough, so I figured I’d dip into the kernel to see what could be done. The impact of scheduling processes and context switches should be minimized by solving the problem in the kernel. Thus far, this is the most involved attempt I’ve made at messing with the Linux kernel. The result was a bit messy, but I got it working. If you want a peek, its on Github.

I modified the code in bcm2708_gpio.c to record the time from a free-running timer whenever the output of a GPIO was changed, or an input state change triggered an interrupt. After managing to get the code to do about what I intended (sysfs has an extra directory level that I haven’t figured out), I connected two GPIO lines together, set one to be an input and one an output, and set the edge of the input to falling. There is nothing special about the falling edge for this test, but the edge had to be set to trigger the interrupt. Then I set the output to one, then zero, and checked the results.

I found that the timing showed 10 to 11μs would elapse between the output state change and running the GPIO interrupt handler when an X server is also running. Without X, I saw a latency of just under 9μs. The timer was configured to increment once every 4ns, so its precision should be more than adequate for these results. I suppose I could have added a significant digit. I’m surprised the times were so high; given the times on the consecutive calls to clock_gettime(), I was hoping for something better.

I know there are people who will blame Linux for the poor result, but this result is the system timing itself; it includes the hardware. What I saw in the BCM2835 documentation seemed to suggest the processor has an interrupt vector table with one entry, just like Microchip’s PIC16F84, an old 8-bit microcontroller. If so, that would suggest something else causes so much latency that there wasn’t a point in having a larger interrupt table. Even some of Atmel’s AVR 8-bit microcontrollers, like the ATtiny25, have several entries, so it isn’t expensive to do.

While BCM2835 offers poor interrupt response times, it does have nice graphics, runs Linux, and can run all the development tools needed for all this messing around in the kernel. No microcontroller is going to do that, unless it is part of a Rube Goldberg machine. I did build the kernel on my AMD64 deskunder computer, though. It’s much faster.

My biggest surprise doing all this is that it is possible to cause a segmentation fault in the kernel and not crash a single process. Do it a few times, though, and it might crash something. It logged me out once.


Car Hacking: Permanent fix for Civic cruise control switch

October 7, 2012

A few months ago, the cruise switch on my 2007 Honda Civic changed from a toggle to a momentary; the mechanical latch in the switch failed. This switch acts as a master enable for cruise control functionality, so the latch failure meant that I had to hold the switch down to use cruise control. The options to fix it were to pay someone two to three hundred or more to do it for me, pay over $80 to get a new switch assembly and install it myself, or attempt to solder a resistor that cost me a penny years ago into the right spot. Only that last option can ensure the problem will never happen again. I figured that if I was going to take apart enough of the steering wheel to replace the switch assembly, I may as well do a little more disassembly to put in the resistor. As far as I’m concerned, all that disassembly is the hard part; figuring out where to put the resistor and soldering it there should be relatively simple. So I did, and it works; it is just like the switch is always down. Since I pressed down the cruise switch for the last time before it broke maybe a week after I got the car and then left it there for years, the fix works just fine for me.

What follows is how I did it. The specifics are for the car I have, but the general concept will likely work for many other cars, too. The first part is disassembling the steering wheel; skip to part 2 below if you don’t have something similar to an 8th generation Honda Civic (2006-2011 models). If you so have something similar (an Accord may prove similar enough) and already know how to take apart the steering wheel, skip to part 1.

I took a few pictures of this process that do not appear here. You can find them on Flickr.

Warning: I will not take responsibility for anything that goes wrong should you attempt to make the changes I document below. Good luck!

Part 0: Disassembly of the steering wheel

Caution: This assembly contains an explosive initiator.

The first step is to disconnect the car’s battery by taking off the negative terminal connection only. After that, remove the air bag. Without power, the air bag cannot deploy. The air bag is in an assembly with the horn switch in the center of the wheel. It is secured by two bolts with Torx-style (ISO 10664)  heads, both of which will need a good deal of torque to remove. You may want to see if you can loosen one before disconnecting the battery. I had to use my drill, which doubles as a very bulky and torque-y electric screw driver. The bolts are on the right and left sides, and are placed parallel to the ground and perpendicular to the car’s direction of travel. There are no covers and they are the largest bolts on the steering wheel, so they are easy to spot.

After the bolts are removed, the air-bag-horn assembly will rest in place. It is still connected by two wire connectors. The first is accessible from the underside of the wheel. There is a panel easily removed with a flat head screwdriver; remove it. Inside is a yellow wire connector for the air bag that is made to ensure a proper connection and ensure that it won’t come loose. At one end is a black slider; slide it closer to the end and then pull the ends apart. It should disconnect easily, but will resist until the slider is moved. The connector is keyed so that it only goes together one way.

From the top side, regular driver’s perspective, pull out the air-bag-horn assembly. Next, move its end of the yellow connector around some plastic stuff to avoid pulling on the wires. After that, disconnect the other wire. It is green with an odd connector that has a strip of exposed metal. On the black plastic of the connector is a little button and the text “push” next to it. It might be hard to see if you aren’t looking closely or have poor lighting. When pushed, the metal strip is easily removed from the plastic end. After this, the air-bag-horn assembly is completely disconnected.

The wheel is sandwiched by two plastic covers. The cruise switch assembly is attached to the front plastic cover, so that is the next item to remove. It is held in place by six screws from the back side of the wheel, and two more made accessible by the removal of the air bag. These are also two sets of screws; the two from under the air bag are different from the six on the back of the wheel. Start with the easiest two. These are on the bottom middle of the wheel when the wheel is positioned level, like for moving straight ahead.

Hard to find screw

Hard to find screw

The remaining four are difficult to get at. There are two on each side of the wheel that are found easily by looking for a cylindrical well; a screw is at the bottom. I found I needed to turn the wheel so that I had room to use a screw driver (the drill is far too large). I had to use the space in front of the lower instrumentation panel, the one with the tachometer, to fit the screw driver. If you need to do this, I suggest placing a soft towel in front of the instrumentation panel to avoid scratching it. I found that the other two screws are hard to find when looking at the back of the wheel. It was easier to find them by looking from the front of the wheel through the opening made earlier in this disassembly. Looking from the front also made it easier to guide the screw drive to the screw head.

The final two screws are a little more obvious; you may already have found them by this point. One is up and to the left of the trademarked word “Honda” in the appropriate font. To the right is a white label stuck on, and further right and up is the other screw. After removing these, disconnect the wiring harness in the center of the wheel. There a tab to secure it on the center bottom of the connector. Now the front plastic piece can be removed.

Part 1: Getting to the cruise switch

Cruise control switch assembly

Cruise control switch assembly

The cruise and audio controls are in separate assemblies attached to the front plastic piece and held by two screws each. Disconnect both sets of controls. The plastic cases of each are held shut by four clasps, two each on the top and bottom. I had to use a couple of small flat head screw drivers to release the clasps. Once you’ve done this on the cruise control set, you’ll see two circuit boards connected by a ribbon cable.

The board on the right is the one connected to the wires that leave the control’s case. Remove its two screws. After this, the board isn’t really secured to the case, but it still won’t move far because the incoming wires are held in place by a zip tie. Destroy that tie so the wires are no longer secure. So far as I can tell, there is no need to replace it.

At this point, you should be able to pull up on the incoming wires and move the board away from its case. This will reveal the cruise switch; it is soldered directly to this board.

Part 2: Grok what the switch does

Cruise control switch assembly

Cruise control switch assembly

If you just want the solution I found for an 8th generation Honda Civic, skip to part 3. Be warned, however, that the cruise control switch assembly could change, even for the same car. For instance, if the switch that Honda was using when my car was built is no longer available, a new assembly could be made with a different switch part. Such a change may give you different results even if the different control assembly you have can work without modification in my car.

When the switch is depressed, it will either create continuity between two or more of the switch’s connection, or break continuity. This fix only works when continuity is made by the button press; this is likely the more common than breaking continuity.  The continuity signals to the car’s computer that the button is depressed, and then the computer will respond to input from the other cruise control switches. This fix places a resistor across the switch’s connections that have continuity only when depressed thereby causing the computer to see the switch as always depressed.

The next step is to figure out which of the switches output have continuity only when the switch is depressed. The best way to do this is to poke around the circuit with a multimeter set to signal continuity while changing the state of the switch. In the case of what I was working with, the switch has six through-hole connections on the board. The two in the middle always have continuity with each other because the circuit on the board connects them. These have continuity with the pin in the upper left only when the button is depressed.

Part 3: Modify the circuit

Cruise control switch fix ready for solder

Cruise control switch fix ready for solder

A resistor that makes the same electrical connection as is made with pressing the switch must now be put in place. I chose a resistor over a wire because a resistor will limit the current; if anything goes wrong, there won’t be much power to make matters worse. I think anything between 100 and 1000Ω will likely work. I used a 470Ω resistor because I have a bunch of 1/8 watt 470Ω resistors. The 1/4 watt variety often found at any store selling components will work, too, but I figured a smaller 1/8 watt one would be easier to work with.

Cruise control assembly with switch fix applied

Cruise control assembly with switch fix applied

I followed the traces on the board to see where I could put the resistor; it doesn’t have to be right next to the switch. I chose to place the resistor close to a wire connector on the board because it looked like it would be easier to solder the resistor there. I used the leads on the resistor to hold it in place while I soldered. After soldering, I removed the extra length on the leads to avoid shorting the circuit. I also retested continuity on the switch to be certain that the resistor was now part of the circuit and that its addition was the only change.

Part 4: Reassemble & final test

Put everything back together. Reconnect the car’s battery as the last reassembly step. Turn the key in the ignition and stop just short of starting the car. At this point, at least with a Civic, the dash light indicating that cruise control is enabled should be lit, and pressing the cruise switch should have no effect.
All done, or just starting

False Steps

The Space Race as it might have been

You Control The Action!

High Frontier

the space colony simulation game

Simple Climate

Straightforwardly explaining climate change, so you can read, react and then get on with your life.