Political Atmosphere
"Political Atmosphere" by Felix Lenz traces the invisible connections between flight turbulence, climate change and war. My task was to write the code for this installation.
Deafening siren
“Political Atmosphere” by Felix Lenz traces the invisible connections between flight turbulence, climate change and war. Flight data is captured by an antenna and sent to a controller. Felix asked me to visually display the flight data and correlate the measured flight density in the sky with the speed of a DC motor. This motor turned a gearbox which ultimately triggered a siren. The more planes in the sky, the more frequently the centerpiece of the exhibition - the deafening siren - is triggered.
Antenna captures data
Acrylic gearbox
The Code
The open source software dump1090 was used to translate the antenna data to json data. This data was then fetched by a React App running inside Electron. If there was a change in flight-density, the React App emitted the data via a websocket. On the receiving end was a Node.js script that controlled the speed of the DC-Motor by changing the pwm signal. This was done by using a L298N motor controller.
// React App running inside Electron
import React, { Component } from 'react';
import Axios from "axios";
import io from "socket.io-client";
let current = 0;
let gain = 0;
let density = 0;
let refresh = 0;
let pwm = 0;
const socket = io(localhost:PORT);
class App extends Component {
constructor(props) {
super(props);
this.state = {
flights: []
};
};
// Get flight-data from dump1090
async componentDidMount() {
try{
setInterval(async () => {
Axios.get("http://localhost:8080/data/data.json").then((response)=>{
this.setState({
flights: response.data,
});
});
}, 5000);
} catch(e) {
console.log(e);
}
}
// Do something with the flight-data
render () {
// Some simple flight density logic
current= this.state.flights.length;
gain= (current > gain) ? current : gain;
density= Math.round((100*current)/(gain));
pwm = density;
// Emit
if (pwm !== refresh) {
refresh = pwm;
socket.emit('message', {density: pwm});
}
// Visual Interface
return (
<div className="App">
{/* funky React interface goes here */}
</div>
);
}
}
export default App;
// Node.js motor-controller running on a Raspberrypi
// Require modules
const Gpio = require('pigpio').Gpio;
const io = require("socket.io")(PORT);
// Setup GPIO
const in1 = new Gpio(23, {mode: Gpio.OUTPUT});
const in2 = new Gpio(24, {mode: Gpio.OUTPUT});
const en = new Gpio(25, {mode: Gpio.OUTPUT});
in1.digitalWrite(0);
in2.digitalWrite(0);
// Set motor speed
function setSpeed( message ) {
let pwm = message.density;
if (pwm === 0) {
in1.digitalWrite(0);
in2.digitalWrite(0);
} else {
in1.digitalWrite(0);
in2.digitalWrite(1);
// Setting the pwm signal
dutyCycle = pwm < 30 ? 75 : Math.round(255 * pwm/100);
en.pwmWrite(dutyCycle);
}
}
// Flight-data from the server
io.on("connection", async socket => {
socket.on("message", async messageData => {
let message = messageData;
await setSpeed(message);
});
});
process.on('SIGINT', function() {
in1.digitalWrite(0);
in2.digitalWrite(0);
process.exit();
});
ARS Electronica 2020
All images are © Felix Lenz 2020. The Project “Political Atmosphere” was designed by Felix Lenz. If you want to read more about it, visit his website. Learn how to run a React App inside Electron here.