Monthly Archives: September 2009

Flash snap

This past week the parts for my project have shown up. I got a surplus 10A solid-state relay for about $8 on eBay (I’m perplexed why SSRs are so expensive – there are like $2 worth of parts in a $20 part), 12 20W lights, and a substantial 600W transformer from intermatic.

The transformer is actually 2 300W transformers rather than a single 600W one. I wanted to verify that the SSR that I got was working, so I got out one of the lights, carefully wired up the primary of the transformer to an extension cord and the 12V output to the light, and plugged it in.

Flash Snap!

The light got really really bright for a really short period of time, and the snap was circuit breaker tripping.

I’m surprised. It’s pretty hard to mess up hooking up a transformer – there are two AC supply wires, two wires on the transformer, and polarity doesn’t matter. I check my connections and make sure that there are no shorts, and try it again.

Snap!

No flash this time because the light got toasted the first time. I pull out my Fluke Multimeter, set it to resistance, and put it across the primary, where it reads 0.1 Ohms. Same reading across the primary of the second transformer. Let’s see, 120 Volts across .1 ohm = 1200 amps, which makes it pretty obvious why the circuit tripped.

It’s really not as simple as measuring the resistance, since transformers are inductors, and resistance isn’t the same thing as impedance, so I go upstairs to make a sandwich, and do a little thinking. What I need is a way to do some measurements of the transformer with a low-voltage AC current across it. I remember there’s an old trick where you put a bulb inline with the load – that limits the current to what the bulb will pass.

I hook up a 7watt nightlight bulb I use to debug my light projects in line with the transformer, and plug it in. At 7 watts, it pulls 7 / 120 = 58mA of current, which means that (V = IR), it has a resistance of 120 / 0.058 = about 2100 ohms.

A voltmeter on the transformer shows 0.25 volts. That’s pretty low. If 0.25 volts results in 58mA through the transformer, putting a full 120 volts on it would give us a current of 480 * 0.058A = 28 Amps, or about 3300 watts. That’s a lower-end result – I actually think it’s quite a bit worse since 3300 watts would only be a mild overage on the circuit, and that level of current takes a fair bit of time (say, half a second) to trip a breaker. I think it’s more likely that we’re looking at 100 amps or so.

And guess what – the second transformer is exactly the same as the first. Must be a manufacturing defect with some of the windings shorted together.


It makes a father proud

Last Friday morning, I was sitting at the kitchen table reading the paper, eating breakfast, and listening to music.

My daughter stuck her head around the corner, smiled, looked at me, and said two words:

“Baba O’Reilly”

Which was her way of demonstrating a fairly obscure bit of music knowledge.

Anybody care to explain why I’m proud?


Outdoor lighting project – controller

The requirements of the control system are pretty simple:

  • Be controlled with a single pushbutton.
  • Support on and off.
  • Turn off the light automatically after a suitable period of time

That’s pretty simple – simple enough that you can do it with an 8-pin AVR controller, like the atTiny12. That programs fine in my STK500 development kit, but on the low-pin-count controllers, many of the pins have shared functions related to programming, so you have to attach/detach them each programming cycle. That’s why I’m using one of the attiny861s that I have left over from another project, where I have plenty of pins. The cost difference doesn’t matter at all in a one-off design.

I spend the usual frustrating time remembering how to set up the programmer so it works. The key to remember is that you need a current build of Atmel’s avr studio so that you can look in the help file to see how to do the wiring. I wasted a couple of hours and almost lost the Magic Smoke before I remembered where to find the information.

The next step is to get the controller configured correctly. Even the simpler AVRs have a ton of options. I’m going to be using one of the timers, so I need to set up the timer registers correctly. In this case, I want a 16-bit counter (set bit 7 of TCCR0A to 1), and I want to divide the 8MHz clock by 256 (set bit 3 off TCCR0B to 1), and so on. All the information is in the atmel data sheet (the 236 page data sheet…) for the controller, but it takes a fair bit of work to get it right.

Or, you can buy a copy of codevision AVR. Not only does that let you write in C rather than assembler, it has a program wizard that lets you use human-understandable settings rather than hex values. So, in this case, you can go into the wizard and say that you want timer 0 to run at 31250 Hz, use a 16-bit counter, and call an interrupt when it overflows, and it will generate the source code (with comments) that does just that. Only two annoying things about it:

  1. It puts all the initialization code at the beginning of main and then the main loop at the end, so you’re constantly having to scroll over that code to get to your main loop.
  2. When you want to update the code, you have to run the wizard and then cut & paste the updated code in the proper place – it can’t fill in the areas you want.

Neither of these are more than a little annoyance. As you can tell I’m a big fan of AVR studio.

So, back to the project. First, we need a way to handle the turning the lights off, and for that we need a timebase. We’re going to use 10 Hz (for reasons that will become apparent later), and it would be most convenient to get an interrupt at that rate. Since the interrupt will happen whenever the 16-bit timer overflows, we need a timebase where the count fits in 16bits (ie  65535). Looking at our options, we see that we can get 8 Mhz / 256 = 31250 Hz as our timer frequency. If we can send an interrupt every 3125 counts, we’ll have our 10 Hz. So…. We take 65535 – 3125 = 62410 = F3CA, and initialize the counter to that value after every interrupt.

And that gives us 10Hz. Or, actually, it gives us 10Hz +/- about 10%, which is the factory calibration tolerance of the internal oscillator. It’s possible to get a better calibration than this by writing to the OSCCAL register – Atmel claims you can get +/- 1% through that approach – but it’s not something needed for this application, so we’ll just stick with whatever we get.

Now that we have that, we can write our interrupt service routine.

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
        // Reinitialize Timer 0 value – 1 second timeout…
    TCNT0H=Timer0H;
    TCNT0L=Timer0L;   
    waitCounter++;
    if (timeRemainingTenths > 0)
    {
        if ((timeRemainingTenths % 600 == 0) &&
            (timeRemainingTenths <= 3000))
        {           
            PORTA.2 = 0;
        }
        else
        {
            PORTA.2 = 1;
        }
        timeRemainingTenths–; 
    }
    else
    {
        PORTA.2 = 0;
    }
}

We have a timeRemainingTenths that sets the timeout value. The if condition handles flashing the lights off for 1/10 second the last 5 minutes so that I can turn off the snowblower and walk back over and hit the button again.

That leaves only the button-control handling code to write. As part of this, I need to handle debouncing the switch: when a mechanical switch closes, it doesn’t close fully but instead bounces open and closed a few times. This bouncing is slow enough that it’s easy for a microcontroller to detect it multiple times, so you need to debounce the switch. There is are dedicated debounce ICs to deal with this – such as the Maxim 6816 series – but in most cases you can do it in software. Or you could use a hall-effect switch that doesn’t need debouncing. The downside of debouncing is that it slows the speed of response.

In this case I don’t need the quick response, so the code is pretty simple:

void Wait(int seconds)
{
    waitCounter = 0;
    while (waitCounter < seconds * 10)
    {
        ;
    }
}

// Declare your global variables here

void main(void)
{
    init();

    while (1)
    {
        if (PINB.0 == 0)
        {
            PORTA.2 = 1;
            timeRemainingTenths = 60 * 60 * 10; // 1 hour 
            Wait(1);

                // Held down, turn off lights…
            if (PINB.0 == 0)
            {
                timeRemainingTenths = 0;
                PORTA.2 = 0;
                Wait(2);
            }   
        }
    };
}

If you look back at the interrupt service routine, you’ll see that the waitCounter variable gets updated at 10Hz. The wait routine uses this variable to provide a way for us to wait a specific number of seconds.

The sensing code takes a bit of explanation. In digital electronics, the concepts “0” and “1” refer to voltage ranges. The crossover point depends on particular semiconductor chemistry used in the electronics, but assume that it’s 2.5 volts in this case (ie 50% of the 5 volt supply we’re using). So, any voltage above 2.5 volts is 1, and below 2.5 volts is 0. If we hook a switch up to a digital input and connect it to ground, when we press the button, the input voltage goes to zero, and the input value is 0. Then, we let go of the button, and the input goes to some indeterminate state. It might be zero, it might be 1, it might go back and forth.

We get around that by using what is called a pull-up resistor, which is connected to Vcc (5V in this case). If the button isn’t pressed, that ensures that we get a high voltage (a 1), and then when it is pressed, we still get zero.

In the past – say in 1980 – you’d use a kind of logic known as TTL, and you had to be really careful how you hooked things up and what values you used, since TTL was a pretty rough approximation of the term “digital”. These days, most logic families are a lot easier to deal with, and in fact on the AVR microcontrollers have built-in switchable pullup resistors.

All of that is a long way of explaining why the code looks for a low value to determine when a switch is pressed rather than a high one.

The code itself is simple. As soon as the button is pressed, we set the time remaining to an hour, and then we wait a second to debounce. If the button is still pressed after a second, we turn off the switch, and then wait 2 seconds to debounce after that press.

That’s about it.

 

 

So, we look at pin 0 on the B port, and if it’s zero (pulled to


Eric vs. the Blend Door

About 10 days ago I was heading down to my Tue/Thu night ride in my truck. It was about 75 degrees out, so I turned down the heat on my Ranger, but it didn’t work – I was stuck on hot, which is pretty darn hot. I had to go on Max AC to get it tolerable.

After a bit of research, I found that the problem was likely to be the mix door. Ford uses a potentiometer to detect the position of the dial in the dash, and then a microcontroller sends the door to the proper position. It’s a fairly elegant design, except that the code self-detects the limits of the door by moving the door and sensing that it slows down. That would be fine, except that the shaft on the door is plastic, and it’s not up to the torque of the actuator, so it breaks. And then, if you want to fix it, you have to pull the whole dash apart to get to it.

This is so common that there are companies that specialize in aftermarket replacements. I bought mine from HeaterTreater.net, and put it in yesterday. It’s a very elegant hack. You take out the actuator, cut the bottom out of the duct with a dremel, vandalize the door so it will come out, and clean out all the shavings. The new door fits in and then you pull a pin so that the spring-loaded shaft seats in the pivot, put the actuator back on, verify that things work, and then close things up with some foil tape.

It would be easy to do if the part of the duct you have to cut wasn’t facing down right up to the firewall. As it was, I had to fall back on my car stereo installation skilz and lie backwards on the seat with my head under the dash.

About 2 hours later, it was done.


Outdoor Lighting Project

I have a lighting issue at my ski place that I need to solve.

If the weather’s good, we just drive up, unlock the gate (in the car’s headlight), and wait for the motion detector lights to kick on.

If there’s a little bit of snow – say, 3″ or so – the Outback handles it fine, and I get out the snowblowblower and clean off the driveway. Except once I get about 50′ away from the house, I can’t see anything any more, and snowblowing in the dark isn’t a lot of fun.

If there’s more snow, we can’t get into the driveway, and have to park out in front, unload in the dark, and then walk across the meadow and through the woods to the house. In the dark.

Seems like we need some lights.

The first choice is whether to go with line voltage or low voltage. Really simple in this case – I need to get the power to two locations about 150′ from the house, and I need to get the lights up into the air. That means a whole lot of trenching through the woods and putting up poles to attach the lights to. Or, it’s running some zip cord through the woods and then mounting some lights up in the trees. So, we’re going the low voltage route.

Which has some problems of it’s own. One of resistance.

The transformer for the system will mount in the house, and that means about 150′ of wire to each of two remote locations. Let’s say we buy 12 gauge wire, just to make it easy. We have 300′ of wire total, and if we look up the resistance, we find that it’s 1.588 ohms/1000 ft, putting us right about 0.5 ohms for the 300′ of wire.

That doesn’t seem like a lot of resistance, so let’s look at some numbers. If we want to run two 20 Watt lights, that will take 40 / 12 = 3.3 amps, so we’ll lose 0.5 * 3.3 or 1.6 volts. With 12 volts running into the run at the start, that means we have 10.4 volts into the lights. If they’re halogen lights, they don’t like that – halogens require full voltage or their lives are reduced considerably. If we bump up to 2 50 watt lights, it’s much worse – we’re pulling 8 amps and losing a full 4 volts in the wire.

The professional low voltage transformers have taps at higher voltages, so we’d hook up the 14 volt tap for the 20W lights, and the 16 volt tap for 50W lights. Unfortunately, the pro transformers are fair bit more expensive than the ones I’d like to buy. Another option would be to go with thicker wire 10 gauge only has about 2/3 of the resistance, but it’s also half again as much copper, so it’s a lot pricier.

As an alternative, let’s consider a system with LED bulbs instead of halogen ones. You can now find 3-5W LED MR16 lamps that in the $20 range, producing the same amount of light as a 20W (ish) halogen. It’s about 5 times more efficient, which means that if you put two of those out, you are only pulling 1 amp, and you only lose 0.5 V. I can probably step down to a smaller wire gauge with the right transformer.

Not sure which way I’m going to go yet. But I do have the control system designed. That’s up next…


Hello

Ths is blog #3 for me.

There’s my work blog, which over the years has had lots of non-work stuff on it, but I’ve been writing less work-related stuff there and don’t want to overwhelm it with other stuff.

There’s RiderX, my bicycle blog.

And now there’s this blog, which will have everything else on it.