CSC270 Team 2 project 2019
Isabelle Hodge and Jenny Baran's Color Theremin
Contents
Proposal - 2019-04-16
Overview
The Goal: an interactive device that allows observers to set R, G, and B levels and then see the resulting color. More advanced versions of the project could also return a picture with that color or complementary colors.
At the moment, we are considering having the RGB input come from three photoresistors that viewers can interact with by moving their hands close to and away from the device. This would allow our project to meet the museum standard, in that viewers would be interacting with it through the glass.
Plan of Attack
- Wire up photoresistors and RGB LED to Arduino.
- Take input from photoresistors and display values as an RGB coded color on the LED.
- Send input values from Arduino to Raspberry Pi
- Run through Colblindor Color Name & Hue tool, output color name to command line.
- Display Google image search results for "[color name] color" on monitor.
Look of Final Project
We will have three photocells set up at some distance from each other so that each can be controlled separately. This can be done with mini breadboards and long wires to the Arduino, which might need some kind of secure case to hold it. The Raspberry Pi has its own case, and so can simply be hooked up to a monitor.
Tests
We will need to run a lot of tests as we calibrate the sensitivity of the photocell sensors. While working on this, we will output the received RGB values to the Serial Monitor, and send them to the RBG LED for a visual representation of our work.
The Project
Materials
3mm CdS photosensitive resistors (3)
To measure the varying resistance created by the photocell with one of the Arduino’s analog pins, we combine it with a fixed resistor and take the voltage between the two.
5mm RGB LED
RGB LEDs can be either cathode or anode types. This project used a cathode type, which has leads as shown below. An anode type would look very similar, but instead of connecting the cathode lead to GND, the anode lead would be connected to 5V.
Arduino MEGA 2560
Dell UltraSharp 1703FP Monitor
Connected to the Raspberry Pi with an HDMI cable.
Raspberry Pi 3 Model B+
In order to program the Raspberry Pi, it's important to know which physical pin numbers match up to which pin numbers in C or Python.
Hardware Setup
We have three photocells providing input to the Arduino, and one RGB LED displaying the generated color (as output from the Arduino). The Arduino is then connected to the Raspberry Pi using a USB-to-Serial cord, and the Raspberry Pi is connected to a monitor using an HDMI cable.
The diagram below shows only a subset of the pins on the Arduino and Raspberry Pi, for the sake of clarity.
Languages & Libraries
- Language: C, Python
- Libraries: kturtle, turtleart (both of these were installed with
$ sudo apt-get install [x]
)
Arduino Code
// Jenny Baran and Isabelle Hodge
// 2019-05-06
// Sponge Pass
// This program reads RGB values from the photocells, and passes
// the values to the Rasberry Pi using USB-to-serial communication.
// pins
const int R_resistor = A1; // photoresistor at Arduino analog pin A1
const int G_resistor = A2; // photoresistor at Arduino analog pin A2
const int B_resistor = A3; // photoresistor at Arduino analog pin A3
const int R_ledPin = 10; // LED pin at Arduino pin 10
const int G_ledPin = 11; // LED pin at Arduino pin 11
const int B_ledPin = 12; // LED pin at Arduino pin 12
// values
byte R_value; // stores value from photoresistor (0-1023)
byte G_value;
byte B_value;
void setup(){
Serial.begin( 9600 );
pinMode( R_ledPin, OUTPUT );
pinMode( G_ledPin, OUTPUT );
pinMode( B_ledPin, OUTPUT );
pinMode( R_resistor, INPUT );
pinMode( G_resistor, INPUT );
pinMode( B_resistor, INPUT );
}
void setColor(int red, int green, int blue) {
analogWrite(R_ledPin, red);
analogWrite(G_ledPin, green);
analogWrite(B_ledPin, blue);
}
void loop(){
R_value = 255 - ( analogRead( R_resistor ) / 4 ); // adjust to 0-257 scale
G_value = 255 - ( analogRead( G_resistor ) / 4 );
B_value = 255 - ( analogRead( B_resistor ) / 4 );
setColor( R_value, G_value, B_value);
Serial.write( R_value );
Serial.write( G_value );
Serial.write( B_value );
delay(1000); //delay for readability
}
Raspberry Pi Code
Python code for serial communication with Arduino
Run with:
$ python3 spongePass.py
This must be run with Python 3, because the int.from_bytes()
command is new in Python 3.
# Jenny Baran and Isabelle Hodge
# 2019-04-25
# Color Display
# This program reads RGB values from numbered text files and displays circles
# of the retreived color and random size.
# Heavily sourced from https://projects.raspberrypi.org/en/projects/modern-art
#!/bin/python3
from turtle import *
from random import *
import time
import os
currentFile = 0
RGB = ["0", "0", "0"]
setup( width=1.0, height=1.0, startx=0, starty=0 )
screensize( 1000,1000 )
# sets current color
def setColor(R, G, B):
colormode(255)
red = R
green = G
blue = B
color(red, green, blue)
# randomly sets a location
def randomplace():
penup()
x = randint(-500, 500)
y = randint(-500, 500)
goto(x, y)
pendown()
# draws a circle of current color in a random place, at a random size
def drawcircle(R, G, B):
radius = randint(10, 100)
setColor(R, G, B)
randomplace()
dot(radius)
# hides turtle pointer
hideturtle()
while( True ):
# generates current filename + path
filename = "/home/pi/final_project/text/" + str(currentFile) + ".txt"
try:
f = open( filename, "r" )
# pulls RGB values from file
contents = f.read().strip()
RGB = contents.split(" ")
f.close()
# removes last used file
os.remove( filename )
except:
# leave previous RGB values and keep running
print( "python got ahead of c" )
# decrement file number (so we look at x again next time instead
# of moving on to x+1)
currentFile -= 1
# set RGB values based on what was pulled from file
R = int( RGB[0] )
G = int( RGB[1] )
B = int( RGB[2] )
drawcircle(R, G, B)
time.sleep(0.25)
# ready for next file
currentFile += 1
Bash code for automatically running programs on startup
We largely followed the Auto Running Programs-GUI tutorial.
To edit the autostart file we used the following command: $ sudo emacs /etc/xdg/lxsession/LXDE-pi/autostart
We then add the following lines to run two bash scripts:
@/home/pi/final_project/bash/run_sponge.sh & @/home/pi/final_project/bash/run_color.sh &
run_sponge.sh:
#!/bin/bash
/bin/sleep 10
/usr/bin/python3 /home/pi/final_project/python/spongePass.py &>> /home/pi/log_sponge.txt
run_color.sh:
#!/bin/bash
/bin/sleep 20
/usr/bin/python3 /home/pi/final_project/python/colorDisplay.py &>> /home/pi/log_color.txt
Progress Log
2019-04-11 Update:
Objective: Brainstorm project ideas and settle on a particular direction.
We immediately found a common interest in making a color based project. We are also interested in basing the controls of our device on the theremin, an instrument that plays music by sensing the musicians hand position and distance from the machine. Our project would take in RGB values based on the distance of someone’s hands to the device.
2019-04-16 Update:
Objective: Build and begin testing RGB sensor
Using the Arduino, a RGB LED, and three photoresistor set ups, we successfully used the photoresistors to adjust the color of the LED. We ran into issues where the LED was taking in too much light, so the LED adds more of a color the less light the correlating photoresistor receives. So far we've wired the Arduino up correctly but need to work on photocell sensitivity. We're going to try swapping resistors.
2019-04-18 Update:
Objective: Transmit color data to Raspberry Pi
Today we approached two elements of your project: the data transfer to the Raspberry Pi and the final graphic display of the input colors. Using a serial receiver-sender setup based on Lab 8 (a two Arduino set up) we successfully saw the transfer of our RGB values to the RPi. Because the values send in a continues stream, we needed a stop and start bit to help the RPi know which value it was receiving. We chose 0 because it is almost impossible for the photoresistors to take in no light at all. We also found a fun simple Python graphic program called “Modern Art” that displayed random colors in various shapes. We decided to use part of this code, changing it to display circles in the colors sent by the Arduino.
2019-04-23 Update:
Objective: Transform values sent by a C program into a form readable by a Python program.
Because our graphics program was in python, we knew we needed a way to read our Arduino sent values. We decided to create a c program called “sponge pass” that would read the RGB values into a txt file that could then be read by the python program. The name sponge pass came from the elementary school relay game where a line of children pass a soaked sponge with the intention of retaining the water and filling a bucket at the end of the line. We had to slow the bod rate to 1200 to account for the overhead in the code, but eventually it successfully passed a text file of values.We have the Arduino code and Arduino/Raspberry Pi communication working. Our next step might be having the Raspberry Pi C code call the Python art program, passing RGB values as arguments.
2019-04-25 Update:
Objective: Put all the pieces together
As we combined our RPi, Arduino, monitor and code, we noticed the colors reflected on the screen did not match the color covered by the user. Many of our text files appear to be taking in incorrect values or the start and stop bits rather than the sent value. After many tests and a visit with Professor Thiebaut we came to the conclusion that our program had too much overhead and the serial bit connection we were using would not be able to keep up with the information being sent. It was unfortunate to learn this so soon before the demonstration, so we also decided we would need to present what we had even if the color communication was not entirely correct. We opted to avoid calling the Python program from the C program by having the C program write RGB values to numbered files. The Python program then reads the values and deletes each file.
2019-04-30 Update:
Objective: Present
We presented our work so far and discussed how we intended to fix the problem: switching from the RX TX pins to transfer data bit by bit, to a Serial to USB cord connection.
2019-05-06 Update:
Objective: Switch to a USB-to-Serial cord data transfer and implement start on reboot
Switching transfer methods required rewriting the sponge pass as a Python program, and after a few hiccups, we did so successfully. We also began implementing start on reboot. By writing a bash command to run the program we thought we had the solution, however, although the graphics window pulled up and began creating circles, spongePass would fail and not transfer the color information. We thought there might be a timing or Arduino issue, when the system rebooted the Arduino would sometimes lose power which could have been throwing the spongePass program off, however, we did not have a way to check the results beyond seeing that no new txt files were added while the programs were running.
2019-05-07 Update:
Objective: Troubleshoot Reboot
Today we met with Professor Thiebaut and discovered the text files were being written to a different location than the graphics generator expected. By changing the text file read and write commands we were able to fix the problem and successfully watch the correct colors be reflected by a rebooted color theremin.
References
- A guide for controlling an RGB LED from the Arduino.
- A tutorial for running programs in the GUI automatically after startup.
- Slides from in-class presentation.
How to Use a Photoresistor (or Photocell) - Arduino Tutorial
- A simple tutorial for using the photoresistor as an input device.
- A project that creates "computer generated modern art" with the Raspberry Pi.
- A reference for wiring RX and TX on the Raspberry Pi.
- A project that uses ultrasonic distance sensors to create a theremin.
- Documentation that explains scheduling a program to run on reboot.
USB-to-Serial Communication Between Arduino and Raspberry Pi
- A guide for using a USB-to-Serial cord to communicate between the Arduino and Raspberry Pi.