Jack Barber / Website Design

Expressing Joy Using Heart-Shaped LEDs

Expressing Joy Using Heart-Shaped LEDs

For a number of years now I have helped Staithes Festival of Arts & Heritage. I produce the programme, developed and support a bespoke application system for the Festival, I built their website and help out with general IT issues

Last year they invited me to give a talk at the Festival. It could be about anything - but knowing my background and skills they suggested something to do with websites. I work with websites all day long, so took the opportunity to talk about something a little different - the intersection between art, design and technology.

I'm no conference speaker, nor am I well qualified to talk about anything to do with art - especially in the presence of actual artists. I've spent my career trying things out, seeing what works and experimenting and as a result I have a broad spectrum of knowledge, but don't know much about anything in particular!

Anyway, not one to turn down a challenge I decided I'd attempt to do something interesting with data over the course of the Festival weekend. I settled on an idea to attempt to capture 'joy'. Not something which can be easily identified, let alone logged in a spreadsheet.

2018 09 05 21.42.59

A few hours of tinkering later and I'd come up with a plan. I would use a pressure pad to allow people to 'jump for joy' and would log the activity. The recorded data could then be displayed, either as a graph or, as it turned out, as an interactive 'art' installation.

I positioned my pressure pad data logger on Staithes High Street and throughout the Saturday visitors to the festival could jump up and down on it - expressing their joy at being at Staithes Festival.

2018 09 08 17.10.30

I wasn't actually with the device all day - so I was glad to see my piece of carpet was fairly grubby by the end of the day. It seemed people had indeed been jumping up and down on it!

On the Sunday I gave my talk - you can flick through my slides here, if you fancy:

https://docs.google.com/presen...

I didn't have a huge audience - probably about 10 people (including various family members). But those who were present were engaged and participated well in the various points of discussing and feedback I'd built into my talk.

2018 09 09 11.34.09

Towards the end of the talk I walked through the steps required to built my miniature art installation. The premise was fairly simple:

  • Plot the amount of joy expressed vs. time using heart-shaped LEDs
  • Use a potentiometer (variable resistor) to move through time
  • Light up the right number of LEDs based on the amount of joy for the current time period

In order to do this, my program did the following:

  • Read the data from the spreadsheet into an array
  • Divided the total length of time into 10 equally sized divisions (10 hours)
  • Calculated the amount of joy expressed within each division
  • Worked out the maximum and minimum amounts of joy (these would be used to define the level at which 1, 2, 3, 4 or 5 LEDs would light up)
  • Monitor the resistance of the potentiometer and use it's maximum and minimum resistance to work out which division of time the user had moved into
  • Change the number of lit LEDs depending on the amount of joy expressed for the particular division of time the user was in (based on the resistance of the potentiometer)

Simple!

The hardware setup was straight forward:

2018 09 08 16.22.57

This is a Raspberry Pi Zero W with 5 LEDs attached to outputs and a variable resistor attached to an input (inputs and outputs set within my script).

Code

I'm no Python expert, so the following is probably a bit sketchy. But it works! Feel free to copy/use/amend as you wish

#import packages to perform particular functions
import RPi.GPIO as GPIO
import time
import csv
#setup GPIO (General Purpose Input Output) pins - this is how we light LEDs, read sensors etc.
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

a_pin = 18
b_pin = 23
led1 = 16
led2 = 12
led3 = 26
led4 = 13

GPIO.setup(led1,GPIO.OUT)
GPIO.setup(led2,GPIO.OUT)
GPIO.setup(led3,GPIO.OUT)
GPIO.setup(led4,GPIO.OUT)
GPIO.output(led1,GPIO.LOW)
GPIO.output(led2,GPIO.LOW)
GPIO.output(led3,GPIO.LOW)
GPIO.output(led4,GPIO.LOW)

#functions for determining value of resistor
def discharge():
 GPIO.setup(a_pin, GPIO.IN)
 GPIO.setup(b_pin, GPIO.OUT)
 GPIO.output(b_pin, False)
 time.sleep(0.005)
def charge_time():
 GPIO.setup(b_pin, GPIO.IN)
 GPIO.setup(a_pin, GPIO.OUT)
 count = 0
 GPIO.output(a_pin, True)
 while not GPIO.input(b_pin):
 count = count + 1
 return count

def analog_read():
 discharge()
 return charge_time()
#get data from CSV file
data = []
with open('joy.csv') as csvDataFile:
 csvReader = csv.reader(csvDataFile)
 for row in csvReader:
 data.append(row[0])

#define time slots - each is a variable, '0'
a = 0
b = 0
c = 0
d = 0
e = 0
f = 0
g = 0
#create an empty array
times = []

#loop through CSV data and increment time slots with correct number of 'jumps'
for theTime in data:
 if theTime[0:2] in '09':
 a += 1
 if theTime[0:2] in '10':
 b += 1
 if theTime[0:2] in '11':
 c += 1
 if theTime[0:2] in '12':
 d += 1
 if theTime[0:2] in '13':
 e += 1
 if theTime[0:2] in '14':
 f += 1
 if theTime[0:2] in '15':
 g += 1
#populate times array with correct values obtained above
times.append(a)
times.append(b)
times.append(c)
times.append(d)
times.append(e)
times.append(f)
times.append(g)

#get max and min items in the times array
max = max(times)
min = min(times)
#generate break points - the points at which the LEDs should turn on/off
difference = max-min
section = difference/4.0

w = section+min
x = (section*2)+min
y = (section*3)+min
z = (section*4)+min
#run the program!
while True:
 period = analog_read()/10
 if period > 6:
 period = 6
 joy = times[period]
 if joy >= w:
 GPIO.output(led1,GPIO.HIGH)
 else:
 GPIO.output(led1,GPIO.LOW)
 if joy >= x:
 GPIO.output(led2,GPIO.HIGH)
 else:
 GPIO.output(led2,GPIO.LOW)
 if joy >= y:
 GPIO.output(led3,GPIO.HIGH)
 else:
 GPIO.output(led3,GPIO.LOW)
 if joy >= z:
 GPIO.output(led4,GPIO.HIGH)
 else:
 GPIO.output(led4,GPIO.LOW)
 time.sleep(0.5)