Sunday, October 11, 2020

Creating Blinkenlights using PyGame

From last time: I'm beginning to a trip down the retro computing rabbithole, and what can be more retro than "Blinkenlights"?

I mean this!


....when the computer does something we flash a whole bunch of lights. It's that easy: I/O? sure.  Register contents? Data and Address lines? Uh huh. "AQUS." "APRES" "CACN"  "CAPR" etc?  Don't know what the hell it means, but, yep.

The primary goal for Racduino: see what data and address lines on the RCA180x are doing with minimal effort when stepping through machine code instructions. It would be not too hard to use LEDs or even small incandescents for this, or an MSO, but I don't want to spend too much time wiring and then rewiring a small element of a larger project.  

Let's use Python and a Raspberry Pi instead and get it done.


My simple dev platform: Raspberry Pi4B, Thonny Python interpreter, keyboard/mouse, and the good old MacBook Pro (Sierra!) for serfing while I work. The board on the right is perf and has pots and momentary switches, wired to dupont type female connectors. For this proof of concept it's used to pull Pi4's GPIO pins to ground (details of Pi4 pullup/down is here).  The larger 23" monitor will be replaced with something much smaller sometime soon.

So how does it work? You can spend a lot of time on the exact look and feel of your Blinkenlight masterpiece, but today this is just a POC, with 5 pins, one rectangle, and one bit of text.

Here's a screenshot with all GPIO pins at +



Now let's pull pin 3 to ground.


Now pins 2 and 3:


You get the idea. 

There are undoubtedly a lot of ways to do this, but for whatever reason, the pygame module seems to work for me. I had never heard of pygame before this project, but the POC code below took minutes to code!  Pygame is easy and well documented. Why not.

OK heres the POC code; when this a lot closer to done I'll git-it.

##########################################

import pygame
import os
from time import sleep
import RPi.GPIO as GPIO
 
#for this dictionary key is GPIO pin and list is
#x,ylocation on screen.  Top left in pygame is 0,0
# positive Y values are LOWER (as if negative).

led_map = {2:[40,40], 3:[70,40], 4:[100,40],5:[130,40],6:[160,40]}
 
#Setup the GPIOs as inputs with Pull Ups since the buttons are connected to GND
GPIO.setmode(GPIO.BCM)
for k in led_map.keys():
    GPIO.setup(k, GPIO.IN, pull_up_down=GPIO.PUD_UP)
 
#Colours
WHITE = (255,255,255)
BLACK = ( 0,0,0 )
GREEN = (0 , 255, 0)
RED = (255,0,0)


 
os.putenv('SDL_FBDEV', '/dev/fb1')
pygame.init()
pygame.mouse.set_visible(False)
screen = pygame.display.set_mode((700, 500))
screen.fill((255,255,255))
pygame.display.update()

#draw background.
pygame.draw.rect(screen,BLACK,(2,2,200,70),1)
pygame.display.update()

#add text
myfont = pygame.font.SysFont('Courier', 20)
textsurface = myfont.render('PI4 GPIO', False, (0, 0, 0))
screen.blit(textsurface,(50,80))
pygame.display.update()


#draw blinkers
def ledsmall (color, loc1, loc2):
    pygame.draw.circle(screen,BLACK,[loc1,loc2],10)
    pygame.draw.circle(screen,color,[loc1,loc2],9)


while True:
    # Scan the buttons
    for (k,v) in led_map.items():
        if GPIO.input(k) == False:
            a = v[0]
            b = v[1]
            ledsmall(RED,a,b)
        else:
            a = v[0]
            b = v[1]
            ledsmall(GREEN,a,b)
         
         
            pygame.display.update()


#####################

I won't go through line by line what this does--I think if you are OK with python it should be pretty self explanatory. If you have questions or can think of improvements comment away....The led_map dictionary captures the GPIO pin as the key and the location of the graphic in a 2 member value list.  Want more LEDs?  Add to this dict. 

It seems fast, bug free, and so far, good enough.

So what's next?  Don't know, but if you need inspiration for your own virtual blinkenlight fiasco (as well as a lot of fun with retro computing props and a great waste of about 6 hours during covid), subscribe to netflix, and have a bunch of time to kill, take a look at the mini-series "Maniac".  

Freeze frame any time you see blinkenlights--there are a many a'blinkin, and then try to name all the other retro computing crap you see on screen--endless fun right? 

I think I see a PDP10, or maybe it's an 11? 70's era video consoles, analog video patch bays, old hard drive caddies, Mono CRT monitors, and on and on. The director said "I want more blinking light!" so I figure the art department had a lot of fun with this. 

And, Emma Stone is foxy to boot. See you next time.

No comments:

Post a Comment

ProMicro HID Keyboard Emulator

Quick one this time. The Arduino ProMicro (examples here and here ) is based on an Atmel 16u4 MCU and has HID keyboard emulation ready to go...