Good afternoon,
I'm working on, what will be a solar powered application where the supply voltage will be subject to slow rise times and it seemed wise to try to minimize the risk of the PIC ending up in an invalid state. So LPBOREN looked like the ideal solution and I set BORV low, thereby enabling a threshold of 1.9V.
All seemed to work as expected, the chip stopped at anything lower than 1.9V and restarted normally at anything over than 1.9V.
Now, I just tested it with a solar panel attached, that charges a 1000mfd as a small reservoir and it no longer works ! During startup, the first thing that happens is an LED pulses for 5mS as an indicator that the program is initializing. However, what is happening is that the LED stays on causing enough drain to stop the supply voltage rising any further indeed it freezes at just over 1.9V.
It does look as though it might be oscillating, not 'scoped it yet but is it possible that the LPBOREN is cycling the reset ? It's held in reset until the supply is OK but then the supply dips and it's then back in reset - ad infinitum !
Removing LPBOREN and it all works and the supply voltage slowly rises up to the design limit of 2.7V (the final version will use a supercapacitor and that is the voltage limit).
Am I missing something ?
I'd have expected some hysteresis to be associated with the chip's 1.9V detection but there's no mention but ... I've just noticed the PWRTE config bit for a 64mS startup delay and that seems to have it working as expected - so I could just give it long delay running into seconds or minutes.
Nevertheless, I've never had the chip lockup without LPBOREN and I can now see the risk associated with LPBOREN - an increase current demand at the threshold of 1.9V can result in a never ending reset / run cycle.
Any advice ? - I don't want to have manual intervention such as a reset button ... just want the chip to run when / if it can.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi, just some thoughts that may help your project.
I believe based on what I read on the microchip datasheets, that LPBORDEN was designed for “momentary” ramp up voltage’s with time frames of milliseconds, usually the time it takes to a power supply or a dc-dc converter to stabilize or charge the decoupling and bulk capacitors. But in your application, it seems that it will be subjected to seconds or even minutes of ramp up, depending on the available solar intensity.
In this case you may need a voltage supervisor circuitry to cover your MCU, there are different approach to do this, from a simple reverse Zener drived transistor or mosfet, to an of the shelf voltage monitor like the TPS3839 (just an example, there are a lot of other parts of different manufacturers) I prefer this last method.
There is a simple explanation of how this system works and it also uses the same part I suggested as example, maybe you don't like his English accent, but I assure you it's better than mine. 😊 https://www.youtube.com/watch?v=BqwUNOHiZ9k
Another thing you can do, taking in to account that your selected PIC has an internal voltage reference; is to program it to measure the Vdd voltage of the chip (the ADC can be programmed to compare Vdd to Vref internally without losing an analog pin) and don’t turn on the led or any other power-hungry device until enough voltage is present. this should prevent a reset loop.
On this block diagram of a 18f45k50 ADC you can see that the adc mux have "vdd" and "vss" switches, and taking into account that the GCB ReadAD10 library just converts port numbers (anX) to a bit register number; in this case you can simply use:
ReadAD10(an31)
To reverse measure Vdd in respect to internal Vref.
Note: refer to your specific datasheet to determine port number needed on your part.
This code should work as an example:
//This program will measure Vdd voltage and show it on an LCD with other registers.
#chip18F45k50,48
#optionExplicit
#defineHI2C_BAUD_RATE400
#defineHI2C_DATAPORTB.0
#defineHI2C_CLOCKPORTB.1DirHI2C_DATAinDirHI2C_CLOCKinHI2CModeMaster
#defineLCD_IO10
#defineLCD_I2C_Address_10x4E
#defineLCD_SPEEDOPTIMAL
#defineLCD_WIDTH16
#defineLCD_Backlight_On_State1
#defineLCD_Backlight_Off_State0LCDBacklight(Off)PVCFG0=0PVCFG1=0fvren=1
#defineADSPEEdLowSpeedDoclslocate0,0printReadAD10(an31)//an31 measures internal VRefLocate1,0printfvrs0printfvrs1printPVCFG0printPVCFG1printfvrenprintfvrstwait250msLoopEnd
I just reviewed your part datasheet, and indeed it uses "An31" for internal Vref, you just need to change the PVCFG register in the code to ADPREF that is used in your part, same numbers apply for vdd (00).
Also remember that the output value of "readad" will be inverted (more is less voltage)
Last edit: Angel Mier 2024-07-24
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'd had thoughts like yours a while back and bought a few TC54s - 2.7V. The TC54 is a MicroChip voltage detector with extremely low power consumption. I had the idea of simply waiting for the supercapacitor to reach full charge using the TC54 to hold the PIC in reset and then ignore the TC54 supply good when the PIC was up and running.
Just have this nagging doubt that whatever implementation, the chip will unexpectedly lock up due to another oversight !
The odd thing is that the chip has never locked up if I don't use brown-out no matter how slowly Vdd rises - but again the risk.
I'd have thought by now that MicroChip would have come up with a bullet proof solution and a chip that won't freeze. The fact that the TC54 exists at all indicates the awareness of the problem. I'd even considered an external watchdog but the complexity grows !
I'll try using the A/D - not something that I've played with - it's a good idea but if the chip freezes then it won't be able to do much at all !
I recollect secure CPU designs in the past where they collectively analysed one another's actions, if one stepped out of line, the others would kill it; that was if the rogue one hadn't already committed suicide ! Much akin to the old VAX Clusters - shared task loading ... a good idea but if you got it wrong, they'd spend all the time passing tasks around to even the load but never found the time to actually run the task.
I've read other threads with great interest but often there's no conclusion - bit like a whodunnit where the last page is missing ... so I'll try to come back and share my chosen "solution".
Thanks
Andrew
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
revised the datasheet, the 16LF1813 also have an internal Vref. I adapted the code to your part, I don't have that part in stock to test but it should work.
//This program will measure Vdd voltage from 1.4v to 3.6 on LF parts.
#chip16lf18313,32
#optionExplicitDimvoltsasInteger//configure internal Vref buffers to 1.024V.CDAFVR1=0CDAFVR0=1ADFVR1=0ADFVR0=1//enable intenal VrefFVREN=1
#defineADSPEEdLowSpeedDovolts=ReadAD10(an31)//an31 measures internal VRefwait250msLoopEnd
I used this clever method to know the battery level of battery powered devices.
Last edit: Angel Mier 2024-07-25
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Angel,
One of those days trying to find why my serial comms keeps producing a couple of random characters following a PIC restart. So I thought I'd build a test program around your code.
Failed on both counts ;o( ...
Serial comms proved to be perfect and I failed to comprehend the numbers coming back from your code. Current test bed is using a 3V battery supply and your example was returning values around 1005 - 1011. What I can not do is actually understand how I might derive a real voltage value - something like 3V would be good.
Gave ChatGPT a good try but, not unexpectedly, it came up with garbage and even invented a couple of non-existent registers. Sometimes, with a bit of effort, it comes up with acceptable code but the best I got was the suggestion that I read the datasheet !
Actually there's very little on the internet about reading battery voltage - a lot of threads without solutions - those that exist rely on resistor voltage dividers or timers seeing how long to charge a capacitor.
Thanks for your time,
Andrew
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I stopped the fast restart cycle by detecting the fact that it was a brown out reset and basically did nothing for 8 seconds or more after which a watchdog timer triggers and the program is allowed to run - that seemed to be a good solution.
However, I have found that the PIC has never locked up and there's an advantage in that the PIC can run, dare I say happily, down to around 1.4 volts, so the LPBOREN settings are commented out for the time being.
Andrew
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I use this to give an approximate battery level.
It uses (for this demo) an LCD to display the battery voltage.
Hopefully this will give you an idea.
'LCD connection settings#DefineLCD_IO4#DefineLCD_SPEEDFAST#DefineLCD_NO_RW'Port assignments#DefineLCD_RSPortA.0#DefineLCD_EnablePortA.1#DefineLCD_DB4PortA.2#DefineLCD_DB5PortC.0#DefineLCD_DB6PortC.1#DefineLCD_DB7PortC.2'set up fixed voltage reference modelFVRCON=b'10000010' ' Set FVREN On and ADC Vref to 2.048VADCON1=b'01010000' 'Left justified, FOSC/16, Vref+ to VDD#DefineAN1=1#DefineFVR=62'was 31 for 16F1829DimADFetchAsWordDimRefVoltsAsWordDimBatVoltsAsWordGet_BatterySubGet_Battery'1) Enable and set the FVR (fixed voltage reference) register for 2.048V setting.'2) Enable and read the A-D FVR ;This is an internal register'3) You now know what the battery voltage is at that time according to:''2.048V / BatVolts = A-D FVR / 255 ;(8 bits is close enough)';Promote values by 100'BatVolts = 52224 / A-D FVR ;A-D FVR reading should be around 175 at 3VDimVuAsByteDimVfAsByteDoRefVolts=ADFetch(FVR)'internal a-d of FVRBatVolts=52224/RefVoltsLocate0,0Print"Voltage "LetVu=BatVolts/100PrintVuPrint"."LetVu=Vu*100LetVf=BatVolts-VuPrintVfPrint"V "Locate1,0Print"Raw "PrintRefVoltsPrint" "Wait750mSLoopEndSub
It separates the decimals from the fractions for display purposes.
I claim no originality for the code, it was pretty much a direct copy from somewhere else in this forum.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Good afternoon,
I'm working on, what will be a solar powered application where the supply voltage will be subject to slow rise times and it seemed wise to try to minimize the risk of the PIC ending up in an invalid state. So LPBOREN looked like the ideal solution and I set BORV low, thereby enabling a threshold of 1.9V.
All seemed to work as expected, the chip stopped at anything lower than 1.9V and restarted normally at anything over than 1.9V.
Now, I just tested it with a solar panel attached, that charges a 1000mfd as a small reservoir and it no longer works ! During startup, the first thing that happens is an LED pulses for 5mS as an indicator that the program is initializing. However, what is happening is that the LED stays on causing enough drain to stop the supply voltage rising any further indeed it freezes at just over 1.9V.
It does look as though it might be oscillating, not 'scoped it yet but is it possible that the LPBOREN is cycling the reset ? It's held in reset until the supply is OK but then the supply dips and it's then back in reset - ad infinitum !
Removing LPBOREN and it all works and the supply voltage slowly rises up to the design limit of 2.7V (the final version will use a supercapacitor and that is the voltage limit).
Am I missing something ?
I'd have expected some hysteresis to be associated with the chip's 1.9V detection but there's no mention but ... I've just noticed the PWRTE config bit for a 64mS startup delay and that seems to have it working as expected - so I could just give it long delay running into seconds or minutes.
Nevertheless, I've never had the chip lockup without LPBOREN and I can now see the risk associated with LPBOREN - an increase current demand at the threshold of 1.9V can result in a never ending reset / run cycle.
Any advice ? - I don't want to have manual intervention such as a reset button ... just want the chip to run when / if it can.
A great question but no experience here. I thought I would say this rather then stay silent.
Hi, just some thoughts that may help your project.
I believe based on what I read on the microchip datasheets, that LPBORDEN was designed for “momentary” ramp up voltage’s with time frames of milliseconds, usually the time it takes to a power supply or a dc-dc converter to stabilize or charge the decoupling and bulk capacitors. But in your application, it seems that it will be subjected to seconds or even minutes of ramp up, depending on the available solar intensity.
In this case you may need a voltage supervisor circuitry to cover your MCU, there are different approach to do this, from a simple reverse Zener drived transistor or mosfet, to an of the shelf voltage monitor like the TPS3839 (just an example, there are a lot of other parts of different manufacturers) I prefer this last method.
Datasheet:

https://www.ti.com/lit/ds/symlink/tps3839.pdf
There is a simple explanation of how this system works and it also uses the same part I suggested as example, maybe you don't like his English accent, but I assure you it's better than mine. 😊
https://www.youtube.com/watch?v=BqwUNOHiZ9k
Hope it helps.
Angel
Last edit: Angel Mier 2024-07-24
Another thing you can do, taking in to account that your selected PIC has an internal voltage reference; is to program it to measure the Vdd voltage of the chip (the ADC can be programmed to compare Vdd to Vref internally without losing an analog pin) and don’t turn on the led or any other power-hungry device until enough voltage is present. this should prevent a reset loop.
On this block diagram of a 18f45k50 ADC you can see that the adc mux have "vdd" and "vss" switches, and taking into account that the GCB ReadAD10 library just converts port numbers (anX) to a bit register number; in this case you can simply use:
To reverse measure Vdd in respect to internal Vref.
Note: refer to your specific datasheet to determine port number needed on your part.
This code should work as an example:
Angel
Last edit: Angel Mier 2024-07-24
I just reviewed your part datasheet, and indeed it uses "An31" for internal Vref, you just need to change the PVCFG register in the code to ADPREF that is used in your part, same numbers apply for vdd (00).
Also remember that the output value of "readad" will be inverted (more is less voltage)
Last edit: Angel Mier 2024-07-24
Hi Angel,
Many thanks for your input.
I'd had thoughts like yours a while back and bought a few TC54s - 2.7V. The TC54 is a MicroChip voltage detector with extremely low power consumption. I had the idea of simply waiting for the supercapacitor to reach full charge using the TC54 to hold the PIC in reset and then ignore the TC54 supply good when the PIC was up and running.
Just have this nagging doubt that whatever implementation, the chip will unexpectedly lock up due to another oversight !
The odd thing is that the chip has never locked up if I don't use brown-out no matter how slowly Vdd rises - but again the risk.
I'd have thought by now that MicroChip would have come up with a bullet proof solution and a chip that won't freeze. The fact that the TC54 exists at all indicates the awareness of the problem. I'd even considered an external watchdog but the complexity grows !
I'll try using the A/D - not something that I've played with - it's a good idea but if the chip freezes then it won't be able to do much at all !
I recollect secure CPU designs in the past where they collectively analysed one another's actions, if one stepped out of line, the others would kill it; that was if the rogue one hadn't already committed suicide ! Much akin to the old VAX Clusters - shared task loading ... a good idea but if you got it wrong, they'd spend all the time passing tasks around to even the load but never found the time to actually run the task.
I've read other threads with great interest but often there's no conclusion - bit like a whodunnit where the last page is missing ... so I'll try to come back and share my chosen "solution".
Thanks
Andrew
Oops ... just noticed a typo in the title - the PIC is actually a 16LF18313.
Yes, the LPBOREN was causing it to reset / start / reset ... an oscillation of about 1kHz !
revised the datasheet, the 16LF1813 also have an internal Vref. I adapted the code to your part, I don't have that part in stock to test but it should work.
I used this clever method to know the battery level of battery powered devices.
Last edit: Angel Mier 2024-07-25
Hi Angel,
One of those days trying to find why my serial comms keeps producing a couple of random characters following a PIC restart. So I thought I'd build a test program around your code.
Failed on both counts ;o( ...
Serial comms proved to be perfect and I failed to comprehend the numbers coming back from your code. Current test bed is using a 3V battery supply and your example was returning values around 1005 - 1011. What I can not do is actually understand how I might derive a real voltage value - something like 3V would be good.
Gave ChatGPT a good try but, not unexpectedly, it came up with garbage and even invented a couple of non-existent registers. Sometimes, with a bit of effort, it comes up with acceptable code but the best I got was the suggestion that I read the datasheet !
Actually there's very little on the internet about reading battery voltage - a lot of threads without solutions - those that exist rely on resistor voltage dividers or timers seeing how long to charge a capacitor.
Thanks for your time,
Andrew
I forgot - the LPBOREN solution !
I stopped the fast restart cycle by detecting the fact that it was a brown out reset and basically did nothing for 8 seconds or more after which a watchdog timer triggers and the program is allowed to run - that seemed to be a good solution.
However, I have found that the PIC has never locked up and there's an advantage in that the PIC can run, dare I say happily, down to around 1.4 volts, so the LPBOREN settings are commented out for the time being.
Andrew
I use this to give an approximate battery level.
It uses (for this demo) an LCD to display the battery voltage.
Hopefully this will give you an idea.
It separates the decimals from the fractions for display purposes.
I claim no originality for the code, it was pretty much a direct copy from somewhere else in this forum.
Thanks for that - I'll give it a try.
Andrew