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.
    • T Offline
      tshead
      last edited by

      @catalin - thanks for looking into this! Here’s all of my sensor-related code (in case there’s some interaction). I’m re-running this code every time the machine boots, including after every deep sleep. FWIW, my impression was that, except for a few bits of information like machine.reset_cause(), returning from deep sleep is like booting from scratch … is that not the case?

      Thanks in advance,
      Tim

          sensors = pysense.Pysense()
          mpp = MPL3115A2.MPL3115A2(sensors, mode=MPL3115A2.PRESSURE) # This is line 45, where it hangs
          si = SI7006A20.SI7006A20(sensors)
          lt = LTR329ALS01.LTR329ALS01(sensors)
      
          ow = onewire.OneWire(machine.Pin("P10"))
          external_temperature = onewire.DS18X20(ow)
          external_temperature.start_conversion()
          short_wl, long_wl = lt.light()
          time.sleep(1.0) # The onewire thermometer requires ~750ms to take a reading
      
          record = {
              "battery": {"value": sensors.read_battery_voltage(), "units": "V"},
              "temperature/internal/1": {"value": mpp.temperature(), "units": "degC"},
              "pressure": {"value": mpp.pressure(), "units": "pascal"},
              "temperature/internal/2": {"value": si.temperature(), "units": "degC"},
              "humidity": si.humidity(),
              "light/ambient/short": short_wl,
              "light/ambient/long": long_wl,
              "temperature/water/1": {"value": external_temperature.read_temp_async(), "units": "degC"},
          }
      
      1 Reply Last reply Reply Quote 0
      • T Offline
        tshead
        last edited by

        Following-up … this has continued to be an issue for me, with my WiPy 2 consistently hanging within 2 - 8 hours of operation (I’m waking-up from deep sleep once per minute to gather data and send it over HTTP). Since removing the MPL3115A2 code completely, it’s been running for 24 hours without a problem.

        Cheers,
        Tim

        1 Reply Last reply Reply Quote 0
        • 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