Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Measure a LiPo battery voltage

    Scheduled Pinned Locked Moved LoPy
    11 Posts 5 Posters 75 Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A Offline
      almeos
      last edited by

      Hello,
      I have a lopy with an expansion board and a lipo battery connected on the jst plug.
      I made some research but I do not find, for my configuration, a simple micropython command to read the battery voltage? (equivalent of read_battery_voltage() for pysense)
      Could someone help me please?
      Denis

      robert-hhR 2 Replies Last reply Reply Quote 0
      • T Offline
        troy salt
        last edited by

        You can create a voltage divider and read the voltage with ADC read. Then do some simple math to back out the voltage.

        A 1 Reply Last reply Reply Quote 1
        • A Offline
          almeos @troy salt
          last edited by

          @troy-salt Thank you for your answer.
          A voltage divider is an additional equipment that I have to connect on the expansion board?

          1 Reply Last reply Reply Quote 0
          • robert-hhR Offline
            robert-hh @almeos
            last edited by

            @almeos If you are using the pycom expansion board: that one gas already a voltage divider built-in, which allows to measure the battery voltage at P16. The Jumper 'Bat' has to be in place for that. The division factor is 2, so the voltage you get at P16 is up to 2.1V. You have to set the ADC to a 11dB attenuation. If you measure 1.8V, the battery voltage is 3.6V. Since the impedance of the voltage divider is rather high, the measurement will be noisy. Sampling several times and calculating the average gives better results.

            Note: If you have an older expansion board, the attenuation factor may be 3.

            A 1 Reply Last reply Reply Quote 0
            • A Offline
              almeos @robert-hh
              last edited by

              @robert-hh Thanks for your answer.
              I placed BAT jumper. My expansion board is V3.1.
              I wrote this code:

              >>> from machine import ADC
              >>> adc = ADC()
              >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
              2499
              >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
              2492
              >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
              2479
              >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
              2515
              >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
              2497
              

              With an average result of 2500, the voltage should be 2500 x 2 = 5000 mV.
              I measured my battery with a voltmeter: 3810mV.
              Where is my mistake?

              1 Reply Last reply Reply Quote 0
              • G Offline
                Gijs
                last edited by

                You probably have USB connected, which would explain why its 5V :) To test the battery voltage, you should remove the USB cable and perhaps use a separate USB-Serial converter to get the data out, or a telnet connection

                A 1 Reply Last reply Reply Quote 0
                • A Offline
                  almeos @Gijs
                  last edited by

                  @Gijs
                  Yes you are right, it was battery and microUSB both powered.
                  I made the same test with the expansion board powered only by the battery (with wifi connection), the result is different (better) but it still does not correspond to the real battery voltage (3810mV):

                  >>> from machine import ADC
                  >>> adc = ADC()
                  >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
                  2162
                  >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
                  2174
                  >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
                  2160
                  >>> adc.channel(attn=ADC.ATTN_11DB, pin='P16').value()
                  2155
                  
                  J 1 Reply Last reply Reply Quote 0
                  • G Offline
                    Gijs
                    last edited by

                    Not sure how to explain this, but it looks like the voltage declines from the charging voltage (around 4.2V) to the battery voltage you measured (3.8V). There could be a slight delay due to the battery chemistry. Also the ADC in the module is not 100% correct. By the way, I'd recommend to use the following instead: (as you keep re-instantiating the ADC internally)

                    from machine import ADC
                    adc = ADC()
                    bat_voltage = adc.channel(attn=ADC.ATTN_11DB, pin='P16')
                    bat_voltage.value()
                    
                    #this should return the voltage with the correct attenuation set above, but without the attenuation from the resistor divider
                    #bat_voltage.voltage()
                    
                    1 Reply Last reply Reply Quote 0
                    • J Offline
                      jcaron @almeos
                      last edited by

                      @almeos you should use .voltage, not .value.

                      .value is the raw value of the ADC in its range which IIRC is 0-4095 (4095=1.1V at 0 dB).

                      If you use .value you need to divide by 4095 and multiply by the max value at the chosen attenuation to get the actual voltage.

                      1 Reply Last reply Reply Quote 2
                      • robert-hhR Offline
                        robert-hh @almeos
                        last edited by robert-hh

                        @almeos The value returned by adc.value() is to be taken with respect to the full range value of 4096, which you read at a input voltage of about 3.5 V. It is NOT a mV value, and the full range Voltage varies from device to device.
                        So a reading of 2160 corresponds to 2160/4095* 3.5 *2 mV ~3.7 V.

                        Edit: In any case you have to make your own calibration.

                        A 1 Reply Last reply Reply Quote 2
                        • A Offline
                          almeos @robert-hh
                          last edited by

                          @Gijs @robert-hh @jcaron
                          Yes it works! Thanks for your help:

                          >>> from machine import ADC
                          >>> adc = ADC()
                          >>> bat_voltage = adc.channel(attn=ADC.ATTN_11DB, pin='P16')
                          >>> bat_voltage.voltage()
                          1898
                          >>> bat_voltage.voltage()
                          1898
                          >>> bat_voltage.voltage()
                          1888
                          >>> bat_voltage.voltage()
                          1894
                          >>> bat_voltage.voltage()
                          1893
                          
                          1 Reply Last reply Reply Quote 1

                          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                          With your input, this post could be even better 💗

                          Register Login
                          • 1 / 1
                          • First post
                            Last post

                          Pycom on Twitter

                          Pycom