Question

I'm trying to build a program that controls an RGB LED through a RaspberryPi.

I was able to build a simple fade program in python using pi-blaster, which works fine but doesn't let me do what I want.

Here's my code:

import time
import sys
import os

blue = 21
green = 23
red = 22


def fade(color, direction, step):
    if direction == 'up':
        for i in range(0, 100, step):
            f=(i/float(100))
            os.system('echo "%d=%f" > /dev/pi-blaster' % (color, f))
        return fade(color, 'down', step)
    else:
        step=-step
        for i in range (100, 0, step):
            f=(i/float(100))
            os.system('echo "%d=%f" > /dev/pi-blaster' % (color, f))
        return fade(color, 'up', step)

input = raw_input("Choose a color (r, g, b): ")
if input == 'r':
    fade(red, 'up', 1)
if input == 'g':
    fade(green, 'up', 1)
if input == 'b':
    fade(blue, 'up', 1)

The problem is that I want to be able to control the fade through an external script / program.

My idea is to have a script which is always listening for user input, so when I type "red" it stops the ongoing fade and starts a new red one, by calling the function I posted before.

I also want to be able to change the speed of the loop but this is already implemented into the "fade" function.

I don't really understand how I could do this. I've read some things on here and I think I may have to use the Threading functions, but I don't really understand how those could work for my project.

Thanks in advance for your help and sorry for my English which is not very good :)

EDIT:

I solved it using a loop checking continuously for keyboard inputs which then calls the fade function using multiprocessing.

I can now kill the fade process using processName.terminate()

Was it helpful?

Solution

There are a lot of ways to doing this, I'll describe a hard way and an easy way to get the basic functionality you want and hopefully they give you some ideas on how you want to solve this. The hard way involves creating a daemon-like script that sits in the background and reads a socket or file for when to change what it's doing. This is probably a good learning experience so don't be afraid of trying this. This method is also similar to the easy method I describe below. You would create a python script that opens a UDP or TCP socket, then it starts a separate process that calls the fade function. The main process listens to the socket, when it gets a new valid command (red, green, blue, quit, etc) it kills the child process and starts another with the new color. You could use threads, but I'm pretty sure killing threads from the parent is not so pretty, so you'd have to use events/locks and maybe some global variables. There are plenty of different ways to do this, but the general idea of one process/thread listens and one does the fading will be the same.

The easy/fast way is to have a bash script that wraps your color changes (red.sh, green.sh, blue.sh). In these scripts they kill any previously running scripts and then start the new fade command. Knowing what to kill can be done a couple of ways, the easiest is probably to write the PID to a file, then when it needs to be killed read that PID number in and kill it.

I know I didn't provide any code and this is long, but there are a lot of ways to do what you are trying to do. Also, you should be able open/write the "/dev/pi-blaster" directly in python (not sure opening device files this way will work):

blaster_file = open("/dev/pi-blaster", "a")
for i in range(100, 0, step):
    blaster_file.write(...)
blaster_file.close()

To change the speed of the loop you could add a delay by using sleep and specify the duration with a keyword:

from time import sleep
def fade(color, direction, step, delay=0):
    ...
    for i in range(100, 0, step):
        ...
        sleep(delay)
    return fade(color, direction, step, delay=delay)

OTHER TIPS

to get much better performance (and as a clarification to the first answer) it is much better to write using python - but you must put a new line after each write with a '\n'

Otherwise the code @daveydave400 gave is spot on

I'm doing something like this:

f = open('/dev/pi-blaster', 'w')
f.write('0=120\n')
#or
f.write('0=%s\n'%amount)

my actual code is in a function - in case you want to use that:

def changer(pin, amount):
    f = open('/dev/pi-blaster', 'w')
    f.write('%d=%s\n'%(pin, str(amount)))

if doing for loops using the the system command method you might find that python stops listening for keyboard input intermittently. This was certainly happening for me. I found that keyboardinterrupt was very hard to achieve with ctrl-c and had to repeatedly hit those keys to get the program to halt. Now i'm writing with python i'm not getting that issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top