morguslethe
Posts: 11
Joined: Thu Jun 11, 2015 8:58 pm

Very strange behavior (time.strftime() kills main thread ??)

Thu Jun 11, 2015 9:44 pm

This is my first python program, and I am experiencing very strange behavior. Long story short, my main thread dies for no reason. The culprit seems to be time.strftime(). I think I need expert help with my code.

Here is how my program is supposed to run:
-pin 17 in BCM numbering is set to IN and pulled DOWN
-pin 17 waits for a RISING edge. when it comes, the threaded callback method "alarm" will trigger

-on rising edge detect, the "alarm" method prints "Rising edge detected at [time.strftime()]". I do the rising edge manually by connecting pin 17 with 3,3V on the pi. The method then removes the edge detection, and adds a new FALLING edge detection. when it comes, the threaded callback method "stagetwo" will trigger

-when "stagetwo" is triggered (by manually connecting pin 17 with 0V on the pi), I print "Falling edge detected". then I sleep for 3 seconds, and print "Exiting from stage two at [time.strftime()]"

-HERE IS THE PROBLEM: after this prints, the main thread somehow dies! I have isolated the problem to a specific line of code. The line of code is:

Code: Select all

print("Exit from stage two at "+time.strftime("%H:%M:%S %d/%m/%Y")+". Main thread should still be printing dots!")
If the above line of code is switched with

Code: Select all

print("Exiting from stage two. Main thread should still be printing dots!")
everything works as I expect!!!

Here is the program being run twice, one without time.strftime(), and one with in picture form:
To see full size image right-click on the image and select view image


Image

Image


What the heck is going on? Why does my main thread die? How could a sub-thread with a correctly executed time.strftime() kill the main thread? Why does time.strftime() work correctly TWO TIMES before (in "alarm" and once in "stagetwo"), but kill the program the third time?

I tried swapping time.strftime() with datetime.datetime.now(), with the same results.

Here is my entire commented code. Please, try to run it on your pi to see if you get the same results. I run my code with sudo python3 filename.py .My python version is 3.2.3 with GCC 4.6.3, my GPIO version is 0.5.11. There are no compile or run errors. I run this connected through SSH to my pi on the same network. My Raspbian version is not more than a few months old.

Code: Select all

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
import time

#First, I want to detect a rising edge. When I detect it, the threaded callback function "alarm" will get triggered.
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

#threaded callback function
def alarm(channel):
	try:
		print("Rising edge detected on pin "+str(channel)+" at "+time.strftime("%H:%M:%S %d/%m/%Y"))
		
		#next, I want to detect a falling edge. When I detect it, the threaded callback function "stagetwo" will get triggered
		GPIO.remove_event_detect(channel)
		
		GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
		
		GPIO.add_event_detect(channel, GPIO.FALLING, callback=stagetwo, bouncetime=300)
	except:
		print("Alarm thread except")

def stagetwo(channel):
	try:
		print("Falling edge detected on pin "+str(channel)+" at "+time.strftime("%H:%M:%S %d/%m/%Y"))

		#the program is now in "stage two". I remove the event detect. 
		GPIO.remove_event_detect(channel)
		
		#after three seconds of "stage two", I exit.
		time.sleep(3)

		####START PROBLEMATIC PART!!!!!!!!!########
		
		#if the first print is uncommented and second print commented, everything is fine
		#if the first print is commented and second UNCOMMENTED, somehow my main thread (printing "." every second) DIES and the program ends. time.strftime() does return and format the correct string. 
		

		#print("Exiting from stage two. Main thread should still be printing dots!")
		print("Exit from stage two at "+time.strftime("%H:%M:%S %d/%m/%Y")+". Main thread should still be printing dots!")
		####END PROBLEMATIC PART!!!!!!!!#########
	except:
		print("Stage two error")
			
		#I set up the pin as it was at the very begginning of the program, so the system is primed to repeat the process.
		GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
		GPIO.add_event_detect(channel, GPIO.RISING, callback=alarm, bouncetime=300)

GPIO.add_event_detect(17, GPIO.RISING, callback=alarm, bouncetime=300)

try:
	print("This is the main thread. It will print a dot every second, forever.")
	
	while 1:
		time.sleep(1)
		print(".")
	
	print("If this prints something is strange")
	
except:
	print("Main thread error")
	GPIO.cleanup()
GPIO.cleanup()           # clean up GPIO on normal exit

Thank you very much for reading my post. For additional info please ask. I obviously don't know much about threaded programming...
Last edited by morguslethe on Fri Jun 12, 2015 10:37 am, edited 1 time in total.

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 9:02 am

Looks like you've got too many brackets after your strftime call. Try this:

Code: Select all

print("Exit from stage two at "+time.strftime("%H:%M:%S %d/%m/%Y")"+. Main thread should still be printing dots!")
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

morguslethe
Posts: 11
Joined: Thu Jun 11, 2015 8:58 pm

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 10:36 am

Sorry, I made a mistake writing the post. The code I'm executing has the correct syntax:

Code: Select all

print("Exit from stage two at "+time.strftime("%H:%M:%S %d/%m/%Y")+". Main thread should still be printing dots!")
I will update the original post.

Additional info: I've tried putting try: except: blocks which catch all exceptions in every part of the code, but none of them get triggered.

User avatar
jojopi
Posts: 3152
Joined: Tue Oct 11, 2011 8:38 pm

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 10:45 am

There is no syntax error in the actual program, or it would not even start.

The main thread does not stop, but rather the whole program gets killed by SIGSEGV. A side effect of using sudo is that the shell cannot distinguish between raise(signum) and exit(128+signum), so bash does not print the "Segmentation fault" message that you would normally see.

A mistake in a Python script should not normally be able to cause a segmentation fault, so the code must be triggering a bug or thread-safety issue in Python itself or one of the C modules time or RPi.GPIO.

The bug is triggered well after the strftime(), on return from the second callback function I believe. So my guess would be that strftime() just affects Python's memory layout somewhat and the real problem is changing between the two callbacks.

I do not think you will see the problem if you set up a single callback for GPIO.BOTH, and then track inside that function what pull and edge it is expecting next.

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 10:56 am

jojopi wrote:There is no syntax error in the actual program, or it would not even start.
A very good point! Silly me. :oops:
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

User avatar
DougieLawson
Posts: 37799
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 11:56 am

elParaguayo wrote:
jojopi wrote:There is no syntax error in the actual program, or it would not even start.
A very good point! Silly me. :oops:
That's not always true with python. It doesn't run a complete syntax check (unlike perl) some things are only ever detected when the bad line of code runs.
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
jojopi
Posts: 3152
Joined: Tue Oct 11, 2011 8:38 pm

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 12:48 pm

DougieLawson wrote:That's not always true with python. It doesn't run a complete syntax check (unlike perl) some things are only ever detected when the bad line of code runs.
Do you have an example of a syntax error that Python will not catch during initial parsing of the file? I know you can create one at run time using eval, exec, or late import of a broken module, but that is not a difference from Perl.

User avatar
DougieLawson
Posts: 37799
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 1:01 pm

Code: Select all

#!/usr/bin/python
import time

try:
  for i in range(0,17):
    if i == 14:
      raise fourteen
    else:
      time.sleep(1)
except:
  printit("Fourteen")
finally:
  print "Done"
It fails to detect the missing function until it tries to run it.
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
PeterO
Posts: 5625
Joined: Sun Jul 22, 2012 4:14 pm

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 1:09 pm

That's a NameError , not a SyntaxError !

If I add

Code: Select all

def printit(text):
    print(text)
the programme will run without changing your claimed syntax error.

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
jojopi
Posts: 3152
Joined: Tue Oct 11, 2011 8:38 pm

Re: Very strange behavior (time.strftime() kills main thread

Fri Jun 12, 2015 1:25 pm

Also, Perl cannot detect that kind of problem until run time either.

Code: Select all

#! /usr/bin/perl
use strict;
use warnings;

for my $i (0..16) {
  fun() if $i == 14;
  sleep 1;
}
print "Done";

morguslethe
Posts: 11
Joined: Thu Jun 11, 2015 8:58 pm

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 8:47 am

jojopi wrote: The bug is triggered well after the strftime(), on return from the second callback function I believe. So my guess would be that strftime() just affects Python's memory layout somewhat and the real problem is changing between the two callbacks.

I do not think you will see the problem if you set up a single callback for GPIO.BOTH, and then track inside that function what pull and edge it is expecting next.
I've modified the program, even though for my project this particular implementation won't be adequate.

I now have only a single callback function. The problem persists.

Is there something I don't get about detecting edges ? If I want to detect a falling edge, I have to set pin to IN and UP, then connect it to GROUND, 1->0, falling edge
If I want to detect a rising edge, I have to set pin to IN and DOWN, then connect it to 3,3v, 0->1, rising edge.

Is my pi broken?? Should I reinstall python3?

See current code:

Code: Select all

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
import time

#First, I want to detect a rising edge. When I detect it, the threaded callback function "alarm" will get triggered.
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

#threaded callback function
def alarm(channel):
	try:
		print("Rising edge detected on pin "+str(channel))
		#print("Rising edge detected on pin "+str(channel)+" at "+time.strftime("%H:%M:%S %d/%m/%Y"))
		
		#next, I want to detect a falling edge.
		
		GPIO.remove_event_detect(channel)
		GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
		
		GPIO.wait_for_edge(channel, GPIO.FALLING)
		
		print("Falling edge detected on pin "+str(channel))
		#print("Falling edge detected on pin "+str(channel)+" at "+time.strftime("%H:%M:%S %d/%m/%Y"))

		#after three seconds of "stage two", I exit.
		time.sleep(3)
		#print("Exit from stage two. Main thread should still be printing dots!")
		print("Exit from stage two at "+time.strftime("%H:%M:%S %d/%m/%Y")+". Main thread should still be printing dots!")
	
			
		#I set up the pin as it was at the very begginning of the program, so the system is primed to repeat the process.
		GPIO.remove_event_detect(channel)
		GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
		GPIO.add_event_detect(channel, GPIO.RISING, callback=alarm, bouncetime=300)
		
	except:
			print("Alarm thread exception")

GPIO.add_event_detect(17, GPIO.RISING, callback=alarm, bouncetime=300)

try:
	print("This is the main thread. It will print a dot every second, forever.")
	
	while 1:
		time.sleep(1)
		print(".")
	
	print("If this prints something is strange")
	
except:
	print("Main thread error")
	GPIO.cleanup()
GPIO.cleanup()           # clean up GPIO on normal exit


User avatar
joan
Posts: 14766
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 9:38 am

Do you need to keep mucking about with the callback?

Perhaps you could keep its state and do something along the following lines.

Code: Select all

#!/usr/bin/env python

import time

import pigpio

GPIO=17

cbf_state = 0

def cbf(gpio, level, tick):
   global cbf_state
   if cbf_state == 0:
      if level == 1: # rising edge
         ts = time.strftime("%H:%M:%S %d/%m/%Y")
         print("Rising edge on "+str(gpio) + " at " + ts)
         cbf_state = 1 # wait for falling edge
   elif cbf_state == 1:
      if level == 0: # falling edge
         ts = time.strftime("%H:%M:%S %d/%m/%Y")
         print("Falling edge on "+str(gpio) + " at " + ts)
         cbf_state = 2 # wait 3 seconds, set watchdog timeout
         pi.set_watchdog(GPIO, 3000) # 3000ms
   else: # cbf_state == 2
      if level == 2: # watchdog expired
         ts = time.strftime("%H:%M:%S %d/%m/%Y")
         pi.set_watchdog(GPIO, 0) # cancel watchdog
         print("Exit from stage two at "+ ts)
         cbf_state = 0 # back to original state

pi = pigpio.pi() # connect to local Pi

cb = pi.callback(GPIO, pigpio.EITHER_EDGE, cbf)

try:
   while True:
      print("dot")
      time.sleep(1)
except:
   pass

print("cancelling")

pi.set_watchdog(GPIO, 0) # make sure watchdog is cancelled
cb.cancel() # cancel callback
pi.stop() # disconnect from local Pi

morguslethe
Posts: 11
Joined: Thu Jun 11, 2015 8:58 pm

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 9:44 am

joan wrote: Do you need to keep mucking about with the callback?

Perhaps you could keep its state and do something along the following lines.
Of course, there are probably many ways to do what I want to do. I tried it my way, and I don't see a real reason why it shouldn't be working. Are threaded callbacks just overall bad? Why the heck do they even exist then? They look and sound very simple, and I've implemented them in a simple way. The only thing that's slightly ugly in my code is the removal and resetting of the of the pin event detection. Reconfiguring a pin while a program is running should work, I'm sure you'll agree.

I'm not trying to sound stubborn... I think it's reasonable to expect this to work my way. It obviously doesn't. I can't help myself anymore, and if none of you can troubleshoot the problem then I'll rewrite my program in Java tomorrow :(

I admit I don't know much about threaded programming or python, but if I can't get this to work maybe it's not for me.

All this program is supposed to do is detect a rising edge, detect a falling edge and print the time, and keep running. There are many ways to do this, but I don't want to play "whack a mole" to hit the correct way from the get-go when I think my way should reasonably work...

I really appreciate the help though! Please don't take my words the wrong way.
Last edited by morguslethe on Sun Jun 14, 2015 10:00 am, edited 1 time in total.

User avatar
jojopi
Posts: 3152
Joined: Tue Oct 11, 2011 8:38 pm

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 9:58 am

morguslethe wrote:I now have only a single callback function. The problem persists.
My theory is that the problem is caused by repeated add_event_detect and remove_event_detect, so you have to trigger on GPIO.BOTH instead of keep changing. This seems to work.

Code: Select all

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
import time

#First, I want to detect a rising edge. When I detect it, the threaded callback function "alarm" will get triggered.
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
nextedge = GPIO.RISING

#threaded callback function
def alarm(channel):

   global nextedge
   thisedge = nextedge
   if thisedge == GPIO.RISING:
     edgename = "rising"
     nextedge = GPIO.FALLING
     GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
   else:
     edgename = "falling"
     nextedge = GPIO.RISING
     GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

   print(edgename+" edge detected on pin "+str(channel)+" at "+time.strftime("%H:%M:%S %d/%m/%Y"))

   if thisedge == GPIO.FALLING:
     #after three seconds of "stage two", I exit.
     time.sleep(3)

     ####START PROBLEMATIC PART!!!!!!!!!########
     print("Exit from stage two at "+time.strftime("%H:%M:%S %d/%m/%Y")+". Main thread should still be printing dots!")
     ####END PROBLEMATIC PART!!!!!!!!#########

GPIO.add_event_detect(17, GPIO.BOTH, callback=alarm, bouncetime=300)

try:
   print("This is the main thread. It will print a dot every second, forever.")
   
   while 1:
      time.sleep(1)
      print(".")
   
   print("If this prints something is strange")
   
except KeyboardInterrupt:
   GPIO.cleanup()
GPIO.cleanup()           # clean up GPIO on normal exit
I do not understand the purpose of the sleep after detecting each falling edge, was it just for debugging? Ideally you should remove it, because it can delay detection of the next rising edge, and inhibit detection of the falling edge after that.

User avatar
RogerW
Posts: 286
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 10:08 am

morguslethe wrote:I can again confirm that even a different time module (datetime) stops the program execution.

All this program is supposed to do is detect a rising edge, detect a falling edge and print the time.
What am I supposed to feel? Having these kinds of problems on such a simple program, with no error messages and no exceptions getting caught is incredibly discouraging.

Somebody please help before I go off on a rant that will make me look bad when the real problem finally gets identified.
I sympathise with your difficulty. I cannot find any decent documentation for RPi.GPIO. It appears to be tha case that there is only one second thread used to run callback functions. You are calling remove_event_detect and add_event_detect from that thread - not the main thread. I wonder if that is the root of your problem.

It might be worth looking at pigpio http://abyz.co.uk/rpi/pigpio/. This is a well written and documented library by joan of this parish. It includes a callback function which I think would enable you to do what you want. It would mean a start again rewrite but might be less frustrating.

Roger Woollett

User avatar
DougieLawson
Posts: 37799
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 10:20 am

RogerW wrote:I cannot find any decent documentation for RPi.GPIO.
The "official" docs are here: http://sourceforge.net/p/raspberry-gpio ... wiki/Home/
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
RogerW
Posts: 286
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 10:30 am

DougieLawson wrote:The "official" docs are here: http://sourceforge.net/p/raspberry-gpio ... wiki/Home/
You are probably right but all I could find there was sample code.

Since the use of the GPIO pins sems to be a fundamental aim of the RPF I am surprised that there is not proper documentation on this site.

User avatar
DougieLawson
Posts: 37799
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 10:48 am

RogerW wrote:
DougieLawson wrote:The "official" docs are here: http://sourceforge.net/p/raspberry-gpio ... wiki/Home/
You are probably right but all I could find there was sample code.

Since the use of the GPIO pins sems to be a fundamental aim of the RPF I am surprised that there is not proper documentation on this site.
There's plenty of documentation at http://raspberrypi.org/forums since it's the #1 most popular subject.

The official RPF docs for GPIO are at:
https://www.raspberrypi.org/documentati ... /README.md
https://www.raspberrypi.org/documentati ... /README.md
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
RogerW
Posts: 286
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 11:22 am

DougieLawson wrote: There's plenty of documentation at http://raspberrypi.org/forums since it's the #1 most popular subject.

The official RPF docs for GPIO are at:
https://www.raspberrypi.org/documentati ... /README.md
https://www.raspberrypi.org/documentati ... /README.md
The forum has plenty of discussion and sample code but not (as far as I can find) documentation. The two links tell me about the hardware but not the details of RPi.GPIO.

What I would like to find is a detailed description of each function. I can type help(GPIO) in idle and get some detail but (for instance) there is no mention of the use of a second thread for callbacks. When working I was used to finding reference manuals which effectively defined the product. Maybe I am being unrealistic but I would have thought that the authors of RPi.GPIO would have provided this.

ghp
Posts: 1466
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Very strange behavior (time.strftime() kills main thread

Sun Jun 14, 2015 11:44 am

Hello,
I was curious to see what happens in this code. Programmed an external pulse generator (100ms high in 500ms period) with an arduino due and ran your code.
With python3, the code behaves the same as you report. Different behavior in python2. This is strange.

In general, your code is imho not a perfect solution. Long delays in these event thread methods seem not to work well.
Could be better to use something like this:

Code: Select all

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
import time

last_lowhigh_time = 0
debug = True

def alarm_both(channel):
    r = GPIO.input(channel)
    if r:
        global last_lowhigh_time
        last_lowhigh_time = time.time()
        if debug:
            print("Rising edge detected on pin "+str(channel))
    else:
        t = time.time();
        if t-last_lowhigh_time < 0.2:
            if debug:
                print ("perfect event")
        else:
            if debug:
                print ("bad event")
        if debug:
            print("Falling edge detected on pin "+str(channel))


GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(18, GPIO.BOTH, callback=alarm_both, bouncetime=40)

try:
    print("This is the main thread. It will print a dot every second, forever.")
   
    while 1:
        time.sleep(1)
        print(".")
   
    print("If this prints something is strange")
   
except:
    print("Main thread error")
    GPIO.cleanup()
GPIO.cleanup()           # clean up GPIO on normal exit

There are no delays now in the event thread methods. Works with python2 and 3. The debug flag allows to switch on/off debug statements, as the print statements consume quite a lot of time.

Your next challenge is: how to trigger an action out from the event handler method, especially when the action procedure takes a long time.
So most possibly your pi is not broken and your software environment looks ok.
Regards,
Gerhard

morguslethe
Posts: 11
Joined: Thu Jun 11, 2015 8:58 pm

Re: Very strange behavior (time.strftime() kills main thread

Mon Jun 15, 2015 8:20 am

jojopi wrote:My theory is that the problem is caused by repeated add_event_detect and remove_event_detect, so you have to trigger on GPIO.BOTH instead of keep changing. This seems to work.
...
Thank you, your code really does work as expected, and throws no sneaky errors. I will use your code and try to modify it. I'll report back on how that goes.
RogerW wrote: It might be worth looking at pigpio http://abyz.co.uk/rpi/pigpio/. This is a well written and documented library by joan of this parish. It includes a callback function which I think would enable you to do what you want. It would mean a start again rewrite but might be less frustrating.
I will definitely look at it in the future, RPi.GPIO was a bad experience... thank you :)
ghp wrote: I was curious to see what happens in this code. Programmed an external pulse generator (100ms high in 500ms period) with an arduino due and ran your code.
With python3, the code behaves the same as you report. Different behavior in python2. This is strange.

...

There are no delays now in the event thread methods. Works with python2 and 3. The debug flag allows to switch on/off debug statements, as the print statements consume quite a lot of time.

Your next challenge is: how to trigger an action out from the event handler method, especially when the action procedure takes a long time.
So most possibly your pi is not broken and your software environment looks ok.
Thank you, right now jojopi's method looks the best, I'll look at your code too if I get stuck somewhere again or later when I have time.

I have hope again and have learned something new. I'll report what I learned from all of this when I finish.

morguslethe
Posts: 11
Joined: Thu Jun 11, 2015 8:58 pm

Re: Very strange behavior (time.strftime() kills main thread

Mon Jun 15, 2015 5:20 pm

I already wrote a long post, but I decided not to post it.
Because it looks like there's something fundamental I don't get, I'll just go ahead and ask:

For my project I have to:
-constantly monitor 20 gpio pins for a rising edge. this can happen at any time, and I have to catch it.
-once a pin is triggered by a rising edge, it has to print out something, then wait for another rising edge
-when the next rising edge comes, the pin will experience a switching signal. The program has to print something, then wait until the signal is stable at 0
-when the signal is stable it has to print something, and configure the pin so it's ready for the next rising edge to repeat the process

things to note: multiple pins can be in the alarm stage or the switching stage at the same time, pins always follow alarm-stage two- reset pattern. reconfiguring the pin while it's in a callback thread didn't work in my experience. wait_for_edge and remove_event_detect don't work inside a sub-thread. Threaded callbacks work strangely when one is activated at the same time as another.

How would YOU go about this?

User avatar
joan
Posts: 14766
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Very strange behavior (time.strftime() kills main thread

Mon Jun 15, 2015 5:44 pm

morguslethe wrote: ...
How would YOU go about this?
I'd use my pigpio Python module.

However I'm not sure what you mean by "the pin will experience a switching signal".

ghp
Posts: 1466
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Very strange behavior (time.strftime() kills main thread

Mon Jun 15, 2015 6:00 pm

Hello,

before making an architecture, some more details needed on timing and number of events per second.
Are input signals in second (or more) or in millisecond range ? And how many of these will come in average per second (a few or hundreds) ?
Are the signals 'clean' or need debouncing ?
If there is a continuous high input volume, 'printing' is a bad choice as it is incredible slow, at least you will need to decouple signal handling from output handling.
Switches will have a max rate of prox 10Hz (good piano players do 15Hz or so). If using a switch, can you make assumptions on a minimum press time. Or do you need to catch even msec pulses ?
And a last question, what happens if you miss a signal. Is this acceptable or do you need each and any ?

Regards,
Gerhard

morguslethe
Posts: 11
Joined: Thu Jun 11, 2015 8:58 pm

Re: Very strange behavior (time.strftime() kills main thread

Mon Jun 15, 2015 6:16 pm

joan wrote:I'd use my pigpio Python module.

However I'm not sure what you mean by "the pin will experience a switching signal".
I've already installed your module, and made a simple callback program. I'm still trying to work with my old one, as I'm SO CLOSE but the program behaves weird when I try to trigger multiple callbacks at once (some don't register). With your module, can I have 20 different sleeping callback threads which get triggered on rising edge, do some stuff (maybe wait in a while loop for a stable 0 for a few minutes), then do other stuff, while other threads do something similar at the same time ? I'm close with my program, but as I've said, it doesn't behave correctly. It only works perfectly if there is only 1 callback thread active at one time.

By switching signal I mean the external signal transmits 0,5 seconds of 3,3v and 0,5 seconds of 0v. So the pin is 0,5 seconds in 1 and 0,5 seconds in 0. I have to wait during this phase until the singal is stable at 0.
ghp wrote: Are input signals in second (or more) or in millisecond range ? And how many of these will come in average per second (a few or hundreds) ?
Are the signals 'clean' or need debouncing ?
...
If using a switch, can you make assumptions on a minimum press time. Or do you need to catch even msec pulses ?
And a last question, what happens if you miss a signal. Is this acceptable or do you need each and any ?
Input signals are consistent for at least 0,5 seconds. These events are rare, they come a few times an hour. The signals are clean, the press time is at least 0,1 seconds long (a human push of a button), and I have to catch all of them. I'm basically making a log.

It should be so simple but I keep hitting these walls... Thanks guys.

Return to “Python”