Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #95411 > unrolled thread

RPI.GPIO Help

Started byJohn McKenzie <davros@bellaliant.net>
First post2015-08-16 19:40 +0000
Last post2015-09-14 05:53 -0700
Articles 7 on this page of 27 — 7 participants

Back to article view | Back to comp.lang.python


Contents

  RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-08-16 19:40 +0000
    Re: RPI.GPIO Help MRAB <python@mrabarnett.plus.com> - 2015-08-16 21:15 +0100
      Re: RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-08-20 15:12 +0000
        Re: RPI.GPIO Help MRAB <python@mrabarnett.plus.com> - 2015-08-20 16:45 +0100
          Re: RPI.GPIO Help alister <alister.nospam.ware@ntlworld.com> - 2015-08-20 15:54 +0000
        Re: RPI.GPIO Help Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-08-20 21:27 -0400
          Re: RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-08-28 17:40 +0000
            Re: RPI.GPIO Help hakugin.gin@gmail.com - 2015-08-28 13:56 -0700
            Re: RPI.GPIO Help Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-08-29 14:21 -0400
    Re: RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-08-31 17:41 +0000
      Re: RPI.GPIO Help hakugin.gin@gmail.com - 2015-08-31 11:25 -0700
      Re: RPI.GPIO Help MRAB <python@mrabarnett.plus.com> - 2015-08-31 19:34 +0100
      Re: RPI.GPIO Help Johannes Bauer <dfnsonfsduifb@gmx.de> - 2015-09-01 10:58 +0200
    Re: RPI.GPIO Help Tim Daneliuk <tundra@bogus-city.tundraware.com> - 2015-08-31 14:07 -0500
      Re: RPI.GPIO Help Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-09-01 02:08 -0400
    Re: RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-09-02 18:50 +0000
    Re: RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-09-09 19:03 +0000
      Re: RPI.GPIO Help MRAB <python@mrabarnett.plus.com> - 2015-09-09 20:29 +0100
    Re: RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-09-10 15:56 +0000
      Re: RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-09-11 18:24 +0000
        Re: RPI.GPIO Help MRAB <python@mrabarnett.plus.com> - 2015-09-11 19:49 +0100
        Re: RPI.GPIO Help hakugin.gin@gmail.com - 2015-09-11 12:00 -0700
        Re: RPI.GPIO Help hakugin.gin@gmail.com - 2015-09-11 12:24 -0700
        Re: RPI.GPIO Help Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-09-11 21:10 -0400
    Re: RPI.GPIO Help John McKenzie <davros@bellaliant.net> - 2015-09-13 06:08 +0000
      Re: RPI.GPIO Help Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-09-13 12:24 -0400
      Re: RPI.GPIO Help hakugin.gin@gmail.com - 2015-09-14 05:53 -0700

Page 2 of 2 — ← Prev page 1 [2]


#96363

FromMRAB <python@mrabarnett.plus.com>
Date2015-09-11 19:49 +0100
Message-ID<mailman.379.1441997544.8327.python-list@python.org>
In reply to#96362
On 2015-09-11 19:24, John McKenzie wrote:
>
>   Hello.
>
>   Thanks to the help of people here and in other newsgroups I seem to have
> something working doing the basics. (Buttons work, colours light up
> appropriately.)
>
>   When I followed MRAB's instructions and read about scopes of variables
> that solved my most recent problem, but it introduced a bug. I think I
> fixed the bug but after all my stupid mistakes and forgetfulness that
> seems too good to be true. I expect there is a better, more elegant, or
> more Pythonic way to do what I did so please feel free to share on the
> subject.
>
>   I had a problem where if I pressed a button while the LEDs were already
> flashing the colour of that button it would block a new colour from
> starting when I pressed a new button. So if the LED strip was red and I
> pressed the red button again nothing would happen when I pressed the blue
> or yellow button. Similar problem for the other two buttons.
>
>   So inside my callbacks I added this code:
>
>     if colour == 1:
>          pass
>      elif colour == 2 or 3:
>          colour = 1
>
>
>   Now it seems OK from my limited testing.
>
[snip]

"colour == 2 or 3" means the same as "(colour == 2) or 3", where 3 is a
true value (zero is a false value; any non-zero number is a true value).

What you mean is "colour == 2 or colour == 3".

A shorter alternative is "colour in (2, 3)".

[toc] | [prev] | [next] | [standalone]


#96364

Fromhakugin.gin@gmail.com
Date2015-09-11 12:00 -0700
Message-ID<2984b094-5458-4d5d-beda-adca10687dcd@googlegroups.com>
In reply to#96362
On Friday, September 11, 2015 at 2:25:15 PM UTC-4, John McKenzie wrote:
> Hello.
> 
>  Thanks to the help of people here and in other newsgroups I seem to have 
> something working doing the basics. (Buttons work, colours light up 
> appropriately.)

<snip>

> def red_button(channel):
>     global colour
>     if colour == 1:
>         pass
>     elif colour == 2 or 3:
>         colour = 1
>         while colour == 1:
>             led.pulse(red=255, green=0, blue=0, repeats=1, duration=2000, 
> steps=50)

<snip>

Another option for this would be:

def red_button(channel):
    global colour
    if colour != 1:
        colour = 1
    # Rest of your original code goes below here


I am currently checking some other options, unfortunately I am not at home or have access to a RPi right now so I am unable to fully test.

[toc] | [prev] | [next] | [standalone]


#96367

Fromhakugin.gin@gmail.com
Date2015-09-11 12:24 -0700
Message-ID<cba8311e-b81b-4caf-b275-ed5867bd2ba8@googlegroups.com>
In reply to#96362
On Friday, September 11, 2015 at 2:25:15 PM UTC-4, John McKenzie wrote:
> Hello.
> 
>  Thanks to the help of people here and in other newsgroups I seem to have 
> something working doing the basics. (Buttons work, colours light up 
> appropriately.)
> 
>  When I followed MRAB's instructions and read about scopes of variables 
> that solved my most recent problem, but it introduced a bug. I think I 
> fixed the bug but after all my stupid mistakes and forgetfulness that 
> seems too good to be true. I expect there is a better, more elegant, or 
> more Pythonic way to do what I did so please feel free to share on the 
> subject.
> 
>  I had a problem where if I pressed a button while the LEDs were already 
> flashing the colour of that button it would block a new colour from 
> starting when I pressed a new button. So if the LED strip was red and I 
> pressed the red button again nothing would happen when I pressed the blue 
> or yellow button. Similar problem for the other two buttons.
> 
>  So inside my callbacks I added this code:
> 
>    if colour == 1:
>         pass
>     elif colour == 2 or 3:
>         colour = 1
> 
> 
>  Now it seems OK from my limited testing.
> 
> 
>  Here is the code that has buttons and colours working and includes my 
> bug fix:
> 
> 
> import atexit 
> import time 
> from blinkstick import blinkstick 
> import RPi.GPIO as GPIO   
> 
> led = blinkstick.find_first() 
> colour = 0
> time_red = 0
> time_yellow = 0
> time_blue = 0
> timestamp = time.strftime("%H:%M:%S")
> 
> GPIO.setmode(GPIO.BCM)
> GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
> GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
> GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)
> 
> 
> def red_button(channel):
>     global colour
>     if colour == 1:
>         pass
>     elif colour == 2 or 3:
>         colour = 1
>         while colour == 1:
>             led.pulse(red=255, green=0, blue=0, repeats=1, duration=2000, 
> steps=50)
> def yellow_button(channel):
>     global colour
>     if colour == 2:
>         pass
>     elif colour == 1 or 3:
>         colour = 2
>         while colour == 2:
>             led.pulse(red=255, green=96, blue=0, repeats=1, 
> duration=2000, steps=50)
> def blue_button(channel):
>     global colour
>     if colour == 3:
>         pass
>     elif colour == 1 or 2:
>         colour = 3
>         while colour == 3:
>             led.pulse(red=0, green=0, blue=255, repeats=1, duration=2000, 
> steps=50)
> 
> 
> GPIO.add_event_detect(22, GPIO.FALLING, callback=red_button, 
> bouncetime=200)
> GPIO.add_event_detect(23, GPIO.FALLING, callback=yellow_button, 
> bouncetime=200)
> GPIO.add_event_detect(24, GPIO.FALLING, callback=blue_button, 
> bouncetime=200)
> 
> 
> while True:
>     if colour == 1:
>         time_red += 1
>     elif colour == 2:
>         time_yellow += 1
>     elif colour == 3:
>         time_blue += 1
> 
>     time.sleep(0.1)
> 
> 
> def exit_handler():
>     print "\033[0;41;37mRed Team:\033[0m ", time_red
>     print "\033[0;43;30mYellow Time:\033[0m ", time_yellow
>     print "\033[0;44;37mBlue Time:\033[0m ", time_blue
>     flog = open("flag1.log", "a")
>     flog.write(timestamp + "\n" + "Red Team: " + str(time_red) + "\n" + 
> "Yellow Team: " + str(time_yellow) + "\n" + "Blue Team: " + str
> (time_blue) + "\n")
>     flog.close()
>     led.set_color(name="black")
> atexit.register(exit_handler)
> GPIO.cleanup()
> 
> 
> 
>  I think I am OK GPIO wise now, although always happy to improve the code 
> and in the long term I want to do so.
> 
>  Will start new threads for more straight forward Python questions like 
> help with saving a log of the results, timing, etc.
> 
>  Thanks for your help, everyone.

I just noticed another potential issue with your code. You added "while" loops to your button functions, you should adjust the code so that the "led.pulse" call is in the main loop.

For example, at the beginning add something like:

pulse_settings = []


Change your button functions to change this new variable when the button is pressed:


def red_button(channel):
    global colour, pulse_settings
    if colour != 1:
        colour = 1
        pulse_settings = (red=255, green=0, blue=0, repeats=1, duration=2000, steps=50)


Then change your main "while" loop:

while True:
    if colour == 1:
        time_red += 1
    elif colour == 2:
        time_yellow += 1
    elif colour == 3:
        time_blue += 1
    led.pulse(pulse_settings)
    time.sleep(pulse_settings[4]) # sets the delay to the duration of the pulse effect


These are merely suggestions, again I do not have access to my RPi to test, your mileage may vary.

[toc] | [prev] | [next] | [standalone]


#96379

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2015-09-11 21:10 -0400
Message-ID<mailman.387.1442020255.8327.python-list@python.org>
In reply to#96362
On Fri, 11 Sep 2015 18:24:53 GMT, John McKenzie <davros@bellaliant.net>
declaimed the following:

	Take into account that I still don't have an R-Pi, so I'm basing all
this on the online documentation. I still don't like all the "global"
statements, but creating class instances, and blocking queues rather
than the busy-loop can be saved for the future

import atexit 
import time 
from blinkstick import blinkstick 
import RPi.GPIO as GPIO 

#define "constants" so updates only need to be done once  
(R, G, B) = (0, 1, 2)		#G is also being used for Y
(REDCH, YELLOWCH, BLUECH) = (22, 23, 24)
RGB = ("#FF0000", "#FF6000", "#0000FF")

led = blinkstick.find_first() 

colour = None
changeTime = None

cumTime = (0.0, 0.0, 0.0)

timestamp = time.strftime("%H:%M:%S")

GPIO.setmode(GPIO.BCM)

GPIO.setup(REDCH, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(YELLOWCH, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BLUECH, GPIO.IN, pull_up_down=GPIO.PUD_UP)


def buttonHandler(channel):
	global colour
	global changeTime

	# get current time
	now = time.time()

	# determine if a change in color is called for
	if colour != R and channel == REDCH:
		newColour = R
	elif colour != G and channel == YELLOWCH:
		newColour = G
	elif colour != B and channel == BLUECH:
		newColour = B
	else:
		return	#do nothing with LED

	#if first time button pressed, no cumulative time
	if changeTime is not None:
		#save delta time from last change to this change
		cumTime[colour] += now - changeTime

	#set globals for next button action
	changeTime = now
	colour = newColour
	#activate LED -- is this a blocking call? if so, other
	#button presses won't respond until after this
	#finishes
	led.pulse(hex=RGB[colour], repeats=1, 
				duration=2000, steps=50)

GPIO.add_event_detect(REDCH, GPIO.FALLING, 
			callback=buttonHandler,  bouncetime=200)
GPIO.add_event_detect(YELLOWCH, GPIO.FALLING, 
			callback=buttonHandler,  bouncetime=200)
GPIO.add_event_detect(BLUECH, GPIO.FALLING, 
			callback=buttonHandler,  bouncetime=200)


def exit_handler():
	# all the exit handler does is set a flag to break out the main 
	# endless loop, letting the main thread clean up
	global	keepLooping
	keepLooping = False

atexit.register(exit_handler)

keepLooping = True
while keepLooping:
    time.sleep(0.1)	#eat time doing nothing

# busy loop has exited because atexit handler has set the it False
# so dump the results of this run
led.set_color(name="black")

print "\033[0;41;37mRed Team:\033[0m ", cumTime[R]
print "\033[0;43;30mYellow Time:\033[0m ", cumTime[G]
print "\033[0;44;37mBlue Time:\033[0m ", cumTime[B]
flog = open("flag1.log", "a")
flog.write("%s\nRed Team: %s\nYellow Team: %s\nBlue Team:%s\n"
			% (timestamp, cumTime[R], cumTime[G], cumTime[B]))
flog.close()

GPIO.cleanup()
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#96487

FromJohn McKenzie <davros@bellaliant.net>
Date2015-09-13 06:08 +0000
Message-ID<Wp8Jx.55913$fJ3.41264@fx16.iad>
In reply to#95411
 Hello, there.

 MRAB, thank you for teaching me proper Python syntax for how I tried to 
use the or operator.

 Dennis, I must have learned allot recently as I believe I understood 99% 
of that code. I see how it is not just more advanced, but actually better 
than what I had. However, line 47 (cumTime[colour] += now - changeTime) 
had an error I could not figure out what to do about. Considering my time 
line I decided not to leave it to latter. Will be using these electronic 
flags at next year's game and for then I intend to just be better about 
everything. Will use your code to learn to get there.

 Hakugin, thank you you as well. I took the basic ideas you showed me for 
improvement and used them. The pulse settings variable was not liked by 
the interpreter, so I simplified it. I turned it into a hex value for 
each button press, then in the main loop I inserted the whole line for 
the LED pulse command, but put "pulse_settings" after "hex=" in the 
arguments. This worked.

 I added a few green blinks of the LED to indicate the starting and 
stopping of the script. Also, I got the log files score print outs upon 
exit working. Very important, and also importantly, I have it so it stops 
after a certain amount of time. For testing, I have it at 60 seconds, but 
games will be 3600 seconds on average when really being used.

 The stopping after a certain amount of time was done in a way that 
apparently technically works, but seems very weird and probably wrong to 
me. You may freak out when you see it. I used an else statement inside a 
while loop and it just feels so strange. At least it works.

 Hoping I might be able to make it so I boot the Pi, it loads the script, 
script waits for the user to tell it how long to make a game, game 
starts, scripts ends game at appropriate time, saves dated log file with 
scores, then waits for user to enter new game length to start new game. 
This is probably way to much to hope to accomplish in time. For next year 
for sure though. It would be better for the referees to operate that way.

 Next I will try and integrate wireless communications. If anyone here 
knows Synapse RF modules well, or at all, PLEASE contact me.


 Here is the code I did up most recently. Again, thanks for all the 
suggestions, code examples, and general help.

import atexit
import sys
import time 
from blinkstick import blinkstick 
import RPi.GPIO as GPIO   

gamestart = time.time()
gamelength = 60

led = blinkstick.find_first() 
colour = 0
time_red = 0
time_yellow = 0
time_blue = 0
timestamp = time.strftime("%H:%M:%S")
pulse_settings = []

led.blink(name="green", repeats=2)

GPIO.setmode(GPIO.BCM)
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)


def red_button(channel):
    global colour
    global pulse_settings
    if colour != 1:
        colour = 1
        pulse_settings = "#FF0000"

def yellow_button(channel):
    global colour
    global pulse_settings
    if colour != 2:
        colour = 2
        pulse_settings = "#FF8900" # Corrected yellow for cheap LED strip.

def blue_button(channel):
    global colour
    global pulse_settings
    if colour != 3:
        colour = 3
        pulse_settings = "#0000FF"


GPIO.add_event_detect(22, GPIO.FALLING, callback=red_button, 
bouncetime=200)
GPIO.add_event_detect(23, GPIO.FALLING, callback=yellow_button, 
bouncetime=200)
GPIO.add_event_detect(24, GPIO.FALLING, callback=blue_button, 
bouncetime=200)

def exit_handler():
    print "\033[0;41;37mRed Team:\033[0m ", time_red
    print "\033[0;103;30mYellow Team:\033[0m ", time_yellow
    print "\033[0;44;37mBlue Team:\033[0m ", time_blue
    flog = open("flag1.log", "a")
    flog.write("\n" + timestamp + "\n" + "Red Team: " + str(time_red) + 
"\n" + "Yellow Team: " + str(time_yellow) + "\n" + "Blue Team: " + str
(time_blue) + "\n")
    flog.close()
    led.blink(name="green", repeats=4)
    led.set_color(name="black")
atexit.register(exit_handler)


while time.time() < gamestart + gamelength:
    if colour == 1:
        time_red += 1
    elif colour == 2:
        time_yellow += 1
    elif colour == 3:
        time_blue += 1
    led.pulse(hex=pulse_settings, repeats=1, duration=2000, steps=50)
    time.sleep(0.1)
else:
    sys.exit()

GPIO.cleanup()



[toc] | [prev] | [next] | [standalone]


#96509

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2015-09-13 12:24 -0400
Message-ID<mailman.480.1442161486.8327.python-list@python.org>
In reply to#96487
On Sun, 13 Sep 2015 06:08:54 GMT, John McKenzie <davros@bellaliant.net>
declaimed the following:

> Dennis, I must have learned allot recently as I believe I understood 99% 
>of that code. I see how it is not just more advanced, but actually better 
>than what I had. However, line 47 (cumTime[colour] += now - changeTime) 
>had an error I could not figure out what to do about. Considering my time 
>line I decided not to leave it to latter. Will be using these electronic 
>flags at next year's game and for then I intend to just be better about 
>everything. Will use your code to learn to get there.
>
	Hmm... Thought I'd taken care of uninitialized conditions but -- since
I couldn't run it on my desktop machine, I'm not surprised something may
have crept into the code.

-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#96567

Fromhakugin.gin@gmail.com
Date2015-09-14 05:53 -0700
Message-ID<ec0d0a3c-f21b-47e0-ba69-ffae46d55fca@googlegroups.com>
In reply to#96487
On Sunday, September 13, 2015 at 2:09:11 AM UTC-4, John McKenzie wrote:
> Hello, there.

<snip>

> 
>  Hakugin, thank you you as well. I took the basic ideas you showed me for 
> improvement and used them. The pulse settings variable was not liked by 
> the interpreter, so I simplified it. I turned it into a hex value for 
> each button press, then in the main loop I inserted the whole line for 
> the LED pulse command, but put "pulse_settings" after "hex=" in the 
> arguments. This worked.
> 

I realized the error with my example after I got home and forgot to update it. The issue was with:

(red=255, green=0, blue=0, repeats=1, duration=2000, steps=50)

I had copied and pasted that and should have removed the "red=", "green=", etc. I'm glad you were able to work it out.

>  I added a few green blinks of the LED to indicate the starting and 
> stopping of the script. Also, I got the log files score print outs upon 
> exit working. Very important, and also importantly, I have it so it stops 
> after a certain amount of time. For testing, I have it at 60 seconds, but 
> games will be 3600 seconds on average when really being used.
> 
>  The stopping after a certain amount of time was done in a way that 
> apparently technically works, but seems very weird and probably wrong to 
> me. You may freak out when you see it. I used an else statement inside a 
> while loop and it just feels so strange. At least it works.
> 
>  Hoping I might be able to make it so I boot the Pi, it loads the script, 
> script waits for the user to tell it how long to make a game, game 
> starts, scripts ends game at appropriate time, saves dated log file with 
> scores, then waits for user to enter new game length to start new game. 
> This is probably way to much to hope to accomplish in time. For next year 
> for sure though. It would be better for the referees to operate that way.
> 

Having the game load when the Pi starts is fairly easy, but I'd recommend searching the official Raspberry Pi forums. Last time I was there I saw quite a few posts on various ways to accomplish this.

As for allowing someone to enter a game time limit you can change your "gamelength" variable assignment to something along the lines of:

gamelength = None

while not isinstance(gamelength, int):
    gamelength = raw_input("Please enter a game time limit:\n")
    try:
        gamelength = int(gamelength) # Converts to integer
    except:
        print("Invalid entry. Time limit must be a number.\n")
        pass # ignore error and allow the loop to start over

I was able to test this code, and you will want to add it before your main game loop.

>  Next I will try and integrate wireless communications. If anyone here 
> knows Synapse RF modules well, or at all, PLEASE contact me.
> 
> 
>  Here is the code I did up most recently. Again, thanks for all the 
> suggestions, code examples, and general help.
> 

<snip>

> 
> while time.time() < gamestart + gamelength:
>

This is actually how I personally would have accomplished the task of having it end at a specific time. There may be other ways though.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web