Skip to content

Instantly share code, notes, and snippets.

@RedRoosterKey
Created February 19, 2017 00:04
Show Gist options
  • Select an option

  • Save RedRoosterKey/54c8e237ac0a13d026621c9903191b7e to your computer and use it in GitHub Desktop.

Select an option

Save RedRoosterKey/54c8e237ac0a13d026621c9903191b7e to your computer and use it in GitHub Desktop.
Facilitates communication with extradimensional entites via a raspberry pi and sensehat (for entertainment purposes only)
#!/usr/bin/python
from sense_hat import SenseHat
from datetime import datetime
import math,os,random,subprocess,time
#
# Background:
#
# I have seen various electronic devices on paranormal TV shows (most popular
# being the Ovilus by Digital Dousing) that claim to convert "ghost energy" into
# actual English words. From the digital dousing website, they claim that their
# ghost box simply "converts environmental readings into words."
# - https://www.digitaldowsing.com/shop/ovilus-v/
# The algorithm for how this is done is not open source and could be as simple
# as this example, which uses a raspberry pi and sensehat to pick up
# "environmental readings" and using changes in that data to seed a random
# number generator later randomly choosing a word from the provided dictionary.
# To get this to work, you will need:
# * A raspberry pi
# * A sensehat
# * The python sensehat library installed
# sudo apt-get install sense-hat
# * A word list - set the "filename" variable (Results vary depending on the
# quality of your word list)
# * (optional) The espeak library installed (if you wish to HEAR the ghosts)
# sudo apt-get install espeak
# Comment out the calls to espeak() if you don't need this.
# You can have this program start up when the raspberry pi is powered by adding
# something akin to the following into /etc/rc.local before the exit 0
#
# # Ghost Box
# cd /home/pi
# su pi -c "python ghostBox.py" &
# This code is very sensitive to physical movement, it works best when set in a
# stationary position and read (or listened to) from about 3 or so meters away.
# VARIABLES
sense = SenseHat()
sense.low_light = True # It's more fun at night :-)
red = (255, 0, 0)
white = (255, 255, 255)
black = (0, 0, 0)
# Put the location of your word list file here.
# The one that Digital Dousing uses is available on their website.
# https://www.digitaldowsing.com/product-guides/ovilus-v/word-list/
filename="ovilus.txt"
# The minimum percent change required to trigger a word.
# A higher number will cause the ghost box to produce fewer words.
# A lower number will cause the ghost box to produce more words.
# 2.5 percent seems to be the magic number based on experimentation.
percent_change_min=2.5
# The number of seconds between readings.
# A higher number will cause the ghost box to produce fewer words.
# A lower number will cause the ghost box to produce more words.
# 5 seconds feels like a good cadence.
rest_period_between_readings=5
# FUNCTIONS
# Displays the message given, in the color given,
# right side up based on the detected acceleration of gravity.
def show_right_side_up_message(sense, message, color):
acc = sense.get_accelerometer_raw()
x = acc["x"]
y = acc["y"]
orientation = 90
if y > 0.75 :
orientation = 0
elif y < -0.75 :
orientation = 180
elif x > 0.75 :
orientation = 270
elif x < -0.75 :
orientation = 90
sense.set_rotation(orientation)
sense.show_message(message, text_colour=color)
# Get a random line from the file with the name provided
# and seed the rng with the given seed.
def get_random_line(seed, filename):
my_file = open(filename,'r')
line = next(my_file)
random.seed(seed)
for num, aline in enumerate(my_file):
if random.randrange(num + 2): continue
line = aline
return line
# Get a heuristic aggregating all sensor data allowing general change detection.
def aggregate_sense_data():
hum = sense.get_humidity()
temp = sense.get_temperature()
temp_from_hum = sense.get_temperature_from_humidity()
temp_from_press = sense.get_temperature_from_pressure()
press = sense.get_pressure()
o = sense.get_orientation()
yaw = o["yaw"]
pitch = o["pitch"]
roll = o["roll"]
mag = sense.get_compass_raw()
mag_x = mag["x"]
mag_y = mag["y"]
mag_z = mag["z"]
acc = sense.get_accelerometer_raw()
x = acc["x"]
y = acc["y"]
z = acc["z"]
gyro = sense.get_gyroscope_raw()
gyro_x = gyro["x"]
gyro_y = gyro["y"]
gyro_z = gyro["z"]
return hum + temp + temp_from_hum + temp_from_press + press + pitch + yaw \
+ roll + mag_x + mag_y + mag_z + x + y + z + gyro_x + gyro_y + gyro_z
# Speak the words verbally through the headphone jack.
# You must have espeak installed for this to work.
def espeak(message):
espeak = 'espeak -s100 "%s" 2>>/dev/null' % message
subprocess.Popen(espeak, shell=True)
# Display a basic animation to get us to look
# at the box before the message is displayed.
# Keeps you from missing words if audio is disabled.
def alert(sense):
spiral_sequence = [
[4, 4],
[3, 4],
[3, 3],
[4, 3],
[3, 3],
[5, 3],
[5, 4],
[5, 5],
[4, 5],
[3, 5],
[2, 5],
[2, 4],
[2, 3],
[2, 2],
[3, 2],
[4, 2],
[5, 2],
[6, 2],
[6, 3],
[6, 4],
[6, 5],
[6, 6],
[5, 6],
[4, 6],
[3, 6],
[2, 6],
[1, 6],
[1, 5],
[1, 4],
[1, 3],
[1, 2],
[1, 1],
[2, 1],
[3, 1],
[4, 1],
[5, 1],
[6, 1],
[7, 1],
[7, 2],
[7, 3],
[7, 4],
[7, 5],
[7, 6],
[7, 7],
[6, 7],
[5, 7],
[4, 7],
[3, 7],
[2, 7],
[1, 7],
[0, 7],
[0, 6],
[0, 5],
[0, 4],
[0, 3],
[0, 2],
[0, 1],
[0, 0],
[1, 0],
[2, 0],
[3, 0],
[4, 0],
[5, 0],
[6, 0],
[7, 0]
]
# set them all white
for x, y in spiral_sequence:
sense.set_pixel(x, y, white)
time.sleep(0.02)
# set them all black
for x, y in spiral_sequence:
sense.set_pixel(x, y, black)
time.sleep(0.02)
# MAIN LOOP
previous=aggregate_sense_data()
alert(sense)
espeak("Ghost Box Starting up!")
show_right_side_up_message(sense, "Ghost Box!", red)
while True:
current=aggregate_sense_data()
change=abs( (current / previous) - 1.0)
if ( (percent_change_min / 100.0) < change ) :
ghost_message = get_random_line(change, filename)
# Logging output
now = datetime.now() # this will not be accurate
# unless you have either a RTC or ntp with internet
print str(now)
print ghost_message
alert(sense)
espeak(ghost_message)
show_right_side_up_message(sense, ghost_message, red)
# it takes time to display the message so no sleep is required
else:
time.sleep(rest_period_between_readings)
previous=current
@Tornnnuts
Copy link
Copy Markdown

Is there any way someone could let me know how to get the ghostbox.py to pull from the ovilus.txt library or where to put the library?

@RedRoosterKey
Copy link
Copy Markdown
Author

Copy from here https://www.digitaldowsing.com/product-guides/ovilus-v/word-list/
put it in a text file

change the filename variable to use the text file you saved.

# Put the location of your word list file here.
# The one that Digital Dousing uses is available on their website.
# https://www.digitaldowsing.com/product-guides/ovilus-v/word-list/
filename="ovilus.txt"

@Tornnnuts
Copy link
Copy Markdown

thanks for the response i am still very new at this. Do i save the ovilus.txt into documents on the raspbian? I am just confused on where to put the list of words and how i can make the program grab from that list

@Tornnnuts
Copy link
Copy Markdown

do i change filename to ovilus.txt?

@Tornnnuts
Copy link
Copy Markdown

where should i put the file once i name it? i am super new to this

@RedRoosterKey
Copy link
Copy Markdown
Author

I would just modify the script to include the full file path. You can get that by running
readlink -f ovilus.txt

Also make sure that the file is readable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment