2

I am attempting to write a program for my school project, on a raspberry pi. The program concept is fairly simple. The pi is looking at 4 GPIO pin inputs, and will output a different basic animation to the LED matrix depending on the input.

The main loop is a simple while(1) loop that always runs. Within this loop, the program is constantly checking to see what the input is from the 4 GPIO input pins on the pi. When the input is matched to one of the if statements, then it runs a short 'animation' in which is displays an image on the LED matrix, waits, clears the matrix, displays another image, waits, and clears again. For example, this could be a 'blinking smiley face' animation where the first image displayed is a smiley face with its eyes open, and the second image is a smiley face with its eyes closed. With the pausing in between the pictures getting displayed, it appears the image on the screen is actually blinking.

This setup is shown below for clarity (not actual code, gets the idea across though):

while(1) {

    currentState = [GPIO.input(pin1), GPIO.input(pin2), GPIO.input(pin3), GPIO.input(pin4)]

    if((currentState[0] == 1) and (currentState[1] == 0) and (currentState[2] == 1) and (currentState[3] == 0)) {
        matrix.SetImage(open_eyes)
        time.sleep(.3)
        matrix.Clear()
        matrix.SetImage(closed_eyes)
        time.sleep(.3)
        matrix.Clear()
    }

    if((currentState[0] == 0) and (currentState[1] == 1) and (currentState[2] == 0) and (currentState[3] == 1)) {
        matrix.SetImage(closed_mouth)
        time.sleep(.3)
        matrix.Clear()
        matrix.SetImage(open_mouth)
        time.sleep(.3)
        matrix.Clear()
    }
}

The issue I am having with this setup is if the input changes during an animation, then it will not cut off the animation it is currently on to start the next. This is obvious the way the code is structured since the currentState variable is only being set at the beginning of the while loop.

To accomplish this immediate switch, I attempted to make each animation a function, and just run the function within the if statements. However, then the program never would break out of those functions to check to see what the input is. I am now stuck, and if anyone has any ideas on how to accomplish this, I would love to hear them.

D. Lew
  • 21
  • 1
  • You could start a thread for the animation, that you could then kill and start another on a new button press. https://stackoverflow.com/a/7752174/7311767 – Stephen Rauch Feb 23 '18 at 02:29

1 Answers1

0

The issue here is time.sleep. During the sleep, the program won't detect changes to the currentState - as you correctly recognise. One way to handle this (I'm not going to write the code for you, but explain the general idea), is to keep your animation state in an object which gets updated on every while loop cycle. Things become a bit more complex than what you have because you will need to track the .3 seconds using some kind of time monitoring. So you'd set your object state to something like:

animation.state = 'blinking' 
animation.started = datetime.now()

Then once you detect .3 seconds have passed, you can change your animation state. If the currentState changes, you can reset the animation state.

Alternatively you could spawn a thread for the animation. That would be natural in some ways (and easy in Go for example) but a bit trickier if you're not used to Python threading.

see sharper
  • 11,505
  • 8
  • 46
  • 65