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

    MPL3115A2 hangs intermittently

    Scheduled Pinned Locked Moved Expansion Board
    wipy 2pysensempl3115a2hang
    16 Posts 4 Posters 3.7k 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.
    • on4aaO Offline
      on4aa
      last edited by

      I am experiencing exactly the same problem with the following short piece of code. Within a minute or two (it varies) the thing hangs without any error message.

      Serial communication also breaks down and a power cycle is required to regain communication with the LoPy Pysense combo.

      import pycom
      import pysense
      import machine
      from MPL3115A2 import MPL3115A2, PRESSURE
      import utime
      import sys
      
      class Device:
      
          def __init__(self):
              self.iteration = 0
              self.sense(self)
              self.timer = machine.Timer.Alarm(self.sense, 3, periodic=True)
      
          def sense(self, device):
              # barometer mode, not raw, oversampling 128, minimum time 512 ms
              self.p = MPL3115A2(board, mode=PRESSURE).pressure()    # in Pa 
              self.iteration += 1
              print('%f Pa | iteration %d' % (self.p, self.iteration))
              pycom.rgbled(0x002200)
              utime.sleep(0.1)
              pycom.rgbled(0x000000)
      
      pycom.wifi_on_boot(False)
      pycom.heartbeat(False)
      board = pysense.Pysense()
      device = Device()
      
      try:
          while True:
              pass
      except KeyboardInterrupt:
          device.timer.cancel()
          sys.exit()
      
      1 Reply Last reply Reply Quote 0
      • on4aaO Offline
        on4aa
        last edited by

        I opened a bug report here:
        https://github.com/pycom/pycom-libraries/issues/46

        1 Reply Last reply Reply Quote 0
        • on4aaO Offline
          on4aa @catalin
          last edited by

          @catalin I posted example code to reproduce the MPL3115A2 hang-up within minutes.

          catalinC 1 Reply Last reply Reply Quote 0
          • catalinC Offline
            catalin @on4aa
            last edited by

            Hi guys, I do reproduce the bug, I am trying to investigate.

            Catalin,

            Have you checked out our docs for the answer? (Now with an easy search function) https://docs.pycom.io
            Check out our newly revamped device management platform, Pybytes! https://pybytes.pycom.io/

            on4aaO 3 Replies Last reply Reply Quote 0
            • on4aaO Offline
              on4aa @catalin
              last edited by

              @catalin I do not know if this is related, but it might be helpful. A similar problem with an MPL3115A2 has been reported a while back on a Raspberry Pi.

              i2c i2c-1: transfer setup timed out was the error given by the Raspberry Pi.

              1 Reply Last reply Reply Quote 0
              • on4aaO Offline
                on4aa @catalin
                last edited by

                @catalin Does the Pysense employ I2C for communicating with the MPL3115A2?
                If so, I am pretty sure we are dealing with an I2C problem.

                The following reading material hints into this direction:

                • Obscure I2C problems
                • SPI vs I2C
                1 Reply Last reply Reply Quote 0
                • on4aaO Offline
                  on4aa @catalin
                  last edited by

                  @catalin Lowering the I2C clock frequency can do wonders.
                  A frequency as low as 50kHz would probably do fine and increase reliability.
                  Also, keep the trace capacitance of SCL and SDA as low as possible.

                  catalinC 1 Reply Last reply Reply Quote 0
                  • catalinC Offline
                    catalin @on4aa
                    last edited by catalin

                    Hi guys,

                    Sorry for the delayed answer.
                    I was able to have the MPL3115A2 interrogation run for ~14 hours, by simply creating the object once, and periodically just calling pressure() method. Would this solve your problem?
                    Probably, a better solution is to have this MPL3115A2 class made static (as in Java).
                    With the previous version, the problem could have been the garbage collector, as for each new instance, new memory(heap) is allocated.

                    Regarding I2C lines, they were designed for up to 400kHz baudrate.

                    Code is here:

                    import pycom
                    import pysense
                    import machine
                    from MPL3115A2 import MPL3115A2, PRESSURE
                    import utime
                    import sys
                    
                    class Device:
                    
                        def __init__(self):
                            self.iteration = 0
                            self.p = MPL3115A2(board, mode=PRESSURE)    # create object just once
                            self.sense(self)
                            self.timer = machine.Timer.Alarm(self.sense, 3, periodic=True)
                    
                        def sense(self, device):
                            # barometer mode, not raw, oversampling 128, minimum time 512 ms
                            self.iteration += 1
                            print('%f Pa | iteration %d' % (self.p.pressure(), self.iteration))
                            pycom.rgbled(0x002200)
                            utime.sleep(0.1)
                            pycom.rgbled(0x000000)
                    
                    pycom.wifi_on_boot(False)
                    pycom.heartbeat(False)
                    board = pysense.Pysense()
                    device = Device()
                    
                    try:
                        while True:
                            pass
                    except KeyboardInterrupt:
                        device.timer.cancel()
                        sys.exit()
                    

                    Catalin,

                    Have you checked out our docs for the answer? (Now with an easy search function) https://docs.pycom.io
                    Check out our newly revamped device management platform, Pybytes! https://pybytes.pycom.io/

                    catalinC 1 Reply Last reply Reply Quote 0
                    • catalinC Offline
                      catalin @catalin
                      last edited by

                      I've verified the assumption that garbage collector is the problem, by calling it every loop, gc.collect(). In about 3 minutes, it's still blocked.
                      The problem seems to be the I2C module.
                      Meanwhile, I guess, you can use the workaround.

                      Catalin,

                      Have you checked out our docs for the answer? (Now with an easy search function) https://docs.pycom.io
                      Check out our newly revamped device management platform, Pybytes! https://pybytes.pycom.io/

                      on4aaO 1 Reply Last reply Reply Quote 0
                      • on4aaO Offline
                        on4aa @catalin
                        last edited by

                        @catalin Dear Catalin, the workaround indeed works fine. You should add it to the Pysense documentation to prevent other people falling in the same trap.

                        However, I am still left with one concern. Could it be that the main while True: pass loop is consuming too much processing power? I have seen this on Linux systems using htop and it was also reported on StackExchange.

                        Hence, my remaining questions are:

                        • How can I check upon MCU usage as htop is not available?
                        • Should I add a utime.sleep(0.2) to the main while True: loop?
                        • When are we going to see uasyncio being support by Pycom? Under my incentive, a couple of good souls removed the last obstacles for uasyncio adoption.
                        1 Reply Last reply Reply Quote 0
                        • S Offline
                          smbunn
                          last edited by

                          Has this problem been fixed? MY code wants to call the MPL3115A2 twice, once in pressure mode and once in atitude mode so needs to be called repeatedly.

                          for count in range (2000):
                              print("Count=", count)
                              vt = py.read_battery_voltage()
                              print("Battery voltage: " +str(vt))
                              dew = si.dew_point()
                              print("Dew point: "+ str(dew) + " deg C")
                              mp = MPL3115A2(py,mode=ALTITUDE) # Returns height in meters. Mode may also be set to PRESSURE, returning a value in Pascals
                              print("MPL3115A2 temperature: " + str(mp.temperature()))
                              temp1 = mp.temperature()
                              alt1 = mp.altitude()+100.0
                              print("Altitude: " + str(alt1))
                              mpp = MPL3115A2(py,mode=PRESSURE) # Returns pressure in Pa. Mode may also be set to ALTITUDE, returning a value in meters
                              press1 = mpp.pressure()
                              print("Pressure: " + str(press1))
                          

                          so declaring it only once probably will not work?

                          1 Reply Last reply Reply Quote 0
                          • catalinC Offline
                            catalin
                            last edited by

                            hi @smbunn,
                            The code was not modified.
                            On a second thought, the altitude is just a simple function of the pressure, considering the same sea-level pressure. This is not ok, as the sea-level pressure varies in time, and from place to place.
                            So, I would recommend, to use just the pressure, and if altitude is required, some arithmetics code has to be added, to get the right altitude. You could use some weather forecast service to obtain the accurate and real-time sea-level pressure.

                            Catalin,

                            Have you checked out our docs for the answer? (Now with an easy search function) https://docs.pycom.io
                            Check out our newly revamped device management platform, Pybytes! https://pybytes.pycom.io/

                            1 Reply Last reply Reply Quote 0

                            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