A More Human Machine

Nariddh Khean
code3100
Published in
10 min readJun 8, 2017

--

Kinetic Biomimicry and the Internet of Things

WHERE WE LEFT OFF

As previously shown in the journal “The Kinetic Façade: A Hyper-Sensitive Solution”, we constructed two prototype frameworks, wherein kinetic façade elements will oscillate. The intention was to mimic a natural “breathing” motion and portray differences in human stress levels seen in the heart and lungs when under duress. However, both solutions failed to generate the desired motion, mainly due to the size of the frame and the translation of force vectors.

Prototype Framework Iterations 1 & 2

In addition to the kinetic façade, as expressed in the journal “Communication: Hardware Hurdles and Forwarding Firmware”,we have conducted explorations into utilising microcontrollers, to actuate motors in the kinetic façade and an array of LED strips for visualisation purposes. However, due to the time restrictions and scope of the studio, we have shelved inquiries into the LED strips, for want of providing one well-reasoned solution, as opposed to two half-arsed solutions.

Documented below are the final hurdles in approaching Group 7’s Kinetic Façade.

TWO STEPS FORWARD (IN A CIRCLE)

After the second prototype experienced materialistic failures, we took a step back and reflected upon what worked, but more importantly, what didn’t.

Firstly, over time, the repetitive movement would cause the force (strings) to find the most efficient path to the object (fabric), meaning that the fabric would rotate off center on the square frame. The method we decided to combat this issue was to create a frame with an even distance from the motor and the connections to the fabric. Furthermore, a potential reason why the motor was having difficulty pulling the fabric was the frictional forces between the fabric and the wooden framework. The larger the surface area of contact between the two materials, the larger the friction is, thus the more difficult it would be for the motor to pull the fabric. Our solution was to reduce the total surface area of the framework’s upward faces (the faces that touch the fabric). And finally, almost in conjunction with the previous point, the purpose of using wood for the first prototypes was the availability of the material, however, is detrimental with the goal of optimising movement by minimising friction.

Our solution: a plastic bucket…

30L Food Grade High Density Polyethylene Bucket

AN ALTERNATE ACTUATOR

As mentioned, one of the reasons behind the failures of the first two prototypes was the poorly designed translation of force vectors. In other words, we were using a motor to provide a pulling force, perpendicular to the desired motion, and around a corner that further lowered the effective pulling strength (not to mention the coefficient of friction of the two materials in contact). As such, the power that the motor provided was not nearly enough to overcome these inefficiencies.

We saw two possible solutions. We either create a more efficient system in an attempt to minimise the loss, or we simply purchase a more powerful motor to brute force the issue. Like most do, we threw money at our problems (though, as stated later on in this journal, we eventually resorted to the former solution because apparently, not enough money was thrown).

A secondary issue, that furthered the need to purchase a new motor, was the imprecision of the previous motor. The crux of the matter was that its rotation was determined by a speed variable. Under load, imprecisions transpire because the input speed does not take into account external resisting forces. A stepper motor, for example, does not have this issue, as it’s rotation is determined by mechanical “steps” in the motor’s architecture. Precision is vitally important in oscillation, because without it, the repetition will shift, thus causing the elements of the façade to eventually jam.

NEMA-17 Bipolar Stepper Motor

After purchasing the NEMA-17 Bipolar Stepper motor from Little Bird Electronics, we popped into the local Jaycar for some advice on wiring it up to a Particle Photon, our desired microcontroller. The lifeless, sunken-eyed, shell of a human-being who attended us indicated that a stepper motor controller module was needed for proper control (we later learned that this was not true at all). Another problem, another purchase.

L298N Stepper Motor Controller Module

Several insignificant technical complications later, we established methods of control over the stepper motor within the Particle IDE.

A MORE HUMAN MACHINE

A fair warning: this whole section gets rather technical. If you, the reader, would rather understand the overall work that was completed, know that this section simply discussed the restrictions of stepper motors on a Particle Photon, and that a variation of rotational speed was not received well by the microcontroller; so, feel free to skip this section. However, it was documented and included in the final journal, as I am of the opinion that the complications that we experienced were rather curious and I would like some professional feedback. Discussion leads to comprehension.

To begin, our goal for the kinetic facade was to mimic the motion of organs that experience pulse position modulation due to stress. Our solution was to control a motor that would pull on a piece of fabric, raising its position on the framework, and then release the tension to allow for gravity to lower it. This up-and-down motion will represent the in-and-out repetition seen in breathing. Thus, our Particle code for controlling a stepper motor included these lines:

int stepsPerRev = 200;void loop() {
myStepper.step(stepsPerRev);
delay(500);
myStepper.step(-stepsPerRev);
delay(2000);
}

Put simply, the stepper motor would rotate clockwise for one full revolution, pause for half a second, rotate counter-clockwise for another full revolution, and then pause for two seconds, only to loop back to the start and repeat these steps indefinitely. However, there is an important line that was intentionally left out:

void setup() {
myStepper.setSpeed(60);

Most entities that oscillate do not move at a constant speed. Dr. Karamjit Singh states that “nature follows periodicity. The day and night, life and death, everything is repetitive. Periodic motion is the motion that repeats itself after a fixed interval of time. There are many types of periodic motion and the most common of them is simple harmonic motion. In SHM, displacement, velocity and acceleration all are sinusoidal.”

With the goal of affecting the speed of the stepper motor to make “a more human machine,” we first needed to have the speed continuously update as the script runs. In order to do that, we can simply move the function that changes the speed, from something that only runs at the start of the script, to something that continuously loops, like so:

void loop() {
myStepper.setSpeed(60);

After that, we need to give the speed function a sinusoidal variable. Below is a simple mathematical statement that maps a sine wave to an amplitude range from 0 to 60 with a wavelength of 2 seconds (at time = 0s, speed = 0; at time = 1s, speed = 60; at time = 2s, speed = 0):

void loop() {
myStepper.setSpeed(30*cos(PI+2*PI*(millis()%2000)/2000)+30);

From here, we scripted some movement that matches the frequency of this wave. We can eliminate the need to dictate the quantity of steps, if we use an “if” statement based off of the properties of the independent variable of the above wave, that is, time:

void loop() {
myStepper.setSpeed(30*cos(PI+2*PI*(millis()%2000)/2000)+30);
if (millis()%2000 < 1000) {
myStepper.step(1);
} else {
myStepper.step(-1);
}
}

It’s at this point where the Particle Photon says “SOS!” Literally. The Particle Photon has a RGB LED that blinked red in the pattern of the Morse Code’s SOS. This means that the firmware has crashed. With the reason still unknown to us, the microcontroller doesn’t do well when we use time to alter the speed variable. We attempted to use different methods to create a variable that uniformly ascends, by either constructing integer variables that increase per repeat of the loop function, or by using the Photon’s internet connectivity to send a HTTP request to a universal clock and extract the seconds value, but nothing worked. So, we we’re in need to find an alternate solution to mimic a natural sinusoidal wave, or scrap the idea completely.

After some frustration, we attempted to implement a solution that avoided the problem all together. Instead of changing a variable that cannot be changed, we found another variable that had the potential to simulate a wave. We experimented with using ‘for loops” to alter the variable in the delay instead of the speed, however was side tracked with what will be described in the next section.

LEARNING FROM MISTAKES

Having finished construction of our third prototype, we put it to the test.

Prototype 3 Unaided
Prototype 3 Aided

Above are two variations of the third prototype, one requiring human intervention and one without. As it stands, the model is not able to function as intended without something (or someone) pushing the fabric down as the motor loosens the tension in the strings. In the video without the helping hand, weights were used to provide the downwards force, to maintain tension in the strings as it loosened, but there is a fine balance. If the weights are too heavy, the motor will not have enough power to overcome the frictional forces and inefficiencies of the system. If the weights are too light, the force they provide will not be able to keep the string in tension.

Our previous intention to brute force the problems of the system by purchasing a more powerful motor was done in vain. So, back to the two solutions; either brute force it or develop a more efficient system. We resorted to the latter.

Reflecting upon the prototype, we found that the points in the system where the string had to translate its force in a perpendicular fashion, seemed to be the location the string had the most trouble moving through. In an attempt to aid this transition, we change the string to a nylon based material (to reduce the potential friction caused by the coarse material of previous string) and added small pulleys. This was the fourth and final prototype:

Prototype 4

COMMUNICATION v2.0

The idea behind using a motor to actuate the kinetic façade was for more than just automation, it was for control. We wanted to be able to change the speed of the oscillation based off data, collated from the environment. For example, we wanted interactions from the Hololens, ultrasonic sensors placed around the pavilion, and maybe even live data from the web, to ultimately play a part in how the façade moves. This is our embodiment of the Internet of Things.

The microcontroller that we are using is called the Particle Photon. The Photon is a brilliant little device, as it has onboard capabilities to connect to local wifi networks (discussed more in the journal, “Communication: Hardware Hurdles and Forwarding Firmware”). Furthermore, Particle offers a functionality called “Tinker”. Tinker allows the user to control and read the voltage of the pins on the Photon, from an application on your phone. We decided to show the powerful, live connectivity of these devices by controlling the kinetic façade’s oscillation speed from this application.

Below are the main components in adding the Tinker functionality to our code:

int tinkerDigitalRead(String pin);
int tinkerDigitalWrite(String command);
int pinIn0 = A0;
int pinIn1 = A1;
int on0;
int on1;
void setup() {
Particle.function("digitalread", tinkerDigitalRead);
Particle.function("digitalwrite", tinkerDigitalWrite);
pinMode(pinIn0, INPUT);
pinMode(pinIn1, INPUT);
}
void loop() {
on0 = digitalRead(pinIn0);
on1 = digitalRead(pinIn1);
if (on0 == LOW && on1 == LOW) {
// State 0 - Off
} else if (on0 == HIGH && on1 == LOW) {
// State 1
} else if (on0 == HIGH && on1 == HIGH) {
// State 2
} else if (on0 == LOW && on1 == HIGH) {
// State 3
} else {
// Nothing
}
}
int tinkerDigitalRead(String pin) {
int pinNumber = pin.charAt(1) - '0';
if (pinNumber< 0 || pinNumber >7) return -1;
if(pin.startsWith("D")) {
pinMode(pinNumber, INPUT_PULLDOWN);
return digitalRead(pinNumber);
} else if (pin.startsWith("A")) {
pinMode(pinNumber+10, INPUT_PULLDOWN);
return digitalRead(pinNumber+10);
}
return -2;
}
int tinkerDigitalWrite(String command) {
bool value = 0;
int pinNumber = command.charAt(1) - '0';
if (pinNumber< 0 || pinNumber >7) return -1;
if(command.substring(3,7) == "HIGH") value = 1;
else if(command.substring(3,6) == "LOW") value = 0;
else return -2;
if(command.startsWith("D")) {
pinMode(pinNumber, OUTPUT);
digitalWrite(pinNumber, value);
return 1;
} else if(command.startsWith("A")) {
pinMode(pinNumber+10, OUTPUT);
digitalWrite(pinNumber+10, value);
return 1;
}
else return -3;
}

By connecting pins D0 to A0, and D1 to A1, we can use the Tinker app to send either an “on” or “off” signal to the digital pins. From there, the analogue pins pick up this signal, and a combination of the two will indicate one of four possible states. Once we’ve connected it up to the phone (ie. the web), we can easily wire up ultrasonic sensors, or use HTTP requests to collect data from the Hololens, or even live data sets. From there, all that’s needed is to remap the values onto a range that the motor can comprehend, and we have generated a data driven kinetic façade.

This control over the kinetic façade is representative of the capabilities of the Internet of Things.

--

--