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.
    • catalinC Offline
      catalin
      last edited by

      Hi @tshead, Could you post the portion of the python code where you call functions from MPL3115A2.py? Are you re-initiating (make a new instance) after each deep sleep?

      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
      • 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