HACK.ART with WiFi Pineapple, Processing, & Arduino

Hak5’s WiFi Pineapple is a penetration testing and security auditing tool for wireless networks. Here I want to talk about using the Pineapple for art — perhaps HACK.ART (or HAK.ART), in the manner of NET.ART. Fortunately, the Pineapple includes an API I can interface with my favorite digital arts medium, Processing, using the HTTP Requests for Processing library and a modification for JSON formatting (essentially, just save this file to the folder your Processing sketch resides in, which adds an addJson function you can see in my following example). To use the API, I first had to install the APITokens module on the Pineapple, and generate a token for Processing to use.

I have written a demo sketch that does the following:

  1. Send a JSON-formatted POST request to the Pineapple’s API to scan all access points within range of the Pineapple.
  2. Send another request to retrieve the results of the scan.
  3. Show the response data as a series of rectangles whose lengths are determined by the APs’ relative signal strengths, and whose colors are determined by the first three octets of their MAC addresses.
  4. Search the response for the occurrence of a particular MAC address, and if it is found, send a signal to an Arduino (which we could program to light an LED, sound a buzzer, or whatever; this would be more useful when including clients in the scan, but you get the idea).

If all you want is a bar chart or alert there are easier ways to make one (you could even write your own Pineapple module), but the Big Idea here, of course, is that you may do many kinds of creative things with these data.


LightStone to Processing

Several years ago, my friend Justin gave me a Journey to Wild Divine set he had found at a good price. I have finally gotten around to getting the data from its biofeedback device (which measures heart rate variability and skin conductance) into Processing so I can use it for weird projects (such as sorcerous robots that respond to fear — MWAHAHAHA!).

I am using Processing 2.0.1 (should also work with 2.2), oscP5 0.9.8, and GlovePIE 0.45. GlovePIE (Programmable Input Emulator) is a Windows program that can read data from many old and new video-game peripherals, including the LightStone device for JtWD (since replaced by the iOM). GlovePIE’s docu says that OSC messages are broken in versions >= 0.40, but I had no problem on a machine running Windows XP SP3 and the latest DirectX update.

The GlovePIE script could not be any simpler:

var.host = "" // host IP address
var.port = 7400 // host port number

SendOsc(var.host, var.port, "/ls_hrv", LightStone.HeartRateVariance)
SendOSC(var.host, var.port, "/ls_scl", LightStone.SkinConductanceLevel)

The processing code is a little longer, so I have placed it at the end of this article. For the example, I just read the data into two variables, then draw bar graphs from those values — here is an image of the output:

One of the cool things about this sketch is you can watch the graph for skin conductance level go up and down with your pulse (I should upload a video). I mapped the values based on those given in the GlovePIE docu and what I observed in Processing. I will tweak them as I play more with this and get a better idea of my actual ranges.

The OSC messages from GlovePie look like this:

received from /
addrpattern /ls_hrv
typetag f
[0] 0.261

Here is the Processing code:

 * LightStone to Processing
 * by Joshua Madara, hyperRitual.com
 * This sketch reads and graphs heart rate variability and
 * skin conductance level data from the LightStone device
 * via OSC messages from GlovePIE.

import oscP5.*;
import netP5.*;

OscP5 oscP5;

float hrv = 0.0; // heart rate variability
float scl = 0.0; // skin conductance level

void setup() {
  size(200, 200);
  // create OSC listener
  oscP5 = new OscP5(this, 7400);
  // plug the input values to functions defined at end of sketch
  oscP5.plug(this, "updateHrv", "/ls_hrv");
  oscP5.plug(this, "updateScl", "/ls_scl");

void draw() {
  background(#012232); // fill background with dark blue
  // draw bar graph for HRV
  fill(#ff0000); // set fill color to red
  float mHrv = map(hrv, 0.0, 0.4, 0, 100); // map hrv to bar height
  rect(50, 150, 25, -mHrv); // draw bar
  // draw bar graph for SCL
  fill(#00f149); // set fill color to green
  float mScl = map(scl, 0.0, 20.0, 0, 100); // map scl to bar height
  rect(125, 150, 25, -mScl); // draw bar

// update hrv value
void updateHrv(float val) {
  hrv = val;
  println("hrv: " + hrv);

// update scl value
void updateScl(float val) {
  scl = val;
  println("scl: " + scl);

Planetary Keys

This is something I made in anticipation of a similarly constructed robot controller for Robomancy.com. The keys were designed in Inkscape and printed onto cotton letterhead, then painted over with Bare Conductive paint (you could just paint the keys; I am not a terribly good painter, so I like to design on and print from a computer). I connected them to MaKey MaKey, which lets you turn pretty much anything that conducts even small amounts of electricity, into a button or switch that is interpreted as a keyboard or mouse action on a computer. I wrote a Processing sketch that reads each key and displays a corresponding color and plays a corresponding note. The black, shungite pyramid is conductive and connected to the ground part of the circuit, so when I touch the pyramid (with my right hand, in the video) and also one of the keys, I pull some of the electricity through my body to ground — enough for MaKey MaKey to recognize which connection I have altered, and activate the appropriate output.

(I have only six of the seven keys wired in the demo video, because more would have required the addition of a mouse action, and I just wanted to keep it simpler than that, but it is possible to use all seven.)

The correspondences I used are from Paul Foster Cases‘s Correlation of Sound and Color (you can find PDF copies online); there are others. If you are interested in his sources, Alison Deadman wrote an excellent article about them: “Letter, Musical Pitch, and Color in the Work of Paul Foster Case” (links to PDF). Dr. Deadman teaches music history and Alexander Technique at East Tennessee State University.

I have imagined many uses for this technology; a variety of ritual interactions. E.g., a conductive talisman that “charges” the magician when she completes a circuit by touching the talisman with one hand and an earthed device (metal stang?) with her other — perhaps triggering lights or video, music or other sound. Or printed/painted psionic devices. Etc. Feel free to share your own ideas in the comments.


Mind Map for Emotiv EPOC + Processing/Arduino

I have made a mind map with MindMeister, which shows how to connect the Emotiv EPOC to Arduino and/or Processing for developing your own mind-controlled applications including interactive art, music, data visualizations, games, neurofeedback, and robot controllers. Link to map (in case embedded map does not work for you): http://www.mindmeister.com/214762396/emotiv-epoc-processing-arduino

Generative Sigils

Related articles: TAD2011.06 Lorenz Attractor | Processing + EPOC via OSC

In his book, Chaos in Wonderland: Visual Adventures in a Fractal World, Clifford Pickover describes methods for generating beautiful, complex images from certain chaotic equations. In the context of the book’s narrative, these images are the dreams of a species of inorganic, computer-like entities called the Latööcarfians — the “dream-weavers of Ganymede.” Here I consider using these images as algorithmically generated magical sigils (cf., generative art).

The images are generated by recursively plotting:

xt + 1 = sin(ytb) + c sin(xtb)
yt + 1 = sin(xta) + d sin(yta)

(There are variant equations that produce “mutations” — see “Appendix A: Mutations of Equations”, pp. 209–210.) Here is a sketch that will draw the following image in Processing:

/** Generative Sigil 1
 * Joshua Madara, hyperRitual.com
 * Based on code on pg. 26 of _Chaos in Wonderland_
 * by Clifford A. Pickover
 * Good ranges for a, b, c, and d:
 * (-3 < a, b < 3)
 * (0.5 < c, d < 1.5)

float a = 1.5641136;
float b = 2.7102947;
float c = 0.9680385;
float d = 0.995141;
float x, y = 0.1;
int counter = 0;
int iterations = 500000;

void setup() {
  size(700,700,P2D); // remove P2D for Processing v2.0
  background(0); // black
  stroke(255,255,255,90); // white, semi-transparent

void draw() {
  translate(width/2, height/2); // draw from center of window
  float xNew = sin(y*b) + c * (sin(x*b));
  float yNew = sin(x*a) + d * (sin(y*a));
  x = xNew; y = yNew;
  point(x*100, y*100);
  if(counter >= iterations) {

Generative Sigil 1

I hypothesize that the key to using such images successfully as magical sigils is to assign non-trivial values to the inputs, a, b, c, and d. E.g., one could randomly generate the values at an auspicious moment, or acquire values from some act or object, and map those to the optimal ranges for the algorithm’s inputs. The magician could wear the Emotiv EPOC during a magical ritual and at the ritual’s apex a Processing sketch could map data from the EPOC to the a, b, c, and d values for generating the image. The images could subsequently be used for divination or evocation.

N.b., even while keeping the input values within optimal ranges, not all sets of values produce interesting images. Here is a Processing function to calculate the set’s Lyapunov exponent (based on the code on p. 62 of Chaos in Wonderland) — values >= 0.5 tend to be more interesting:

float calcLyapunovExponent(float a, float b, float c, float d) {
  float Lsum = 0;
  float n = 0;
  float x = 0.1;
  float y = 0.1;
  float  xe = x + 0.000001;
  float ye = y;
  float xx, yy, xsave, ysave, dLx, dLy, dL2, df, rs, L = 0;
  float bigNumber = 2139095039; /* Pickover's algorithm calls 
     for a long int (1000000000000) here, but I often get NaN returned 
     when using it in Processing, and I have found that using a 
     large float returns a value close enough to Pickover's to 
     be useful. */
  for(int i=0; i<10000000; i++) {
    xx = sin(y*b) + c*sin(x*b); yy = sin(x*a) + d*sin(y*a);
    xsave = xx; ysave = yy; x = xe; y = ye; n++;
    xx = sin(y*b) + c*sin(x*b); yy = sin(x*a) + d*sin(y*a);
    dLx = xx - xsave; dLy = yy - ysave; dL2 = dLx*dLx + dLy*dLy;
    df = bigNumber*dL2; rs = 1/sqrt(df);
    xe = xsave + rs*(xx - xsave); ye = ysave + rs*(yy - ysave);
    xx = xsave; yy = ysave; Lsum = Lsum + log(df); L = 0.721347*Lsum/n;
    x = xx; y = yy;
  return L;