PIC Code for 2 Supercapacitor Stac

A project log for Single SuperCapacitor UPS for Raspberry Pi

A last gasp Uninterruptible Power Supply for any Raspberry Pi computer.

Bud BennettBud Bennett 11/18/2019 at 03:040 Comments

It took a while to get this done. Apple recently updated its OS to 10.15 - Catalina - and that threw a monkey wrench into the works. Microchip’s MPLABX software is 32-bit software that Apple had declared “persona non grata”.  It doesn’t work on my iMac anymore. I had to install the MPLABX software on my Parallels incantation of Windoze 10, which went smoothly, but even afterward MPLABX refused to work with the old files since they did not conform to Windoze path naming conventions. I was forced to move the Microchip design files onto the Parallels partition in order for the software to cease its complaints. 

Enough of that. I managed to get the new code for the PIC10F322 working in spite of the Microchip software’s limitations. The changes from the PIC10F202 are significant. Here’s the flowchart for the 322:

Most of this is the same as the PIC10F202 program. The RA0 input is the shutdown command from the Raspberry Pi. The code requires it to be asserted for 5 continuous samples, 10ms apart, before committing to a shutdown after a 20 second delay. The only addition is to monitor the voltage on the supercapacitor stack and prevent shutdown of the LTC4041 until the voltage at SCAP has decreased below 2.5V. Even so, the code expanded dramatically. I’m kind paranoid about stuff not working in noisy environments, so I built in a few safeguards. All of the measurements are averaged via an 8-sample rolling average. This creates a bit of delay, but also reduces any interference or noise by a factor of nearly 3-fold. The MEASURE FSCAP block contains a bit of code:

The PIC10F322 has an 8-bit ADC, but it is referenced to VDD. It has an internal voltage reference, but the ADC can only use it as a in input. Therefore, in order to get rid of the VDD sensitivity, the ADC must take two measurements: one of the internal reference voltage wrt VDD, and another of the desired input voltage wrt VDD. The first measurement must be divided into the second to eliminate VDD.'s difficult to divide without floating point arithmetic, so I had to be a bit creative. Here's the math:

X  = Vref/VDD*255

Y = Vin/VDD*255

256* Y/X = Vin/Vref * 256

I figured out that the result of the division had to be multiplied by 2^8 (256) in order to maintain the fixed point arithmetic of the division. So a ratio of 1 is equal to 255. Any result above 255 is more than unity and below 255 is less than unity. I found a PIC routine on the internet here that accomplishes this nicely. I used it almost word for word.

I also found that I needed to divide the result by a factor of 4 in order to keep it within an 8-bit range. The result of the division creates a 2-byte result, if the ratio is larger than unity. Dividing by 4 keeps it within 8-bits over the expected range. To create a threshold for high or low input value I added a constant to the divider result and checked for the overflow in the carry bit.

I programmed an 8-pin DIP version of the PIC10F322 and tested it in on the bench. The first item was the 20 second delay prior to shutdown:

Close enough. The remaining tests involved determining the accuracy of the VSCAP measurement vs. VDD:

VDD          AN2

4.60V     2.442V

5.00V     2.442V

5.40V     2. 447V

That's pretty good! Better than expectations, considering the resolution of the 8-bit ADC is about 20mV.

The last test was to determine what the latency in detecting the SCAP voltage falling through the threshold, given all of the mathematical processing involved:

It's not bad -- less than 10ms to detect that SCAP is falling below the threshold. The trace above shows the RA1 output responding to a falling voltage on AN2. The voltage dropped 100mV, from 2. 525V to 2.425V. 

It appears the PIC code is good enough to prove the concept. I'll be ordering new PCBs from OSH Park tomorrow. The PIC code is posted in the files section of this project.