The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

Category: Electronics Workbench

Electrical & Electronic gadgets

  • Refurbished LED Panels

    A recent Squidwrench meeting produced a treasure trove of discarded LED lighting, including a shoplight-style fixture in a narrow, finned aluminum extrusion. It was in “known-bad” condition, so I extracted the four LED panels, connected each one to a widowmaker cord, and determined I had two good ones, a mostly working one sporting some dead LEDs, and a corpse.

    The working panels showed the power supplies produced about 19 V across two parallel strings of six LEDs, with each string running at 350 mA for a total of 700 mA = 13 W. I wired up a quartet of 6 Ω power resistors to check out the power supplies from the suspect panels:

    LED Panel - power supply test setup
    LED Panel – power supply test setup

    The supply in the background is truly dead. I can’t tell whether it killed the LEDs or the gaggle of failing LEDs dragged it down with them.

    Some multimeter probing revealed enough live LEDs to restore the partially working panel. A rather sweaty interlude at the SqWr hot-air rework station transplanted the good LEDs, whereupon combining it with the live supply gave me a third fully functional panel:

    LED Panel - restored
    LED Panel – restored

    I did the test firing in the Basement Laboratory, because I’m nowhere near crazy enough to deploy a widowmaker line cord on the SqWr Operating Table in public.

    I bandsawed the last working LED from the gutted donor panel:

    LED Panel - single LED test
    LED Panel – single LED test

    The SMD LEDs mount on traces applied to and electrically insulated from the aluminum sheet, so unsoldering them required way more heat than you (well, I) might expect at first glance. A snap-on condenser lens over each LED concentrates the light into a nice cone, producing a narrow sheet of light from each panel.

    The elaborate aluminum extrusion seems much too heavy for the individual panels, but those open-frame supplies definitely need more than casual protection. Now that LEDs are more common than when these panels came off the assembly line, I should probably replace the supplies with enclosed constant-current drivers and be done with it.

  • Squidwrench Electronics Workshop: Session 5

    Topics for today’s Squidwrench Electronics Workshop: Session 5 in a continuing series.

    Having discussed transistors as current-controlled current sources, we can now select one as a victim use one as a switch, then add capacitors to learn about exponential charging, and introduce the oscilloscope as a vital tool.

    NPN Switch - protoboard
    NPN Switch – protoboard

    So, we proceed:

    Transistors as switches

    Review graphical parameters

    • saturation voltage for high Ic
    • cutoff voltage for near-zero Ic
    • resistive load line: VR = Vcc – Vc
    • power dissipation hyperbola (at all Vc)
    • secondary breakdown limit (at higher Vc)

    Something like this, only drawn much larger and with actual numbers:

    Transistor characteristics - saturation and cutoff - load line
    Transistor characteristics – saturation and cutoff – load line

    Reminder of linear vs. log scales converting hyperbolas into straight lines.

    NPN transistor as “to ground” switch

    • where to measure device voltages?
    • passing mention of flyback diodes
    • IB needed for saturation?
    • Darlington transistors: beta multiplier, VBE adder

    For example:

    NPN switch - LED
    NPN switch – LED

    Without the LED, you get nice square waves:

    NPN - 100 Hz - 2.2k - no cap - Vc
    NPN – 100 Hz – 2.2k – no cap – Vc

    An ancient green LED reduces Vc by a little over a volt:

    NPN - 100 Hz - 2.2k green LED - no cap - Vc
    NPN – 100 Hz – 2.2k green LED – no cap – Vc

    Discuss PNP transistor as “from supply” switch

    • why VCC must not exceed controller VDD
    • kill microcontroller and logic gates

    Wire up pulse gen to transistor

    • function generator for base drive voltage
    • collector resistor (then LED) as output
    • how do you know what it’s doing?
    • add oscilloscope to show voltages
    • explanation of scope functions!

    Capacitor as charge-storage devices

    Useful ideas and equations

    • C = Q/V
    • so C = ΔQ/ΔV
    • therefore i = C * Δv/Δt
    • energy = 1/2 * C * V²

    Charging capacitor from a voltage source through a resistor

    • Exponential waveform: e^t/τ
    • time constant τ=RC
    • show 3τ = 5%
    • and 5τ < 1%

    Add cap to transistor switch with R to soften discharge path

    • charge vs discharge paths
    • calculate time constants
    • wire it up
    • verify with oscilloscope

    The circuit will look like this:

    NPN switch - Cap charge-discharge
    NPN switch – Cap charge-discharge

    Discussion of parts tolerance: 100 nF caps are really 78 nF

    With one cap:

    NPN - 100 Hz - 2.2k 2.2k 78nF - Vc Vcap
    NPN – 100 Hz – 2.2k 2.2k 78nF – Vc Vcap

    Add another cap for twice the time constant:

    NPN - 100 Hz - 2.2k 2.2k 2x78nF - Vc Vcap
    NPN – 100 Hz – 2.2k 2.2k 2x78nF – Vc Vcap

    Let the scope calculate 10-90% rise time:

    NPN - 100 Hz - 2.2k 2.2k 2x78nF - Vc Vcap - rise fall times
    NPN – 100 Hz – 2.2k 2.2k 2x78nF – Vc Vcap – rise fall times

    Useful relations:

    • rise time = 2.2 τ (compare with calculations!)
    • rise time = 0.34/BW

    Do it on hard mode with the old Tek scope for pedagogic purposes.

    That should soak up the better part of four hours!

     

  • Streaming Radio Player: I2C Display

    Although I2C on the Raspberry Pi fails with devices using clock stretching, cheap I2C OLED displays seem to work well enough to not generate any problems search-able with the obvious keywords:

    RPi I2C OLED
    RPi I2C OLED

    Given a picture of the header pinout, the wiring is trivially easy:

    RPi I2C OLED - RPi header detail
    RPi I2C OLED – RPi header detail

    Using yellow for the ground hurts a bit, but that’s what I get for peeling the SPI cable down to four wires. The pin directly adjacent to the green wire is also ground, should that be easier to reach.

    Tweaking the Luma driver to use I2C doesn’t require much:

    #from luma.core.interface.serial import spi
    from luma.core.interface.serial import i2c
    
    ... snippage ...
    
    # reduce SPI bus from default 8 MHz to (maybe) avoid OLED failure-to-start
    #serial = spi(device=0,port=0,bus_speed_hz=1000000)
    
    # use I2C bus to avoid SPI timing spec failure
    serial = i2c(port=1,address=(0x78 >> 1))     # PCB label = 0x78, low bit = R/W
    

    The OLED PCB lists the I2C address with the R/W bit

    And then It Just Works, with one gotcha. Although the Python program shuts itself and the system down, the wall wart continues to supply power and, because the I2C bus doesn’t include a Reset line, the OLED display doesn’t know the RPi has gone away. So you must issue a command to turn it off before shutting down:

    device.cleanup()        # ideally, switches to low-power mode
    rc = subp.call(['sudo','shutdown','-P','now'])
    

    Now, to discover what works … oddly … with these displays.

  • Tektronix AM503 Current Probe Amplifier: Failed Electrolytic Capacitor

    The same Tektronix AM503 current probe amp with the slightly disconnected JFET developed a nasty 120 Hz hum, which can mean only one thing:

    Tek AM503 - corroded capacitor
    Tek AM503 – corroded capacitor

    Dunno how I missed that while I had the cover off, but there it is. For future reference it’s C165, 47 µF 50 V, with an 8709 date code.

    This being a PCB made back in the old days, likely with self-adhesive tape strips, the component pads inside ground and power pours lack thermal isolation decorations.

    The solder joints on the bottom side looks better than these, honest:

    Tek AM503 - replaced capacitor
    Tek AM503 – replaced capacitor

    The new cap is 56 µF 50 F, which seems Close Enough.

    The other caps have reasonable ESRs, but I must lay in a stock of high-voltage ‘lytics, as the “new” one is definitely old enough to know better, too.

    Now that I check, the amp still produces a very low amplitude 2 MHz sine wave on its 1 mA/div and 2 mA/div settings, suggesting Something Is Not Right™ in the front end, but it works well enough to let me defer that fix until later.

     

  • Frayed Power Drop

    The neutral conductor is down to its last three strands:

    Damaged neutral - over Redondo near pole 62859
    Damaged neutral – over Redondo near pole 62859

    Perhaps the power drop got snagged twice, because there’s a splice only a few feet away:

    Damaged neutral and splice - over Redondo near pole 62859
    Damaged neutral and splice – over Redondo near pole 62859

    Spotted overhead on Redondo near Rt 376 during an evening walk. I reported it using Central Hudson’s dead streetlight page, because there seems no other way to get their attention. It may be the homeowner’s responsibility, in which case a second splice will surely appear after the next power outage.

  • Raspberry Pi I2C Bus Timing vs. BNO055 Clock Stretching

    An Adafruit BNO055 connected to a Raspberry Pi 3 I2C bus, despite knowing it won’t work:

    I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd error
    I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd error

    The I2C bus ticks along at 100 kHz (nominal) = 62.5 kHz (actual), as described a while ago.

    The three digital traces along the bottom are D0 = SCL, D1 = SDA, and D2 = trigger raised when the Python program detects an error.

    The upper trace shows the SCL current (1 mA/div) between the Pi and the BNO055, as described yesterday, with the latter stretching the clock whenever the current goes negative.

    The fourth burst is the BNO055 sending the chip’s temperature in response to a simple request:

    
    temp_c = bno.read_temp()
    
    

    A closer look at the last transaction:

    I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd error - SCL glitch
    I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd error – SCL glitch

    I commend to your attention a useful tutorial on I2C bus protocols / transactions / signalling.

    Over on the left, the BNO055 has SCL held low (-2 mA) during the ACK phase of the previous byte. The first upward SCL edge marks the ACK, with the BNO055 holding SDA low during the edge until the Pi drops SCL.

    The BNO releases SDA when SCL goes low again, whereupon SDA goes high, exactly as it should.

    Now, things gets ugly.

    The -1 mA current on SCL shows both the Pi (+1 mA) and the BNO (-2 mA) are pulling SCL low.  The BNO is clock-stretching after the ACK, which the Pi can’t handle.

    The Pi seems to think the rising edge of SCL occurs when it stops pulling SCL down, at the point where the SCL current goes from -1 mA to -2 mA, halfway though the high SDA pulse. It reads SDA at that point and receives an incorrect binary 1 bit from SDA, because the BNO hasn’t yet seen a rising SCL edge.

    The SCL rising edge occurs when the BNO055 releases SCL and produces the SCL sliver.

    Here’s a very close look at the sliver:

    I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd error - Pi SCL mistiming
    I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd error – Pi SCL mistiming

    The two vertical cursors bracketing the sliver mark the 16 µs SCL timing produced by the Pi’s SCL clock, which is not the 10 µs you’d expect at 100 kHz.

    The right cursor sits on the next rising edge, so the left cursor marks where SCL should rise: exactly where the Pi releases its hold on SCL and expects it to pop up.

    That error happens about 6% of the time, producing a chip temperature 128 °C higher than reality. The other 94% of the reads either work correctly or, perhaps, encounter a bogus SDA state coincidentally delivering a binary zero that looks good.

    Here’s a sample of a “good” read:

    I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd OK - long SCL high
    I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd OK – long SCL high

    The stop bit is now off to the right, so the last rising SCL edge is the ACK. Counting leftward eight edges from the ACK, the left cursor marks where the SCL edge should be for bit B7. Instead it occurs instantly after the BNO releases its hold on SCL, shown by the transition from -2 mA to 0 mA. I don’t know the setup and hold times for the Pi’s I2C port, but 250-ish ns seem aggressive; I think the data transitions should happen close to the down-going SCL edges.

    Running the I2C bus at 200 kHz seems to work fine, but it still has the same aggressive SDA-to-SCL setup time. Here’s a close look at the same situation as in the previous photo, with SCL set for 200 kHz:

    I2C 200kHz - BNO055 SCL 1 mA-div - Rd OK - 250 ns SDA-SCL setup
    I2C 200kHz – BNO055 SCL 1 mA-div – Rd OK – 250 ns SDA-SCL setup

    This being a read, the BNO sets SDA to whatever it should be, then releases its clock-stretching hold on SCL about 200 ns later. The Pi raises SCL shortly thereafter and it apparently Just Works. Maybe it’s Good Enough to be consistent, but I’d like to run more tests before trusting it.

    Anyhow, that’s how the Pi’s I2C hardware doesn’t handle a chip using clock stretching.

  • Raspberry Pi I2C vs. Bosch BNO055 Clock Stretching: SCL Current Visualization

    Clipping a Tek A6302 Hall effect current probe around the I2C SCL line between a Raspberry Pi and an Adafruit BNO055 sensor breakout board:

    RPi I2C SCL current probe
    RPi I2C SCL current probe

    The arrow on the probe points toward the Pi, so (conventional) current flowing through the 10 kΩ pulldown resistors into the Pi will be positive and current flowing from the Pi into the BNO055 will be negative.

    The top (yellow, analog) trace shows the current (1 mA/div) flowing through SCL:

    I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd error
    I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd error

    The four distinct current levels show the clock state:

    • +1 mA = Pi pulling low
    • 0 mA = SCL high, no sinks active
    • -1 mA = Pi and BNO055 pulling low (clock stretching!)
    • -2 mA = BNO055 pulling low

    The 0 mA baseline isn’t exactly at zero, because the AM502 amp has thermal drift like you wouldn’t believe, particularly with the gain cranked to 1 mA/div.

    The probe + amp calibration seems slightly bogus: a 3.3 V supply pulled to ground at the Pi through the 10 kΩ resistor on the BNO055 breakout should deliver 0.33 mA, not nearly 1 mA. It’s close enough for now; I should cook up a probe calibration fixture.

    The BNO055 sinks about 2 mA, which suggests a 1.6 kΩ pullup to 3.3 V on the Pi. Although you’re supposed to have one pullup on the I2C bus lines, some casual searching with the obvious keywords shows the Pi has 1.8 kΩ resistors on board.

    Huh. Who knew?

    So Adafruit’s advice to add 2.2 or 3.3 kΩ pullups at the BNO055 (admittedly, for a Beaglebone, not a Pi, but I suspect some folks miss such details) lowers the parallel resistance to about 1 kΩ, just about as low as you should go. It is not obvious to me that reducing the resistance by a factor of two will change the bus timing by enough to rescue a marginal situation (stipulated: the Pi is beyond marginal). TI has a useful App Note  on the subject of I2C pull up resistance calculations.

    Anyhow, I now have a way to examine the Pi’s clock stretching bugginess in grim detail, which is the point of this exercise. Note that the hardware bug has remained un-fixed (probably tagged WONTFIX) in all Pi silicon versions, including the Pi 3 as of 2018.