With Python, how to prevent two threads from writing simultaneously to display
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
add a comment |
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
add a comment |
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
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
python callback interrupt
asked Nov 22 '18 at 3:15
NilsNils
1
1
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
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.
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
add a comment |
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.
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
add a comment |
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!
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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!
add a comment |
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!
add a comment |
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!
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!
answered Nov 29 '18 at 11:33
NilsNils
1
1
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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