Boron Solar Charging with 1.5.0-rc1

For easy measurements, I use a Tripler Board, INA219, and OLED screen, all available from the Particle Store, currently for $28 total.

The picture below shows the testing of a 2W Voltaic Solar Panel.

The Li-Po Positive conductor runs through the INA219 screw terminal, measuring the Current Entering or Leaving the Li-Po and the operating Voltage.

The Code samples the INA219 as fast as possible (168 times) during a 1-second time slice, and reports the following values on the OLED screen each second:

  • mA for the last second (charge or discharge)
  • Li-Po Voltage
  • mW for the last second (charge or discharge)
  • mW Average for the entire runtime
  • mWH NET for the entire runtime (deficit or surplus).
  • Seconds of runtime
  • number of Samples measured during the last second (SPS, or samples-per-second)

This makes quick work for testing Firmware changes (SystemPowerConfiguration) and various Solar Panels in actual sunlight conditions.
I originally used a xenon on the Tripler Board to operate the INA219 and the OLED, with a slightly different wiring layout. That enabled me to have a separate Li-Po for the Boron being tested.
I determined it’s not worth the effort, and now just use the Boron as shown in the Picture for typical testing.
I still use a Xenon on the Tripler to check if a Boron recharges during/after sleep events… but no problems so far with 1.5.0-rc1.

The Boron’s typical usage is 64 mW by itself. Adding the INA219 and the OLED increases this to 100 mW. Just remember that the code reports the energy entering or leaving the Li-Po. IE: a 0 mW result means the typical 100 mW demand is being sourced by the Solar Panel, with no surplus available. This 100 mW changes to 64 mW for the Boron ONLY if you decide to operate the Tripler with a Xenon instead and measure the Boron’s independent Li-Po (requires a common Ground wire).

So far I haven’t found any problems with Solar Charging on 1.5.0-rc1.
I would love any suggestions for improvements to the Code, LINK.

BOM Links:
Tripler Board
Cables w/ connectors, Amazon


@Rftop this is an awesome share and update, thank you very much!

The only thing I noticed on first review of your code is you do not have your usual “be care…” note on the .batteryChargeVoltage(4208) line. I would hate for a new user to grab copy your code verbatim and not know the ramification of this particular line without at least a comment as a warning.

I am extremely excited to hear that 1.5.0-rc1 appears to be checking out!

In this line are you saying you have completed some sleep testing and it appears to work with 1.5.0-rc1?

I still use a Xenon on the Tripler to check if a Boron recharges during/after sleep events… but no problems so far with 1.5.0-rc1.

Thank you again!

1 Like

Correct. But I haven’t performed extensive testing with Sleep on 1.5.0-rc1, so I can’t say anything for certain. As you know, there are so many specific use-cases.

But a Boron on 1.5.0-rc1 does appear to continue to re-charge during and after Sleep Events, even when cycling the Solar Panel Connection (simulating Clouds) while Asleep. The same is true for EN Pin Shutdown.

I love the ability (with the OLED Screen) to immediately see the Solar Panel’s Performance, and actual Li-Po Charging, under changing Cloud conditions and also while changing the angle of the panel to the sun. You get real-life measurements instead of guessing what a Specific “Rated” Solar Panel will produce.

It’s also neat to watch the mWH NET value increase, such as storing 1 hours worth of energy in 5 minutes of sunshine.

The Tripler, INA219, and OLED screen aren’t needed for a final install, but it’s a useful tool for Panel testing, firmware testing, and site/location analysis.

Nice to hear Solar charging is working as expected.

Can you test the different sleep Mode power consumption levels now that they should have been improved for lower sleep currents?

I havent had time to test these yet but I’m interested in sleep stop mode where the wake programmed delay time can be used.

Sure, I’ll start a new Thread since I won’t be using the INA219 for Sleep Current Measurements.

[Edit] I’m not seeing the proposed 140 µA for “Sleep 2.0”. The best I see is 662 µA with HIBERNATE. Double that for STOP modes. Li-Po @ 4.10V.
I need to do some more digging into Sleep 2.0 before I start a Thread.

1 Like

@rickkas7 Do you have any advice achieving the new lower power sleep modes you were talking about before the new firmware was released?

Sorry about that. The low-power fixes are scheduled for 1.5.0 final, but are not actually in 1.5.0-rc.1. Only the sleep API changes are in 1.5.0-rc.1.


@Rftop, you make an excellent point. Real-life measurements with actionable data will help drive the R&D on solar Borons. Thank you for being such a trail blazer on this subject.

Thanks @Backpacker87, I’m excited to get the Boron’s back off the shelf.

I’m having trouble figuring out how to correctly disable charging using the new SystemPowerConfiguration API.

@avtolstoy (or anyone else), can you provide any hints for the best way to disable Li-Po charging when the measured enclosure temperature is too high, using the new API ?

It appears that calling pmic.disableCharging(); works in the meantime, but this doesn’t persist after an EN Pin Shutdown.

I’m assuming that adding a disableCharging feature to the new API would allow users to manage Li-Po charging according to battery temperature, even when using EN Pin Shutdown for the lowest-power cases ?

I believe the Goal should be for a User’s call to disable Charging should retain Absolute Control, (overriding the next init, shutdown, reset, etc), until the conditions (mainly temp) to Resume Charging are confirmed by the User’s Code. In my mind, recharging a significantly “drained” Li-Po in an elevated temperature is the main safety concern for these devices.

Thanks in advance !

1 Like

The feature to disable DeviceOS management of the PMIC has been added in and is included in 1.5.0-rc.1.

        SystemPowerConfiguration conf;

It’s better to run this in STARTUP() macro, as otherwise in order for this feature flag to take effect, a reset will be required.


I’m testing the new API and the “old” way (direct PMIC calls).

Both modes will continue to Operate the Charging During an EN Pin Shutdown in the last setting before Shutting Down (Enable/Disable Charging), as expected. Reminder: we need to check the enclosure Temperature immediately after a EN Pin Shutdown or Standby Sleep Mode, to decide if charging should be enabled or disabled.

Both modes also appear to recharge the Li-Po appropriately.
The one difference that I’ve noticed is in my “Mode 2” below (direct PMIC calls), the charging current is determined at Boot/Startup. This is not expected, from what I remember from the PMIC datasheet.
In the Field, this means lower Li-Po charging current if the Panel isn’t producing when the Boron Starts.
Due to this, I prefer the new API mode (SystemPowerConfiguration), or Mode “1” in the code snip below:


PMIC pmic;
SystemPowerConfiguration conf;

int myTestMode = 1;   //  1 = API  2 = PMIC

STARTUP( selectMode() );

void selectMode()  {
  // (1) API MODE
  // Known: 3.78V Li-Po, 850 mW Available from Panel @ 5.08V on TEST STAND, 50 mW used by Boron in Manual Mode, OLED, & INA219
  // Charging Results : 3.84V @ Li-Po, 208 mA, 790 mW , Panel Output (Vusb) holding at 5.07V AS EXPECTED
  if (myTestMode == 1) {
    .feature(SystemPowerFeature::USE_VIN_SETTINGS_WITH_USB_HOST) ;

  //  (2) PMIC Mode
  // Known: 3.78V Li-Po, 850 mW Available from Panel @ 5.08V on TEST STAND, 50 mW used by Boron in Manual Mode, OLED, & INA219
  // Charging Results: 3.82V @ Li-Po, 114 mA, 435 mW , Panel Output (Vusb) holding at 6.45V, DPDM Not Working
  // After Reset : 3.84V @ Li-Po, 195 mA, 750 mW , Panel Output (Vusb) holding at 5.07V AS EXPECTED
  // After more testing, the PMIC Mode will default to the lower charging depending on if the Source is present (Panel Producing) at Startup or Not.
  // Reset or EN Pin Shutdown while the Panel is operating is why the 750 mW charging is reached in PMIC Mode
  if (myTestMode == 2) {

    pmic.setInputCurrentLimit(900) ;        
    pmic.setChargeCurrent(0, 0, 1, 0, 0, 0);


Mode 1 will still obey your call for pmic.disableCharging(); when enclosure temperature is too high.

I’ll perform similar charging tests with the Sleep Modes next to see if any differences show up between the API and PMIC code.

Thanks again @avtolstoy, and everyone else involved.


thanks for your reply. please come back with updates when you’ll have some. also, may i ask you questions if i would have some? i see you’re much knowlegeable than me in these things. thank you

@Abnalsid, Welcome to the Community. Ask away.

Update w/ Sleep:
Using Stop Mode (System.sleep( {}, {}, sleepTime); ) shows the same recharging performance as previous test in this thread, with both the API and PMIC modes.

I still prefer the new API (what I called mode 1 in the code snip), for the reasons mentioned previously.

Standby Sleep, or System.sleep(SLEEP_MODE_DEEP); will WAKE the Boron when the Solar Panel Output cycles. IE, when the Panel begins to provide a Voltage Source- the Boron will wake up from Deep Sleep.

A typical Solar Install will use a progressive timed sleep schedule depending on the Li-Po Voltage or SOC. It’s not too hard to size the Panel and Li-Po so the Boron can remain on 24/7 most of the time, if needed.
As a last resort- if the SOC drops below 40% for instance, it could go into Deep Sleep Instead of timed, knowing that the Boron will automatically wake from Deep Sleep once the Solar Panel gets sunshine.

Tests performed with a 2W Voltaic Solar Panel using the USB connector on a Boron LTE running 1.5.0-rc1.

@Rftop, thank you very much for the additional information.

One statement that caught my attention was:

Standby Sleep, or System.sleep(SLEEP_MODE_DEEP); will WAKE the Boron when the Solar Panel Output cycles. IE, when the Panel begins to provide a Voltage Source- the Boron will wake up from Deep Sleep.

Is this technique purely software based, or are you adding hardware to make this possible?

Thank you very much!

That has happened out of the Box since 1.3.1-rc1, maybe even before that.
Here’s a Thread.

I’ve tried to quantify what Voltage causes the Wake Event (from Deep Sleep) with an adjustable power supply.
I wasn’t successful, as it appears the speed that the voltage increase occurs plays a role, not just the V.

1 Like

appreciated and thread added to learning task. you are really helpful. if you don’t mind, may i dm you with possible questions?

@Abnalsid Sure, you can message me. I’ll be glad to help if I can.
But post in the forum if you can, as you can get various opinions and thoughts.
Plus, the discussion will likely help others in the future :slight_smile:


i’m always thinking that asking too much questions (some of which might be obvious for some people) might bother someone especially with my small delice project. i’m just trying to be polite. but i’m going to take your advice :slight_smile: thanks

Thank you for sharing. I am starting to get some field experience with Solar powered Boron sensors. As part of this, I wanted to be able to switch back and forth between “Solar Optimized” settings and the system defaults. If I take what you have done for the API approach and added a “default” setting. Would this make sense? Can it be called during program execution or does it need to be done at restart?

// Power Management function
void PMICreset() {
  if (sysStatus.solarPowerMode) {
    conf.powerSourceMaxCurrent(900)                                  // default is 900mA
    .powerSourceMinVoltage(4840)                                     // Set the lowest input voltage to 4.84 volts best setting for 6V solar panels
    .batteryChargeCurrent(1024)                                      // default is 512mA matches my 3W panel
    .batteryChargeVoltage(4208)                                      // Allows us to charge cloe to 100% - battery can't go over 45 celcius
    .feature(SystemPowerFeature::USE_VIN_SETTINGS_WITH_USB_HOST) ;
  else  {
    conf.powerSourceMaxCurrent(1500)                                 // default is 900mA this let's me charge faster
    conf.powerSourceMinVoltage(4208)                                 // This is the default value for the Boron
    conf.batteryChargeCurrent(1024)                                  // default is 2048mA (011000) = 512mA+1024mA+512mA)
    conf.batteryChargeVoltage(4112)                                  // default is 4.112V termination voltage
    .feature(SystemPowerFeature::USE_VIN_SETTINGS_WITH_USB_HOST) ;



Chip, as far as I know- that should work.
But you could probably keep the higher values for MaxCurrent and ChargeCurrent between the Solar Vs Default Settings.

For Solar, you should get more Watts from you panel using .powerSourceMinVoltage(5080) verses your (4840)