With Python, how to prevent two threads from writing simultaneously to display












0















I'm working on a Raspberry Pi project where I have an OLED display that is continuously updated with information in a Python while True-loop. However, whenever I press a button (GPIO 5) I would like to display some other static information (e.g. system info) for as long as the button is depressed, or possibly for a predefined period of time. When the button is released, the "main loop" may take over again.
I have tried to implement this using RPi.GPIO and a callback function for the display of system info, but the problem is of course that even during the callback function execution, the main loop continues writing to the OLED, creating garbage on the OLED if GPIO 5 is depressed: Both "threads" are writing simultaneously to the OLED...



I assume I need a way to pause the execution of the main loop during the callback function and I have experimented with Semaphore and aquire/release but with no luck. I have also considered the possibility of having two callback functions in combination with Semaphore, but since the info displayed in the main loop should be continuously updated (e.g. not interrupt-driven) I'm not so sure that is a solution for me.



At this point I am not even sure what to google next. Perhaps someone in here can enlighten me? Is this perhaps a totally wrong way of doing this kind of thing? (Limited experience with Python...)



Below is a simplified code example that simulates what I would like to do.



import time
import Adafruit_GPIO.SPI as SPI
import RPi.GPIO as GPIO
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# Initialize
disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
disp.begin()
disp.clear()
disp.display()
image = Image.new('1', (disp.width, disp.height))
draw = ImageDraw.Draw(image)
font = ImageFont.load_default()
GPIO.setmode(GPIO.BCM)
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

def clear_display():
draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
disp.image(image)
disp.display()

# Callback function
def display_system_info(channel):
draw.text((0, 0), "System info displayed", font=font, fill=255)
draw.text((0, 9), "for five seconds.", font=font, fill=255)
disp.image(image)
disp.display()
time.sleep(5)
clear_display()

GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

try:
while True:
for counter in range(7):
draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
disp.image(image)
disp.display()
time.sleep(1)
clear_display()
except KeyboardInterrupt:
GPIO.cleanup() # clean up GPIO on CTRL+C exit
GPIO.cleanup() # clean up GPIO on normal exit


Many thanks for any help.



/N










share|improve this question



























    0















    I'm working on a Raspberry Pi project where I have an OLED display that is continuously updated with information in a Python while True-loop. However, whenever I press a button (GPIO 5) I would like to display some other static information (e.g. system info) for as long as the button is depressed, or possibly for a predefined period of time. When the button is released, the "main loop" may take over again.
    I have tried to implement this using RPi.GPIO and a callback function for the display of system info, but the problem is of course that even during the callback function execution, the main loop continues writing to the OLED, creating garbage on the OLED if GPIO 5 is depressed: Both "threads" are writing simultaneously to the OLED...



    I assume I need a way to pause the execution of the main loop during the callback function and I have experimented with Semaphore and aquire/release but with no luck. I have also considered the possibility of having two callback functions in combination with Semaphore, but since the info displayed in the main loop should be continuously updated (e.g. not interrupt-driven) I'm not so sure that is a solution for me.



    At this point I am not even sure what to google next. Perhaps someone in here can enlighten me? Is this perhaps a totally wrong way of doing this kind of thing? (Limited experience with Python...)



    Below is a simplified code example that simulates what I would like to do.



    import time
    import Adafruit_GPIO.SPI as SPI
    import RPi.GPIO as GPIO
    import Adafruit_SSD1306
    from PIL import Image
    from PIL import ImageDraw
    from PIL import ImageFont

    # Initialize
    disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
    disp.begin()
    disp.clear()
    disp.display()
    image = Image.new('1', (disp.width, disp.height))
    draw = ImageDraw.Draw(image)
    font = ImageFont.load_default()
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

    def clear_display():
    draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
    disp.image(image)
    disp.display()

    # Callback function
    def display_system_info(channel):
    draw.text((0, 0), "System info displayed", font=font, fill=255)
    draw.text((0, 9), "for five seconds.", font=font, fill=255)
    disp.image(image)
    disp.display()
    time.sleep(5)
    clear_display()

    GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

    try:
    while True:
    for counter in range(7):
    draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
    disp.image(image)
    disp.display()
    time.sleep(1)
    clear_display()
    except KeyboardInterrupt:
    GPIO.cleanup() # clean up GPIO on CTRL+C exit
    GPIO.cleanup() # clean up GPIO on normal exit


    Many thanks for any help.



    /N










    share|improve this question

























      0












      0








      0








      I'm working on a Raspberry Pi project where I have an OLED display that is continuously updated with information in a Python while True-loop. However, whenever I press a button (GPIO 5) I would like to display some other static information (e.g. system info) for as long as the button is depressed, or possibly for a predefined period of time. When the button is released, the "main loop" may take over again.
      I have tried to implement this using RPi.GPIO and a callback function for the display of system info, but the problem is of course that even during the callback function execution, the main loop continues writing to the OLED, creating garbage on the OLED if GPIO 5 is depressed: Both "threads" are writing simultaneously to the OLED...



      I assume I need a way to pause the execution of the main loop during the callback function and I have experimented with Semaphore and aquire/release but with no luck. I have also considered the possibility of having two callback functions in combination with Semaphore, but since the info displayed in the main loop should be continuously updated (e.g. not interrupt-driven) I'm not so sure that is a solution for me.



      At this point I am not even sure what to google next. Perhaps someone in here can enlighten me? Is this perhaps a totally wrong way of doing this kind of thing? (Limited experience with Python...)



      Below is a simplified code example that simulates what I would like to do.



      import time
      import Adafruit_GPIO.SPI as SPI
      import RPi.GPIO as GPIO
      import Adafruit_SSD1306
      from PIL import Image
      from PIL import ImageDraw
      from PIL import ImageFont

      # Initialize
      disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
      disp.begin()
      disp.clear()
      disp.display()
      image = Image.new('1', (disp.width, disp.height))
      draw = ImageDraw.Draw(image)
      font = ImageFont.load_default()
      GPIO.setmode(GPIO.BCM)
      GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

      def clear_display():
      draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
      disp.image(image)
      disp.display()

      # Callback function
      def display_system_info(channel):
      draw.text((0, 0), "System info displayed", font=font, fill=255)
      draw.text((0, 9), "for five seconds.", font=font, fill=255)
      disp.image(image)
      disp.display()
      time.sleep(5)
      clear_display()

      GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

      try:
      while True:
      for counter in range(7):
      draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
      disp.image(image)
      disp.display()
      time.sleep(1)
      clear_display()
      except KeyboardInterrupt:
      GPIO.cleanup() # clean up GPIO on CTRL+C exit
      GPIO.cleanup() # clean up GPIO on normal exit


      Many thanks for any help.



      /N










      share|improve this question














      I'm working on a Raspberry Pi project where I have an OLED display that is continuously updated with information in a Python while True-loop. However, whenever I press a button (GPIO 5) I would like to display some other static information (e.g. system info) for as long as the button is depressed, or possibly for a predefined period of time. When the button is released, the "main loop" may take over again.
      I have tried to implement this using RPi.GPIO and a callback function for the display of system info, but the problem is of course that even during the callback function execution, the main loop continues writing to the OLED, creating garbage on the OLED if GPIO 5 is depressed: Both "threads" are writing simultaneously to the OLED...



      I assume I need a way to pause the execution of the main loop during the callback function and I have experimented with Semaphore and aquire/release but with no luck. I have also considered the possibility of having two callback functions in combination with Semaphore, but since the info displayed in the main loop should be continuously updated (e.g. not interrupt-driven) I'm not so sure that is a solution for me.



      At this point I am not even sure what to google next. Perhaps someone in here can enlighten me? Is this perhaps a totally wrong way of doing this kind of thing? (Limited experience with Python...)



      Below is a simplified code example that simulates what I would like to do.



      import time
      import Adafruit_GPIO.SPI as SPI
      import RPi.GPIO as GPIO
      import Adafruit_SSD1306
      from PIL import Image
      from PIL import ImageDraw
      from PIL import ImageFont

      # Initialize
      disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
      disp.begin()
      disp.clear()
      disp.display()
      image = Image.new('1', (disp.width, disp.height))
      draw = ImageDraw.Draw(image)
      font = ImageFont.load_default()
      GPIO.setmode(GPIO.BCM)
      GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

      def clear_display():
      draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
      disp.image(image)
      disp.display()

      # Callback function
      def display_system_info(channel):
      draw.text((0, 0), "System info displayed", font=font, fill=255)
      draw.text((0, 9), "for five seconds.", font=font, fill=255)
      disp.image(image)
      disp.display()
      time.sleep(5)
      clear_display()

      GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

      try:
      while True:
      for counter in range(7):
      draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
      disp.image(image)
      disp.display()
      time.sleep(1)
      clear_display()
      except KeyboardInterrupt:
      GPIO.cleanup() # clean up GPIO on CTRL+C exit
      GPIO.cleanup() # clean up GPIO on normal exit


      Many thanks for any help.



      /N







      python callback interrupt






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 '18 at 3:15









      NilsNils

      1




      1
























          3 Answers
          3






          active

          oldest

          votes


















          0














          I am solving situations like this with global varialbe - buttonPressed.
          When you press button (GPIO 5), buttonPressed is set to True and main loop does nothing.
          Hope it is clear for you and will help you.



          import time
          import Adafruit_GPIO.SPI as SPI
          import RPi.GPIO as GPIO
          import Adafruit_SSD1306
          from PIL import Image
          from PIL import ImageDraw
          from PIL import ImageFont

          # Initialize
          disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
          disp.begin()
          disp.clear()
          disp.display()
          image = Image.new('1', (disp.width, disp.height))
          draw = ImageDraw.Draw(image)
          font = ImageFont.load_default()
          GPIO.setmode(GPIO.BCM)
          GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

          buttonPressed = False

          def clear_display():
          draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
          disp.image(image)
          disp.display()

          # Callback function
          def display_system_info(channel):
          global buttonPressed
          buttonPressed = True
          draw.text((0, 0), "System info displayed", font=font, fill=255)
          draw.text((0, 9), "for five seconds.", font=font, fill=255)
          disp.image(image)
          disp.display()
          time.sleep(5)
          clear_display()
          buttonPressed = False

          GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

          try:
          while True:
          if(not buttonPressed):
          for counter in range(7):
          draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
          disp.image(image)
          disp.display()
          time.sleep(1)
          clear_display()
          except KeyboardInterrupt:
          GPIO.cleanup() # clean up GPIO on CTRL+C exit
          GPIO.cleanup() # clean up GPIO on normal exit


          Try and let me know.






          share|improve this answer
























          • I played around with your suggestion but the strange thing is that if I add print commands to verify whether I am inside the callback function or not, I can see that even if I am inside the function, the main loop keeps printing tings to my OLED despite the fact that I added the "if not buttonPressed" check. Probably because the add_event_detect looks for edges.

            – Nils
            Nov 22 '18 at 14:56



















          0














          Depending on your application I'd avoid doing any real work inside of the callback. Instead I'd only set a flag which the main thread/loop can handle or add the events to a queue which is processed by the main thread/loop.






          share|improve this answer
























          • That is a plausible solution. However, I assume I then have to constantly check whether this flag is 1/0...and then I could just as well constantly check if the button is pressed. Or did I perhaps misunderstand your suggestion?

            – Nils
            Nov 22 '18 at 14:59











          • Constant checking if the button is pressed (polling) might be even better. I'm not sure how the event is implemented, but if it is an interrupt you could cause all kinds of strange (timing) issues by constantly pressing the button (whatever your application is doing, it will be interrupted). Some buttons/switches also suffer from bouncing contacts, so even if you think you pressed it only once it might be detected as several very quick presses.

            – katzenversteher
            Nov 28 '18 at 5:23





















          0














          I realized interrupts was not a good path to walk for this particular application. Instead, I re-wrote my code so that it's only possible to push the button when the main loop is idle and waiting...which is most of the time of course. Thanks for input!






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53423361%2fwith-python-how-to-prevent-two-threads-from-writing-simultaneously-to-display%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            I am solving situations like this with global varialbe - buttonPressed.
            When you press button (GPIO 5), buttonPressed is set to True and main loop does nothing.
            Hope it is clear for you and will help you.



            import time
            import Adafruit_GPIO.SPI as SPI
            import RPi.GPIO as GPIO
            import Adafruit_SSD1306
            from PIL import Image
            from PIL import ImageDraw
            from PIL import ImageFont

            # Initialize
            disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
            disp.begin()
            disp.clear()
            disp.display()
            image = Image.new('1', (disp.width, disp.height))
            draw = ImageDraw.Draw(image)
            font = ImageFont.load_default()
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

            buttonPressed = False

            def clear_display():
            draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
            disp.image(image)
            disp.display()

            # Callback function
            def display_system_info(channel):
            global buttonPressed
            buttonPressed = True
            draw.text((0, 0), "System info displayed", font=font, fill=255)
            draw.text((0, 9), "for five seconds.", font=font, fill=255)
            disp.image(image)
            disp.display()
            time.sleep(5)
            clear_display()
            buttonPressed = False

            GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

            try:
            while True:
            if(not buttonPressed):
            for counter in range(7):
            draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
            disp.image(image)
            disp.display()
            time.sleep(1)
            clear_display()
            except KeyboardInterrupt:
            GPIO.cleanup() # clean up GPIO on CTRL+C exit
            GPIO.cleanup() # clean up GPIO on normal exit


            Try and let me know.






            share|improve this answer
























            • I played around with your suggestion but the strange thing is that if I add print commands to verify whether I am inside the callback function or not, I can see that even if I am inside the function, the main loop keeps printing tings to my OLED despite the fact that I added the "if not buttonPressed" check. Probably because the add_event_detect looks for edges.

              – Nils
              Nov 22 '18 at 14:56
















            0














            I am solving situations like this with global varialbe - buttonPressed.
            When you press button (GPIO 5), buttonPressed is set to True and main loop does nothing.
            Hope it is clear for you and will help you.



            import time
            import Adafruit_GPIO.SPI as SPI
            import RPi.GPIO as GPIO
            import Adafruit_SSD1306
            from PIL import Image
            from PIL import ImageDraw
            from PIL import ImageFont

            # Initialize
            disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
            disp.begin()
            disp.clear()
            disp.display()
            image = Image.new('1', (disp.width, disp.height))
            draw = ImageDraw.Draw(image)
            font = ImageFont.load_default()
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

            buttonPressed = False

            def clear_display():
            draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
            disp.image(image)
            disp.display()

            # Callback function
            def display_system_info(channel):
            global buttonPressed
            buttonPressed = True
            draw.text((0, 0), "System info displayed", font=font, fill=255)
            draw.text((0, 9), "for five seconds.", font=font, fill=255)
            disp.image(image)
            disp.display()
            time.sleep(5)
            clear_display()
            buttonPressed = False

            GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

            try:
            while True:
            if(not buttonPressed):
            for counter in range(7):
            draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
            disp.image(image)
            disp.display()
            time.sleep(1)
            clear_display()
            except KeyboardInterrupt:
            GPIO.cleanup() # clean up GPIO on CTRL+C exit
            GPIO.cleanup() # clean up GPIO on normal exit


            Try and let me know.






            share|improve this answer
























            • I played around with your suggestion but the strange thing is that if I add print commands to verify whether I am inside the callback function or not, I can see that even if I am inside the function, the main loop keeps printing tings to my OLED despite the fact that I added the "if not buttonPressed" check. Probably because the add_event_detect looks for edges.

              – Nils
              Nov 22 '18 at 14:56














            0












            0








            0







            I am solving situations like this with global varialbe - buttonPressed.
            When you press button (GPIO 5), buttonPressed is set to True and main loop does nothing.
            Hope it is clear for you and will help you.



            import time
            import Adafruit_GPIO.SPI as SPI
            import RPi.GPIO as GPIO
            import Adafruit_SSD1306
            from PIL import Image
            from PIL import ImageDraw
            from PIL import ImageFont

            # Initialize
            disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
            disp.begin()
            disp.clear()
            disp.display()
            image = Image.new('1', (disp.width, disp.height))
            draw = ImageDraw.Draw(image)
            font = ImageFont.load_default()
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

            buttonPressed = False

            def clear_display():
            draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
            disp.image(image)
            disp.display()

            # Callback function
            def display_system_info(channel):
            global buttonPressed
            buttonPressed = True
            draw.text((0, 0), "System info displayed", font=font, fill=255)
            draw.text((0, 9), "for five seconds.", font=font, fill=255)
            disp.image(image)
            disp.display()
            time.sleep(5)
            clear_display()
            buttonPressed = False

            GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

            try:
            while True:
            if(not buttonPressed):
            for counter in range(7):
            draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
            disp.image(image)
            disp.display()
            time.sleep(1)
            clear_display()
            except KeyboardInterrupt:
            GPIO.cleanup() # clean up GPIO on CTRL+C exit
            GPIO.cleanup() # clean up GPIO on normal exit


            Try and let me know.






            share|improve this answer













            I am solving situations like this with global varialbe - buttonPressed.
            When you press button (GPIO 5), buttonPressed is set to True and main loop does nothing.
            Hope it is clear for you and will help you.



            import time
            import Adafruit_GPIO.SPI as SPI
            import RPi.GPIO as GPIO
            import Adafruit_SSD1306
            from PIL import Image
            from PIL import ImageDraw
            from PIL import ImageFont

            # Initialize
            disp = Adafruit_SSD1306.SSD1306_128_64(rst=None)
            disp.begin()
            disp.clear()
            disp.display()
            image = Image.new('1', (disp.width, disp.height))
            draw = ImageDraw.Draw(image)
            font = ImageFont.load_default()
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

            buttonPressed = False

            def clear_display():
            draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
            disp.image(image)
            disp.display()

            # Callback function
            def display_system_info(channel):
            global buttonPressed
            buttonPressed = True
            draw.text((0, 0), "System info displayed", font=font, fill=255)
            draw.text((0, 9), "for five seconds.", font=font, fill=255)
            disp.image(image)
            disp.display()
            time.sleep(5)
            clear_display()
            buttonPressed = False

            GPIO.add_event_detect(5, GPIO.RISING, callback=display_system_info, bouncetime=200)

            try:
            while True:
            if(not buttonPressed):
            for counter in range(7):
            draw.text((0,counter*9), "Printing line {0:d}".format(counter), font=font, fill=255)
            disp.image(image)
            disp.display()
            time.sleep(1)
            clear_display()
            except KeyboardInterrupt:
            GPIO.cleanup() # clean up GPIO on CTRL+C exit
            GPIO.cleanup() # clean up GPIO on normal exit


            Try and let me know.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 22 '18 at 8:23









            KoxoKoxo

            1944




            1944













            • I played around with your suggestion but the strange thing is that if I add print commands to verify whether I am inside the callback function or not, I can see that even if I am inside the function, the main loop keeps printing tings to my OLED despite the fact that I added the "if not buttonPressed" check. Probably because the add_event_detect looks for edges.

              – Nils
              Nov 22 '18 at 14:56



















            • I played around with your suggestion but the strange thing is that if I add print commands to verify whether I am inside the callback function or not, I can see that even if I am inside the function, the main loop keeps printing tings to my OLED despite the fact that I added the "if not buttonPressed" check. Probably because the add_event_detect looks for edges.

              – Nils
              Nov 22 '18 at 14:56

















            I played around with your suggestion but the strange thing is that if I add print commands to verify whether I am inside the callback function or not, I can see that even if I am inside the function, the main loop keeps printing tings to my OLED despite the fact that I added the "if not buttonPressed" check. Probably because the add_event_detect looks for edges.

            – Nils
            Nov 22 '18 at 14:56





            I played around with your suggestion but the strange thing is that if I add print commands to verify whether I am inside the callback function or not, I can see that even if I am inside the function, the main loop keeps printing tings to my OLED despite the fact that I added the "if not buttonPressed" check. Probably because the add_event_detect looks for edges.

            – Nils
            Nov 22 '18 at 14:56













            0














            Depending on your application I'd avoid doing any real work inside of the callback. Instead I'd only set a flag which the main thread/loop can handle or add the events to a queue which is processed by the main thread/loop.






            share|improve this answer
























            • That is a plausible solution. However, I assume I then have to constantly check whether this flag is 1/0...and then I could just as well constantly check if the button is pressed. Or did I perhaps misunderstand your suggestion?

              – Nils
              Nov 22 '18 at 14:59











            • Constant checking if the button is pressed (polling) might be even better. I'm not sure how the event is implemented, but if it is an interrupt you could cause all kinds of strange (timing) issues by constantly pressing the button (whatever your application is doing, it will be interrupted). Some buttons/switches also suffer from bouncing contacts, so even if you think you pressed it only once it might be detected as several very quick presses.

              – katzenversteher
              Nov 28 '18 at 5:23


















            0














            Depending on your application I'd avoid doing any real work inside of the callback. Instead I'd only set a flag which the main thread/loop can handle or add the events to a queue which is processed by the main thread/loop.






            share|improve this answer
























            • That is a plausible solution. However, I assume I then have to constantly check whether this flag is 1/0...and then I could just as well constantly check if the button is pressed. Or did I perhaps misunderstand your suggestion?

              – Nils
              Nov 22 '18 at 14:59











            • Constant checking if the button is pressed (polling) might be even better. I'm not sure how the event is implemented, but if it is an interrupt you could cause all kinds of strange (timing) issues by constantly pressing the button (whatever your application is doing, it will be interrupted). Some buttons/switches also suffer from bouncing contacts, so even if you think you pressed it only once it might be detected as several very quick presses.

              – katzenversteher
              Nov 28 '18 at 5:23
















            0












            0








            0







            Depending on your application I'd avoid doing any real work inside of the callback. Instead I'd only set a flag which the main thread/loop can handle or add the events to a queue which is processed by the main thread/loop.






            share|improve this answer













            Depending on your application I'd avoid doing any real work inside of the callback. Instead I'd only set a flag which the main thread/loop can handle or add the events to a queue which is processed by the main thread/loop.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 22 '18 at 9:28









            katzenversteherkatzenversteher

            583310




            583310













            • That is a plausible solution. However, I assume I then have to constantly check whether this flag is 1/0...and then I could just as well constantly check if the button is pressed. Or did I perhaps misunderstand your suggestion?

              – Nils
              Nov 22 '18 at 14:59











            • Constant checking if the button is pressed (polling) might be even better. I'm not sure how the event is implemented, but if it is an interrupt you could cause all kinds of strange (timing) issues by constantly pressing the button (whatever your application is doing, it will be interrupted). Some buttons/switches also suffer from bouncing contacts, so even if you think you pressed it only once it might be detected as several very quick presses.

              – katzenversteher
              Nov 28 '18 at 5:23





















            • That is a plausible solution. However, I assume I then have to constantly check whether this flag is 1/0...and then I could just as well constantly check if the button is pressed. Or did I perhaps misunderstand your suggestion?

              – Nils
              Nov 22 '18 at 14:59











            • Constant checking if the button is pressed (polling) might be even better. I'm not sure how the event is implemented, but if it is an interrupt you could cause all kinds of strange (timing) issues by constantly pressing the button (whatever your application is doing, it will be interrupted). Some buttons/switches also suffer from bouncing contacts, so even if you think you pressed it only once it might be detected as several very quick presses.

              – katzenversteher
              Nov 28 '18 at 5:23



















            That is a plausible solution. However, I assume I then have to constantly check whether this flag is 1/0...and then I could just as well constantly check if the button is pressed. Or did I perhaps misunderstand your suggestion?

            – Nils
            Nov 22 '18 at 14:59





            That is a plausible solution. However, I assume I then have to constantly check whether this flag is 1/0...and then I could just as well constantly check if the button is pressed. Or did I perhaps misunderstand your suggestion?

            – Nils
            Nov 22 '18 at 14:59













            Constant checking if the button is pressed (polling) might be even better. I'm not sure how the event is implemented, but if it is an interrupt you could cause all kinds of strange (timing) issues by constantly pressing the button (whatever your application is doing, it will be interrupted). Some buttons/switches also suffer from bouncing contacts, so even if you think you pressed it only once it might be detected as several very quick presses.

            – katzenversteher
            Nov 28 '18 at 5:23







            Constant checking if the button is pressed (polling) might be even better. I'm not sure how the event is implemented, but if it is an interrupt you could cause all kinds of strange (timing) issues by constantly pressing the button (whatever your application is doing, it will be interrupted). Some buttons/switches also suffer from bouncing contacts, so even if you think you pressed it only once it might be detected as several very quick presses.

            – katzenversteher
            Nov 28 '18 at 5:23













            0














            I realized interrupts was not a good path to walk for this particular application. Instead, I re-wrote my code so that it's only possible to push the button when the main loop is idle and waiting...which is most of the time of course. Thanks for input!






            share|improve this answer




























              0














              I realized interrupts was not a good path to walk for this particular application. Instead, I re-wrote my code so that it's only possible to push the button when the main loop is idle and waiting...which is most of the time of course. Thanks for input!






              share|improve this answer


























                0












                0








                0







                I realized interrupts was not a good path to walk for this particular application. Instead, I re-wrote my code so that it's only possible to push the button when the main loop is idle and waiting...which is most of the time of course. Thanks for input!






                share|improve this answer













                I realized interrupts was not a good path to walk for this particular application. Instead, I re-wrote my code so that it's only possible to push the button when the main loop is idle and waiting...which is most of the time of course. Thanks for input!







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 29 '18 at 11:33









                NilsNils

                1




                1






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53423361%2fwith-python-how-to-prevent-two-threads-from-writing-simultaneously-to-display%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                    Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                    A Topological Invariant for $pi_3(U(n))$