The Rambler
The Rambler is my second automaton, and what I consider my first real kinetic sculpture. The pieced consists of a Brother Electric Typewriter, a piece of tissue paper from a roll which it types onto, and the board that holds the control components.
The text that the piece prints is selected from the last statements of former Death Row Inmates. I’ve had access to this data for a while, and have been working with it as a narrative subject for work for a while. It currently only uses a small number of phrases due to size restrictions.
This project began with the simple goal of bypassing the keyboard of an electric typewriter. The technology has a wide variety of applications, and I intend to use this type of machine further, although I want to find some way to make the controller smaller. The current version using relays is visually impacting, but it overrides the piece performatively.
I began this project with no useful documentation on how to go about my task. I eventually figured out that the typewriter runs off an 8×8 matrix that was held in a 16-pin header normally connected to the keyboard. connecting any pin from the top 8 to one from the bottom 8 constituted a key press. It simply remained to automate this function.
These notes (particularly the matrix) were what allowed me to make the piece function by reverse-engineering the matrix.
I did make a frizzing diagram. It has been simplified for the sake of convenience. the two loose wires are a jumper that I had manually connect upon turning the typewriter on. The switch it connected to was a reset switch on the bottom of the keyboard.
code:
String I[18] ={"I hope you let go of all of the hate because of all my actions.",
"I came in as a lion and I come as peaceful as a lamb.",
"I am at peace.",
"I hope society sees who else they are hurting with this.",
"I hope both victims find in their hearts to forgive me. ",
"I have forgave everyone and I love everyone.",
"I forgive myself.",
"I love you all and I will be waiting for you all.",
"I will be listening.",
"I am ready Warden.",
"I am sorry.",
"I love you all.",
"I am always going to be with you.",
"I love you all,",
"I love you all.",
"I love you Father.",
"I love you Father.",
"I love you Savior."};
int latchPinA = 1;
int clockPinA = 8;
int dataPinA = 3;
int latchPinB = 2;
int clockPinB = 10;
int dataPinB = 5;
int latchPinC = 4;
int clockPinC = 11;
int dataPinC = 6;
int latchPinD = 7;
int clockPinD = 12;
int dataPinD = 9;
int writeA = 0;
int writeB = 0;
int writeC = 0;
int writeD = 0;
int del = 175;
int ll = 0;
char s;
void hitA(int val) {
writeA += val; digitalWrite(latchPinA, LOW);
shiftOut(dataPinA, clockPinA, MSBFIRST, writeA);
digitalWrite(latchPinA, HIGH); delay(del/2);
writeA -= val; digitalWrite(latchPinA, LOW);
shiftOut(dataPinA, clockPinA, MSBFIRST, writeA);
digitalWrite(latchPinA, HIGH); delay(del/2);
ll += 1;
}
void hitB(int val) {
writeB += val; digitalWrite(latchPinB, LOW);
shiftOut(dataPinB, clockPinB, MSBFIRST, writeB);
digitalWrite(latchPinB, HIGH); delay(del/2);
writeB -= val; digitalWrite(latchPinB, LOW);
shiftOut(dataPinB, clockPinB, MSBFIRST, writeB);
digitalWrite(latchPinB, HIGH); delay(del/2);
ll += 1;
}
void hitC(int val) {
writeC += val; digitalWrite(latchPinC, LOW);
shiftOut(dataPinC, clockPinC, MSBFIRST, writeC);
digitalWrite(latchPinC, HIGH); delay(del/2);
writeC -= val; digitalWrite(latchPinC, LOW);
shiftOut(dataPinC, clockPinC, MSBFIRST, writeC);
digitalWrite(latchPinC, HIGH); delay(del/2);
ll += 1;
}
void hitD(int val) {
writeD += val; digitalWrite(latchPinD, LOW);
shiftOut(dataPinD, clockPinD, MSBFIRST, writeD);
digitalWrite(latchPinD, HIGH); delay(del);
writeD -= val; digitalWrite(latchPinD, LOW);
shiftOut(dataPinD, clockPinD, MSBFIRST, writeD);
digitalWrite(latchPinD, HIGH);
ll += 1;
}
void holdShift() {
writeD += 128; digitalWrite(latchPinD, LOW);
shiftOut(dataPinD, clockPinD, MSBFIRST, writeD);
digitalWrite(latchPinD, HIGH); delay(del);
}
void liftShift() {
writeD -= 128; digitalWrite(latchPinD, LOW);
shiftOut(dataPinD, clockPinD, MSBFIRST, writeD);
digitalWrite(latchPinD, HIGH); delay(del);
}
void hitEnt() {
hitD(64);
delay(ll * 32);
ll = 0;
}
void zeroRelays() {
writeA = 0;
writeB = 0;
writeC = 0;
writeD = 0;
digitalWrite(latchPinA, LOW);
shiftOut(dataPinA, clockPinA, MSBFIRST, 0);
digitalWrite(latchPinA, HIGH);
digitalWrite(latchPinB, LOW);
shiftOut(dataPinB, clockPinB, MSBFIRST, 0);
digitalWrite(latchPinB, HIGH);
digitalWrite(latchPinC, LOW);
shiftOut(dataPinC, clockPinC, MSBFIRST, 0);
digitalWrite(latchPinC, HIGH);
digitalWrite(latchPinD, LOW);
shiftOut(dataPinD, clockPinD, MSBFIRST, 0);
digitalWrite(latchPinD, HIGH);
delay(del);
}
void setup() {
//set pins to output so you can control the shift register
pinMode(latchPinA, OUTPUT);
pinMode(clockPinA, OUTPUT);
pinMode(dataPinA, OUTPUT);
pinMode(latchPinB, OUTPUT);
pinMode(clockPinB, OUTPUT);
pinMode(dataPinB, OUTPUT);
pinMode(latchPinC, OUTPUT);
pinMode(clockPinC, OUTPUT);
pinMode(dataPinC, OUTPUT);
pinMode(latchPinD, OUTPUT);
pinMode(clockPinD, OUTPUT);
pinMode(dataPinD, OUTPUT);
zeroRelays();
}
// relay : 0 1 2 3 4 5 6 7
// values: 1 2 4 8 16 32 64 128
void processString(String str){
int len = str.length();
for (int i = 0; i < len; i++){
s = str.charAt(i);
if(s == 'a'){
hitA(1);
} else if(s == 'b'){
hitA(2);
} else if(s == 'c'){
hitA(4);
} else if(s == 'd'){
hitA(8);
} else if(s == 'e'){
hitA(16);
} else if(s == 'f'){
hitA(32);
} else if(s == 'g'){
hitA(64);
} else if(s == 'h'){
hitA(128);
}
else if(s == 'i'){
hitB(1);
} else if(s == 'j'){
hitB(2);
} else if(s == 'k'){
hitB(8);
} else if(s == 'l'){
hitB(4);
} else if(s == 'm'){
hitB(16);
} else if(s == 'n'){
hitB(32);
} else if(s == 'o'){
hitB(64);
} else if(s == 'p'){
hitB(128);
}
else if(s == 'q'){
hitC(1);
} else if(s == 'r'){
hitC(2);
} else if(s == 's'){
hitC(4);
} else if(s == 't'){
hitC(8);
} else if(s == 'u'){
hitC(16);
} else if(s == 'v'){
hitC(32);
} else if(s == 'w'){
hitC(64);
} else if(s == 'x'){
hitC(128);
}
else if(s == 'y'){
hitD(1);
} else if(s == 'z'){
hitD(2);
} else if(s == ','){
hitD(4);
} else if(s == '.'){
hitD(8);
} else if(s == '/'){
hitD(16);
} else if(s == ' '){
if (ll > 55){
hitEnt();
} else {
hitD(32);
}
}
//------------------------CAPS------------------------------
else if(s == 'A'){
holdShift();
hitA(1);
liftShift();
} else if(s == 'B'){
holdShift();
hitA(2);
liftShift();
} else if(s == 'C'){
holdShift();
hitA(4);
liftShift();
} else if(s == 'D'){
holdShift();
hitA(8);
liftShift();
} else if(s == 'E'){
holdShift();
hitA(16);
liftShift();
} else if(s == 'F'){
holdShift();
hitA(32);
liftShift();
} else if(s == 'G'){
holdShift();
hitA(64);
liftShift();
} else if(s == 'H'){
holdShift();
hitA(128);
liftShift();
}
else if(s == 'I'){
holdShift();
hitB(1);
liftShift();
} else if(s == 'J'){
holdShift();
hitB(2);
liftShift();
} else if(s == 'K'){
holdShift();
hitB(4);
liftShift();
} else if(s == 'L'){
holdShift();
hitB(8);
liftShift();
} else if(s == 'M'){
holdShift();
hitB(16);
liftShift();
} else if(s == 'N'){
holdShift();
hitB(32);
liftShift();
} else if(s == 'O'){
holdShift();
hitB(64);
liftShift();
} else if(s == 'P'){
holdShift();
hitB(128);
liftShift();
}
else if(s == 'Q'){
holdShift();
hitC(1);
liftShift();
} else if(s == 'R'){
holdShift();
hitC(2);
liftShift();
} else if(s == 'S'){
holdShift();
hitC(4);
liftShift();
} else if(s == 'T'){
holdShift();
hitC(8);
liftShift();
} else if(s == 'U'){
holdShift();
hitC(16);
liftShift();
} else if(s == 'V'){
holdShift();
hitC(32);
liftShift();
} else if(s == 'W'){
holdShift();
hitC(64);
liftShift();
} else if(s == 'X'){
holdShift();
hitC(128);
liftShift();
}
else if(s == 'Y'){
holdShift();
hitD(1);
liftShift();
} else if(s == 'Z'){
holdShift();
hitD(2);
liftShift();
} else if(s == '?'){
holdShift();
hitD(16);
liftShift();
} else {
hitD(32);
}
}
hitEnt();
}
void loop() {
zeroRelays();
for (int i = 0; i < 18; i++){
String sub = I[i];
processString(sub);
delay(200);
}
}