• Power Reduction Multi-Processor Redesign

    Jake Wachlin03/27/2021 at 17:54 1 comment

    The previous SOL design worked great for the most part. It was low power-enough to operate for indefinite time, even through a Northern Michigan winter with minimal sunlight. However, it did have some overall design issues.

    • It was set into a deep-sleep mode for storage and shipping, but the current was high enough that without solar charging it would die rapidly (roughly 30 days)
    • The system architecture was odd
      • Data was temporarily stored between uploads in the ESP32 flash. This raised concerns about flash wear over time.
      • The ESP32 is very slow to wake up  from deep sleep (~500,000X slower than STM32 in my initial testing), so sampling of solar power cannot be too often without using too much average power.
      • The ESP32 ADC has poor accuracy, so an external I2C ADC was used. This had a limited  bandwidth, also slowing down sampling.

    As both a fix to these issues, and a design challenge with the STM32 platform (that I am recently getting experience with), I designed a new version that uses a STM32L432KBU6 ultra-low power Cortex-M4 processor for the hardware interfacing and an ESP32 for WiFi only. The STM32 periodically wakes up, samples power from the solar panel, and stores data temporarily in an FRAM IC. FRAM has no wear limitations like flash, and can be written over indefinitely at full SPI clock speed. To reduce sleep power even further, The STM32 gates power to the ESP32, the temperature sensor, and the voltage divider used to monitor the battery. When data is ready to upload, the STM32 powers on the ESP32, loads data from the FRAM, and sends it over UART to the ESP32 for upload.

    Reviewing Power Consumption from Previous Version

    To understand the upgrades of this design,  we first need to understand the power consumption of the previous version. With the ESP32 awake and connected to WiFi, we see overall 157mA consumption. While high, this system is only in this state for a very small portion every day, when it uploads data. Much more often, it is in deep sleep mode. Here, the power consumption is much lower, down at 0.809mA. The image below shows the current profile in deep sleep. The periodic spikes are due to the accelerometer used for "wake-on-shake" for configuration sampling..

      This power consumption is the main issue, in "storage/shipping" mode, this is the power consumption, and it will drain the battery in ~1 month.

    Firmware Design and Power Consumption for New Version

    The most difficult part of this new design is managing two microcontrollers and their respective states. They are connected with a UART for bidirectional communications, and each has a state machine with timeout to handle the communication. We cannot be sure that any message will be sent or received correctly, so it needs to default back into a low power mode eventually. I generated a messaging interface where each message has two header bytes, a message type byte, two length bytes, the message buffer itself, then a checksum byte.

    The key benefit for this new design is that solar power measurement is both much faster (so less time spent in high power awake mode), and the awake mode itself requires less power. Whereas the previous version would require ~1.5s at ~30mA, this new version only requires ~53ms at ~12mA. This is an overall reduction of ~71X for each sample! The image below shows the power profile of a single wakeup-sample-sleep cycle.

    The deep sleep mode for this design is also far better than the previous design. The LDO for the ESP32 is disabled in sleep, and the temperature sensor and voltage divider are both power gated so that they require no power in deep sleep. The STM32 is in Stop 2 mode with RTC on, the ADXL362 acclerometer is in wakeup mode (requiring 270nA), and the FRAM is in sleep mode. Overall, the consumption is down to roughly 6-7uA, roughly 130X better than the previous version. The image below shows this current profile. The spikes are the accelerometer sampling.

    The low deep sleep power and fast sampling enables some...

    Read more »

  • Small-Run Build and Testing

    Jake Wachlin08/21/2020 at 00:59 0 comments

    After good success of the new design revision with entirely sealed enclosure, I decided to build a small batch of 10 units for testing all over and comparison of results between units. I again used JLCPCB to build 10 assembled devices. I added the ESP32 module by hand, and hand-soldered the solar panel and battery connectors. They all came together nicely. The picture below shows 3 of the 10 units.

    The picture below shows the inside of the device. The PCB quality is functionally OK, but the silkscreen is certainly lacking and was peeled off before I received them.

    To test the devices against each other, I set up two of the new units outside right next to each other.

    For the test, both ran for 7 days straight, with a mix of sunny and mixed cloudy days in north-west Michigan. About halfway through, I took both units briefly inside to reprogram them. Initially, they were set up to take a measurement at 60 second intervals during sufficient sunlight. To get better data on the match between both units, I changed it to measure at 10 second intervals.

    The plot below shows the measurements of the two new units over the full test. The gap around halfway is due to the reprogramming. Overall, the total energy estimates for the two units are within 3% of each other. Perhaps more importantly, they estimate the same capacity factor, which is important for evaluation of the use of solar energy.

    Looking at one cloudy day's worth of data with both devices measuring at 10 second intervals. The two devices match nicely.

    Zooming even further, we can see both devices track well even during short periods of cloud cover.

    Finally, one major issue with the last minor revision was that it had no working temperature sensor. This new design has one, which is used to determine when it is safe to charge the lithium-ion battery onboard. Both devices match well, and it is clear that these units get very hot in direct sunlight, so much so that they are not charged mid-day.

    Overall, I am very happy with this new small-batch order. We will be setting them up with friends and family around the country and generate even more test data soon.

  • Outdoor Survivability Update

    Jake Wachlin06/30/2020 at 15:35 0 comments

    This project has been mostly on hold for a while. Not because of an issue, but because the previous SOL version was operating well outside in Northern Michigan for about 9 months between August 2019 to April 2020. In April, I started noticing some issues. SOL was still sending data to our server as normal, but the power measurements looked very wrong and the battery had stopped charging. Upon inspection, water had gotten inside the case and caused  corrosion. Specifically, the wires to the solar panel had broken, causing the issues. I tried to fix it, but the damage was done.

    Water ingress was always a concern. I had used an IP rated waterproof enclosure, but I had drilled holes for the LED indicator light, solar panel wires, and capacitive touch button. All were "sealed" with adhesives and/or gaskets, but it was still a known weakpoint. In addition, the capacitive touch button was always an issue. I had a lot of trouble tuning the settings to be appropriately responsive while not triggering false positives all the time. It also added a step in assembly which took time to build.

    With these known issues, I made a design update.

    The new version was meant to again use an IP-rated enclosure, but this time I would drill no holes in it. For this to work, the solar panel must be inside the enclosure, and therefore the enclosure must be transparent. This does raise the question of how much light is absorbed or reflected from the transparent cover. I do not yet know the answer to that. Because the cover is clear, PCB mounted LEDs can be used to indicate modes. Finally, instead of a capacitive touch button used to enter configuration mode, I used a LIS3DH low power accelerometer in "wake-on-shake" mode. This accelerometer can monitor acceleration at 10Hz while consuming 3-4uA, and will wake up the ESP32 on a shaking event. Therefore, the user can give SOL a quick shake to enter configuration mode. In testing this is very easy and reliable. The addition of an accelerometer also raises the possibility of sensing roll and pitch of the device to infer information about roof angle.

    I used JLCPCB for the assembly. They assembled most of the parts except through-hole components and the ESP32 module itself. I did the rest. SOL is mounted in a Hammond Manufacturing polycarbonate enclosure with transparent lid. The solar panel is a perfect fit into the lid, with a bit of hot glue added to hold it in place. The picture below shows SOL assembled and connected to the solar panel.

    The PCB then mounts into the enclosure as shown below. Unlike the previous enclosure which had a cut-to-fit gasket, which always had a seam, this enclosure has a one-piece gasket for a (presumed) better seal.

    Fully assembled, the system looks like below. The PCB and battery are now exposed to direct sunlight, so there is some potential concern of UV degradation.

    Finally, the image below shows this new version outside next to the old version.

    The data is coming in to our server. After 2 days, the data mostly looks good. There are a few issues though. The temperature always shows 0C. The LIS3DH accelerometer contains a temperature sensor that I had planned to use. However, it appears that sensor is only useful for relative measurements and must be calibrated carefully. I do not want the added hassle of calibration when that sensor is mainly for approximate measurements to disable charging outside of acceptable conditions. Also, during nighttime, the system is reading nonzero solar panel voltage of about 1.3V. It is not clear if this is a bug, or if the bright moon or house lights are causing this. This solar panel will produce a nonzero voltage with very little light, although there will be effectively zero power available.

    This new version also has a different charging setup. The previous version had a very simple voltage regulator to 4.2V, then a Schottky diode to the battery. It was current limited by nature due to the limited current available from the solar panel, but was nominally...

    Read more »

  • SOL in the Wild

    Jake Wachlin08/30/2019 at 02:18 0 comments

    It has been a while since the last update, but lots has been done. Bugs have been worked out, and a prototype has been outside collecting data for the past month. For this recent round of prototypes, I outsourced the assembly to Macrofab. It was surprisingly cheap, and the boards came out really nice. 

    The enclosure I used has a rubber O-ring, but there are a few holes drilled in the lid. I sealed the LED hole and the solar panel holes with superglue. The screw used as a capacitive button has an O-ring of its own, and seems to seal well. I closed the case, and left it in the shower for a few minutes. No leaks were seen.

    I had previously proved on another prototype that the device can now charge itself using the solar panel, so I was confident in now leaving it outside long term. Not a bad place to leave it...

    For about a month now, it has been continuously monitoring the available solar power. It senses every 20 seconds during the day, and sensing slower at night to save power. Every 300 datapoints, it connects to WiFi and uploads the data to our server. If you're curious, the data is visible in real time here.

    With some basic calculations about the solar panel's efficiency and known area, we can calculate the available irradiance throughout its lifespan. This data matches typical values for the area (northwest Michigan). It has a "shoulder" on the data due to a shadow from the house. It is already providing the hyper-local data this project intended to provide!

    Summarizing the data here, we extrapolate a potential 5 kWp solar panel installation at the same inclination as SOL. The daily energy production is fairly significant.

    It is really fulfilling to bring a project like this to this point, where the original intention is working! But now there is so much more to do. We plan to deploy more of these prototypes and begin the algorithm development for making sense of this rich dataset.

  • Temperature Effects

    Jake Wachlin03/17/2019 at 17:47 0 comments

    With the polar vortex effecting much of northern North America this past winter, there was some "discussion" among politicians about how solar power would operate in the cold temperatures. Undeniably cold can negatively effect batteries, snow cover on panels can block sunlight, and shorter days (and incidence angle changes, depending on if the panels are on trackers and which direction they face) reduce the total amount of solar energy available. However, solar panels actually perform at a higher efficiency when cold.

    Let's look at the data. SOL has been operating in my windowsill for another month. There are still some issues with missing data and timing drift to resolve, but the measurements themselves seem to be quite reliable and repeatable. My apartment is astonishingly poorly insulated, so a fairly wide variety of temperatures on the PCB of SOL are recorded. A quick look at the plots in this paper show that at a given power generation point, a colder cell will have a higher open circuit voltage.

    The point of SOL, of course, is to determine how much power is available from sunlight. So, unlike that paper, power is not a known input. We only know, at a given point in time, the internal temperature of SOL, the open circuit panel voltage, the short circuit current, and the power at the maximum power point. Because SOL is in my windowsill, its temperature changes with the outside temperature and the amount of sunlight hitting it. In the plot below, we see a separation of open circuit peak panel voltage based on temperature. As in the paper above, with generated power held constant, the peak voltage is higher for lower temperatures. 

    Further, it seems likely that there is a link between temperature and sunlight hitting SOL, especially since SOL is inside and my apartment is not 93 degrees F. The fact that SOL measures peak overall power at low temperatures similar to peak overall power at high temperatures may imply that it is more efficiently converting sunlight to electrical power at low temperatures.

    Thankfully, for the goal of SOL, which is to determine how much power a large solar installation could produce, the effect of temperature can be assumed the same on SOL and a larger installations, so that we do not need to know the effects of temperature of SOL's efficiency to make these predictions.

  • Power and Clouds

    Jake Wachlin02/10/2019 at 23:08 0 comments

    I did some further analysis on the data recorded by SOL over the past few days. Of note were the peaks in recorded power in the afternoon of the 7th and 8th, which did not appear the next days. I correlated the data with historical weather data on shortwave light intensity and cloud cover. During the days with the peaks in power, the cloud cover cleared up somewhat, and the peak predicted intensity was relatively high. As noted before, SOL was not in direct sunlight for these tests, so the absolute value isn't important here, but it is encouraging that it seems likely that those higher power sections were due to real phenomena.

  • Firmware and Data Update

    Jake Wachlin02/10/2019 at 21:04 0 comments

    Adaptive Timing

    In a previous log, I had mentioned that SOL should be set up to adaptively change its sleep time based on the measured solar intensity. There are two main reasons for this. First, this will save a lot of battery during the night. Previously, it would read data at regular intervals (e.g. 60 seconds) all the time. During the night, the power is zero, so there is no need to sample. Secondly, it would allow the system to generate more accurate energy estimates during high-power scenarios. Coincidentally, since SOL is charged by the sun (theoretically at least), it can afford to use more energy during times when it charges faster.

    I made a firmware update to test one concept for this adaptive timing. My original thought was to have the timing change according to some tunable filter driven by the peak power measurement. However, if we see the power is high, we ideally would instantly jump to short intervals. I created a very simple algorithm in which a minimum and maximum time interval are given. If the power is over some threshold, the interval jumps immediately to the minimum. If it drops below the threshold, the interval is slowly incremented to the maximum. Here, the minimum interval was 30 seconds, the maximum was 300 seconds, and the power threshold was 7 mW. This seems to work quite well. The below image shows the relative time of each datapoint for 3000 datapoints. The zig-zag is caused by the transitions between 30-300 second intervals over the course of about 4 days.


    SOL has now been running for a week and has recorded and uploaded about 6000 datapoints. The single cell 14500 li-ion battery has dropped from 4.02V to 3.80V during that time. It does not appear to be charging, even though I changed the charging control resistor so that the desired charging current is 12mA. The peak current measured through those days was about 5.5mA, so it is expected that the battery has not charged. SOL is in a windowsill, but never in direct sunlight, so soon I will test if it charges in higher intensity light.

    Looking at the energy that could be extracted based on the measured peak power from SOL's panel, we see that even in a windowsill, SOL can easily power itself. The battery is about 0.7 Wh, and over about three days, it could have ideally (with 100% charging efficiency) extracted about 0.3 Wh.

    RTC Bug Fix

    There was a bug with processing the time from the RTC which caused some readings to be corrupted. This has been fixed. The bitmask used when loading the hour value was wrong, so anything after 19:00 was incorrectly recorded.


    Due to the above RTC bug, not all the data from the past week is valid. We will consider only the data after that was fixed.

    First, consider a calculation of available solar intensity. The solar panel has an effective area of 44x63mm (listed as 50x70mm, but I'm ignoring the bezel), and I assume an efficiency of 10%. That is low for a modern panel, but this one is very cheap so likely not great. Here, SOL was inside, in a windowsill surrounded by tall buildings, so it isn't receiving direct sunlight. Therefore, the peak intensity is fairly low. For reference, peak direct sunlight is typically given as somewhere around 1300W/m^2.

    SOL is not installed outside in a reasonable location as it should be, of course, so the following calculations are more academic than anything. Nonetheless, it is interesting to look at the kind of calculations that can be done with SOL's data.

    First, consider the energy available to a larger, 33 m^2 (355 ft^2) system. We assume the system has an overall 25% efficiency. Over a little more than 3 days, the total energy was almost 10kWh.

    Second, we can take the above and calculate the cost of the electricity generated. Assuming the US national average of $0.12/kWh, this is almost $1.20 worth of electricity.

    Third, we can consider the net carbon effect. This is a much more difficult calculation to make. Each state has a different energy source breakdown, so the offset of...

    Read more »

  • SOL V3 Assembly and Testing

    Jake Wachlin12/02/2018 at 19:22 0 comments

    Version 3 Goals

    Version 3 had a few simple goals. First and most obvious was to fix design mistakes in version 2:

    • The trace from the output of the temperature sensor to the ESP32 ADC was accidentally overlapped by a ground trace, causing version 2 to not be able to measure temperature.
    • I forgot the load capacitors on the RTC oscillator, so the RTC did not keep time.

    Second, version 3 was designed to be easily programmable. All the necessary pins were brought to a ZIF (zero insertion force) connector, and an adapter board for a FTDI Basic 3.3V was made, so that I could use the two onboard buttons to toggle EN pin (to reset) and IO0 pin (to enter bootloader mode), without having to manually touch jumper wires to ground.


    On previous versions, I assembled by laying down small bits of solder paste on each pad using the syringe it comes in. However, this process is very slow, and often results in too much solder paste on fine pitch packages. For version 3, the ZIF connector is a 0.5mm pitch package, so I bought a stencil from OSH Stencils, and used that to apply the solder paste. This gives a more even amount of solder paste on each pad, and speeds up the assembly process. The three version 3 boards I assembled are shown below with solder paste applied and the ZIF connector placed.

    As previously mentioned, version 2 was a bit of a pain to program, requiring me to manually touch jumpers on the EN and IO0 pins to ground at certain times. I did this by connecting through a breadboard. It worked, but it wasn't good, and I had to be very carefully not to accidentally short something.

    To fix this, I built an adapter board for the FTDI basic, which has the corresponding ZIF connector for version 3 programming, as well as female header pins for programming version 2. Below, the adapter board is shown connected to version 2. The two buttons on the adapter board are for reset and bootloader entering.

    When used with version 3, the ZIF connector and FFC (flat flexible cable) allow me to program very easily, by just clicking the buttons before (holding the IO0 button while toggling EN to enter bootloader) and after (toggling EN to reset after programming).

    Server Setup

    Ryan has done some great work setting up a server at solsensor.com (all source is here). This allows us to step away from the simple IFTTT/Google Sheets setup used previously. While that was useful as a proof of concept, it obviously wasn't a long-term solution. It limited the amount of data that could be uploaded at each API call, and had restrictive rate limiting. Our server does not yet have a front end to show the data, but works well as a back-end.

    Firmware Re-write

    The new server side built by Ryan led me to re-architect the SOL firmware. The old firmware was admittedly hacked together to get it working, but I was waiting to redo it until the server side API was designed. This firmware will be put in the github soon. There are some major changes:

    • SOL V3 does not have an EEPROM chip, so all datapoints between uploads are stored on the ESP32. The RTC memory is used to cache datapoints in RAM, and then data is stored permanently in a SQLite database in the ESP32 flash memory.
    • The connections to the server are all new. HTTPS is used to upload data in batches to the server. This showed some limitations in the ESP32 hardware.
      • The API includes an endpoint to upload a single datapoint, or an array of datapoints. At first, I uploaded the data one-at-a-time with the single datapoint endpoint, but this was VERY slow. It took about 3-4 seconds per datapoint, which is pretty unacceptable, given the low power needs of SOL. It's not 100% clear why, but my guess is this is due to the encryption needed for HTTPS. When I changed to uploading data as arrays, the time per data chunk was still 3-4 seconds, even though 100 datapoints or more are uploaded at a time. The firmware allows me to define the chunk size here, and uploads all new data as a number of chunks, vastly improving throughput.
    • Data...
    Read more »

  • SOL V3 Early Design

    Jake Wachlin11/03/2018 at 19:06 0 comments

    SOL V2 design documents and firmware have now been added to the project Github. 

    As previously detailed, V2 has some design faults that need to be addressed. Further than that, some upgrades can be made to add functionality and ease setup. Programming was made easier by routing all the needed ESP32 pins to a pin header. The device is programmed with the Arduino IDE through a SparkFun FTDI Basic 3.3V, but it requires three pins to be connected to ground when programming, and it requires IO0 to be held low on boot to enter bootloader, then the EN pin must be brought low to reset the device. This is done currently by alternately plugging in and removing jumper wires from a breadboard. It works, but it's annoying. To make it easier, I designed an interface board from the FTDI Basic with pushbuttons to switch IO0 and EN pins. It has a 6-pin ZIF connector which will be used to connect a ribbon cable to a corresponding 6-pin ZIF connector on SOL V3. Programming will be extremely simple then.

    Some people I have discussed the project with have asked if SOL is able to run standalone, completely disconnected from WiFi. This could be useful if evaluating a field mounted PV setup, for example. Currently, this isn't possible. The EEPROM used to store data is small, not large enough to store data for a long time (6+ months is the target). 

    However, I have been playing with the idea of using the flash storage on the ESP32 for this. Recently, I learned about a port of sqlite to the ESP32. I tested it out, and it is very easy to use and quite fast. Flash has limited lifetime in write cycles per page, but by storing intermediate logging data in the ESP32 RTC sram, and only writing in chunks, recording data over a year should be possible without risking flash degradation. The current SOL firmware only requires about 650KB, and the ESP32 module used has 4MB of flash storage. A rough calculation of storing data at 5 minute intervals over 12 months indicates about 2.9MB needed, so it seems ballpark possible. A similar approach would also allow me to remove the EEPROM storage. The ESP32 also has easy interfacing to an SD card, offering effectively unlimited storage, but that adds components, size, and cost to the design.

  • Diodes Work Better One Way

    Jake Wachlin10/03/2018 at 01:00 0 comments

    As I said in the previous project log, the voltage measured in the IV sweep seemed low, compared to what I expected for the solar panel and based on what I saw on SOL V1. Suspiciously, the voltage seemed to be clamped at around 0.75V. This solar panel can theoretically reach an open circuit voltage higher than the max input voltage of the battery charger IC, so I added a zener diode as a voltage clamp. The 0.75V seemed suspiciously similar to the forward voltage of the diode. Indeed, when I double checked the board, the diode was soldered backwards. I removed the diode, and re-ran the IV sweep test. Now, under a desk lamp, the max voltage is up to about 5V, which is much more realistic. Ill have to wait for tomorrow to see the measurements under sunlight, but I'm expecting good results.

    Through assembly and testing, I've also found a number of other issues with this build. I had accidentally run the trace for the temperature sensor output over a ground trace, so it is unable to measure temperature (I may attempt to cut the trace to get it working.) I also forgot a decoupling capacitor for the ADC, although the ADC seems to still be working OK. I will likely make a V2.1 design that makes some of those quick fixes soon, but am waiting to get V2.0 fully tested first.