Random Checker New Ghost Hunting Equipment

Share

Hello, my paranormal family! I wanted to share a piece of new DIY equipment we developed in-house at San Diego Haunted, the “Random Checker.” As with all of our equipment builds, we will provide the knowledge needed to build and test this device in this device in the field. Let us know your results, as we will share ours in time.

Abstract: Is there a correlation between perceived high levels of strangeness (paranormal events) and a change in “Randomness?” The Idea for this device came to me after reading about the “Global Consciousness Project ,” of course, long after it had concluded. The results of the project claimed to show a correlation between regional, worldly events and randomness; the results of that study were heavily contested. For my interest, I am less concerned about the results of the GCP and more interested in defining a reasonable margin of variance in pseudorandom digital coin flips to determine when random is acting random in a localized specific area.

The device we built uses an Arduino Uno as the microcontroller. Analog Pin 0 is considered noisy, and we additionally added a 2-inch wire antenna to aid in localized voltage changes. A reading of pin 0 seeds built-in Arduino function random() the result is a pseudorandom sequence which we defined in line 116 of the code to define Heads or Tails outcomes. Digital pin 2 writes high for heads led and digital pin four writes high for tails led when called by random. The current code defines digital pins, 6 heads and 8 tails to show when those averages are above the defined variance point, which we have set to .03. In our newest code revision, it seemed redundant to have two LEDs to display variances and caused confusion to the eye. So we now only use heads variance led.

The need for useful visual data lead us to add a small I2C LCD display 128 x 64. The LCD is powered off the 3.3V pin and the corresponding ground pin of the Arduino. LCD pins for SDA and SCL are connected to the corresponding pins of the Arduino.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET 4        // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define ANALOG_PIN 0
#define HEAD_LED 2
#define TAIL_LED 4
#define VARIANCE_OUT_HEAD 6
#define VARIANCE_OUT_TAIL 8
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

uint16_t totalHeadsCount = 0;
uint16_t totalTailsCount = 0;
uint16_t numberOfFlips = 0;
float prevMeanHead, prevMeanTail;

void setup()
{
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
  {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Welcome");
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 17);
  display.println("This is");
  display.println("a Splash");
  display.println("Screen");
  display.display();
  delay(5000);
  pinMode(HEAD_LED, OUTPUT);
  pinMode(TAIL_LED, OUTPUT);
  pinMode(VARIANCE_OUT_HEAD, OUTPUT);
  pinMode(VARIANCE_OUT_TAIL, OUTPUT);
  randomSeed(analogRead(ANALOG_PIN)); 
}

float getAverage(int count, int flips)
{
  float average = (float)count / (float)flips;
  Serial.println(average, 6);
  Serial.println(F("...and this should be getting closer to 0.5"));
  return average;
}

void printFlipCount(int flips)
{
  Serial.print(F("Count after "));
  Serial.print(flips);
  Serial.println(F(" flips"));
}

float HeadStats(int flips)
{
  float currentAvg, variance;
  Serial.print(F("Total Heads = "));
  Serial.println(totalHeadsCount);
  Serial.print(F("..and the average for heads is now at "));
  currentAvg = getAverage(totalHeadsCount, flips);
  if (flips > 10)
    variance = ((currentAvg - prevMeanHead) / prevMeanHead) * 100;
  else
    variance = 0;
  prevMeanHead = currentAvg;
  Serial.print(F("..and the variance for heads is now: "));
  Serial.print(variance, 2);
  Serial.println(F("%"));
  return variance;
}

float printTailStats(int flips)
{
  float currentAvg, variance;
  Serial.print(F("Total Tails = "));
  Serial.println(totalTailsCount);
  Serial.print(F("..and the average for tails is now at "));
  currentAvg = getAverage(totalTailsCount, flips);
  if (flips > 10)
    variance = ((currentAvg - prevMeanTail) / prevMeanTail) * 100;
  else
    variance = 0;

  prevMeanTail = currentAvg;
  Serial.print(F("..and the variance for tails is now: "));
  Serial.print(variance, 2);
  Serial.println(F("%"));

  return variance;
}

void loop()
{
  float variance;
  int coinFlip = random(0, 2);

  if ( coinFlip == 0) {
    totalHeadsCount++;
    digitalWrite(HEAD_LED, HIGH);
    delay(250);
    digitalWrite(HEAD_LED, LOW);
  } else {
    totalTailsCount++;
    digitalWrite(TAIL_LED, HIGH);
    delay(250);
    digitalWrite(TAIL_LED, LOW);
  }

  numberOfFlips++;

 //display stats after every 10th flip
  if (numberOfFlips % 10 == 0) {

    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0, 0);
    Serial.println();

    printFlipCount(numberOfFlips);

    variance = HeadStats(numberOfFlips);

    display.print(F("Number of Flips: "));
    display.println(numberOfFlips);
    display.print(F("Heads Count: "));
    display.println(totalHeadsCount);
    display.print(F("Heads avg: "));
    display.println(prevMeanHead);
    display.print(F("Heads var: "));
    display.print(variance);

    if (abs(variance) > 0.2){
      display.println(F("% *"));
      digitalWrite(VARIANCE_OUT_HEAD, HIGH);
    }
    else{
      display.println(F("%"));
      digitalWrite(VARIANCE_OUT_HEAD, LOW);
    }

    variance = printTailStats(numberOfFlips);

    display.print(F("Tails Count: "));
    display.println(totalTailsCount);
    display.print(F("Tails avg: "));
    display.println(prevMeanTail);
    display.print(F("Tails var: "));
    display.print(variance);

    if (abs(variance) > 0.2){
      display.println(F("% *"));
      digitalWrite(VARIANCE_OUT_TAIL, HIGH);
    }
    else{
      display.println(F("%"));
      digitalWrite(VARIANCE_OUT_TAIL, LOW);
    }

    display.display();

  }
}

A minimum sample of 1,000 coin flips is required to establish the expected bell curve variance margin. The variance LED will be on for most of the duration to 1000 flips. At 1,000 flips the LED will sometimes go on and off. At 3,000 flips, the margin of variance we determined at .03 should be sufficient to determine whether the expected random is within tolerance. When the LED on pin six is lit, localized randomness is less random than expected.

Our hope is that in conjunction with other paranormal monitoring equipment, we can get data to either support or not support conjunctions with paranormal events while randomness on the coin flipper device appears not random.