-
Update: use moving averages to inform charging and LED states
08/03/2025 at 21:45 • 0 commentsI've noticed that the module's LEDs will flicker between states if it is on the edge of thresholds for charging during normal use. As it was implemented, single ADC readings were used to inform device decisions. It seems as noise in the ADC readings might result in single readings being inaccurate for informing the module's LED and charging states. I've decided to implement a simple moving average algorithm to smooth out any fluctuations.
Simply put, the MCU will collect ADC readings as they become available and immediately index them into a FILO queue. As new data becomes available, the oldest ADC data will be overwritten by the newest addition. A simple average is calculated using the data in this queue every time new data replaces old data. This average is then used to inform any decisions to change the LED state or cease/begin charging.
As the MCU is currently configured, it will collect new ADC readings and perform this averaging every 100 ms.
-
Bug fix: wait for linear regulator output to start up before enabling PMOS
07/27/2025 at 01:52 • 0 commentsI realized that switching on both the linear regulator and PMOS output transistor at the same time could result in a condition where the battery could discharge into the linear regulator during startup. To prevent this, I added a loop where the regulator voltage is checked with the ADC prior to activating the PMOS transistor for charging.
Also, instead of updating control pin states on every loop iteration, they are now only updated on state changes.
-
Bug fix and clock speed update 07/25/2025
07/25/2025 at 19:38 • 0 commentsAs I am running the board off of a +5V USB input, I can take advantage of the full clock speed of the ATtiny824 and run off of the 20 MHz internal oscillator without a prescaling the output to CLK_PER. I decided to do this as it lets me run the ADC at an effective 10 MHz (CLK_PER/2), reducing the amount of time it takes to perform an ADC read. Why?
On the schematic, an ADC read circuit using discrete transistors is used to prevent the battery from powering the ATtiny824 through its GPIO pin ESD protection diodes. To properly bias PMOS transistor Q1, a 100K ohm resistor (R2) is placed between its source and gate. The gate of Q1 is connected to the drain NMOS transistor Q2; when Q2 is activated by the MCU, current will flow from R2 to ground through Q2 and Q1 will conduct.
Note that the battery is directly connected to Q1's source and so current will flow through R2 whenever an ADC read is performed. This reduces the efficiency of the charge circuit, as current is diverted to this biasing resistor during ADC reads. The solution in the current implementation is to simply reduce the amount of time this circuit is active. This is accomplished by achieving faster ADC reads through speeding up the MCU.
Of course, I had to increase the ADC sampling duration to account for the fact that the transistor pair Q1/Q2 takes time to activate. Using a short sampling duration doesn't give the MCU enough time to wait for the battery voltage to appear and results in oddities when a battery is removed mid-charge, such as a "medium" charge being present. The idea is that removing a battery mid-charge should result in the 3.2V charge voltage abruptly appearing at the empty battery terminal, which tells the MCU that a "fully-charged" battery is present and to shut off the regulator. This would result in 0V appearing at the terminal and the user being informed that no battery is inserted.
I also noticed that the INTFLAGS register was never cleared for the TCB0 capture interrupt in the old code, which means that the ISR would fire off too often. Oops!
Zachary Murtishi