Kirlian Device—Arduino code

Repository

This is the official repository for the source code of the original Kirlian Device, constructed using Arduino components. You can download a zip file with all the associated resources, or copy and paste from the code below. The software is released under the Creative Commons Attribution-NonCommercial CC BY-NC which means that you can remix, hack and play around with the code as you please as long as you attribute and release the result non-commercially.

The series of Kirlian Photographs were created using a bespoke device the Kirlian Device. The housing was constructed using laser cut stacking slices, and houses an array of Arduino UNO board, an Arduino WiFi Shield, Two 5V batteries and a Pololu RGB Led Strip. The code is designed to perform a scanning operation, retrieve the RSSI value of an previously specified SSID, and render it into a colour using a five colour heatmap scheme.

The following code details the interaction between the components. As can be gathered from the definition, the Pololu LED Strip is connected to pin 9 for Digital Communications, and a button is connected to pin 2. The function of this pin is to trigger or interrupt the scanning and rendering function. In order to listen to this event continuosly, the code uses a debounce Interrupt. A more detailed tutorial on creating the Kirlian Device will be added soon to this website.

Couple of notes on the operation of this code. The version of WiFi Shield that I used had a glitch in the initial handshake between the UNO and the Shield. Therefore, when the circuit is run for the first time, it might be necessary to press the reset button repeatedly until the connection is established.

#include < SPI.h >
#include < WiFi.h >
#include < PololuLedStrip.h >

PololuLedStrip<9> ledStrip;
#define LED_COUNT 30
rgb_color colors[LED_COUNT];
rgb_color color;
const int buttonPin = 2;
const unsigned int DEBOUNCE_TIME = 1000;
static unsigned long last_interrupt_time = 0;
float r,g,b;
volatile boolean scanActive=false;
String ssidTarget="KirlianDevice";
int maxRssi=38;
int minRssi=70;
boolean networkPresent;
int prevInt;
int intensityInt;
int absRssi;
int buttonState = 0;   
int led = 9;    
float invPercentage;
float prevInvPercentage;
float mappedValueR;
float mappedValueG;
float mappedValueB;


void setup() {
  attachInterrupt(0, debounceInterrupt, CHANGE);
  pinMode(buttonPin, INPUT); 
  Serial.begin(9600); 
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    for(int i=0; i<3; i++){
      writeLedStrip(255,0,0);
      delay(500);
      writeLedStrip(0,0,0);
      delay(500);
    }

    // don't continue:
    while(true);
  } 
  // scan for existing networks:
  scanNetworks();
}

void loop() {

  buttonState = digitalRead(buttonPin);
  // Serial.println(buttonState);
  if (scanActive == true) { 
    Serial.println(scanActive);
    Serial.println("Scanning"); 
    Serial.println("GOT HERE");  
    delay(200);
    // scan for existing networks:
    scanNetworks();  
    buttonState = digitalRead(buttonPin);
    if (networkPresent==false||absRssi==0){
      writeLedStrip(0,0,0);
      Serial.println("The network is not present, LED won't turn on");
    }

    else if (absRssi < maxRssi){
      //  writeLedStrip(255,0,0);  
      invPercentage=100;

      Serial.println("Netowrk outside limits, LED intensity to max");
      // delay(2000);
      //writeLedStrip(0,0,0);
      easeValues();
    }

    else if(absRssi > minRssi||absRssi==minRssi){
      // invPercentage=0;
      //      easeValues();

      writeLedStrip(0,0,0);

      Serial.println("Netowrk outside limits, NO LED");
      delay(20);
      //    writeLedStrip(0,0,0);
    }

    else {

      convertValues(); 
      easeValues();
    }
  }

  if (scanActive == false){
    writeLedStrip(0,0,0);

  }

}

//----------------------------------------------------------------------------

void scanNetworks() {
  // scan for nearby networks:
  int numSsid = WiFi.scanNetworks();
  if (numSsid == -1)

  { 
    //  Serial.println("Couldn't get a wifi connection");
    networkPresent=false;
    while(true);

  } 
  networkPresent=false;

  for (int thisNet = 0; thisNet < numSsid; thisNet++) {
    String ssidComparison=WiFi.SSID(thisNet);
    if(ssidComparison.equals(ssidTarget)){
      int rssi=WiFi.RSSI(thisNet);
      int tempRssi=abs(rssi);
      //      Serial.println(tempRssi);     
      if (tempRssi>11&&tempRssi<100){
        absRssi=tempRssi;
        networkPresent=true;
        Serial.print(" RSSI   ");
        Serial.println(absRssi);
      }
      if (tempRssi==4370){
        absRssi=10;
        Serial.println("Error on 4370"); 
      }
    }
  }
}

//----------------------------------------------------------------------------

void convertValues(){
  if(networkPresent){    
    float rssiRemapped=((absRssi-maxRssi));
    float ratio=abs(minRssi-maxRssi);
    float rssiPercentage=rssiRemapped/ratio;
    float interimInvPercentage=1-rssiPercentage;
    invPercentage=interimInvPercentage*100;
    int intensity=int(invPercentage*255);
    intensityInt=int(intensity);
  }

  else {
    int intensityInt=0;
    int rssiValue=0;
  }
}

//----------------------------------------------------------------------------
void easeValues()
{

  r=getHeatMapValueR(prevInvPercentage);
  g=getHeatMapValueG(prevInvPercentage);
  b=getHeatMapValueB(prevInvPercentage);
  writeLedStrip(int(r),int(g),int(b));
  delay(10);
  if (invPercentage==0){
    writeLedStrip(0,0,0);
    delay(10);
  }

  if (prevInvPercentage < invPercentage){
    float steps=invPercentage-prevInvPercentage;
    int intSteps=int(steps);

    for(int i=0; i < intSteps; i++){
      prevInvPercentage=prevInvPercentage+1;
      r=getHeatMapValueR(prevInvPercentage);
      g=getHeatMapValueG(prevInvPercentage);
      b=getHeatMapValueB(prevInvPercentage);
      //Serial.println("*");
      writeLedStrip(int(r),int(g),int(b));
      delay(10);
    }
  }

  else if (prevInvPercentage>invPercentage){
    float steps=prevInvPercentage-invPercentage;
    int intSteps=int(steps);
    Serial.println(intSteps);

    for(int i=0; i < steps; i++){
      prevInvPercentage=prevInvPercentage-1;
      r=getHeatMapValueR(prevInvPercentage);
      g=getHeatMapValueG(prevInvPercentage);
      b=getHeatMapValueB(prevInvPercentage);

      writeLedStrip(int(r),int(g),int(b));
      delay(10);
    }
  }
  prevInvPercentage=invPercentage;

}


//----------------------------------------------------------------------------

float getHeatMapValueR(int value) {
  if (value>0&&value<25) {
    float reading=(value-0);
    float percentage=reading/25;
    mappedValueR=0;
  }
  else if (value>=25&&value<50) {
    float reading=(value-25);
    float percentage=reading/25;
    mappedValueR=0;
  }  
  else if (value>=50&&value<75) {
    float reading=(value-50);
    float percentage=reading/25;
    float inversePercentage=1-percentage;
    mappedValueR=255*percentage;
  }  
  else if (value>=75&&value<100) {
    float reading=(value-75);
    float percentage=reading/25;
    float inversePercentage=1-percentage;
    mappedValueR=255.0;
  }  
  return abs(mappedValueR);
}


float getHeatMapValueG(int value) {
  if (value>0&&value<25) {
    float reading=(value-0);
    float percentage=reading/25;
    mappedValueG=255*percentage;
  }
  else if (value>=25&&value<50) {
    float reading=(value-25);
    float percentage=reading/25;
    mappedValueG=255;
  }  
  else if (value>=50&&value<75) {
    float reading=(value-50);
    float percentage=reading/25;
    float inversePercentage=1-percentage;
    mappedValueG=255;
  }  
  else if (value>=75&&value<101) {
    float reading=(value-75);
    float percentage=reading/25;
    float inversePercentage=1-percentage;
    mappedValueG=255*inversePercentage;
  }  
  return mappedValueG;
}


float getHeatMapValueB(int value) {
  if (value>=0&&value<25) {
    float reading=(value-0);
    float percentage=reading/25;
    mappedValueB=255.0;
  }
  else if (value>=25&&value<50) {
    float reading=(value-25);
    float percentage=reading/25;
    float inversePercentage=1-percentage;
    mappedValueB=255*inversePercentage;
  }  
  else if (value>=50&&value<75) {
    float reading=(value-50);
    float percentage=reading/25;
    float inversePercentage=1-percentage;
    mappedValueB=0;
  }  
  else if (value>=75&&value<101) {
    float reading=(value-75);
    float percentage=reading/25;
    float inversePercentage=1-percentage;
    mappedValueB=0;
  }  
  return mappedValueB;
}

//----------------------------------------------------------------------------

void writeLedStrip(int rColor,int gColor,int bColor){
  color.red = rColor;
  color.green = gColor;
  color.blue = bColor;

  Serial.print(color.red);
  Serial.print(", ");
  Serial.print(color.green);
  Serial.print(", ");
  Serial.print(color.blue);
  Serial.println(" ");


  for(byte i = 0; i < LED_COUNT; i++)
  {
    colors[i] = (color);
  }
  ledStrip.write(colors, LED_COUNT);  
  delay(25);
}

void stateChange(){
  scanActive = !scanActive;
  Serial.println("CHANGE_______________");

}

void debounceInterrupt() {
  unsigned long interrupt_time = millis();
  if (interrupt_time - last_interrupt_time > DEBOUNCE_TIME) {
    stateChange();
  }
  last_interrupt_time = interrupt_time;
}