As many other human beings who once apon a time were present in the bolwerK realm, I received an invitation to come to Kasterlee, to the Frans Masereelcentrum. The object was clear: work with the bolwerK archive. The form, size, way in which to deal with this archive was open. As Masereel is the place to print (silk screen, letterpress and lots of other stuff I don’t even know the name of), I decided that the way of dealing with the archive should be through print, a topic I know nothing about.
I do feel comfortable around electronics and physical computing. So I started thinking about a meeting point between these two with the *archive archive archive* mantra repeating in the back of my head.
So, after some thinking I stumbled upon the existence of conductive paint. http://www.bareconductive.com/
And I ordered a jar.
And then what…
…
Posters!
Posters as interfaces!
Talking posters, playing soundfiles related to the bolwerK archive!
Capacitive interactive posters, playing soundfiles related to the bolwerK archive!
I had cracked it.
The idea was there.
In my head.
In Kasterlee it was the challenge to see whether the reality in my head could/would correspond with the physical realm, including one microcontroller (Arduino), a waveshield for playing sound, some resistors, paper, conductive thread and somebody who masters screenprinting. And the code for the Arduino. And the soundfiles. Hmm. Not there yet…
With the added sauce of stress concerning a misplaced laptop power supply (mine), I managed to get the painted prototype (not silkscreened) working, it gave me data, numbers in the serial port as you can see on the pictures.


I was very lucky that Bare Conductive had just put up a manual on working with the paint entitled: “Building a Capacitive Proximity Sensor using Bare Paint”. Translated for non-techies this means that when you hover your hand over the conductive surface, something can happen.
http://www.bareconductive.com/capacitance-sensor
Then came these serious tasks: make an image for the silkscreen installation, screenprint it, sew a conductive thread in the conductive printed surface, make the capacitive sensor work with sound. Then, multiply the amount of posters by three…
I chose two images for the posters: a hand and a circle. A hand because this part of the body is quite central in the bolwerK projects I was involved with (handshakes, greetings, excercises for hand and wrist…). The hand is like a shadow stuck to the paper. The image of a circle has multiple meanings: a circle can be a “bol” in Dutch, a circle can be a full stop (part of interpunction), as it is very black it could even be a black hole, a gateway to another universe, a vortex in which the archive may be evaporated or redefined…
From this part of the text onwards, I will guide you to through some images.
The hand has been cut out in a red foil, because everything which is red will become the positive image when you screenprint.

The Wikipedia page on silkscreen & screenprinting has some great animated gifs:

Making the screen

Screen machinery (and Lieven and Wauter)

The screen is ready for printing

A close-up

Screenprinting – the movie
If the player does not work, click
here.
The result: a hand and a sphere silkscreened with conductive paint, three layers on top of each other

A close-up of the conductive thread in the poster. I had to add conductive paint by hand with a paintbrush, in between printing the layers. Quite stressy and this requires clear instructions by the screenprinter and the “retouche” person.

The backside of the poster, showing the conductive thread

Another close-up of the conductive thread in the poster: the black conductive surface needs to be as smooth as possible. The ink quickly logs up the pores of the screen. It’s quite hard to make nice surfaces…

A colourful intervention in the poster by bolwerK: a cursor

Asking two nice graphic designers advice on how you place an image in a poster (the cursor). Apparently, it’s all about ratio’s.

Finalizing, hooking up electronics to the posters

The posters, ready and waiting for some electronic input

It works! The code needs some tweeking by e-mail afterwards.

When you hover your hand above one of the dots or the hand, a sound or a story will be played. I chose:
– An audio rendition of “Stops, or How To Punctuate” by Paul Allardyce (1855-1895), the part on the Full Stop. (Thanks F)
– A sound work by an invited artist, made in Kasterlee.
– And a Hello from Vorst, Brussels.

As you can see, the posters are connected with a cable to an Arduino and a waveshield. The waveshield is connected to a speaker.
Here is the final Arduino code. It is a Frankenscript of the code for capacitive sensors and the code for the djette (a bolwerK project). You need the waveshield library (AF_Wave) and the capacitive sensor library (CapSense).
Interpunctie03-111025a Arduino Code Zip
#include
#include
#include "util.h"
#include "wave.h"
#include
CapSense cs_9_7 = CapSense(9,7); // 10 megohm resistor between pins 4 & 2, pin 2 is sensor pin, add Bare Paint
CapSense cs_9_6 = CapSense(9,6); // OPTIONAL: for sensor 2, 10 megohm resistor between pins 9 & 6, pin 6 is sensor pin, add Bare Paint
CapSense cs_9_8 = CapSense(9,8); // OPTIONAL: for sensor 3, 10 megohm resistor between pins 9 & 8, pin 8 is sensor pin, add Bare Paint
/////////////////////////////////////////////////////////////////////////////// WAVESTUFF
AF_Wave card;
File f;
Wavefile wave; // only one!
uint32_t wavsamplerate = 22050;
char * wavname; // filename WAV file
uint8_t tracknum = 0;
void settrack(uint8_t num){
switch (num){
case 0:
wavname = “SOUND1.WAV”;
break;
/* case 1:
wavname = “TRACK1.WAV”;
break;
case 2:
wavname = “TRACK2.WAV”;
break;
case 3:
wavname = “TRACK3.WAV”;
break;
case 4:
wavname = “TRACK4.WAV”;
break;
case 5:
wavname = “TRACK5.WAV”;
break;
case 6:
wavname = “TRACK6.WAV”;
break;
case 7:
wavname = “TRACK7.WAV”;
break;
case 8:
wavname = “TRACK8.WAV”;
break;
case 9:
wavname = “TRACK9.WAV”;
break;
case 10:
wavname = “TRACK10.WAV”;
break;
case 11:
wavname = “TRACK11.WAV”;
break;
case 12:
wavname = “TRACK12.WAV”;
break;
case 13:
wavname = “TRACK13.WAV”;
break;
case 14:
wavname = “TRACK14.WAV”;
break;
case 15:
wavname = “TRACK15.WAV”;
break;
case 16:
wavname = “TRACK16.WAV”;
break;
case 17:
wavname = “TRACK17.WAV”;
break;
case 18:
wavname = “TRACK18.WAV”;
break;
case 19:
wavname = “TRACK19.WAV”;
break;
case 20:
wavname = “TRACK20.WAV”;
break;
case 21:
wavname = “TRACK21.WAV”;
break;
case 22:
wavname = “TRACK22.WAV”;
break;
case 23:
wavname = “TRACK23.WAV”;
break; */
}
card.reset_dir();
}
void ls() {
char fname[13];
int ret;
card.reset_dir();
putstring_nl(“Listing:”);
while (1) {
ret = card.get_next_name_in_dir(fname);
if (!ret) {
card.reset_dir();
return;
}
Serial.println(fname);
}
}
bool active_file = false;
void playfile(char *name) {
while (wave.isplaying) {
wave.stop();
}
card.reset_dir();
if(active_file) {
Serial.println(“closing previous file”);
card.close_file(f);
}
card.reset_dir();
f = card.open_file(name);
Serial.print(“opening new file “);
Serial.println(name);
if (!f) {
putstring_nl(” Couldn’t open file”);
return;
}
active_file = true;
if (!wave.create(f)) {
putstring_nl(” Not a valid WAV”);
return;
}
// ok time to play!
wave.play();
}
/////////////////////////////////////////////////////////////////////////////////////////// SETUP
void setup() {
cs_9_7.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate on channel 1 – just as an example
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println(“Talky Poster!”);
// Set the output pins for the DAC control. This pins are defined in the library
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
if (!card.init_card()) {
putstring_nl(“Card init. failed!”);
return;
}
if (!card.open_partition()) {
putstring_nl(“No partition!”);
return;
}
if (!card.open_filesys()) {
putstring_nl(“Couldn’t open filesys”);
return;
}
if (!card.open_rootdir()) {
putstring_nl(“Couldn’t open dir”);
return;
}
/*
pinMode(buttons[B_REED_SWITCH], INPUT); // reed switch
pinMode(buttons[B_NEXT], INPUT); // button next
pinMode(buttons[B_NORMAL], INPUT); // button normal
TCCR2A = 0;
TCCR2B = 1<
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1< */
ls();
}
/*
SIGNAL(TIMER2_OVF_vect) {
check_switches();
}
*/
/*void check_switches()
{
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
byte index;
for (index = 0; index < NUMBUTTONS; index++) { currentstate[index] = digitalRead(buttons[index]); // read the button if (currentstate[index] == previousstate[index]) { if ((pressed[index] == LOW) && (currentstate[index] == LOW)) { // just pressed justpressed[index] = 1; } else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) { // just released justreleased[index] = 1; } pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed } //Serial.println(pressed[index], DEC); previousstate[index] = currentstate[index]; // keep a running tally of the buttons } } bool normal_mode = false; float avgSpeed = 0.0f; float curSpeed = 0.0f; unsigned long curTime, prevTime;*/ /////////////////////////////////////////////////////////////////////////////////////////// LOOP //boolean samplerate_changed = false; uint32_t lastReedRead = 0; void loop() { char c; long start = millis(); long total1 = cs_9_7.capSense(30); long total2 = cs_9_6.capSense(30); // OPTIONAL for sensor 2 long total3 = cs_9_8.capSense(30); // OPTIONAL for sensor 3 // Serial.print(millis() – start); // OPTIONAL: check on performance in milliseconds Serial.print(“t”); // OPTIONAL: tab character for debug windown spacing Serial.println(total1); // OPTIONAL: To use additional sensors,change Serial.println to Serial.print for proper window spacing Serial.print(“t2”); // OPTIONAL: tab character for window spacing for sensor output 2 Serial.print(total2); // OPTIONAL: print sensor output 2 Serial.print(“t3”); // OPTIONAL: tab character character for sensor output 3 Serial.println(total3); // print sensor output 3 if (total1>350) {
//if (!wave.isplaying) {
playfile(“SOUND1.WAV”);
//}
}
if (total2>130) {
//if (!wave.isplaying) {
playfile(“SOUND2.WAV”);
//}
}
if (total3>130) {
//if (!wave.isplaying) {
playfile(“SOUND3.WAV”);
//}
}
delay(200);
/* check_switches();
if(pressed[B_NEXT] && pressed[B_NORMAL]) {
justpressed[B_NEXT]=0;
justpressed[B_NORMAL]=0;
Serial.println(“two buttons pushed”);
}
else if( justpressed[B_NEXT] ) {
justpressed[B_NEXT]=0;
Serial.println(“B_NEXT pushed”);
settrack(tracknum);
Serial.println(wavname);
playfile(wavname);
tracknum++;
}
else if( justpressed[B_NORMAL] ) {
justpressed[B_NORMAL]=0;
Serial.println(“B_NORMAL pushed”);
normal_mode =!normal_mode;
if(normal_mode) {
Serial.print(“playing a fixed bitrate”);
wave.setSampleRate(wave.dwSamplesPerSec);
}
else {
Serial.print(“playing a dynamic bitrate”);
}
}
if(justpressed[B_REED_SWITCH])
{
justpressed[B_REED_SWITCH] = 0;
prevTime = curTime;
curTime = millis();
lastReedRead = curTime;
curSpeed = float(curTime – prevTime);
// cumulative average
const float alpha = 0.5f;
avgSpeed = avgSpeed * (1.0f – alpha) + curSpeed * alpha;
Serial.print(“curSpeed: “);
Serial.print(curSpeed);
Serial.print(” avgSpeed: “);
Serial.println(avgSpeed);
// TIMING constantes
//
const float x1 = 1000.0f; // slow sensor timing
const float x2 = 150.0f; // fast sensor timing
const float y1 = 5000.0f;
const float y2 = 25000.0f;
const float m = (y2-y1) / (x2-x1);
float fsamplerate = (avgSpeed * m ) – m * x1 + y1;
if (fsamplerate > 0.0f) wavsamplerate = fsamplerate;
else
wavsamplerate = 0.0;
samplerate_changed = true;
Serial.print(“fsamplerate: “);
Serial.println(fsamplerate);
Serial.print(” wavsamplerate: “);
Serial.println(wavsamplerate);
}
if (millis() – lastReedRead > 700) {
if(wavsamplerate>100) wavsamplerate -= 100;
samplerate_changed = true;
// lastReedRead = millis();
}
if(samplerate_changed && wave.isplaying && !normal_mode) {
if (wavsamplerate>25000) wavsamplerate= 25000;
wave.setSampleRate(wavsamplerate);
samplerate_changed = false;*/
}
I was lucky to get caught in the gravity pull of bolwerK. All collaborations were wonderful, crazy, sharp, complex, heavy, light at the same time. So, I guess, thanks, bolwerK! is quite appropriate.
Lieven – huge thanks for your patience with the stubborn conductive ink and putting up with the lack of time.
(slight warning, inviting artists to work on archive generates more data and bigger archive – end of warning)