Reading inputs saving battery (STM8L151) - Page 1
Forum section: electronics / general

author: Leo86
author_rank: Contributor
timestamp: April 19, 2021, 09:05:12 pm
content: Hi everyone!I need read a inputs (PC0, PB7 and PB4) of microcontroller (STM8L151). For read inputs, i put HI level in pin PC4 and this moment i read every input, connected by resistor 2M2. When i end read inputs i put level LOW in PC4 for saved energy battery.When i read inputs in moment PC4 is HI, my inputs stay with diferent wrong values, every time that read.My doubt is if my external pullups are very big (2M2). This is cause of my problem?EN_SWITCH_HI; // PC4 = 1for(i = 10; i; i--){__no_operation(); // wait}flagS.valLevel = 0;flagS.level_1_L = SENS_1; // input PB7 (without internal pullup)flagS.level_2_ML = SENS_2; // input PC0 (without internal pullup)flagS.level_3_MH = SENS_3; // input PB4 (without internal pullup)EN_SWITCH_LO; // PC4 = 0thanks

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 20, 2021, 07:00:08 am
content: You can just use builtin pull-ups instead. Turn them on by setting bits in Px_CR1 before reading then turn off by clearing.

author: Leo86
author_rank: Contributor
timestamp: April 22, 2021, 12:58:28 am
content: I use external pullups (2M2) because the internal pullups are weak (60k). So, external pullups with 2M2 saving power of battery.My problem is that microcontroller read wrong values, when PC4 = "1", to ativate inputs.Are the external pullups too high?

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 22, 2021, 01:21:49 am
content: Why 2.2M? The inputs have a leakaje of 200nA at worst. Most 50nA.Pullups are 45K, it could be too much current depending on your application.But if enable them before reading, and after then disable again, the power draw will be minimal.The best would be to set PC4 as output high level, wait few uS, read the inputs, set PC4 as input and leave.That way no power being wasted anywhere while not reading. Those pins are not going to consume anything.In most stm32 you can set the pins as analog (Not adc related), that way they're completely disconnected from anything.It isn't input, neither output, just nothing.I think your problem is that you're not waiting enough time for the input pin capacitance to get charged.Each pin is about 5pF. If you calculate RC constant for 2.2M and 3.3V is 11us!And for 98% of the voltage you need 5RC, so 55uS.How many time does counting to 10 take? I doubt anything close to 50uS!And I hope the compiler is not doing it even worse by optimizing the loop!Code:for(i = 10; i; i--){__no_operation(); // wait}Try yourself, how many time it takes. Something like:Code:// Start Ex. Timer 1, configured at the same speed as the core.PC4 = 1;// Enable outputwhile(!SENS_1 || !SENS_2 || !SENS_3);// While any input is read low// Stop timer here. (But don't clear it)// Read Timer counter value, convert into time, and adjust your loop with 50% extra time for safety.// Ensure to do it few times to get a consistent result.I would just connect it with something lower like 100K, 5RC will be 1.5uS.And for 10K, 5RC would be 250nS. How often are you going to read the inputs?If it's battery critical, I guess the MCU will be in sleep most of the time.Guessing you read the inputs maybe 20 times a second.You use 10K values, wait 4uS every time, read and disable, let's say it takes 5uS.That's 100uS/second.With 4x10K you get 1.32mA peak consumption. The resistors will draw 1 second of power every 2.7hours.For 1 hour and consume 1.32mAh, it would take almost 14 months!

author: Leo86
author_rank: Contributor
timestamp: April 22, 2021, 02:28:32 am
content: Hi DavidAlfa.I thought a 2M2 resistor (or a higher value) would be better for saving battery. Because in certain moments the external pullup would be connected to the GND directly depending on the condition of the key placed by the user.In the attached schematic when the switches are for the GND the current is maximum, so with external pullup resistors with a high value like 2M2 the consumption is reduced in comparison with the internal pullups. After I read the inputs of the switches I put the PC4 = 0 to save battery (My VCC 2,5V)But, what i understood 2M2 is a very large value, rigth?. If i want to use 2M2 or a higher value i should consider the capacitance of the STM8 inputs to read the inputs.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 22, 2021, 06:28:11 am
content: Using so weak pullups saves pretty nothing: the energy dissipated with pullups on is proportional to on_time/R, but to charge the input capacitance you need a delay proportional to R, so it is R/R at the end.Energy wasting starts when the pullup is so strong that you don’t need any delay at all.

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 22, 2021, 04:29:53 pm
content: I guess if you did read anything? It doesn't seem so...

author: Leo86
author_rank: Contributor
timestamp: April 22, 2021, 06:52:54 pm
content: Hi David.Sorry, maybe i don't have explain the answers of your questions.In my code the time these routine is 5us.for(i = 10; i; i--){__no_operation(); // wait}I understood what you said, that these time of loop don't is enough when using external pullups 2M2. If i want using external pullups with 2M2, i should increase time of loop.Other question is that with pullups 2M2 the time to execute this is 20usPC4 = 1;while(!SENS_1 || !SENS_2 || !SENS_3);PC4 = 0;I think that if I use internal pullups, I will not have any problems with time due to the internal capacitance of 5pF. However, I will have to put them (all inputs) in an analog configuration condition so as not to consume battery during deep sleep.Another possibility is to use lower resistor values ​​so that I don't have to spend a lot of time waiting for them to stabilize, as you explained.(I can't waste a lot of time waiting for the inputs to stabilize).

author: ogden
author_rank: Super Contributor
timestamp: April 22, 2021, 07:42:20 pm
content: Quote from: Leo86 on April 22, 2021, 06:52:54 pmBy increasing time of the loop you will increase time of MCU consumption which most likely is measured in tens of mA. You want to wake-up, quickly check button state and sleep. You can't do it using such a big values of pull-ups. Better follow suggstion - use internal pull-ups and disable them while sleeping.

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 22, 2021, 08:15:34 pm
content: I never said to use the pullups all the time? Only enable them few uS before reading the inputs!You save a pin and the resistors. Use the resources properly and you won't have any power issues.Don't read the inputs all the time in the loop, because what's the matter on reading a human activated button 10000 times per second?20 times per second is already enough. O even 100. More, why? That is wasting power.So that's the thing with the pullups.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 22, 2021, 08:52:10 pm
content: DavidAlfa, OP’s code in the first message is already doing exactly what you are proposing - turn on the pullup, delay, sample, turn off the pullup. The only problem there is delay time vs pullup resistance (and that part of your info is relevant).

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 22, 2021, 09:18:27 pm
content: Nope, he's not using the internal pullups, which is what I referred to in my last message.What I'm saying is that the lower resistor values are not a problem for the power consumption if you program it correctly.You avoid waiting useless time (That is also wasted power), and if you limit the reading frequency to a reasonable rate that's all.And add the capacitance of the traces and the external circuitry it's connected to.It could go well above 20pF. More time.

author: Leo86
author_rank: Contributor
timestamp: April 23, 2021, 02:05:09 pm
content: Hi DavidAlfa and Folks!Reading the application note AN3147, i understood that any I/O of microcontroller STM8L can generate additional consuption of ~10uA. If i don't using external pullups (2M2) only internal pullups (~60k), and read inputs 20 times per second and disable the internal pullups when i'm not reading the inputs, could generate consumption 10uA per I/O, rigth?. When in the worst case using 2M2 external pullups the battery consumption is 1.1uA per I/O.Battery consumption = ( (Battery voltage)/(External PullUps) )*Number InputsBattery voltage -> 2.5VExternal PullUps -> 2200000 OhmNumber Inputs -> 3Battery consumption = ((2,5/2200000)*3 = 3.4uAExternal pull-up resistors connected at all times in battery (without IO control PC4)!From everything we talked about here, I understand that using external pullups 2M2 (or larger) connected directly to the battery would be the minimum consumption that could be done.

author: ogden
author_rank: Super Contributor
timestamp: April 23, 2021, 04:25:16 pm
content: Quote from: Leo86 on April 23, 2021, 02:05:09 pmThat's it? This is what you said in your original post. So you did not learn muchTry to re-read whole thread, do not ignore parts you don't understand but instead - ask questions? Hint: check electrical energy formula. Hint2: you focus on pull-ups, yet STM8L151 consumes MUCH MORE current than pull-up!

author: Buriedcode
author_rank: Super Contributor
timestamp: April 24, 2021, 05:35:18 pm
content: Whilst I'm really just re-stating what others have said, another voice to try and hammer home the point can't hurt can it?When saving power you should do some calculations - ones that involve time as well as current. Having something that is always on, drawing 5uA will draw the same power as something that takes 0.5mA for 10ms. You seem to be focused on the instant current consumption rather than looking at the bigger picture which involves dynamically tunring things on and off, as and when you need them.As at least two people have stated quite clearly in this thread, using external "high-value" pullups doesn't always reduce power consupmtion, because the pullups have to work with the capacitance of the input pin - which means you have to wait between the change in input and reading the pin. That wait is time - time your microcontroller is active, and will draw more power than having a 45k pullup resistor pulled to ground. Your initial problem really does sound like your high resistance pullups just aren't strong enough to pull the pins voltage up quickly enough for you to read them.Also -why have pull ups permenantly connected to VCC when you only need them whilst reading inputs? Internal pull ups can also be enabled/disabled without having to use an extra IO as you would for external pullups.I'll say it again - Power saving is about having full control over things such as pull ups - which your micro has -they only have to be active shortly before reading the state of the pin, then they can be turned off.Your input is pulled to ground when active correct? This means that whilst active, it will pull the pull up resistor to ground, and by your values, draining I+V/R = 2.5 / 45k = 55uA per input. But for how long? 55uA for 10ms every second will draw 10% of the current as 5uA for a permenantly connected pullup.How long are these inputs pulled to ground? Are you reading user input buttons? Or time-critical interrupt type inputs where your micro needs to react quickly?

author: Leo86
author_rank: Contributor
timestamp: April 25, 2021, 09:44:33 pm
content: Hi Buriedcode, Thank you very much for your help and everyone here!"When saving power you should do some calculations - ones that involve time as well as current. Having something that is always on, drawing 5uA will draw the same power as something that takes 0.5mA for 10ms. You seem to be focused on the instant current consumption rather than looking at the bigger picture which involves dynamically tunring things on and off, as and when you need them."Yes, my application sleep in (Halt mode = TA(55°C) 1.2uA typ ) and wakeup every 100ms using RTC.The point is that to use internal pull ups, the microcontroller has to disable internal pullups, when not reading as inputs. Be it 1 time in 1s or 100 times per second.When I am not reading I will disable the internal pullups and the consumption for floating I / O is 10uA.Consumption will be permanently 10uA even when the microcontroller is in HALT MODE (AN3147, Floating I/Os could generate additional consumption in the range of a few 10 µA.), rigth?"As at least two people have stated quite clearly in this thread, using external "high-value" pullups doesn't always reduce power consupmtion, because the pullups have to work with the capacitance of the input pin - which means you have to wait between the change in input and reading the pin. That wait is time - time your microcontroller is active, and will draw more power than having a 45k pullup resistor pulled to ground. Your initial problem really does sound like your high resistance pullups just aren't strong enough to pull the pins voltage up quickly enough for you to read them."So, if i use external pullups of 2M2or 10Min every input, connected diretly in battery i only wait one time before enter in while(1), as show follow:configGPIO();delay(DELAY_10ms);while(1){readInputs();EnterHaltMode();...}I only wait once for the I / O capacitors to charge. 5pF*10M= 100us. Rigth?*I can use 10M (Ultra-low leakage per I/0: 50 nA)How long are these inputs pulled to ground?One or more of these inputs can remain connected to the GND, according to the user's configuration forever.Are you reading user input buttons? Or time-critical interrupt type inputs where your micro needs to react quickly?No critical problems with time.Thanks folks!

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 27, 2021, 09:55:53 am
content: Config straps polling example of one STM8L-based BMS:- config pins as GPIO_Mode_In_PU_No_IT- wait 10us- test IDR bits- config pins as GPIO_Mode_Out_PP_Low_Slow - so unconnected inputs are "tamed", inputs connected to GND consume no additional powerIn preparation for sleep most of input pins are configured as GPIO_Mode_Out_PP_Low_Slow too.

author: Buriedcode
author_rank: Super Contributor
timestamp: April 27, 2021, 08:25:38 pm
content: Ok, so you have three IO's, that are using for the user to "set and forget" via jumpers or switches, that permenantly switch these IO's to GND. You wish to wakeup every 100ms to perform various tasks, including reading the state of these IOs, in case the user has changed them.I have skimmed over that application note (AN3147) and it mentions the possibility of floating IO leakage:QuoteNote they said, could, not would. If your user sets an IO to GND, the current leakage would be much less. You could disable the pull-up resistor for these IO during sleep to reduce power consumption, only re-enabling them when you read them to check that they are still at GND.I say, measure the current consumption yourself whilst in sleep with floating IO's in-cricuit (also note the capacitance on the IO will be greater than the datasheet, unless it is unconnected).Another possibility is, to leave the internal pullups permenantly connected to the IOs, and instead of having these three IO switched to GND, they are switched to another IO. When you wake up, you pull this IO to GND, read the state of the three switches/jumpers, then either make this IO high, or change it to an input with internal pullups. This will consume pretty much zero current during sleep and the switches are only connecting the pullups to GND when you're reading them.

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 28, 2021, 08:14:32 am
content: That's too much drama going on! Since that MCU only has pull-up or no pullup:- In the initial configuration: Set low state in all pins. This setting doesn't matter in input mode. It doesn't change whether the pin is set to input or output.- Idle state: Set pins as output. Being in low state, there's no consumption.- Read state: Set pins as input, enable pull-ups, wait few uS, read the inputs.- And thats' all.Do a proper reading. Couldn't be easier! Page 120.https://www.st.com/resource/en/reference_manual/cd00218714-stm8l050j3-stm8l051f3-stm8l052c6-stm8l052r8-mcus-and-stm8l151l152-stm8l162-stm8al31-stm8al3l-lines-stmicroelectronics.pdf