Introduction: Etch-a-Sketch - W/Arduino & Processing
I did this one to help learn about Processing and how it integrates with Arduino.
Basically what I have is this:
An Arduino Duemilenova which is housed in an old band safe deposit box. The Arduino has 2 potentiometers attached to it. One represents the x axis and the other the y axis coordinates. I glued some red plumbing values handles to the pots . As one turns the pots, the output goes to the analog pins 0 and 1 . This is mapped to a value between 0 - 1023 for the x and y coordinates.
Then it is sent as a serial stream to the laptop which has a Processing sketch running. Physically there is a USB cable connecting the Arduino and the laptop.
This sketch maps the 0-1023 to a position on the screen and plots a point there.
BUT things are not that simple for this project;
I added 3 switches to the Arduino
1. - to allow the drawing to take place. By turning this off, one can move the point where drawing will begin. Sketches can be seperated.
2. to clear the screen . Must be careful when hitting this switch as it will erase the screen.
3. to allow for a change of color. A table of color selections comes up. By pressing the correct button on the keyboard, one can change the color.
Each of these switches sends a unique character in the serial stream when they are activated.
The Processing sketch also looks for these characters and reacts accordingly.
Also I played around with the screen size for my laptop which caused some code changes.
The code I have used is below: First the Arduino code and then the Processing code. Both the Arduino and Processinmg code started with a copy from someone else which I acknowledge in the comments . The Ardiuno is pretty simple with the pots going to analog pins 0 and 1 and each switch goes to a digital pin, either 3,5 or 7.
The Processing code is heavily modified by me to get the colors options .
Arduino:
--------------------------------------------------------
--------------------------------------------------------
Processing Code
// Etch-a-Sketch10
// by Trevor Shannon
//
// based on Graph
// by David A. Mellis
// modified by cdubois 7/2011
import processing.serial.*;
Serial port;
String buff = "";
String buff1 = "";
String buff2 = "";
String buff0 = "";
String clearScreen = "NO";
String stopDraw = "NO";
String newColor = "NO";
String moveit = "NO";
String stopit = "NO";
String firsttime = "YES";
char c = 'H'; // test for clearing
char d = 'H'; // test for drawing
int x = 0;
int y = 0;
int oldx = 0;
int oldy = 0;
int a = 0;
int index = 0;
int NEWLINE = 10;
// Store the last 10 values received so we can graph them.
int[] valuesx = new int[10];
int[] valuesy = new int[10];
// variables for color
color backg = color(0, 0, 0);
color lines = color(348,90,90);
void setup()
{
size(1023,512);
frameRate(10);
port = new Serial(this, "COM5", 9600);
// If you know the name of the port used by the Arduino board, you
// can specify it directly like this.
//port = new Serial(this, "COM1", 9600);
background(backg) ;
}
// ----------------------------------------------------------
// ------------------------------------------------------------
void draw()
{
drawlines();
movecursor();
selectcol();
checkswitches();
while (port.available() > 0)
{
serialEvent(port.read());
}
}
// ----------------------------------------------------------
// Functions
// =========================================================
// ===========================================================
void selectcol()
{
if (newColor == "YES") {
PFont font;
font = loadFont("Serif.plain-16.vlw");
textFont(font);
fill(255,255,255);
text("Select a Color", 25, 25);
fill(348,90,90);
text("Red - press R", 25, 45);
fill(237,151,12);
text("Orange - press O", 25, 65);
fill(236,237,12);
text("Yellow - press Y", 25, 85);
fill(12,237,28);
text("Green - press G", 25, 105);
fill(12,47,237);
text("Blue - press B", 25, 125);
}
else {
PFont font;
font = loadFont("Serif.plain-16.vlw");
textFont(font);
fill(0,0,0);
text("Select a Color", 25, 25);
text("Red - press R", 25, 45);
text("Orange - press O", 25, 65);
text("Yellow - press Y", 25, 85);
text("Green - press G", 25, 105);
text("Blue - press B", 25, 125);
}
}
// ============================================================
// ============================================================
// ============================================================
// ============================================================
// ============================================================
// ============================================================
// now have turned pots so want to draw lines
void drawlines() {
if (stopit == "NO") {
for (int i = 0; i < 9; i++){
stroke(lines);
strokeWeight(4);
smooth();
// point(x,y);
line(1023 - valuesx[i], 512 - valuesy[i], 1023-valuesx[i + 1], 512 - valuesy[i + 1]);
}
}
}
// ===============================================================
// ==============================================================
void serialEvent(int serial)
{
if (serial != NEWLINE) {
// Store all the characters on the line.
buff += char(serial);
}
else {
// The end of each line is marked by two characters, a carriage
// return and a newline. We're here because we've gotten a newline,
// but we still need to strip off the carriage return.
buff = buff.substring(0, buff.length()-1);
String[] list = split(buff, ',');
// read the string
// if the clear screen button was pressed, a "C" will be in
// the 4th character position
char c = buff.charAt(4);
// if no longer want to draw, an "N" will be in the first position
char d = buff.charAt(0);
// if want to erase, an "E" will be in 2nd char postion
char e = buff.charAt(2);
buff1 = list[3];
buff2 = list[4];
// have seen a N so need to stop drawing
if (d == 'N') {
stopDraw = "YES";
}
else
{
stopDraw = "NO";
}
// Clear the screen
// have seen a C so need to clear as soon as possible
if (c == 'C') {
clearScreen = "YES";
}
else
{
clearScreen = "NO";
}
// change colors
// have seen an E so need to put text in corner
// and wait for selection
if (e == 'E') {
newColor = "YES";
}
else
{
newColor = "NO";
}
// Parse the String into an integer. We divide by 4 because
// analog inputs go from 0 to 1023 while colors in Processing
// only go from 0 to 255.
x = Integer.parseInt(buff1)/1;
y = Integer.parseInt(buff2)/2;
println(x);
println(y);
// Clear the value of "buff"
buff = "";
// create an array of ten points for the line
for (int i = 0; i < 9; i++)
{
valuesx[i] = valuesx[i + 1];
valuesy[i] = valuesy[i + 1];
}
// Add the received value to the array.
valuesx[9] = x;
valuesy[9] = y;
}
}
// ================================================
// -------------------------------------------------
void movecursor()
{
// want to move to different spot
// so want to move point but want it to dissappear as it moves
if((stopit == "YES")&&(moveit == "YES")) {
// erase old point
if(a >0) {
stroke(backg);
point(oldx ,oldy );
}
// for (int i = 0; i < 9; i++){
stroke(255,255,255);
strokeWeight(4);
point(1023 - x ,512 - y );
// save location to be erased next time
//
oldx = 1023 - x;
oldy = 512 - y;
a=a+1;
}
}
// ================================================
// -------------------------------------------------
void checkswitches()
{
// now it is time to test switch changes
if ((stopDraw == "YES")&& (clearScreen == "YES")) {
stopit = "YES";
background(0);
}
// Could get here if stopDraw switch is on but not clearScreen
// ie just want to move the positioning without drawing
if ((stopDraw == "YES") && (clearScreen == "NO")) {
stopit = "YES";
moveit = "YES";
}
// if stopdraw not switched , then do nothing
if (stopDraw == "NO") {
stopit = "NO";
moveit = "NO";
}
}
// ================================================
// -------------------------------------------------
// ================================================
// -------------------------------------------------
void keyPressed()
{
// red
if (key == 'r' || key == 'R') {
lines = color(348,90,90);
}
// orange
if (key == 'o' || key == 'O') {
lines = color(237,151,12);
}
// yellow
if (key == 'y' || key == 'Y') {
lines = color(236,237,12);
}
// green
if (key == 'g' || key == 'G') {
lines = color(12,237,28);
}
// blue
if (key == 'b' || key == 'B') {
lines = color(12,47,237);
}
}
A short video of it in action follows:
Basically what I have is this:
An Arduino Duemilenova which is housed in an old band safe deposit box. The Arduino has 2 potentiometers attached to it. One represents the x axis and the other the y axis coordinates. I glued some red plumbing values handles to the pots . As one turns the pots, the output goes to the analog pins 0 and 1 . This is mapped to a value between 0 - 1023 for the x and y coordinates.
Then it is sent as a serial stream to the laptop which has a Processing sketch running. Physically there is a USB cable connecting the Arduino and the laptop.
This sketch maps the 0-1023 to a position on the screen and plots a point there.
BUT things are not that simple for this project;
I added 3 switches to the Arduino
1. - to allow the drawing to take place. By turning this off, one can move the point where drawing will begin. Sketches can be seperated.
2. to clear the screen . Must be careful when hitting this switch as it will erase the screen.
3. to allow for a change of color. A table of color selections comes up. By pressing the correct button on the keyboard, one can change the color.
Each of these switches sends a unique character in the serial stream when they are activated.
The Processing sketch also looks for these characters and reacts accordingly.
Also I played around with the screen size for my laptop which caused some code changes.
The code I have used is below: First the Arduino code and then the Processing code. Both the Arduino and Processinmg code started with a copy from someone else which I acknowledge in the comments . The Ardiuno is pretty simple with the pots going to analog pins 0 and 1 and each switch goes to a digital pin, either 3,5 or 7.
The Processing code is heavily modified by me to get the colors options .
Arduino:
/*
* Etch-a-Sketch_wswitches
*
* A simple program to read two potentiometers connected to analog 0 and 1, interpret them as an ordered pair (x,y)
* and send them via serial to the computer
*
* based on Graph: http://www.arduino.cc/en/Tutorial/Graph
* 7/2011 - modified by cdubois
*/
#include <Stdio.h>
// for pots
int xCoord;
int yCoord;
char coords[10];
// for switches
// variables for input pin and control LED
// input 7 is to clear screen
// input 3 is to begin drawing again
// input 5 is to change color
int digitalInput3 = 3; // draw
int digitalInput5 = 5; // change color
int digitalInput7 = 7; // clear
int LEDpin = 13;
// variable to store the value
int value3 = '0';
int value5 = '0';
int value7 = '0';
void setup()
{
// declare pin modes
pinMode(digitalInput3,OUTPUT);
pinMode(digitalInput5,OUTPUT);
pinMode(digitalInput7,OUTPUT);
pinMode(LEDpin,OUTPUT);
Serial.begin(9600);
}
void loop()
{
// read the value on digital input
value3 = digitalRead(3);
// write this value to the control LED pin
digitalWrite(LEDpin,value3);
// switch to draw is checked
// if the value6 is high then send the letter "Y" else send "N"
// Serial.print(value3);
if (value3 ){
Serial.print("Y," );
}
else
{
Serial.print("N," );
}
// switch to change color is checked
// if the value6 is high then send the letter "E" else send "N"
value5 = digitalRead(5);
if (value5 ){
Serial.print("E," );
}
else
{
Serial.print("N," );
}
value7 = digitalRead(7);
// switch to clear screen is checked
// Serial.print (value7);
if (value7 ){
Serial.print("C," );
}
else
{
Serial.print("L," );
}
xCoord = analogRead(0);
yCoord = analogRead(1);
sprintf(coords, "%d,%d", xCoord, yCoord);
Serial.println(coords);
// delay(5);
}
* Etch-a-Sketch_wswitches
*
* A simple program to read two potentiometers connected to analog 0 and 1, interpret them as an ordered pair (x,y)
* and send them via serial to the computer
*
* based on Graph: http://www.arduino.cc/en/Tutorial/Graph
* 7/2011 - modified by cdubois
*/
#include <Stdio.h>
// for pots
int xCoord;
int yCoord;
char coords[10];
// for switches
// variables for input pin and control LED
// input 7 is to clear screen
// input 3 is to begin drawing again
// input 5 is to change color
int digitalInput3 = 3; // draw
int digitalInput5 = 5; // change color
int digitalInput7 = 7; // clear
int LEDpin = 13;
// variable to store the value
int value3 = '0';
int value5 = '0';
int value7 = '0';
void setup()
{
// declare pin modes
pinMode(digitalInput3,OUTPUT);
pinMode(digitalInput5,OUTPUT);
pinMode(digitalInput7,OUTPUT);
pinMode(LEDpin,OUTPUT);
Serial.begin(9600);
}
void loop()
{
// read the value on digital input
value3 = digitalRead(3);
// write this value to the control LED pin
digitalWrite(LEDpin,value3);
// switch to draw is checked
// if the value6 is high then send the letter "Y" else send "N"
// Serial.print(value3);
if (value3 ){
Serial.print("Y," );
}
else
{
Serial.print("N," );
}
// switch to change color is checked
// if the value6 is high then send the letter "E" else send "N"
value5 = digitalRead(5);
if (value5 ){
Serial.print("E," );
}
else
{
Serial.print("N," );
}
value7 = digitalRead(7);
// switch to clear screen is checked
// Serial.print (value7);
if (value7 ){
Serial.print("C," );
}
else
{
Serial.print("L," );
}
xCoord = analogRead(0);
yCoord = analogRead(1);
sprintf(coords, "%d,%d", xCoord, yCoord);
Serial.println(coords);
// delay(5);
}
--------------------------------------------------------
--------------------------------------------------------
Processing Code
// Etch-a-Sketch10
// by Trevor Shannon
//
// based on Graph
// by David A. Mellis
// modified by cdubois 7/2011
import processing.serial.*;
Serial port;
String buff = "";
String buff1 = "";
String buff2 = "";
String buff0 = "";
String clearScreen = "NO";
String stopDraw = "NO";
String newColor = "NO";
String moveit = "NO";
String stopit = "NO";
String firsttime = "YES";
char c = 'H'; // test for clearing
char d = 'H'; // test for drawing
int x = 0;
int y = 0;
int oldx = 0;
int oldy = 0;
int a = 0;
int index = 0;
int NEWLINE = 10;
// Store the last 10 values received so we can graph them.
int[] valuesx = new int[10];
int[] valuesy = new int[10];
// variables for color
color backg = color(0, 0, 0);
color lines = color(348,90,90);
void setup()
{
size(1023,512);
frameRate(10);
port = new Serial(this, "COM5", 9600);
// If you know the name of the port used by the Arduino board, you
// can specify it directly like this.
//port = new Serial(this, "COM1", 9600);
background(backg) ;
}
// ----------------------------------------------------------
// ------------------------------------------------------------
void draw()
{
drawlines();
movecursor();
selectcol();
checkswitches();
while (port.available() > 0)
{
serialEvent(port.read());
}
}
// ----------------------------------------------------------
// Functions
// =========================================================
// ===========================================================
void selectcol()
{
if (newColor == "YES") {
PFont font;
font = loadFont("Serif.plain-16.vlw");
textFont(font);
fill(255,255,255);
text("Select a Color", 25, 25);
fill(348,90,90);
text("Red - press R", 25, 45);
fill(237,151,12);
text("Orange - press O", 25, 65);
fill(236,237,12);
text("Yellow - press Y", 25, 85);
fill(12,237,28);
text("Green - press G", 25, 105);
fill(12,47,237);
text("Blue - press B", 25, 125);
}
else {
PFont font;
font = loadFont("Serif.plain-16.vlw");
textFont(font);
fill(0,0,0);
text("Select a Color", 25, 25);
text("Red - press R", 25, 45);
text("Orange - press O", 25, 65);
text("Yellow - press Y", 25, 85);
text("Green - press G", 25, 105);
text("Blue - press B", 25, 125);
}
}
// ============================================================
// ============================================================
// ============================================================
// ============================================================
// ============================================================
// ============================================================
// now have turned pots so want to draw lines
void drawlines() {
if (stopit == "NO") {
for (int i = 0; i < 9; i++){
stroke(lines);
strokeWeight(4);
smooth();
// point(x,y);
line(1023 - valuesx[i], 512 - valuesy[i], 1023-valuesx[i + 1], 512 - valuesy[i + 1]);
}
}
}
// ===============================================================
// ==============================================================
void serialEvent(int serial)
{
if (serial != NEWLINE) {
// Store all the characters on the line.
buff += char(serial);
}
else {
// The end of each line is marked by two characters, a carriage
// return and a newline. We're here because we've gotten a newline,
// but we still need to strip off the carriage return.
buff = buff.substring(0, buff.length()-1);
String[] list = split(buff, ',');
// read the string
// if the clear screen button was pressed, a "C" will be in
// the 4th character position
char c = buff.charAt(4);
// if no longer want to draw, an "N" will be in the first position
char d = buff.charAt(0);
// if want to erase, an "E" will be in 2nd char postion
char e = buff.charAt(2);
buff1 = list[3];
buff2 = list[4];
// have seen a N so need to stop drawing
if (d == 'N') {
stopDraw = "YES";
}
else
{
stopDraw = "NO";
}
// Clear the screen
// have seen a C so need to clear as soon as possible
if (c == 'C') {
clearScreen = "YES";
}
else
{
clearScreen = "NO";
}
// change colors
// have seen an E so need to put text in corner
// and wait for selection
if (e == 'E') {
newColor = "YES";
}
else
{
newColor = "NO";
}
// Parse the String into an integer. We divide by 4 because
// analog inputs go from 0 to 1023 while colors in Processing
// only go from 0 to 255.
x = Integer.parseInt(buff1)/1;
y = Integer.parseInt(buff2)/2;
println(x);
println(y);
// Clear the value of "buff"
buff = "";
// create an array of ten points for the line
for (int i = 0; i < 9; i++)
{
valuesx[i] = valuesx[i + 1];
valuesy[i] = valuesy[i + 1];
}
// Add the received value to the array.
valuesx[9] = x;
valuesy[9] = y;
}
}
// ================================================
// -------------------------------------------------
void movecursor()
{
// want to move to different spot
// so want to move point but want it to dissappear as it moves
if((stopit == "YES")&&(moveit == "YES")) {
// erase old point
if(a >0) {
stroke(backg);
point(oldx ,oldy );
}
// for (int i = 0; i < 9; i++){
stroke(255,255,255);
strokeWeight(4);
point(1023 - x ,512 - y );
// save location to be erased next time
//
oldx = 1023 - x;
oldy = 512 - y;
a=a+1;
}
}
// ================================================
// -------------------------------------------------
void checkswitches()
{
// now it is time to test switch changes
if ((stopDraw == "YES")&& (clearScreen == "YES")) {
stopit = "YES";
background(0);
}
// Could get here if stopDraw switch is on but not clearScreen
// ie just want to move the positioning without drawing
if ((stopDraw == "YES") && (clearScreen == "NO")) {
stopit = "YES";
moveit = "YES";
}
// if stopdraw not switched , then do nothing
if (stopDraw == "NO") {
stopit = "NO";
moveit = "NO";
}
}
// ================================================
// -------------------------------------------------
// ================================================
// -------------------------------------------------
void keyPressed()
{
// red
if (key == 'r' || key == 'R') {
lines = color(348,90,90);
}
// orange
if (key == 'o' || key == 'O') {
lines = color(237,151,12);
}
// yellow
if (key == 'y' || key == 'Y') {
lines = color(236,237,12);
}
// green
if (key == 'g' || key == 'G') {
lines = color(12,237,28);
}
// blue
if (key == 'b' || key == 'B') {
lines = color(12,47,237);
}
}
A short video of it in action follows: