[Python] Change Scroll pHat buffer based on user input


#1

Hey!

First of all, I am having a ton of fun playing around with the Pi Zero and Scroll pHAT – thanks for putting this little LED wonder out there! But as this is my first time programming since I was a nipper, I’m having a little bit of trouble getting over a certain hurdle.

I’m familiar with while loops to scroll the string in the buffer across the LEDs, but I’m unsure how to change what’s in the buffer based on the user’s input. Also I want to use an initial message as a prompt, a bit like a print("context") would give the user context. Can anyone help?

import time
import scrollphat

# I'm clearing anything in the buffer on execution
scrollphat.clear()
scrollphat.set_brightness(7)
scrollphat.set_rotate(True)

# This is the initial prompt, asking user for input
def greet_me():
    while True:
        scrollphat.write_string("Say hello to me", 11) # Write message to buffer
        scrollphat.scroll() # Move buffer left by one column
        time.sleep(0.1) # Sleep 0.1 seconds, continue loop

# This is the response based on user input: clear buffer then respond
def say_thanks():
    scrollphat.clear()
    while True:
        scrollphat.write_string("Hello you!", 11)
        scrollphat.scroll()
        time.sleep(0.1)

greeting = ""

while greeting != "hello":
    greet_me()

What I want to do next is run through the say_thanks() loop when greeting == "hello". I need to set greeting = input() at some point but I’m not sure where. What do you reckon, oh wise ones?

Thanks in advance for any help!


#2

This will take some thought- it’s actually a more complicated problem than it might first appear. That’s because it might require Python do two things simultaneously;

  • Display and scroll “Say hello to me” on the screen
  • Continuously ask the user for input

And it must change what it’s doing based upon that input.

Since input() is blocking, ie: it stops program execution until a user has entered something and hit return, you can’t ordinarily wait for input and keep the display updated in a timely fashion. Calling input() would stop the scrolling text while it waited.

brief waffle about input

You must also be wary of the difference between input and raw_input in Python 2.x, and the non-existence of raw_input in Python 3. Briefly input in Python 2 allows you to insert executable code in your program flow. So if you drop into Terminal and run:

python -c "print(input())"

And type hello, then hit return, you’ll see:

NameError: name 'hello' is not defined

And if you type 1==2 and hit return, you’ll see:

1==2
False

Which means Python has evaluated what you typed in.

/end waffle

Your best bet to avoid complexity is to do so mething like the following:

  1. Display and scroll the welcome message
  • Clear the display
  • Call input and wait for user input
  • Check the users response
  • Act accordingly
  • Goto 1

All of this will happen in the context of one and only one while True loop. Since while True blocks indefinitely, you can only (unless you create a multi-threaded program or call break in really weird ways) ever sensibly have one of these loops.

So in pseudocode:

def display_message(message):
    write_to_screen(message)
    scroll_message()
    clear_screen()
    
while True:
   display_message("Say hello to me")

   user_input = wait_for_input()

   if user_input == "hello":
       display_message("Hello you!")
   else:
       display_message("WROOONGG!!")

Scroll pHAT has a buffer_len method that tells you the length of the buffer, you can use this to figure out how far you should scroll to show a string.

Scrolling should generally be something like this:

for x in range(scrollphat.buffer_len()):
    scrollphat.scroll()

Hopefully this does more to help you than confuse you!


#3

Thanks so much for this! It works perfectly and will really help me with the next stage of my project. You’re awesome!