Archive for September, 2010

Liquid Tin from MG Chemicals

I had been using a mix it yourself from powder solution for tin plating. It’s a PIA and has to be heated prior to use. I heard about Liquid Tin some time ago. Not only do you not have to mix it, you don’t have to heat it. I didn’t bother with it because if it’s not broken, why fix it. Well, two weeks ago, I got aggravated with tin plating so I figured I would give it a shot. I cannot believe how well it works. I feel like an idiot for wasting my time now. I guess I assumed that a solution you heated would work faster and better but I was seriously wrong. Liquid tin works almost instantly and seems much more tolerant of not getting that last spec of oxide off with the scrub pad. I highly recommend it.

ARM Cortex M0 and GPIO Port Address Masking

ARM has apparently decided they want to go after markets traditionally reserved for 8-bit and 16-bit applications. They have released the new Cortex M0 core, a lower capability 32-bit core, with mostly 16-bit instructions, targeting cost sensitive applications. The only company, that I know of, selling chips based on this core is NXP with their LPC1100 series. This isn’t a huge surprise; two other typical ARM adopters that spring to mind, ST and TI, both have there own 8/16 bit lines and they wouldn’t want to compete with themselves.

After review the LPC1100, I have to say, they have quite a convincing case for using their product in lieu of 8-bit micros in many applications. To start, it is shockingly cheap, you can get these parts at mouser starting around 1$ for QTY 1. So, in the cost arena, it truly does compete well with 8-bit parts. It can be had significantly cheaper, for example, than a similarly spec’ed ATMEGA. The LPC1111 with 8KB program memory and 2KB RAM costs $1.30 at QTY 1; the new ATMEGA88PA, with 8KB and 1KB costs $3.05. I am not going to say the ATMEGA has no advantages vs. the LPC1111, because I am sure that it does (I have not looked in detail) but the Cortex M0 part has some very big computational advantages here. The chip runs at 50Mhz and runs most instructions in 1 cycle, including single cycle multiply. Compare that to the ATMEGA series which tops out at 20 MIPS or the PIC18 series which tops out at 16 MIPS. That’s a huge difference in power. The only thing I know if that comes close anywhere near 3$ is the Atmel XMega series which does 32 MIPS. The XMega also has a set of peripherals that blows away the LPC, it is too bad most xMega models are never in-stock anywhere.

If that weren’t enough, the LPC1100 series lists ridiculous power consumption figures. The chip consumes 3mA at 12Mhz and 9mA running at full bore at 50mhz, in active mode. At 3V and 4Mhz, the ATMega88PA is already consuming almost 3ma and doing only 1/3 the work. To the best of my knowledge, Atmel’s most efficient 8-bit micro is the xMega, which consumes about 12ma at 32mhz. If we make an apples to oranges comparison with one of Microchip’s new darlings of power efficiency, the PIC16LF1823, things look a little better. The Pic uses 0.84ma at 16Mhz. Remember though, the PIC instruction cycle is 4 clocks long, so 16Mhz here can be though of as 4Mhz when comparing to an Atmel or LPC. To compare it to the LPC figure, we can roughly estimate by multiplying by 3 and getting about 2.52mA for 12 Mips. Slightly better, but this is comparing a much less capable micro in a different class with no hardware multiply. So basically, the power figures are impressive. It is worth noting that the PIC16LF1823, can be run on 1.8V, in which cases it only uses 0.47ma at 16Mhz.

One particular implementation defined feature (defined by NXP and not ARM) that caught my eye was the way in which bits can be assigned to the GPIO ports in one cycle using address masking. This feature is also implemented by the NXP Cortex M3 series. Rather than having one register address for a GPIO port, or even 3 (INV, SET, CLR) like many micros, the LPC1100 series has 16,000 or so register addresses for each GPIO port. The address serves as a bit mask for the port assignment. For eample, The adress range for PORT 1 is 0×5001 0000 to 0×5001 3FFC. The port is 12 bits wide and the mask bits are bits 13 through 2 of the address. The hex number 0×3000 expands to the binary number 11 0000 0000 0000. As you can see only bits 12 and 13 are high. Those bits correspond to 11 and 12 of the port. So, no matter what I write to address 0×5001 3000, only pin 11 and pin 12 of the port are effected. I think that is an incredibly useful feature and I much prefer it to the set, invert, and clear triage of registers. The Texas instruments Cortex M3 series employs a similar addressing scheme but the ST M3 series does not.

Are ARM vendors going to steal all of Microchips business overnight? No, of course not. Currently, the LPC1100 series consists of one line of chips, offered in two packages, QFN32 and TGFP48. Obviously, that can’t compete with the huge range of micros offered by 8-bit vendors. Nor can ARM compete with the huge amount of support already available from 8-bit vendors for typical 8-bit applications. For example, if I need the lowest cost method of implementing embedded Ethernet, I will still be headed to Microchip. However, for those situations where NXPs limited range of Cortex M0 micros happens to fit the needs of your application, they make a very convincing argument.

AC Current Sensing Part 2

I am going to follow-up my last post on current sensing with a real world example. I am going to set up an example circuit designed to sense current flowing from a 24V 60Hz AC Source using a 5V instrumentation amplifier. Before we do that, however, I want to illustrate the relationship between the ground in a circuit that has been rectified into DC and its original source. Note this example set-up:

Rectified Ground Relationship

An exaggerated sense resistor is used for clarity. Here we examine the sense voltage relative to rectified ground. This is the oscilloscope result:

Sense Resistor Voltages

Sense Resistor Voltages

As you can see, we have an ugly waveform on the top. Sometimes pin 1 (blue channel) of the sense resistor is at a higher potential, sometimes pin 2 (yellow channel) is. The red waveform is the difference between the two channels, it represents the sense voltage, and of course, is perfectly sinusoidal. The scope is set up for DC coupling here. The key point here is that the AC voltage is always positive with respect to your rectified ground. This will always be the case as long as a pin of your resistive sense element is aligned with either of the AC source nodes. If you try to sense across a reactive element (capacitor, inductor) or place your sense resistor in between reactive elements, the voltage will be out of phase with the voltage you rectified from; as a result, part of the waveform will be negative relative to rectified ground.

The schematic below represents a circuit designed to exploit this “always positive” property to sense current. If you consult the original post, you’ll see that we need to offset the voltage so that the single supply micro can tell if it is negative or positive. We could use a quad op-amp chip, use 3 op-amps for an instrumentation amplifier and the final op-amp to buffer our offset voltage. In this case, however, it is going to be much easier to use a pre-packaged instrumentation amplifier. I have chosen the Analog Devices AD8293 amplifier. It is a fixed gain amp, offered in either 80 or 160 gain. It has very good characteristics and accuracy and is reasonable priced at $1 – $2 USD in very low quantities. Especially useful for our purposes here, it has a high impedance REF pin for offsetting the output. The datasheet specifically states that no buffering of this offset is necessary. Its major limitation is low bandwidth but that won’t be an issue for sensing from the 60hz mains. I have set up the following circuit.

Current Sensing CircuitAs you can see, the voltage is divided down by a factor of 11 so that it is in range of our amplifier, which then amplifies the difference by 160. It would have made more sense here to use the AD8293G80 80 gain version and use a higher sense resistance like 0.4 ohms, but I only had the AD8293G160 on hand. The net result is that our sense voltage is amplified by a factor of 14.55 [formula: (1/11) * 160] and referenced to half of VCC .  Since the offset divider is radiometric, no matter where the supply moves, the offset will always be exactly half of the ADC top value. Here is the oscilloscope shot of the results. The oscilloscope ground is connected to the rectified ground and the probe is connected to the ADC OUT to ADC IN line.

DC Coupled

DC Coupled Waveform

AC Coupled Waveform

AC Coupled Waveform

As you can see from the DC waveform, the voltage is well within the sensing range or a 5V microcontroller. When selecting your range, make sure that your full scale expected current range does not cover the full scale ADC range. You will want some margin for detecting fault conditions. Using my Fluke 87 true RMS meter, I measured the circuit voltage to be 23.3VAC and the total resistance to be 78.2. This would equate to about 298mA which would create create a sense voltage of about 59.6mV across the 0.2 ohm sense resistor. When amplified by the 14.55 gain, our expected output voltage is about 867mV RMS. Per the oscilloscope shot, the measured result is 860mV RMS, quite an impressive result.

In order to calculate RMS current in the micro, the waveform must be sampled at regular intervals and combined into an RMS figure. The following is a psuedo-code example:

/* The following is pseudo for concept illustration. It has not been checked or debugged  */
int results_array[1000];
int result_count;
//get a full 60hz cycle of 16.66 ms
begin_time = get_millisecond_tick();
result_count = 0;
while ((get_millisecond_tick() - begin_time) < 16.66)
{
    startADCConversion();
    while (isDoingConversion());
    int result = getADCResult() - 512; //subtract half value for 10-bit ADC to get signed result
    results_array[result_count] = ConvertADCValuetoAMPS(result);
    result_count++;
}
int total = 0;
int i;
for (i = 0; i < result_count; i++)
{
    total += results_arry[i] ^ 2; //square each term and add them up
}
total /= result_count; //divide by the total number of terms
int TrueRMSCurrent = sqrt(total); //the square root is the RMS value

The main point of caution about this circuit is that it is extremely sensitive to common mode error caused by resistor divider mismatch. For this demonstration, I manually matched two 10k resistors, then matched two 1k resistors. 1% tolerance resistors can not be counted on here. Unchecked you will simply end up with useless readings. Basically, you have three choices here.

  1. Use 0.1% tolerance resistors
  2. Match the resistors for like values manually
  3. Implement trimming

The Cost of Confidence

I made some minor changes to a prototype before ordering the final PCBs. Of course, I made a mistake. It was the kind of annoying mistake that results from not paying attention. I am now the proud owner of 100 green coasters.