Sonic Pi driven LED BarGraph project using RasPiO ProHat Experimenter’s Kit


Recently I received my Kickstarter reward from RasPiO of a ProHat and experimenter’s Kit. I wondered what project I might utilise to put it through its paces, and thought that I might try and emulate something of the recent project I did with a PiconBoard and McFaceRobot from 4Tronix. The experimenter’s kit came with 5 beefy leds of various colours and an MCP3008 8 channel A/D converter. There was also a 10k potentiometer  and a 10k resistor, and so I had nearly all the parts required to build a similar project. All I needed to get from the junk box were a couple of capacitors with which to feed in the audio signal from the Raspberry Pi Audio Output socket. The value of these is not too critical. I used two 10uF electrolytic capacitors of around 15v max working voltage, but I have also got the project working with two 0.1uF capacitors as well, albeit with a slightly lower audio signal. The only other additional component was an old 3.5mm jack to jack lead, which I chopped in half and used one section as an input lead for the Audio from the Raspberry Pi.

I actually did the project twice. The first time I failed to notice that the gpiozero library had built in support for a LEDbargraph and I wrote code to do this from scratch using GpioZero support for 4 leds in PWM mode (PWMLED). This was not too difficult to do, but in fact the project was much easier using the built in GpioZero code with the main loop of the program essentially using just two commands.

I initially built the circuit on the ProHat using the supplied leads, and this made it very quick to get it working. However it was not easy to see the leds because of the wires, and for a more permanent installation I then placed the wires with shorter ones cut more appropriately nearer to the lengths required.

I attempted (rather badly) to produce a circuit layout using Fritzing. I manufactured the ProHat image from a minibreadboard with single strip top and sides from the perforated board fritzing part. This gave a reasonable representation, although the top strip is slightly offset to the left. However if you use the hole legend provided it should work out OK.
You can click the image for a larger version, and use the back button to return.


The Leds are slightly contorted as it didn’t seem to be possible to “flp” them hirizontally, but I have marked the + (longer lead) led in each case. Also the centre pin of the potentiometer is in fact in the third row from the bottom, not the third, with the leg of the resistor in the third row above it. Also make sure that the orientation of the electrolytic capacitors, and the MCP3008 are correct with the negative -ve sides of the capcitors connected to the audio input, and the dimple on the MCP3008 (shown as a white dot) orientated as shown. Also be careful that gnd and 3v3 connectgions are plugged into the correct sockets, clearly marked on the ProHat. At the bottom the three connections symbolise the audio lead, with the outer wire sheath being ground, and the two inner wires the left and right audio inputs. It doesn’t matter which way round these are connected. The circuit diagram is shown below:


The software consists of a fairly straightforward python program shown below:

#! /usr/bin/env python
#sound sensitive led array, for use with sonic pi
#using an RPiO ProHat and components from the RPiO Explorer Kit
#two 10uF capacitors required in additon, plus a 3.5mm jack audio lead
#written by Robin Newman, June 11th 2016
from gpiozero import MCP3008, LEDBarGraph
from sys import argv,exit
#do some rudimentary arg checking
if len(argv)<2:
    print("Need sensitivity argument e.g. 40 (try range 30-100)")
    sensitivity=int(argv[1])#get sensitivity from arg as an integer
print("sensitivity set to: "+str(sensitivity)) #print sensitivity value set
print("Adjust potentiometer until all leds just out, then start music input")
print("ctrl+C to exit the program")
inp=MCP3008(channel=0,device = 0) #adc input channel 0 used
#4 leds plugged between the GPIO pins below and ground.
#No series resitors required on ProHat board
#set up GPIOZERO LEDBarGraph: referenced by graph
graph=LEDBarGraph(red,yellow,green,blue,pwm=True) #4 led bargraph with pwm mode
try: #use try with exceptions to give clean exit
    while True: #main loop
        #calculate graph input value 4 from adc reading. Offset by 0.5
        #multiply by sensitivity value
        v=sensitivity*(inp.value - 0.5)
        #graph input value max and min keep it between 0 and 1
        #min(1,v) sets a to ceiling value of 1
        #max(0,  {VALUE}) prevents graph input from going below 0

except KeyboardInterrupt:
    print "\nExiting"
#    print "An error occured" #uncomment when programm debugged OK
    print "\nFinished"

The hub of the prgoram is the While loop.This essentially repeatedly takes a sample reading from the MCP3008 adc channel 0, multiplies it by a sensitivity value, and then passes it ot the GpioZero LedBarGraph function together with a list of four led connected gpio pins. The function works out how many leds to light depending on the value of the input. The range 0->1 is split into four equal segments. Within each segment the active led’s brightness varies from 0 to max, fed with a varying Puse Width Modulated signal. Thus from 0-> 0.25 the Red led comes on, from 0.25 to 0.5 the yellow and so on till all leds are fully lit when the signal reaches 1. The input fed to the function graph.value is actually calculated by taking the offset from the “no input signal” value of the adc which is adjusted by the potentiometer to give a value just below that at which the red led first starts to glow. The sensitivity multiplier governs how rapidly the input changes with increased audio signal fed on top of the static value by the two input capacitors. The sensitivity is quite high, so that the small fluctuations of the audio signal can cause the adc output to fluctuate between 0 and 1, giving the full input range of the bar graph. Because it is possible to get both a negative value for v and a value above 1 depending on the potentiometer setting and the sensitivity value, the value of graph.value is clamped so that it cannot go below 0 or above 1. This is done by using the min and max functions. min(1,v) uses the min function to prevent maximum values exceeding 1. max(0,{VALUE}) prevents the value of graph.input from going negative.

I also did another variation of the layou, utilising a RasPIo GPIO pin layout board I had. I attached this to one corner of the ProHat using a spare pillar, and mounted the four leds on this board keeping them in place with some blue tack. I then used some of the jumper leads supplied with the experimenter kit to attach the leds to their original places on teh ProHat Board. Two images below plus a further vidoe show this version in operation:



A video explaining the project and showing it in use is here

Video of alternative layout in action here

Download the program here