Monday, October 4, 2010

Good bearings

So, I finally figured out what the deal was with my accelerometer needing to be asked twice what the value was.

As it turns out, I wasn't actually giving the chip time to reply. I thought the micro would automatically handle receiving the data value, so I all I had to do was send the ACK at the end. In fact, the command that sends the ACK actually tells the micro controller to wait until the entire data byte has been transmitted, and then transmits the ACK.

So, when I was storing the value before sending the ACK, I was storing the value that I originally had in the register (the address of the accelerometer chip) and then waiting for the data and finally sending the ACK. Now, I've changed it so that it waits for the data and sends the ACK before storing the data value in the register.

How did I figure all of this out? With an O-scope! I simply modified my code so that it would give me a voltage spike on one of the output pins while it was reading the data from the register. What I noticed was that it was spiking before it was supposed to. Here's an example of what I mean:


Here's a plot of the two I2C lines while talking to the compass chip. The spike I was noticing was right after the "Chip Address and Read" segment, but before the "High Byte" that means that I never gave it time to actually read back the data!

Oh, what's that? You didn't know that I got the compass working too? Did you even read the title to this post?

Yep, it's working. Doing the reflow soldering was a little tricky because the compass doesn't really have QFN-24 footprint (I don't think it's a standardized footprint). The main difference is that the compass doesn't have the huge ground plate that QFN-24 provides. As seen here:


My solution was to simply cover the stencil with tape:

and carefully cut around the center holes:

Ta Da!

So, the compass works! It did need a little calibration. There's a routine that it can run wherein you're supposed to slowly spin it around while it collects data. When you tell the routine to stop (it recommends anywhere from 6 seconds to 3 minutes long), it does some math and figures out what magnetic fields are local to it (inherent in the circuit it's on) and what magnetic fields are due to the Earth. I didn't know I was going to need a calibration function, so I'll have to work that into the final design somehow.

The compass reports bearing as 1/10 a degree per digit. Here, you can see it displaying the top 4 bits of the compass bearing. Notice how dramatically it changes as the compass passes magnetic north.



Punctual, but Problematic

So, you haven't seen an update out of me in a while. This is because I've been struggling over the past week with getting my clock to return accurate, or at least consistently inaccurate results.

My test method was to use a little program that I wrote that would give me a 10 second count down before starting a timer that increments the LEDs once per minute. The idea was to use the 10 seconds to synchronize the timer with a timer known to be accurate and then let it run for a few hours and see how far off the minute mark it was. Take the number of seconds it's off, divide by total number of seconds elapsed, and multiply by 1 million to get the parts per million (ppm) accuracy.

See, every crystal oscillator needs to be "tuned" with some Load Capacitors. I tried my best to match the Load Caps to the 22pF rating on the crystal's spec sheet (even taking into account the parasitic capacitance on the breadboard), but I still couldn't get good results.

This is me measuring the capacitance that the crystal and chip would see (so, just the load capacitors). I tried to get it as close to 22pF as possible.

Note the two twisted wire pairs sticking up; each of those account for about 2-3pF and were very touchy.

The most upsetting part was how inconsistent my results were. The only certain thing was that wild variations in the capacitance made for wild variations in accuracy.

Well, it turns out that the timer on my iPod, which I assumed to be accurate, was far from it. After switching over to a Timex stopwatch, I got much nicer results. First, I managed to get around 30-35ppm consistently for over a day. Convinced that it was at least consistent, I tried lowering the load capacitance to see if I could improve accuracy. Dropping the 20pF caps for 15pF got me 20ppm accuracy.

I don't think I'll be able to exactly account for all of the capacitances that can interfere with my circuit's accuracy off hand. I think my official solution is going to be guessing the proper load capacitance in my final circuit, and replacing it with a different set of capacitors if it turns out not to be accurate. I'm actually fairly certain that this is how the pros do it. Build a prototype, figure out the best capacitance, and then repeat for 10000 more. At 20ppm, it would lose about 1.7 seconds a day. This is already perfectly acceptable, but I'm sure I can get it even closer when I build the final version.

On another semi-positive note, I got my accelerometer working!

So, convinced that my accelerometer was completely fried last time, I ripped it off the board to survey the damage. It looked like it had been soldered well, but it still didn't work. I was pretty certain that I had baked the chip too hard.

This time around, I wanted to be careful. I grabbed my Le Cruset pot and an infra-red temperature gun and attempted to simulate a reflow oven using a gas stove. The goal was to heat it at 200C for as long as it needed to melt the solder paste and then remove it immediately after.

I even got a video of it!




Well, after all of this, I was sad to learn that my chip still wasn't responding to any input. I simply couldn't get it to acknowledge its own address. This is exactly the behavior I got last time. Completely removing the chip got the same results.

The chip's address consists of a 7-bit number. When talking to it, you always add an 8th bit to indicate if you want to read from it (1) or write to it (0). The address is always sent first followed by the 8th indicator bit.

The address of the accelerometer was listed as 0011100. I was transmitting 00011100, using the aforementioned protocol for writing to the address, and the chip was ignoring me. Well, I was reading up on the I2C protocol at work today when I realized that I was an idiot.

In I2C, numbers are always transmitted most significant bit ("leftmost bit") first! That means that instead of sending 00011100, I should have been sending 00111000! Well, I tried this first thing when I got home, and I got the chip to talk!

Now, it still took me an hour to work out some of the details of getting something useful out of the chip, and I'm fairly convinced that the datasheet is wrong on this one...

The datasheet says that in order to receive a single byte from the chip, you must do the following:



Doing this resulted in me receiving the address of the chip as the current accelerometer data. This was the value that I loaded into the "TWDR" register that was supposed to be replaced by the data from the accelerometer. I was convinced that the whole thing just wasn't working and therefore not updating my register value. I struggled with this for about an hour or so (I had some other bugs along the way), but then I tried this:



This is for reading more than one byte from the slave. Note that the "master" (my microcontroller) sends an Master Acknowledge (MAK) after the first bit of data. Well, I found that for some reason, the first bit of data is always just the address that you sent it. The second piece, however, is what you really want.

I'm not really sure what's going on here. I never got the "single data" condition to return anything but an address, but I suppose I can live with just throwing out a garbage value to get to the good stuff...

The sheet even talks about a special mode of addressing (where you add 0x80 to the subaddress (register address) that you're looking for), that enables "multiple reads", but I'm still not entirely sure how that works. I think it's supposed to run through all the registers sequentially, but I haven't really found a use for it.

If more trouble crops up in the future, I'll look into these issues more, but as is, the accelerometer works exactly how I want to.

Here it is showing its Y data in binary!





It's 2's compliment with each digit representing about 18 milli-Gs. I turned it to 90 degrees and got back 0b111000 which works out to about 1.008G! Awesome!

Now, the real sad part of this story is that, convinced that I had blown yet another chip, I went ahead and ordered another breakout board...two actually (just to be safe), all before realizing my addressing error. That's another $20 down the drain unless I use another .5mm pitch LGA-16 chip in the future. Also, I'll never know for sure, but I might have never fried the first chip after all...

Monday, September 27, 2010

Me and the Cap'n

So, it turns out that clock crystals need a "load capacitance" between each of their two pins and ground. I'm not entirely certain what these capacitors even do, but I do know that they are critical to keeping good time.

That nixie tube clock that I made originally had a clock crystal in it that had no load capacitors. This resulted in it being inaccurate.

Well, it isn't obvious from this video, but over the course of a day, it would lose 2 minutes of time or so. I ended up fixing the problem the lazy way and just used a "Crystal Oscillator" which is a three terminal device that takes Vcc and Gnd and gives you a pretty square wave. All of the load caps and everything are built in. Unfortunately, these guys are too big to fit in a watch, so I still have to figure out what the deal is with these load caps.

I'm getting a couple conflicting answers. Here's what the AVR data sheet has to say:

In the table above, it lists Ci as 18pF on tosc1 and 8pF on tosc2. I read somewhere that you can typically expect stray capacitance to be around 5pF or so, and the clock crystal's data sheet lists CL as 12.5. This makes the value of Ce around 0pF for tosc1 and 12pF for tosc2.

Hrm...

What does the crystal's data sheet have to say?

Soo... I'm pretty sure I can ignore the Rd because it's "as required" and my AVR data sheet makes no mention of a resistor like that.

So, this is a little ambiguous. I'm really not certain what to do. I think I might just follow the crystal's data sheet because the math for the AVR's data sheet is really weird. Besides, I'm fairly certain these capacitors won't saturate, so using bigger caps (like the 22uF) can't do too much damage, right?



Tik Tok

I have a clock!

So last night/today, I worked on getting the clock part of my AVR working. Here's the basic rundown.

The ATmega48A has what's called an asynchronous timer. A timer usually works by simply incrementing a number on a fixed interval of time and doing something special when that number reaches a certain value. Most of the time, the timer will just increment every time the processor's clock ticks. An asynchronous timer is special in that it can clock along at an entirely different pace.

While the processor is chugging along at 8MHZ, my clock timer is clicking along at 32.768kHz. How do I know this? Because I have it connected to a 32,768Hz clock crystal. Why such an odd number? Lemme explain.

So, let's say we increment our number at the 32.768kHz speed. The counter is an 8 bit number which means it will overflow after 256 clock ticks. That makes my overflow event happen at a rate of 128 times per second. That seems kind of fast. Luckily, there's something called a prescaler that can be set in the AVR's code. The prescaler sets how many clock ticks the chip should ignore before incrementing its counter by one. If you set this prescaler to 128, the clock will increment exactly once every second.

Clock crystals are incredibly accurate, so this dude should have no trouble keeping time.

Now what about power? Surely, I can't afford to be running a micro controller at 8MHz all the time. Luckily, the ATmega48A has the ability to enter a Power-Save mode where it will shut down all unnecessary actions and keep just the counter running. The idea is to have the chip wake up every second just for a millisecond or so and then go back into Power-Save mode for the remainder of the second. My actual code will have the chip waking up to update the time, but for now, I just have it blink an LED.

Here's a video of it in action. It only draws 1 microamp! (I had to actually unplug the programmer which was drawing 15 microamps)



The LED is extremely dim in the last part, because the multimeter will not allow enough current to pass when it's measuring on the 200 microamp scale.

The only thing I have left to look at as far as the clock goes is adding some load capacitors to my quartz crystal. These caps are necessary for keeping a crystal extremely accurate, so I'll need to figure out what's required before I trust my watch not to lose time.

Sunday, September 26, 2010

Dearly Departed

So today was something of a downer.

I received my LGA-16 breakout board from proto-advantage.com yesterday, and decided to give reflow soldering another shot with my digital accelerometer, the LIS33DE.

The LIS33DE is the first 3V chip I've used that cannot also run at 5V. Because of this, I decided to re-do my breadboard and get myself a 3V power supply. I found an old PC power supply that can output 3.3 volts which is close enough. I've got some mounting posts that I'm planning on bolting to the power supply to make it a little easier to manage, but for tonight, I just used some alligator clips to bring the 3.3V to my board.

Now, along this process, I did a very stupid thing. I left my micro controller and temperature probe connected to the board. I've always been a fan of hot-plugging in the face of adversity, but in this case, I was a little too reckless, and not only killed another micro controller, but also the temperature probe!

Luckily, I had backups of both, and while desoldering a SOIC part is tedious, it's by no means impossible.

What is very sad is my accelerometer. I'm not sure exactly what went wrong, but I was unable to get it to do anything intelligent. It wouldn't even acknowledge its own address.

Concerned that maybe I had some shorts in my solder, I tried applying some heat to the traces and letting the solder move around. I even added more solder, concerned that there was an open somewhere. I finally just ripped the chip off the board and found that neither was an issue (testament to my awesome solder paste stenciling skills).

What I'm putting on the death certificate though is "Got Baked."

I think I turned the toaster oven up a little too high (450F) for too long (like 10 minutes) and completely burned the chip up. I guess it makes sense that it's a little more sensitive than a temperature probe, huh... That also explains why the toaster smelled not only like burned food bits (like usual), but also like burned plastic. The poor guy didn't stand a chance.

I'm ordering a new chip and break out board. Proto-advantage usually takes like 2 weeks to deliver, so in the meantime, I'm going to continue working on the Real Time Clock, and the buzzers.

I'm going to be trying a different method for reflow in the future (especially before I even touch my $25 compass!) I've read on this page about doing reflow soldering in a skillet. The advantage here is that it will heat the chip from below and hopefully melt the solder paste before the chip gets too warm. Also, I learned that you're pretty much supposed to remove the chip as soon as the paste turns liquid. Now, I didn't really watch the chip when using the toaster oven in the first place, but the skillet should make the board much more visible.

Saturday, September 25, 2010

And the good lord said, let there be LED!

So, I haven't updated in a while (it's been one hell of a week), but just to get you up to speed. I got my new micro controllers and everything is just peachy there. Don't worry, I found a new home for the old ones:

More importantly, I got my LEDs!

These dudes are small. Like, you have no idea. Let my try to give you an idea with these pictures:

Such wasteful packaging

Everyone knows Washington had wooden teeth, but did you know that Lincoln had LED eyes?

I really had to mind my Ps and Qs dealing with these guys. Especially the Ps. At some point, the word "people" sent an LED flying.

It wasn't so small that I couldn't solder it, however. Let's just say that I'm very very glad I bought all the stuff I did, especially the glasses.

One technique I devised for holding the LED still was using tape sticky side up.
I wasn't very careful though, so I did melt the tape a little...

My technique was to flip the LED on its back, dab some solder on its contacts, and then heat the wire and touch it to the contacts. The flux pen was indespensible in this process. With enough flux on the led, I could just blob solder on and it would form two neat little mounds on the contacts. A little flux on the wire also helped make the joint.

I think my plan for the actual circuit is going to be to blob solder on the contacts, then flip the LED over and heat the footprint while lightly pressing the LED down.

So, if you've been keeping up with my blog, you've probably read about my concern that the LEDs wouldn't be bright enough especially when driving them at the requisite 30% duty cycle. I am no longer worried about this. In the following video, the LEDs switch between 30% duty cycle and red being on for 100% duty cycle and the other two being off. I also shake the camera around a little so you can get an idea of the switching frequency. Keep in mind that I intentionally slowed it down. I will presumably be driving them at the fastest frequency I can.




I actually did another test driving them at 20mA instead of 30mA (which is right at their absolute maximum). They are certainly bright enough even at 20mA which means I can use all of the awesome constant-current sinks that I found.

Next on my agenda is talking to the real time clock. I'm actually working in a lab tomorrow where I have to click a button every 30 seconds to take a picture with a digital microscope. I have an old mouse circuit board lying around, so I'm going to try to see if I can get my AVR's real time clock to click the button for me. I'll keep you posted.

Tuesday, September 21, 2010

I think I'm thinking too hard

I've been pondering this current-limiting nonsense all day, and I think I'm overthinking.

The issue is this: If I want to get maximum brightness out of my LEDs, I'm going to want to overdrive them a bit because I can run them at a maximum of33.3% duty cycle (if I have three LEDs lighting up at the same time). LEDs that are rated for 20mA of constant current might be rated for up to 100mA of peak current. Apparently, nobody make a 40+mA constant-current LED driver that runs at 3V. Oh well.

I think I'm going to bite the bullet on this one, and I think I'll be okay. I ordered a bunch of 0402 LEDs to play with (they're very very very small). I want to see how bright they are and how much abuse they can take.

I also ordered some banana plug binding posts so I can convert an old ATX power supply to a lab power supply.