Make a custom button pad for Raspberry Pi [Pt I]

Categories Interaction, RMIT

I needed a button matrix to use as an interface for a new digital instrument that I’m making as part of my undergraduate major project. Something like the monome would probably work quite well, but I cannot justify being lazy and paying for one when I feel like I could probably hack some existing things together and end up with a custom result.

In earlier posts I talked about establishing serial connection between raspberry pi and arduino, because initially I intended to read a button array with the arduino and then send little data packets via usb that told the raspberry pi which buttons were pressed.

Previous design exploration: 16-Digit Keypad connected to Arduino, connected via USB serial to Raspberry Pi using a 3.5″ TFT LCD Screen as display.

For a few reasons, particularly the latency issues, this wasn’t a viable solution. I am vaguely aware that the arduino could be cut out of the process, and the button array read by the raspberry pi directly, but I’m also vaguely aware that to try and figure out how to do that may set me back a month.

The solution was to buy a cheap USB Keyboard, gut it, rip the chip out and hook it up to a custom button array made up of a 5 x 5 grid of N/O buttons.

I like this solution in that it doesn’t really matter which contacts I solder the buttons to, so long as each button triggered a different keystroke. I can then assign each button to it’s specific keystroke and then map each keystroke to it’s corresponding position in my Processing/Python sketch.

Ultimately, the keyboard is controlled by a small chip that communicates via USB. The chip has two banks of 13 contact points. To get any of the ~101 keystrokes available you have to close the circuit between two specific contact points.

So I started blindly shorting the board with alligator clips and a probe with notepad open on my laptop to capture the keystrokes.

Ended up with some glitch poetry

Now I just need to perform the time-consuming task of soldering up an array of N/O buttons to the keyboard chip, based on the combinations that results in 25 useful keystrokes (letters, numbers, punctuation – no function or naviagation keys). Then I need to house it all in a 3D printed case.

continue to Part II

Displaying webcam video on Raspberry Pi using pygame

Categories Open-source, Programming, RMIT, Visuals

Another small exploratory project related to my undergraduate Major Project had me trying to stream video onto a small 3.5″ TFT LCD display using a webcam connected to a Raspberry Pi mini computer.

 

Firstly, not all USB webcams work with the Raspberry Pi, so after trying randomly to find a working webcam I discovered this list of Raspberry Pi verified peripherals and bought myself a Logitech C100 for $20 on ebay.

Secondly, USB webcams seem to be horribly slow on the Raspberry Pi, pulling dodgy framerates at what might be <10fps at their full resolution (in my case 640×480 pixels). Originally, I was using the custom imgproc library (available here) but found that there was either a lack of simple documentation for extended functionality like scaling and so on, or that the library wasn’t built to perform those sorts of tasks. Eventually I settled upon using the pygame library (which you can get here). The documentation for pygame is thorough and easy to navigate, making troubleshooting and extension or exploration of the library very easy to do.

In order to combat the low framerate and because resolution is not a priority (for the purposes of the concept I will be testing) I decided to pull the webcam feed in at a much lower resolution (32×24 pixels) and then scale it up to full screen (640×480 pixels). I’m unsure if the webcam can actually pull the feed in at 32×24 pixels, I have to look into that – and perhaps some pixel dropping techniques.

I wrote the code, copied it over, connected the webcam to the Raspberry Pi and ran the following python script:

import sys
import pygame
import pygame.camera

pygame.init()
pygame.camera.init()

#create fullscreen display 640x480
screen = pygame.display.set_mode((640,480),0)

#find, open and start low-res camera
cam_list = pygame.camera.list_cameras()
webcam = pygame.camera.Camera(cam_list[0],(32,24))
webcam.start()

while True:
    #grab image, scale and blit to screen
    imagen = webcam.get_image()
    imagen = pygame.transform.scale(imagen,(640,480))
    screen.blit(imagen,(0,0))

    #draw all updates to display
    pygame.display.update()

    # check for quit events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
        webcam.stop()
        pygame.quit()
        sys.exit()

After a brief pause a pygame window pops up and the webcam feed is shown on the screen, scaled to fullscreen. The framerate is better than the full resolution webcam feed, but is still very slow by modern standards.

 

Drawing in Python using Arduino data via serial

Categories Open-source, Programming, Visuals

Following on from my previous post where I established serial communication between an Arduino and a Raspberry Pi, I needed to find out if I could store the data being sent from the Arduino in a variable on the Raspberry Pi and use it to alter some functions in a Python script.

I wrote up a piece of code that tries to read the data from the serial and use it to change the colour of a circle drawn in the center of a 640 x 480 pixel screen:

# Title: Arduino2RPiSerial
 #
 # Goal: to draw a circle based on colour values sent from the arduino
 #

import pygame
 import sys
 import serial

pygame.init()

#create a screen
 screen = pygame.display.set_mode((640,480))

#create colour
 redValue = 255
 fgColour = (redValue,0,0)
 bgColour = (0,0,255)

screen.fill(bgColour)

#serial(device,baud)
 ser = serial.Serial('/dev/ttyACM0',9600)

# LOOP
 while 1 :

#Update from serial
 redValue = ser.readline()
 #update colour value
 fgColour = (redValue,0,0)
 pygame.draw.circle(screen, fgColour, (320,240), 200, 0)
 pygame.display.update()
 pygame.time.delay(5)

# check for quit events
 for event in pygame.event.get():
 if event.type == pygame.QUIT:
 pygame.quit(); sys.exit();