Threading on EV3 micropython

1.1k views Asked by At

I am trying to write some code for my EV3 brick. I am really struggling to get multithreading to work. I am using threading module, it throws no error but function that are supposed to run on another thread aren't run at all. My code:

   #!/usr/bin/env pybricks
   from pybricks.hubs import EV3Brick
   from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                    InfraredSensor, UltrasonicSensor, GyroSensor)
   from pybricks.parameters import Port, Stop, Direction, Button, Color
   from pybricks.tools import wait, StopWatch, DataLog
   from pybricks.robotics import DriveBase
   from pybricks.media.ev3dev import SoundFile, ImageFile

   import threading


   # Create your objects here.
   ev3 = EV3Brick()

   def color_thread():
       print("color_thread")
       ev3.light.on(Color.ORANGE)
       wait(100)
       ev3.light.on(Color.GREEN)
       wait(100)

   def speaker_thread():
       print("speaker_thread")
       ev3.speaker.beep(200,100)
       wait(100)
       ev3.speaker.beep(500,100)
       wait(100)
   
   
   t1 = threading.Thread(target=color_thread)
   t2 = threading.Thread(target=speaker_thread)
   
   t1.start()
   t2.start()
   

So the expected output would be:

   color_thread
   speaker_thread

and some visible and hearable indication (changing lights and making sounds) but output is:

   Starting: brickrun --directory="/home/robot/olgojChorchoj_Stropochod" "/home/robot/olgojChorchoj_Stropochod"
   ----------
   ----------
   Completed successfully.

and no other indication of those two functions running what so ever.

Can you please tell me what am I doing wrong ? thx

1

There are 1 answers

0
Sylvester Kruin - try Codidact On

The problem here is that the program is ending before the threads get a chance to run. Since you're not running any time-consuming code while running the threads, the threads don't have anything to "run behind", so to speak, so they just exit immediately.

There are two solutions here. I'll explain the simpler one first.

Soultuion 1: using wait() after calling the threads

You can call wait() right after calling the threads. This gives the threads time to execute before the program exits. Here is what the end of the program would look like:

t1.start()
t2.start()
wait(230)

Notice that I wait for 230 milliseconds, not 200, to give the processor some breathing room, since it's not super fast.

Solution 2: putting only color_thread in a thread

The other, and perhaps less precise, option is to only have color_thread() run in a thread, and call speaker_thread() directly. Here is what the end of the program would look like:

# Create only one thread, for color_thread
thread = threading.Thread(target=color_thread)

# Start color_thread, and call speaker_thread directly
thread.start()
speaker_thread()