Thursday, August 13, 2026

Quotes - Engineering

“If you were plowing a field, which would you rather use: two strong oxen or 1024 chickens?”
— Seymour Cray
  
"... AI won't replace people, but maybe people that use AI will replace people that don't."
 - Andrew Ng, 2024 
 
"My Favorite Programming Language is Solder."
- Steve Ciarcia
Also atrributed to Bob Pease, Terry Pratchett, and others 
  
"Every year there are 200,000 Chinese engineering graduates, and they don’t know what we know. We can solve problems they cannot.” 
- Robert A. Pease, Analog Circuits: World Class Designs, 2008
 
"... there's no patent on intellectual capability."
- Jim Williams, Interview with Bob Dobkin and Jim Williams April 19, 2006
Silicon Genesis: Oral Histories of Semiconductor Technology
 
"I may be the only person at an electronics flea market who will pay more for the busted stuff!"
- Jim Williams, The Importance of Fixing,  
The Art and Science of Analog Circuit Design

"No one believes an analysis – except the person who did it.
Everyone believes a test – except the person who did it."
- ???

‘‘The best way to predict the future is to invent it.’’
 - Alan Kay

“Successful engineering is all about understanding how things break or fail.”
- Henry Petroski

"engineering ... is the art of doing that well with one dollar, which any bungler can do with two after a fashion."
- Arthur M. Wellingtony, The Economic Theory of the Location of Railways

"Engineer - the man who can do for a reasonable cost what another would expend a fortune on"
- Rutherford Aris, Vector, Tensors and the Basic Equations of Fluid Mechanics 

“In God we trust. All others bring data.”
- Bo Lojek, History of Semiconductor Engineering

"Research is when you don't know what you're doing."
- ??? 

“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.”
- Antoine de Saint-Exupéry, Airman's Odyssey
 
The cheapest, fastest, and most reliable components are those that aren’t there.
- C. Gordon Bell

"When you test you find something is wrong."
- Donald Trump (May 14, 2020, about the COVID tests)

I would rather have a general who was lucky than one who was good.

- Napoleon Bonaparte

"Perfect is the Enemy of Good Enough"
- Eric Johns (October 1988), U.S. Naval Institute Proceedings: 37

“If an expert says something can be done he is probably correct, but if he says it is impossible then consider getting another opinion.”
- Richard Hamming, The Art of Doing Science and Engineering 

People who are really serious about software should make their own hardware.
- Alan Kay

The management question, therefore, is not whether to build a pilot system and throw it away. You will do that. […] Hence plan to throw one away; you will, anyhow.

Brooks's Law: 
Adding manpower to a late software project makes it later.

The Second-System:

    This second is the most dangerous system a man ever designs. 

 - Brooks, The Mythical Man Month

... this was going to be one of these Onion Syndrome deals - you peel off a couple layers, and cry; then you peel off a couple more layers, and cry some more.
- Bob Pease, What's All This Ground Noise Stuff, Anyhow?

Thinking is recommended. Heck, thinking is required.
- Bob Pease, Troubleshooting Analog Circuits

... a little known tenet of precision op amp circuits: Williams's Rule.  Williams's Rule is simple: always invert (except when you can't).
- Jim Williams, Analog Circuit Design: Art, Science, and Personalities


"Any idiot can count to ONE ..."
- Quoted by Samuel Wilensky in Analog Circuit Design: Art, Science, and Personalities
(maybe attributed to Bob Wildar)

Anyone can build a bridge that stands up, but only an engineer can build a bridge that just barely stands up.
- ????

"A user interface is like a joke – if you have to explain it, it's not that good."
- ????
 
In software, debugging is harder than writing code.  If you write the code as clever as you can, then you are not smart enough to debug it.
- ????

All problems in computer science can be solved by another level of indirection, except for the problem of too many layers of indirection.
-????

... practicing what was called "the mushroom theory of management." ... defined it as follows: "Put 'em in the dark, feed 'em shit, and watch 'em grow."
- Tracy Kidder, The Soul of A New Machine

Hardware eventually fails. Software eventually works.
-Michael Hartung

Quotes - Math and Science

 
"Even Hilbert had only a few tricks!"
- Gian-Carlo Rota, "Ten Lessons I Wish I Had Been Taught", 1997 
 
“Good, He did not have enough imagination to become a mathematician.” 
- David Hilbert, after learning that a student in his class had
dropped the subject in order to become a poet.
(David Darling, The Universal Book of Mathematics)  
 
"How can you do physics and poetry at the same time? The aim of science is to make difficult things understand able in a simpler way; the aim of poetry is to state simple things in an incomprehensible way. The two are incompatible." 
- Dirac once said to Oppenheimer
(Helge Kragh, "Dirac: A Scientific Biography")  
  
"A good building should not show its scaffolding when completed."
"No self-respecting architect leaves the scaffolding in place after completing his building."
- Gauss  
 
“There’s a tradition of scientists approaching senility to come up with grand, improbable theories. Wolfram is unusual in that he’s doing this in his 40s.” 
- Freeman Dyson told Newsweek in 2002 
 
"If I had to choose one book to take to a desert island, I would take Zygmund’s Trigonometric Series if I thought I might be rescued, but Hardy and Wright’s Number Theory if I knew that I was never coming back." 
 - T.W.  Körner, Foreword to A Course of Pure Mathematics, 2008
  
"... true knowledge can only be acquired piecemeal, by the patient interrogation of nature."
- Edmund Whittaker, A History of the Theories of Aether and Electricity

"The first time you go through the subject, you do not understand it at all. The second time, you think you understand it, except for one or two small points. The third time, you know that you do not understand it, but you are so used to the subject that it does not bother you anymore."
- Arnold Sommerfeld, about thermodynamics

"All science is either physics or stamp collecting."
- Ernest Rutherford

"those who can, do; those who can't, teach."
George Bernard Shaw, Man and Superman

"Research is when you don't know what you're doing."
- ??? 

In real estate, it is location, location, location.  In mathematics, it is notation, notation, notation.
- ????
 
... where there is no confusion there is no prestige.
-Linderholm, Mathematics Made Difficult

Wednesday, August 12, 2026

Review of Computer Architecture Seventh Edition

 We had discussed the six editions of the authoritative text on computer architecture.  Eight years after the 6th edition, we have the 7th edition, published in October 2025.  A quick scan of the table of content seems to show no new major concept. There is no large increase of page counts, only about 40 pages (out of 1,563 pages including all appendices).  A third author is added.  RISC-V continues as an example for instruction set principle. The famous processor performance chart is extended by a few years, but only to 2022 and the performance increases from 2015 is revised up to 9% a year (from 3.5%).  The top processor at 2017 is Intel Core i7 4.2GHz with performance score of 49,935, and at 2022 Intel Xeon E-2388G 3.2GHz with score 88,833.  Note the performance increase of 80% while the clock speed actually goes down (though the boost speed is a little higher).  The Moore's law seems to continue but performance increase has been significantly curtailed since 2004 when the Dennard's scaling law ended.

 What has been going on in this eight years?  The emergence of AI, represented by ChatGPT that made debut in 2022 is the most significant.  There is a mad dash to adopt AI in every industries and in everyday life.  And datacenters that support AI are being built in a such scale that causes shortage in chips and propels NVidia to one of the most valuable companies.  The vulnerability of computer architecture to malicious attack such as Meltdown and Spectre stunned computer architecture community.  The bedrock of the modern processor techniques of cache memory and speculative execution can be exploited.  The security issues are addressed in the new edition: side-channel attacks on the memory system and speculative and multithreading execution unit. With this the authors admonish the lack of adequate tools to address the security issues in processor design.

The chapter on warehouse-scale computing debuted in the fifth edition (2011) (as the book cover starts to show cloud).  The discussion always seems to me having been a little weak.  That situation has largely been remedied in this new edition.  But curiously, the concept of request-level parallelism, coined when the WSC was first introduced is merged into thread-level parallelism, as the cores become more numerous.

And the chapter on domain-specific architecture debuted in the sixth edition (2017) has shown significant improvements.

 Despite of many clever architectural innovation, the quantitative aspect of the computer design still seems naive.  The mathematical tools are so elementary (as in only elementary school arithmetic).  Perhaps we need to introduce more sophisticated tools or language to model computer architecture more precisely. Queuing theory was introduced briefly related to storage system.

 The realization of the similarities between vector processors and GPUs is significant. It bridges the two seemingly disparate concepts and allows a more uniform discussion, using the traditional language of computer architecture to discuss the GPUs which have evolved their own terminologies, unfamiliar to the outsiders.  As the GPUs break through the original 3D graphics accelerator to more general high-performance computing, that is especially suited for the AI processing.  And the GPUs have introduced low resolution float number computing unit particularly targeted the AI applications.

This may be possibly the last edition by the two original authors.  In any case, it is a remarkable run of 35 years when the first edition was published in 1990, when the Intel i486 just came out.  However, since there is no new concept introduced in this edition, is the field of Computer Architecture becoming barren?

Thursday, May 7, 2026

Tatung Rice Cooker

The Tatung Rice Cooker is legendary.  It is durable, easily lasting twenty or thirty years.  Its construction is very simple and rugged, devoid of fancy electronics.  Currently it commands of a price of $200, several times that of the competitors.  But it often fails in a rather simple way: the power cord.  The power cord can break near the plug at the strain relief, at the entry point to the interior because of repeated twisting and flexing and the ring terminals inside because of rust (the neutral terminal seems more likely to rust, why is that?).  Replacing the power cord can extend its life for many more years.  The repair is simple.  Once the bottom cover held by one screw is removed, the wiring is clearly shown.  Note that the fiberglass sleeves are placed over the power cord wire.  The insulation has to withstand high temperature, so choose the power cord with temperature rating of 105°C.

The circuit diagram probably looks like this,

Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings
Ink Drawings

The temperature control is achieved by a magnetic switch.  When  the lever is pushed, the magnets close the springy electric contacts to power the heating coil.  The heating coil is about 18 Ohms, which is about 800W at 120V, which is the rated power.  When the coil heats up, the resistance increases and the power settles down about 740W.  The coil is completely sealed to prevent oxidation. When the water evaporates, the temperature goes up rapidly and the magnet loses magnetic field and breaks the contact.  It can be verified that the switch does not close immediately afterwards.  When the temperature is below the magnet's Curie temperature, this demagnetization is reversible.  Because the temperature drops when the contact is broken, the magnet does not lose the magnetization permanently.  The Curie temperature is 450°C for ferrite magnet.  The switch is open at about 220°C and the magnet regains its magnetic field below 160°C.

There is also a keep-warm switch, which adds a resistor (about 380 Ohms) to the coil and reduces the heating power (to about 35W) and keeps temperature around 50°C.

  

Sunday, February 22, 2026

Port MicroPython to PolarFire SoC

 We have built MicroPython for STM32F429DISC previously.  We'll use it as a guide to port MicroPython to MPFS Discovery Kit and Beagle-V Fire, featuring PolarFire SoC.  It is straightforward to compile for the minimal configuration.  We aim to achieve the same functionalities as STM32F429DISC.  In the hardware-wise comparison, the shortage of non-volatile memory can be overcome by using a micro-SD card.  PolarFire RISC V supports both single and double precision floating point; STM32F429 supports only single precision. 

STM32F429I-DISC1MPFS-DISCO-KITBeagle-V Fire
CPUCortex-M4FQuad RV64IMAFDCQuad RV64IMAFDC
Flash2M128K128K
SRAM256K1.8M1.8M
SDRAM8M1G2G
eMMC--16G
SPI Flash--16M
Debug/ProgST-LINKFlashProFlashPro
USB-UART133
Ext Headers2x 2x32RPi + MikroBusBeagle Cape 2x 2x23
ConnectorsMIPI CSIM.2 PCIe, MIPI CSI, QSH-40
ADC Channels24?-7
DAC Channels2--
User LEDs2812
Push Buttons222
Dip Switches-8-
SensorMEMS gyro--
USBOTG-OTG
Ethernet-1 GigE1 GigE
Display2.4" QVGA LCD touch--
Ext Storage-microSDmicroSD

The STM32F429DISC build includes the following modules.

>>> help('modules')
__main__          builtins          json              select
_asyncio          cmath             machine           socket
_onewire          collections       math              stm
array             deflate           micropython       struct
asyncio/__init__  dht               network           sys
asyncio/core      errno             onewire           time
asyncio/event     framebuf          os                uasyncio
asyncio/funcs     gc                platform          uctypes
asyncio/lock      hashlib           pyb               vfs
asyncio/stream    heapq             random
binascii          io                re
Plus any modules on the filesystem

The MicroPython does not seem have a good way to manage configurations.  The #define parameters that affect the build can come from a number of places, many include files and many makefiles.  And the dependencies are not always clear.

First MICROPY_CONFIG_ROM_LEVEL can range from minimum, core, basic, extra to full, which enables more feature.  We can change it from minimum to extra.  This enables the majority of features, including compiler, stack check, helper REPL, EMACS keys in REPL, scheduler, micropython module, etc.  

 Then we add the additional options enabled by STM32.  We include FROZEN_MANIFEST, which requies in the micropython-lib submodule.  We enable VFS, which turns out have some tricky dependencies.  We have to define MICROPY_VFS_FAT in the makefile in order to bring in the oofatfs.  This compiles to about 300K (text+data).  STM32 uses a portion (112K out of 2M) of its Flash to make a file system that stores initialization files like "boot.py" and "main.py". We will make use of the micro SD card.

 Next, we want to enable floating number.  We run it on one of the application cores that support floating number.  We set MICROPY_FLOAT_IMPL to double in the makefile.  This causes additional variable to be set.  This compiles to 360K and the math module is available.

We enable the machine module by defining MICRO_PY_MACHINE.  The machine module supports peripherals such as uart, spi, i2c, timer etc; board specific code has to be write to make them work. Additional python modules can be added to manifest.py.  We also include the network module.  Another useful module in STM32 is stm, which provides access to peripheral registers and we implement a similar module. The compiles to 430K.

At this point, we have the following modules,

>>> help('modules')
__main__          builtins          json              select
_asyncio          cmath             machine           socket
array             collections       math              struct
asyncio/__init__  deflate           micropython       sys
asyncio/core      errno             mpfs              time
asyncio/event     framebuf          network           uasyncio
asyncio/funcs     gc                os                uctypes
asyncio/lock      hashlib           platform          vfs
asyncio/stream    heapq             random
binascii          io                re

Now we have to write some actual code.  As a warm-up, we first add the LED class to the machine module.  Extra classes can be added by defining MACHINE_EXTRA_GLOBALS in the port modmachine.c, which is inserted into extmod/modmachine.c.  STM32 has a separate module, pyb, that contains the LED and other devices with some overlap with machine.  We can borrow code from STM32 and only change the GPIO code.  There are 8 user LEDs that can now be controlled by from Python.

Before we add the drivers for the other peripherals, GPIO, SPI, I2C, UART, Timers, we want to look into the Micropython compilation and assembly code for RISC-V by defining EMIT_RV32 and EMIT_INLINE_RV32.  MicroPython can emit native code instead of byte code.  The decorator @micropython.asm_rv32 seems to work; as example,

>>> @micropython.asm_rv32
... def mul(a0,a1):
...     mv(t0,a0)
...     mv(t1,a1)
...     mul(a0,t0,t1)
...
>>> mul(5,10)
50

But @micropython.native does not. It crashes when running the function with that decorator; the cause of the crash is illegal instruction.  Interestingly, it does not work on STM32 either.   EMIT_THUMB_ARMV7M is enabled by default, but disabling it does not solve the problem.  We'll have to investigate further.  In addition, we need to extend to support RV64.

 


 

Thursday, February 12, 2026

Sinusoidal Oscillator on PSoC

Sinusoidal signal can be generated with the wave DAC and low pass filter.  But here we will attempt to generate sine wave the analog way.  We will use a servo loop to stabilize the adjustable amplitude.

As a warm-up, we will try the simple classic Wien bridge oscillator using one PSoC opamp and a miniature light bulb.  The bulb has a resistance of 67 Ohms cold and 170 Ohms at 6mA.  It produces a nice sine signal.  




Friday, February 6, 2026

Troubleshooting a Quartz Clock

 A twenty-five year old quartz clock stopped working.  I'm curious to see what has failed.   Opening up the clock, we see a simple one-layer PCB with a COB (chip-on-board), a crystal, a transistor and a magnetic buzzer.  The clock movement comes from the stepper motor with a coil resistance of 545Ω; the coil is driven in the alternative directions every second.  A number gears form the hour, minute and second hand.  The alarm is set with another gear that causes a spring loaded contact to short out two pads when the hour hand coincides with the alarm hand and as the hour hand moves it pushes the contact away from the pads to stop the buzzer.

The clock was not completely dead.  Occasionally, it started, but it would soon stop moving.  All the electrical connections seemed OK.  To be sure of no cold soldering joints, I reflowed all the joints.  I probed all the connections that were possible to get to and it appeared that the voltages were getting to the circuit; both the stepper coil terminals sat at the rail and there were bias voltages on the quartz crystal terminals.  I could not see any obvious wrong.  During the course of troubleshooting, despair set in the first time.  Where should I go from here?

We stepped back and asked, what could possibly go wrong for 25-year old device?  Nothing on the electronics side: the COB was unlikely, the crystal might age and be out of frequency spec but not dead, and the buzzer was irrelevant.  It was more likely the wear-and-tear of the mechanical parts. 

Now I started to take apart of more the mechanical parts.  The gears seemed free to move, so I should see some movement if the electronics were driving it.  I could eventually rule out mechanical issues by noting that some voltages for the alarm were not at the correct values.  The voltages at the crystal leads would be stuck at a higher values and the voltages to the motor coil was static when compared with when it was running (the pulse to the motor was brief but still visibly to the multimeter). It implied the clock was not oscillating and the circuit did not start.  I even replaced the crystal with another one that came from a digital watch, but it did not work.  It was progress but still frustrating.

After somewhat aimlessly and repeatedly probing, I noticed that it could consistently start when the multimeter leads were placed between one of the crystal lead and the negative terminal of the battery.  I could observe the voltage decreasing from around 1V to 0.7V.  Curiously, on the PCB, there is an unpopulated footprint between the crystal lead and the negative terminal of the battery.  So perhaps placing a 10MΩ resistor and/or some capacitor there might work.  And putting the leads on the other crystal terminal stopped the clock.  However, after started, the clock would stop after a short time and leaving the probes on the circuit would not keep it running.

But why would it need an extra capacitor now?  Is aging a factor?  Has the oscillator circuit deteriorated?  Accumulation of dust or FOD causes leakage or stray capacitance?   Here we went back to the fundamentals: how does a crystal clock work?  Quartz is a pure SiO2 crystal with the piezoelectric property, i.e. an electric field physically deforms the crystal structure and vice versa.  There is a restoring force that would result in vibration.  

So dust and FOD are a strong hypothesis.  A thorough cleaning of the PCB with 99% isopropyl alcohol miraculously worked; now it could consistently start.

Analog Ground and Digital Ground

 I think this concept of analog ground and digital ground trips every young engineer.  The school did not teach me about this when going through the standard EE curriculum. You may first encounter this when using analog-to-digital converters or some microcontrollers or other mixed-signal devices.

There are plenty of application notes talking about it.  You might hear about separating analog ground from digital ground because the digital ground is noisy.  It sounds appealing.  So you draw too different ground symbols to keep them separate.  Then the question becomes where and how do you tie them together.  Some suggest tying together with an inductor which would be high impedance to AC to keep noise out.  Some say tying at the power input and others say under the ADC.  There are also ground planes, split planes.

 Why do some ICs have two or more grounds (some power devices have power grounds)?  You have to look at this from an IC designer's point of view; say you are designing a successive approximation analog to digital converter, which has a sample-and-hold, comparators, and voltage reference, and digital decoder and interface circuitry.  Every time, the digital gates switch, small pulse of current flows out of the ground node through the GND pin; if this pin is shared by all these circuit blocks, it generates a common-mode voltages (mostly from the parasitic inductance of the bond wire), which is small enough not to affect the digital circuitry but can be significant to the analog circuitry.  So here you kick the can down to road by using a separate pin and let the board design deal with it.  Now the IC designer does not mean to have the two grounds at different potentials.  So it seems that these ground pins should be tied right under the IC, which is the recommendation of many datasheets and application notes.   

Some mixed-signal devices, like analog to digital converters, should be treated more like analog devices (like opamps).  But for some devices like microcontrollers, the analog circuitry is only a small fraction of the overall device; it does not seem to make sense to be a part of the analog circuitry.

The key to the solution is to consider current flow.  When a digital gate launches an edge transition, which is incredibly fast dvdt driving mostly trace  or pin capacitance.  The return current flows with it; it tries to follow a path of least impedance, which if not properly designed may sweep through board areas with sensitive analog circuitry.

 

Wednesday, November 19, 2025

LED Flashlight Again

I wrote about some LED flashlight that I built or purchased many years ago.   Recently the incandescent bulb on my Garrity flashlight burnt out.  I tried to find an LED replacement bulb.  At the price $3.5 a piece, it was disappointing: 0.3W@3V, 30 Lumens.  The LED bulb went from drawing 100mA at 3V to 7mA at 2.6V and is completely off at 2.4V.  That means it cannot be used with rechargeable NiMH batteries and the Li-Ion battery voltage is too high.  I decided to build my own LED replacement bulb (P13.5S type) again.  I want to run on both two NiMH cells or one Li-Ion cell (1.8-4.2V).  LTC3429 used previously can run on a Lithium-Ion battery but as a linear regulator with the efficiency in the 60s%.  

Here is a simpler solution.  We configure the circuit to be always boost.  We can take advantage of the built-in current limit of converters.  In LT1615, the switch current limit is 350mA.  We eliminate the Schottky diode; only an inductor and a capacitor are needed.  It works down to 1V (single alkaline cell).  Because LT1615 operates with a fixed off-time control, the switching frequency changes with the input voltage, from 200-300KHz. The average current through the LED varies from 85-140mA. The efficiency is around 80%.  It has as few components as it can possibly get.  The deficiency is that LT1615 is relatively expensive ($3 a piece at volume quantity) and its current limit is a little too low.

                                Ink Drawings

Here is the actual implementation. 

 

Thursday, November 13, 2025

Testing Antonki Thermometer/Hygrometer

 Antonki Thermometer/Hygrometer is sold at $8 for two.  It claims a temperature range of -50 to 70°C (-58 to 158°F) with accuracy +/-1°C and relative humidity range 10% to 99% with accuracy of +/-5%.  It is good value if it is indeed accurate.

We use SHT31 and HTU21 breakout boards with Arduino Nano and an OLED display module (0.96" OLED 128x64).  Arduino 3.3V output is used to power the sensors and the display.  Very quickly, we pull together the code needed to read from the sensors and display the data on the OLED module.  It shows the power of Arduino.   We update the reading every 3s.

 For temperature, we also have the analog thermometer, thermocouple, and PRT measured by multimeter, and Fluke non-contact IR thermometer.   The temperatures are measured at four settings, ambient (22°C), refrigerator (3°C), freezer (-18°C), and heater (50°C).

Here are the results.  It is pretty good at the room temperature, likely at which it is calibrated, but the readings deviate greater at the colder temperatures.

Sensor Freezer Refrigerator Ambient Heater
Antonki -15.9 5.5 22.2 46.5
HTU21 -17.3 5.8 22.6 46.5
SHT31 -17.1 5.5 22.4 46.6
TC -21.0 3.0 18.0 46.0
PRT -17.4 6.0 22.8 48.5
Thermometer -19.0 3.0 22.0 51.0
Fluke -16.4 4.2 22.546.5

We compare a few humidity readings.  Since HTU21 and SHT 31 disagree by 10%, it is hard to assess the accuracy.

Sensor Reading 1 (% RH) Reading 2 (% RH) Reading 3 (% RH)
Antonki 55.0 31.0 71.0
HTU21 46.5 26.2 59.0
SHT31 56.4 34.6 69.4

 It should also be noted that the response time of Antonki is slow; it takes time to stabilize the readings, especially the humidity.  

 In conclusion, Antonki Thermometer/Hygrometer is usable at normal room temperature range.

Tuesday, October 14, 2025

A Toaster Oven

 A very simple toaster oven costs about $20.  While the most consumer electrical appliances have microcontrollers inside and some are internet connected; this oven is pretty much mechanically controlled.  It has two quartz heating elements, 500W each  (measured around 4.5A each), at the top and the bottom.  The cold resistance is about 14 Ohms; Over 17A is drawn initially.  A spring winded mechanical timer sets time up to 30min or staying on.  The timer is more or less accurate (off by less than 3 mins for 30 mins).  The mechanical timer switches the live AC wire. 

The neural wire goes to the temperature control knob, which turns to set the temperature up to 450F in the toast mode, which both heat elements are on; the turning just pushes a spring loaded switch.  Turning further to the bake and the broil mode to turn on only the bottom and the top respectively; no temperature control in these two modes.  The temperature is controlled by a heat activated switch.  It does not actually sense the oven temperature, instead a current passes through a metal strip, which can be seen glow red; the heat bends a nearby bimetal strip to actuate the switch.  There is no earth ground connection; that seems risky if the AC wire is shorted to the chassis.


 How would this design compare with a more electronically controlled design in cost and reliability?

Monday, September 22, 2025

LED Fluorescent Tube Replacement

 The once ubiquitous fluorescent light tubes are gradually being replaced by the LED light.  The once popular compact fluorescent bulbs are already near extinct.  Two of my 3' fluorescent tubes are not working right: they do not light up fully.  They are the F30T12 rapid start type (30W, 1.5" diameter).   The ballast is rated at 120V 0.65A and has eight wires: white and black for neural and live AC input, two tubes share one pair of yellow wires and one pair of red and blue go to the other end of the tubes with the so-call "tombstone" holders.  While I'm not sure if the tubes are or the electronic ballast are bad (I do suspect the ballast since the tubes work sometimes), replacing with LED tubes is less expensive than getting new ballast or fluorescent tubes.  

An 18W T8 (1" diameter) LED tube costs about $7 (at quantities of a pack of 4); it can be installed plug-and-play (Type A) or with the ballast removed (Type B).  It is rated at 100-277V 0.18A.  It claims 45W equivalent and 2520lm 6000K, which would imply 140lm/W, a little high (as a comparison, a Philips 18W puts out 2000lm 6500K). The tube is made of two rows of LEDs, total 120 individual LEDs (laid out on a PCB with groups of 5 in parallel).  The back side is aluminum, where the LED PCB is mounted on, and the front is transparent plastic cover (not frosted).  The two pins at each end are shorted.  The tubes work when plugged into the existing fixture without modification, but I could notice some flickering and humming of the ballast.  There was a slight delay for the LEDs to turn on when starting cold; once warmed up, it started instantly.  When I measured the input current, I was surprised that it read 0.9A (that is over 100W), not only it exceeded the LEDs current by a lot (should be less than 0.4A) and but also more than the ballast rating.  Also the ballast seemed to fail completely after a few times.  I definitely need to try bypassing the ballast, which is straightforward.  Each LED tube draws only 0.135A, 16W (measured by the multimeter and the power meter); it is much better without the ballast: instant start, no humming and lower power (reduction of more than 50% with at least similar brightness if not brighter).

The common electronic ballast circuit is a resonant half bridge with a capacitor bypass.  Initially the current flows through this capacitor and heats up the filament; a higher strike voltage is generated to start arc discharge through the tube.  Afterwards the current through the bypass capacitor and the filament is reduced and the voltage across the tube is also lowered. A transformer feedback sustains the oscillation, which is over 10KHz. Some include power factor correction. The question is how the LED tube is able to tolerate the high voltage from the ballast.  One possibility is that it has a low-pass filter to attenuate the high-frequency voltage.

When I took down the ballast, it felt rather heavy, 3.5 lbs.  I realized that it is not an electronic ballast; it is the magnetic type.  The ballast is over 30 years old (possibly manufacture in 1991 based on a marking on the ballast). The inductance measurements are: black-white 390mH (10Ohms), yellow 47uH (0.4Ohm), blue 48uH (0.4Ohm), red 109uH (0.4Ohm).  The coils provide heating to the cathode.  The coils appear DC isolated.  When 120V AC is applied to black-white, about 4V AC on each coils, across yellow and blue is 226V and yellow and red is 5V (something seems faulty here).  Between blue and red is 1.4H, yellow and blue is 1H, yellow and red no inductance.  So there is an additional coil that is connected through capacitors; it functions like autotransformer to generate the high voltage.  So I suspect a broken capacitor.  Unfortunately, the ballast is completely potted.


Another question is, does a Type A only LED tube work without a ballast?  Testing confirms it does not work.  This is because this type of LED tube requires higher voltage provided by the ballast.  Other explanations out there make no sense. 

Friday, September 19, 2025

NVMe Speed Test

 The computer peripheral bus is eventually settled on PCIe and one small form factor expansion card is M.2 which provides up to 4 PCI express lane.   NVMe SSDs are now widely used and getting inexpensive.  Coming in size 2280/60/42/30.  M Key.


- Patriot Memory P310 NVMe PCIe M.2 Gen 3 x4 480GB $29.49 (6 cents/GB) 11/24

- Patriot Memory P310 NVMe PCIe M.2 Gen 3 x4 240GB $18.99 (8 cents/GB) 10/24

- Western Digital WD Blue Gen 3 x4 M.2 2280 500GB $49.99 (10 cents/GB) 6/22

- Lexar E-series 64GB Micro SD 100MB/s U3, A1,  $6.13 (10 cents/GB) each (for a pack of 3) in 10/24, 

- UGREEN 10Gbps M.2 NVME to USB3.3 Gen 2 $15.99 in 11/24

- ORICO M.2 NVMe USB3.1 Gen 2 (10Gbps) $18.99 in 6/22


ORICO + Patriot 480GB + Macbook Pro Linux

gnome-disks benchmark, 100MB 100 Samples
Average Read 458.4 MB/s
Average Write 417.6 MB/s
Average Access time 0.22 msec

dd if=/dev/zero of=/media/davex/Pat480G/dump.bin bs=1G count=100 status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 1696.78 s, 63.3 MB/s

dd of=/dev/null if=/media/davex/Pat480G/dump.bin bs=1G count=100 status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 242.579 s, 443 MB/s


UGREEN + Patriot 480GB + Macbook Pro Linux

exFAT

dd if=/dev/zero of=/media/davex/PAT480GXFAT/dump.bin bs=100M count=4K status=progress
429496729600 bytes (429 GB, 400 GiB) copied, 956.569 s, 449 MB/s

sudo dd if=/dev/sdd of=/dev/null bs=100M count=4K status=progress
429496729600 bytes (429 GB, 400 GiB) copied, 974.971 s, 441 MB/s

UGREEN + Patriot 480GB + PC Windows 10

exFAT

winsat disk -drive d
> Disk  Random 16.0 Read                       215.03 MB/s          7.8
> Disk  Sequential 64.0 Read                   642.06 MB/s          8.2
> Disk  Sequential 64.0 Write                  661.92 MB/s          8.2
> Average Read Time with Sequential Writes     0.190 ms          8.6
> Latency: 95th Percentile                     0.321 ms          8.8
> Latency: Maximum                             0.610 ms          8.9
> Average Read Time with Random Writes         0.192 ms          8.9

UGREEN + Patriot 240GB + Macbook Pro 

gnome-disks benchmark, 100MB 100 Samples
Average Read 458.5 MB/s
Average Write 420.8 MB/s
Average Access time 0.08 msec

dd if=/dev/zero of=/media/davex/Pat240G/dump.bin bs=1G count=100 status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 718.181 s, 150 MB/s

dd of=/dev/null if=/media/davex/Pat240G/dump.bin bs=1G count=100 status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 242.159 s, 443 MB/s


ORICO + Patriot 240GB + Macbook Pro Linux

NTFS

dd if=/dev/zero of=/media/davex/Pat240G/dump2.bin bs=100M count=1K status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 811.527 s, 132 MB/s

ext4

sudo dd if=/dev/zero of=/media/davex/Pat240G/dump.bin bs=100M count=1K status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 240.032 s, 447 MB/s

tr '\0' '\377' < /dev/zero | sudo dd of=/media/davex/Pat240G/dump2.bin bs=100M count=1K status=progress iflag=fullblock
107374182400 bytes (107 GB, 100 GiB) copied, 261.163 s, 411 MB/s

sudo dd if=/dev/random of=/media/davex/Pat240G/dump2.bin bs=100M count=1K status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 429.978 s, 250 MB/s

exFAT

dd if=/dev/zero of=/media/davex/PAT240GXFAT/dump2.bin bs=100M count=1K status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 250.026 s, 429 MB/s

dd if=/media/davex/Pat480G/Lux2e/Lux2e.vdi of=/media/davex/PAT240GXFAT/Lux2e/Lux2e.vdi bs=100M status=progress
124962996224 bytes (125 GB, 116 GiB) copied, 422.505 s, 296 MB/s

UGREEN + Patriot 240GB + Raspberry Pi 5

exFAT

dd if=/dev/zero of=/media/davex/PAT240GXFAT/dump2.bin bs=100M count=1K status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 415.082 s, 259 MB/s

dd of=/dev/null of=/media/davex/PAT240GXFAT/Lux2e/Lux2e.vdi bs=100M count=1K status=progress
124962996224 bytes (125 GB, 116 GiB) copied, 327.183 s, 382 MB/s

Patriot 240GB + Raspberry Pi 5 (nvme)

exFAT

dd if=/dev/zero of=/media/davex/PAT240GXFAT/dump2.bin bs=100M count=1K status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 297.226 s,  361 MB/s

dd of=/dev/null of=/media/davex/PAT240GXFAT/Lux2e/Lux2e.vdi bs=100M count=1K status=progress
124962996224 bytes (125 GB, 116 GiB) copied, 278.538 s, 449 MB/s


UGREEN + Patriot 240GB + Jetson Nano

exFAT

dd if=/media/davez/PAT240GXFAT/Lux2e/Lux2e.vdi of=/dev/null bs=100M status=progress
124970336256 bytes (125 GB, 116 GiB) copied, 561.616 s, 223 MB/s

dd of=/media/davez/PAT240GXFAT/dump.bin if=/dev/zero bs=100M count=1K status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 1405.02 s, 76.4 MB/s


UGREEN + WD 500GB + Macbook Pro 

ext4

gnome-disks benchmark, 100MB 100 Samples
Average Read 456.6 MB/s
Average Write 329.8 MB/s   (start off at 420 MB/s , drop to 260 MB/s after half way)
Average Access time 0.21 msec

sudo dd if=/dev/zero of=/media/davex/SYSTEM/dump.bin bs=100M count=1K status=progress
107374182400 bytes (107 GB, 100 GiB) copied, 401.139 s, 268 MB/s


WD 500GB + Raspberry Pi 5 (nvme)

ext4

sudo dd if=/dev/zero of=/media/davez/SYSTEM/dump.bin bs=100M count=1000 status=progress
104857600000 bytes (105 GB, 98 GiB) copied, 321.092 s, 327 MB/s

sudo dd of=/dev/null if=/media/davez/SYSTEM/dump.bin bs=100M status=progress
104857600000 bytes (105 GB, 98 GiB) copied, 116.73 s, 898 MB/s


The file format block size has a significant effect on the speed; it is a tradeoff between the speed and disk space utilization.

Friday, August 29, 2025

Boltpower K-3 Jump Starter

 Product specifications (on the case):

    Capacity: 12000mAh
    Lifecycle: above 1000 times
    Output: 12V
    USB Port: 5V 2.1A/1A
    Input: CC/CV 15V/1A
    Starting Current: >200A
    Peak current: 400A(<3s)
    LED life: 100,000H
    LED: 1W
    LED lumen: 86LM
    Operating Temperature: -20C - 60C
    Fully charge time: about 3 hours
    Size: 185x83x43mm
 
Measured total weight: 384g, battery pack weight: 266g (138 x 42 x 28 mm, cell 128 x 42 x 6 mm).  Compared with a 22.2V 1300mAh, (65A (50C) continuous, 104A burst discharge) battery pack weighs 207g (1.42" x 1.07" x 4.12"),  12000mAh claim seems highly exaggerated; in the same density, it would be about 3300mAh.  A range of 638g to over 820g for 12000mAh 3S battery pack is reported by an internet search.  The most generous explanation is 12000mAh is total of 3 cells, which would imply 4000mAh in the ballpark of something reasonable.  If it does indeed produce 200A, it would be 4000mAh at the 50C discharge rate.  Also one search result for the marking on the battery cell "LPB 7442125" is a LiPo cell  of  3.7V/3300mAh (7 x 42 x 125 mm), which is in line with our estimate.  A further comparison, a 11,600mAh (3.7V) power bank is 336g (case included).
 
After some years, but not too many uses, it started bulging in the middle and the casing cracked.  Not surprisingly it is caused by the swollen LiPo battery pack.

 

  
Removing 4 screws with a size 1 Philips screwdriver to open the casing.  The battery pack is secured to the case with an adhesive strip.

 The charging controller is MP26123 (QFN16), a switching battery charger, which supports 2 or 3-cell battery pack with charging current up to 2A. One thing to notice is that the electronics does not have access to the cell voltages, which implies that cell balancing is not done by the the main PCB.  Perhaps there is something inside the battery pack. 
 
There are two other switching regulators, as evident in the two inductors, 6.8uF and 330uF, for the USB 5V and the other constant current drive for the 1W LED respectively.  One of the USB connectors has resistors on the signals to indicate higher current.  One component is identifiable, EMB20P03G, which is a P-channel MOSFET, 30V, 10A, 20mOhms in the SO-8 package.  U7 is suspected to be a microcontroller, which would decode the push button, and control the 4 LED indicators and the LED light pattern. 
 
We are going to something dangerous: deflate the battery pack.  There are a plenty of warnings on the internet of not puncturing the battery pack; but they are really about shorting the cell layers.  If we are careful only to pierce the package not cells, we can release the gas not damaging the cells.  Inside the pouch is a stack of thin layers, copper foil coated with graphite (anode), electrolyte (lithium salt in organic solvent) in the gel form saturating the separator, aluminum foil coated with lithium compound (such as lithium cobalt oxide, cathode). Puncturing the separator shorts the anode and the cathode which generates heat and can ignite the flammable electrolyte.  It is also warned that the gases are toxic; it appears that the main gas is CO2, O2, but there are also CO and others, so well ventilated area is required.  First we discharge the battery as much as possible by turning on the LED light; the LED shuts off at around 9.8V.  The voltage will drift back up a little.
 
Removing the wrapper reveals the three swollen battery pouches.
 

 
 We poke a small hole almost horizontally to the pouch, but not touching the lithium ion cell stack and after squeezing out the gases, we seal the hole quickly with Kapton tape.  Then we wrap them back together.  The seal is probably not perfect; that could affect the battery cells, such as drying up the electrolyte, but we don't expect it to work for too long or use it for high discharging.  I did smell some odor when the gases were released. 
 
 We now charge the battery pack with 15V/1A.  We should expect about 2-3 hours of charging time if there is still significant capacity left.   It took 4 hours for the LED indicator to stop blink.  The end voltage is 12.54V; the charging effectively stopped after 3 hours and probably transitioned from constant current to constant voltage after 2 hours.  We'll run a discharge time to confirm the capacity using the USB current meter; we use an LED light that draws 0.5A from 5V.  When fully discharged (at shutoff), the voltage is 9.9V and the measured capacity is 15,800mWh.  Assuming 15% loss, that puts the capacity at 1670mAh, perhaps 40 to 50% of the original capacity.

Tuesday, May 13, 2025

USB current/energy meter

$4.79 (+shipping and tax for $7.23 total) Shenzhen Rongbo Jiachuang Technology Co, before the tariff was imposed on the Chinese goods.


The device draws about 22mA by itself.  There is 0.2-Ohm resistance between the input and the output.  The current measurements seem to have about -10mA offset, which is a large error in the low current measurements; above 200mA, the measurement error is less than 5%.  It may have calibrated at around 0.5A, the common USB port current.

Fluke 87USB meter
0.0070.00
0.0310.02
0.0390.03
0.0630.05
0.0990.09
0.1420.13
0.2050.20
0.4670.47
0.9030.92
1.4381.47
2.1462.17

The DC voltage measurements have 30-40mV offset and gets worst at higher voltage (the spec is +/-0.5%).  The AC RMS voltage measurement has a bandwidth greater than 3000Hz.  And there is some sort of data manipulation, the voltage measurements do not update consistently.

It is a good enough for casual USB power measurements.


Friday, May 9, 2025

MicroPython On STM32F429 Discovery

We try out MicroPython on STM32F429 Discovery kit.  We pull the MicroPython v1.25.0 source code from github.  

First `make -C mpy-cross` to build MicroPython cross compiler.

Then in ports/stm32, `make BOARD=STM32F429DISC submodules` to pull in libhydrogen, micropython-lib and stm32lib.  

We need the GNU compiler  arm-none-eabi-gcc; we use GCC version 13.3.1  from STM32CubeIDE 1.18.1.  `make BOARD=STM32F429DISC` to build.  The size of the firmware is about 320KB.  STM32F429 has 2MB Flash.

We use stlink to flash; we build stlink v1.8.0 from the source.   We need to specify the USB device ID, `export STLINK_DEVICE="0483:374b"` and `make BOARD=STM32F429DISC deploy-stlink` to download.  openocd can also be used.

Connect to the STLINK USB serial port with minicom -D /dev/ttyACM0

>>> MicroPython v1.25.0 on 2025-04-24; F429I-DISCO with STM32F429

Type "help()" for more information.

We can turn on the red LED with pyb.LED(1).on().

Connecting to the micro USB port, we get another serial device /dev/ttyACM1 and a storage device of 240KB.  There is one 112KB FAT partition on the storage device; the partition has the python scripts, 'boot.py' and 'main.py', which are executed at the start.  We can edit the files (like printing a message) and CTRL-D to restart.  We can the output.   Connecting to /dev/ttyAMC1, we also get a REPL console.  The output goes to both serial ports.

Next we want to do something with the 3-axis gyro (I3G4250D) and the 240x320 LCD (ILI9341).

Friday, April 11, 2025

A Portable LED Lamp

 A foldable LED lamp that is powered by USB costs as little as $3-4.  The overall design seems relatively pleasing; the foldable and adjustable features are practical.  One single touch button controls three levels of brightness and three light color temperatures.  We take a look at its electronics.

5V comes in from the micro USB connector and goes through a diode.  There is an unidentifiable IC driving two what appear to transistors (likely NPN) and receiving a capacitive touch button input.  There are unpopulated footprints, possibly for the battery powered variant. There are total 32 LEDs on two PCB strips, with two different types of white LEDs, warm and cool installed next to one another.  The brightness control is probably through PWM.   With the base resistors of 3300 Ohms, each transistor perhaps runs at about 120mA driving 16 LEDs, only 7.5mA per LED, which seems a little low.  The LED forward voltage is perhaps 3.4V; the dissipation of each transistor is 120mW, which is tolerable for a SOT23 package.  We'll take a few measurements to check our speculations.





We measured the outputs from the IC (using AN8008 multimeter's frequency and duty measurement function), and found the PWM frequency to be 20KHz and the duty cycles of 10%, 40%, and 99% for the three brightness settings respectively.