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

    threading - thread starts, but main does not run

    Scheduled Pinned Locked Moved MicroPython
    threadthreading
    9 Posts 3 Posters 1.8k Views 3 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.
    • G Offline
      gregcope
      last edited by gregcope

      Hi All,

      I want to run a thread in the background, reading I2C GPS pytrack data and feeding a micropyGPS object to constantly update GPS/GNS data.

      In the main thread I want to read from the same micropyGPS object to occasionally update location data.

      I have a main.py that does;

      my_gps = MicropyGPS()
      py = Pytrack()
      L76micropyGPS = L76micropyGPS(my_gps, py)
      while (True):
          print("my_gps.parsed_sentences : {}".format(my_gps.parsed_sentences()))
          time.sleep(2)
      

      This creates creates the object that then starts a thread thus;

      class L76micropyGPS:
      
          GPS_I2CADDR = const(0x10)
      
          def __init__(self, my_gps, pytrack=None, sda='P22', scl='P21'):
              <snippage>
              self.my_gps = my_gps
              # start thread feeding microGPS
              _thread.start_new_thread("GPS", self.feedMicroGPS(), ())
      
          def feedMicroGPS(self):
              print('Running feedGps_thread id: {}'.format(_thread.get_ident()))
              someNmeaData = ''
              while True:
                  # get some NMEA data
                  someNmeaData = str(self.i2c.readfrom(GPS_I2CADDR, 128))
                  print(" feedGps_thread - gpsChars recieved : {}".format(len(someNmeaData)))
                  # Pass NMEA data to micropyGPS object
                  for x in someNmeaData:
                      self.my_gps.update(str(x))
                  time.sleep(2)
      

      Actual behaviour - I see the thread start, and get I2C data, whilst updating the object, but the main thread never gets beyond creating that object - ie the while loop never executes.

      My expected behaviour is the thread runs in the background (in this case printing data) and then the main thread carries on running (and can see the new GPS data).

      Have I mis understood something about _threading on micropython?

      Complete code: https://github.com/gregcope/L76micropyGPS

      T 1 Reply Last reply Reply Quote 0
      • T Offline
        timh @gregcope
        last edited by timh

        @gregcope Have a look at the docs and your call to start_new_thread

        _thread.start_new_thread(function, args[, kwargs])
        Start a new thread and return its identifier. The thread executes the function with the argument list args (which must be a tuple). The optional kwargs argument specifies a dictionary of keyword arguments. When the function returns, the thread silently exits. When the function terminates with an unhandled exception, a stack trace is printed and then the thread exits (but other threads continue to run).

        At the moment you are passing in a 'string' GPS as the first argument and the result of the function call self.feedMicroGPS() in the second.

        Your start_new_thread call should look like _thread.start_new_thread(self.feedMicroGPS, <some args>)

        When the docs say pass a function, your are passing a function/method handle and not calling the function.

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

          Thanks @timh tried that (or something similar);

          Changed main to include;

          L76micropyGPS = L76micropyGPS(my_gps, py)
          
          gpsThread = L76micropyGPS.startGPSThread()
          print("startGPSThread thread id is: " + startGPSThread)
          

          And class L76micropyGPS to (separate out the thread start to its own method, so I can call thread stop in another method);

              def startGPSThread(self):
                  # start thread feeding microGPS
                  self.gps_thread = _thread.start_new_thread(self.feedMicroGPS())
          

          My expected behavour is that the Main thread gets to this line just after thread start and Main carries on (with Thread in background also carrying on;

          print("startGPSThread thread id is: " + startGPSThread)
          

          This never happens ....
          Output (that just carries on)

          Free Mem: 2535984
          Free Mem post pytrack instantiation: 2534320
          Free Mem post my_gps instantiation: 2533616
          Running feedGps_thread id: 1073503820
           feedGps_thread - gpsChars recieved : 226
           feedGps_thread - gpsChars recieved : 139
           feedGps_thread - gpsChars recieved : 141
           feedGps_thread - gpsChars recieved : 139
          
          T 1 Reply Last reply Reply Quote 0
          • T Offline
            timh @gregcope
            last edited by timh

            @gregcope Hi Greg.

            You missed the crucial bit in my email. You code still calls self.feedMicroGPS() once and it's result is passed to start_new_thread.

            self.gps_thread = _thread.start_new_thread(self.feedMicroGPS())

            should be

            self.gps_thread = _thread.start_new_thread(self.feedMicroGPS)

            G 1 Reply Last reply Reply Quote 1
            • G Offline
              gregcope @timh
              last edited by

              @timh Many thanks.

              self.gps_thread = _thread.start_new_thread(self.feedMicroGPS)
              

              I found that did NOT work.

              But

              self.gps_thread = _thread.start_new_thread(self.feedMicroGPS, ())
              

              Does work - ie you have to supply an empty arg list, otherwise it does not return.

              Is that a bug? Should it not throw an exception?

              T 1 Reply Last reply Reply Quote 0
              • T Offline
                timh @gregcope
                last edited by

                @gregcope Sorry I missed the arglist 2nd argument altogether.

                I was focusing on the first arg, where you were still calling a function/method and passing it's result to start_new_thread rather than passing the function handle.

                As to bug, that probably should raise an expecption, but thats in the _thread library

                G 1 Reply Last reply Reply Quote 0
                • G Offline
                  gregcope @timh
                  last edited by

                  @timh said in threading - thread starts, but main does not run:

                  @gregcope Sorry I missed the arglist 2nd argument altogether.

                  I was focusing on the first arg, where you were still calling a function/method and passing it's result to start_new_thread rather than passing the function handle.

                  As to bug, that probably should raise an expecption, but thats in the _thread library

                  No problem - thanks for all your help.

                  @Seb - where do i raise bugs?

                  sebS 1 Reply Last reply Reply Quote 0
                  • sebS Offline
                    seb @gregcope
                    last edited by

                    @gregcope

                    As in report a bug? The relevant github repo is usally the best place for such things:

                    Firmware: https://github.com/pycom/pycom-micropython-sigfox/issues
                    Libraries: https://github.com/pycom/pycom-libraries/issues
                    Documentation: https://github.com/pycom/pycom-documentation/issues
                    Pymakr: https://github.com/pycom/pymakr-atom/issues

                    G 1 Reply Last reply Reply Quote 0
                    • G Offline
                      gregcope @seb
                      last edited by

                      @seb said in threading - thread starts, but main does not run:

                      https://github.com/pycom/pycom-libraries/issues

                      Ta.

                      Opened;

                      https://github.com/pycom/pycom-micropython-sigfox/issues/158

                      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