Gas station without pumps

2015 July 31

Newer dimmer software

Filed under: Uncategorized — gasstationwithoutpumps @ 17:16
Tags: , ,

I just posted yesterday about new software for my PWM dimmers that provides smoother control of the light levels (having 256 levels plus off, rather than 63 levels plus off) with a 256:1 brightness range rather than the approximately 256:6 range of the previous code.

There was a bit of a problem with the lowest light level—it was more like 1/20th as bright as the second highest, rather than 1/2, and it flickered annoyingly. The other low light levels were also rather far apart, causing noticeable steps in brightness for about the first 10 steps.

So today I rewrote the code to have a genuine 512:1 brightness range (plus off), without the super-dim setting. This was a bit tricky to do, because the ATtiny13A has only a single 8-bit counter to use for PWM or any other timing.  I also wanted the minimum on-time for a pulse to be at least 5µs and the maximum PWM period to be less than 5ms.

What I did was to use the 8-bit PWM for the higher brightness levels, but turn it off for 3 PWM periods out of 4 for the low light levels.  I use the timer overflow interrupt to keep track of which PWM period I’m on, and to turn the PWM on or off.  To avoid glitches, I wait until the counter has counted up past the end of the PWM pulse, so that the PWM is only turned on or off when the output is low.  (That’s not quite true—for turning the light off or operating in the top half of brightness, I can switch the PWM mode at any time—it is only when I’m trying to do one out of four PWM periods that I need to be careful about glitches.)

I don’t have a full 1024-bit PWM range.  In addition to OFF, I have 303 light levels, 63 for low light levels (from a duty cycle of 2/1024 to 64/1024 in steps of /1024) and 240 for high light levels (from a duty cycle of 17/256 to 256/256 in steps of 1/256)

The conversion from the linear 10-bit analog-to-digital reading (0–1023) to pulse lengths is done by the following method:

if ADC >= 512
    use SHORT PWM (256)
    expon = ADC>>7
    frac = 0x80 + (ADC & 0x7f)
    pulse_len = 1+ (frac>> (7-expon))
else if ADC >= 8
    use LONG PWM (1024)
    pulse_len = 1 + (ADC >> 3)
else
    turn PWM off

The transition between the short and long PWM periods is evident in a plot of the pulse width and duty cycle:

For the first half of the range, I use a linear scaling for potentiometer to brightness, and for the second half I use a stepwise linear approximation to an exponential.

The minimum pulse width is about 6.7µs, and the long PWM period is about 3.4ms.  There is a trivial modification to allow 1/1024 duty cycle (change the first threshold from 8 to 4), but the shortest pulse is then too short to turn on the LED boards, giving either a very dim light or no light, depending on exactly how low the drain voltage gets in the available time.

I also added some hysteresis to the reading of the analog-to-digital converter, to avoid flicker from digitization noise when the value was near a threshold. The new code is a bit bigger than the previous code (372 bytes instead of 222), but still well below the 1kB limit of the flash.

I’ll need to reprogram the desk lamps again.

Seventh weight progress report

Filed under: Uncategorized — gasstationwithoutpumps @ 10:27
Tags: , , ,

In 2015 New Year’s resolution , I said that I want to lose 10–15 pounds by June 2015. In Weight-loss progress report, Second weight-loss progress reportThird weight-loss progress report , Fourth weight-loss progress reportFifth weight-loss progress report, and Sixth weight-loss progress report I provided monthly updates.

My weight was remarkably stable in July, and my average weight since May 1, when I switched from weight loss to weight maintenance is 158 lbs.  I think I’d prefer 157 lbs, but I’m happy with how stable the weight has been and am not going to change any habits to try for an adjustment that is less than the normal random fluctuation in weight.

My weight stayed within my target range for all of July.

My weight stayed within my target range for all of July.

Despite my predictions last month, I bicycled up to campus several times in July, though I only averaged 3.48 miles/day for the month, which is less than the 4.05 miles/day I’ve averaged over the last 400 days.

2015 July 30

Getting KL25Z bootloader to work without Windows 7

Filed under: Circuits course — gasstationwithoutpumps @ 20:26
Tags: , , , , ,

The one thing I hate about the Freedom KL25Z boards is that they are shipped with a bootloader that doesn’t work.  More precisely, they are shipped with a bootloader that works only with Windows 7, not Mac OS X, not Linux, and not even Windows 8.  (Note: never get P&E Micro to do any software work for you—they are responsible for this crappy bootloader.)  There is a newer bootloader from P&E Micro, but you need a Windows 7 computer to download it, so that does no good at all (it’s worse than that: see below).

I bought a new KL25Z board recently, to replace one that my son borrowed for Futuristic Lights, and soldered up the headers today, and was ready to test it out. I was hoping that they were now using one of the newer P&E bootloaders, that supposedly works on Macs (I’ve never seen a P&E bootloader that works with Macs, but I was willing to believe that P&E got enough complaints that they eventually fixed their bugs). Unfortunately, what I got is

MicroBoot Kernel Version is: 1.05
Bootloader Version is: 1.09

but P&E Micro reports

Bootloader versions 1.10 and earlier are not allowing firmware update and MSD FLASH programming on my OpenSDA board, with the Linux, MacOS, or Windows 8/8.1 operating systems.

I understand that on some of their newer boards, Freescale is using the mbed.org bootloader, which is the one I want to install on my KL25Z board. My choices at this point seem to be:

  • Take the 6.5-mile bicycle ride round-trip to campus to use an ancient Windows 7 machine from the circuits lab (this is what I’ve done in the past).
  • Buy a Windows 7 laptop to use at home, for initializing KL25Z boards and for testing PteroDAQ multi-platform support.
  • Look on the web for a workaround.
  • Ask my son if he found a workaround for his Linux laptop.

I’m too lazy to bike to campus (I did that cycle ride 4 times in the last 6 days), and I can’t get a laptop delivered instantly (and it will take quite a bit to put aside my aversion to Windows enough to buy even an $85 used laptop with Windows). That leave the web search and asking my son.

I did find a workaround on the web for Windows 8 [https://community.freescale.com/message/440982#440982]:

Configure “Do not allow locations on removable drives to be added to libraries”  as discussed here: http://answers.microsoft.com/en-us/windows/forum/windows8_1-hardware/how-do-i-prevent-system-volume-information-files/815b0046-d631-4419-a43e-44083a3733f5 and you should be able to do updates from Windows 8.1.

I don’t know whether this workaround works, as I don’t have access to a Windows 8 machine to test it on.

My son pointed me to a workaround that has been posted for Linux systems [http://karibe.co.ke/2014/04/changing-the-firmware-on-freescale-freedom-boards-in-linux/], and that he has used successfully. I tried that on Mac OS X, but the utilities for manipulating mounting of disks is different—you need to use ‘diskutil unmount’ and there is no “modprobe”.

I tried doing the closest corresponding actions on Mac OS X, but they did not work.  I could unmount and mount the disk easily enough (it showed up as /dev/disk1, which can be most easily discovered with ‘diskutil list’), but copying the mbed sda file to the disk still had no effect.

We tried the original script from karibe.co.ke on my son’s Linux laptop, and it worked ok.  We could install the mbed.org firmware (from https://developer.mbed.org/handbook/Firmware-FRDM-KL25Z) using the Linux script with the unmount/mount trick. The mbed software worked as usual to download PteroDAQ to the board.

I think tried some more experimenting. We updated the Bootloader to v1.11, using the latest download from P&E Micro, as pointed to by their OpenSDA page. The update worked, to the extent that the Bootloader reported being v1.11, instead of 1.09, but despite P&E’s claims, it still did not work with Mac OS X. I could not download P&E micro .SDA files nor  the 20140530_k20dx128_kl25z_if_opensda.s19 file from mbed.org.

So we used my son’s Linux laptop again to put the mbed software on the KL25Z board, and I’ll have to be carefully not to get into Bootloader mode unless either he’s around with his laptop or I’m willing to cycle to campus.  (Or I break down and get a junky Windows laptop just for rebooting KL25Z boards.)

My son has been suggesting that we get a junky Windows box, so that he can test out the multi-platform features of PteroDAQ without having to cycle to campus with me.  I might do that while he is away at Ashland next week, if I can find a cheap enough laptop that I believe will actually function.

New dimmer software

Filed under: Uncategorized — gasstationwithoutpumps @ 15:46
Tags: , , , , ,

Based on the success of the stroboscope software, I rewrote the dimmer software for my desk lamp (see LED lamp projects for more about the lamps).  The new software provides smoother control of the light levels (having 256 levels plus off, rather than 63 levels plus off) and now has a 256:1 brightness range rather than the approximately 256:6 range of the previous code.

I removed a lot of the general-purpose crap that was inherited from core13 (which was in turn stripped down from the Arduino core software).  I did not get rid of all of core13, so I could probably take out another 50–100 bytes, but the code is down to 222 bytes (and the ATtiny13A has 1kB of flash, so I’m way below the limit).

The actual brightness range of the new dimmer is a bit more than 256:1, because on the shortest pulse the FET doesn’t turn all the way on.  The pulse duration from the ATtiny13A is approximately 3.4µs times the brightness level (9.6MHz clock divided down by 4 and by 8), but I had deliberately slowed the FET transitions by adding a series resistor to the gate, so that nFET doesn’t finish turning on for 5.2µs (as judged by the end of the Miller plateau on the gate).  So at the lowest brightness level, the nFET does not turn all the way on and the voltage on the drain only gets down to 3.5V, which leaves 5.5V across the LED board—enough to turn on the LED, but with only about 10mA, not 118mA. At this low level, the LEDs sometimes flicker, perhaps as a result of some thermal feedback effects. The all flicker together, so the effect is probably in the dimmer’s nFET, not on the LED boards.

ATtiny output (green) and gate voltage (yellow) at 2V/division and 2µs/division for the shortest pulse length.   The gate voltage has not quite reached the end of the Miller plateau before being discharged again.

ATtiny output (green) and gate voltage (yellow) at 2V/division and 2µs/division for the shortest pulse length. The gate voltage has not quite reached the end of the Miller plateau before being discharged again.

ATtiny output (green) and drain voltage (yellow) at 2V/division and 2µs/division for the shortest pulse length.  The BitScope BS-10 oscilloscope clips the voltage to 5.5V—it actually goes to 9V.

ATtiny output (green) and drain voltage (yellow) at 2V/division and 2µs/division for the shortest pulse length. The BitScope BS-10 oscilloscope clips the voltage to 5.5V—it actually goes to 9V.

At the next brightness level, the drain voltage does drop to 0V for at least 2.4µs and stays low enough for the LED board to be at maximum current (below 2.5V) for at least 5.5µs.  There is an enormous difference in brightness between length 2 and length 1 pulses (more like 1:20 than 1:2), because of the low current for pulse length 1, but for length 2 and longer the steps in brightness are pretty much as one would expect from the pulse lengths.

ATtiny output (green) and gate voltage (yellow) at 2V/division and 2µs/division for the shortest pulse length.   The gate voltage has gone past the end of the Miller plateau and started charging past that point. The Miller plateau is also visible on the discharge as the nFET turns off.

ATtiny output (green) and gate voltage (yellow) at 2V/division and 2µs/division for the shortest pulse length. The gate voltage has gone past the end of the Miller plateau and started charging past that point. The Miller plateau is also visible on the discharge as the nFET turns off.

ATtiny output (green) and drain voltage (yellow) at 2V/division and 2µs/division for the  second shortest pulse length.  The BitScope BS-10 oscilloscope clips the voltage to 5.5V—it actually goes to 9V.  The longer pulses allow the nFET to turn on fully.

ATtiny output (green) and drain voltage (yellow) at 2V/division and 2µs/division for the second shortest pulse length. The BitScope BS-10 oscilloscope clips the voltage to 5.5V—it actually goes to 9V.
The longer pulses allow the nFET to turn on fully.

The conversion from the linear 10-bit analog-to-digital reading (0–1023) to pulse lengths is done by the following method:

expon = ADC>>7
frac = 0x80 + (ADC & 0x7f)
pulse_len = ADC < 0x20? 0:  ADC < 0x40? 1: 1+ (frac>> (7-expon))

The stepwise nature of the brightness at low levels is apparent in a plot of the conversion function:

The steps in brightness are quite visible at the low end, but after the first 10 steps, the differences are small enough not to be easily noticed.

The steps in brightness are quite visible at the low end, but after the first 10 steps, the differences are small enough not to be easily noticed.

Overall, I’m pleased with the rework of the dimmer code. I’ll probably have to solder up another of the dimmer boards this summer, since I’ll want one for the light fixture that I haven’t started building yet and one for the Halloween stroboscope.

2015 July 29

LED strobe using dimmer board

Filed under: Uncategorized — gasstationwithoutpumps @ 23:49
Tags: , , , , , ,

In the evenings this week, I soldered up another PWM controller for the LED lamp projects, and programmed it with the ISP cable I made.  The intent was to use this dimmer either with the breakfast-room lighting fixture (which I’ve not made yet) or reprogram it to act as a strobe rather than a dimmer, to replace the Xenon-tube-based Velleman strobe kit that failed last Thanksgiving.

This project took me much longer than expected, because of stupid mistakes I made:

  • I forgot that there was a silkscreen error on the dimmer boards that I had designed.  The outline for the voltage regulator is flipped, because I had not noticed when reading the spec sheet shows the device from the bottom—I’m used to chip views being from the top.  This is the second time that I’ve soldered a voltage regulator on one of the boards backwards, and had to cut it off and replace it with a new one.  I guess I’d better take a permanent felt-tip marker and draw the correct orientation on the remaining boards, so that I don’t make that mistake a third time.
  • When playing with new code for the strobe, refamiliarizing myself with the ATtiny13A processor, I changed the prescaling on the system clock from the default 1.2MHz down to about 75kHz.  What I had not realized is that the on-chip clock is used during the reprogramming also, and the Arduino ISP is not set up for slowly clocked chips.  I found code for TinyISP, which has code for 128kHz clocks, but even when I modified it for 75kHz clocks I couldn’t reprogram the chip (always getting the “Yikes! invalid device signature” message with a signature of 0). Eventually, I gave up, unsoldered the ATtiny13A and put in a new one.  I’ll be very careful in future not to slow down the system clock so much.
  • I got the strobe working this morning, but when I looked at the output pin that was driving the FET gate, it was only going up to 1.3V, not 5V, and the pulse was much longer than I expected.  This mystified me for a while, but I finally realized that I had forgotten to turn the pin on as an output, so I was driving the output just through the built-in pullup resistor, resulting in a very large RC time constant.  The flat top I was seeing on the pulse was probably the Miller plateau.  Enabling the output pin correctly got me back to crisp 5V pulses of the designed duration.
  • The designed duration for the pulses was a bit too short, resulting in a somewhat dimmer than desired flash.  Lengthening the pulse to 1ms was fine for the slow strobes, but at high flash rates the strobe got too bright. So I reprogrammed the flashes so that the on-time was 1/64th of the off-time, but with a maximum on-time of 1.6ms. (I also tried on=off/128 with a maximum of 1ms, but I liked the 1/64 better).

I timed the strobe pulses from the board (looking at the output of the ATtiny13A pin 6, which is also connected to the MISO pin of the ISP header, so is easy to connect a jumper wire to) with PteroDAQ (through a voltage divider, to drop the voltage from 5V to 2.75V).  By triggering the PteroDAQ on edges of the signal, and averaging many measurements, I got very precise timing measurements:

setup on-time off-time
slowest setting, 1:64 1.63745ms 1.52372s
fastest setting, 1:64 104.958µs 6.98761ms
slowest setting, 1:128 955.277µs 1.55881s
fastest setting, 1:128 51.3123µs 6.99286ms

The difference in the “slowest” settings is probably just from my inability to set the knob identically—it has to be just above a threshold below which the strobe doesn’t flash at all. In any case, I have a period from 7.1ms (141Hz) to 1.525s (0.6556Hz), which is a pretty useful range.  I also made the range very smooth, by taking the 10-bit ADC range and converting it to this 215:1 range sort of exponentially with just a few instructions:

if adc < 40, then OFF
exp = adc >> 7
frac = 0xff - (adc & 0x7f)
off_time = (frac << 8) >> exp
The tiny number of instructions provides a surprisingly smooth and strictly decreasing approximation to the desired exponential.

The tiny number of instructions provides a surprisingly smooth and strictly decreasing approximation to the desired exponential.

The transition is smooth because every time an increment increases the exponent, the frac part is doubled (from 0x80 to 0xff).I use a 16-bit word for the off_time and count it down with an interrupt once every 26.67µs (256 of the approximately 9.6MHz clock ticks). I think that I’ll do a similar thing for controlling the duty cycle of the dimmer, rather than the table of bytes that I currently use, though the duty cycle is limited to a single byte, so I’ll only have 256 levels, and not 1024, and I’ll want the duty cycle to increase exponentially, rather than decreasing, but those are easy fixes.

I also reduced the size of the program in flash, by getting rid of some of the overly general code from core13 and just manipulating the peripheral control registers directly.  I didn’t need to do this, as the ATtiny13A has 1kB of flash, but I got down to 364 bytes (and could probably strip out another 50–100 by getting rid of even more of core13).  The old dimmer code, which doesn’t have much more to do, currently takes 806 bytes, so I might try tightening that up tomorrow.

I also tried powering the strobe off a 9V battery.  The LED board takes about 117mA when turned on (see LED board I-vs-V curve), and if I keep the duty cycle below 1.5%, then the average current is dominated by the ATtiny13A’s worst-case 6mA current, and the total current for the board is probably less than 8mA.  According to Duracell’s data sheet for their 9V alkaline battery, I should be able to get about 50 hours of life before the voltage drops below 6.7V (at which point the LED board no longer maintains the constant current, but I could run the strobe a bit longer getting dimmer).  The 6.7V is also about the voltage where the LDO voltage regulator starts being unable to supply 5V to the ATtiny13A, though that is less of a bottleneck, as the chip can run with the 9.6MHz internal clock down to 3V with no problems.

The battery does not have to provide a full 117mA for the pulses, as there is a 470μF polymer electrolytic capacitor on the dimmer board.  Delivering 117mA for 1.6ms is only 187μC, so the voltage on the capacitor would dip at most 0.4V during the pulse, even without the battery.  The 9V battery has an internal resistance of 2Ω–4Ω, so it could provide 117mA with about a 0.35V drop, so the capacitor isn’t really necessary for one LED board.  It probably increases the efficiency slightly, as the I2R power loss in the internal resistor is reduced if the current is spread out (half the current for twice as long is only half the I2R loss).

I could put more LED boards on the strobe, as the dimmer is designed to handle 5A or more, but battery  operation would limit me to about 10 boards before the voltage drop was large enough to cause problems for the current regulation.  One LED board is bright enough for a Halloween pumpkin, but I could run wires between pumpkins to power several off the same controller.  (I could also keep the controller in the house, powered by a wall wart, and run wires out to the LED boards—I could then power 40 or 50 LED boards off the strobe, though I’d have to watch out for IR drop in the wiring.)

I might try wiring up 10 boards tomorrow, and see whether a battery really can power that many.

Next Page »

%d bloggers like this: