//https://www.instructables.com/id/Capacitive-Sensing-for-Dummies/
//https://www.arduino.cc/en/Tutorial/Smoothing
//https://howtomechatronics.com/tutorials/arduino/how-to-use-a-rgb-led-with-arduino/
#include <CapacitiveSensor.h>
// how to install libraries https://learn.sparkfun.com/tutorials/installing-an-arduino-library
// download capsense lib here https://playground.arduino.cc/Main/CapacitiveSensor/
//send at pin 3, receive at pin 4, 1-10M ohm resistor between
CapacitiveSensor cs_3_4 = CapacitiveSensor(3, 4); // 1-10 megohm resistor between pins 4 & 3, pin 3 is sensor pin, add wire, foil
const int numReadings = 10; // size of array/number of readings to keep track of (higher = slower)
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int brightness = 0; // initialize delay time at 0
//int ledPin = 11;
int newAverage = 0; //store values after mapping
int redPin= 11;
int greenPin = 12;
int bluePin = 13;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
// initialize serial communication with computer:
SerialUSB.begin(9600); //start serial communication via USB cable
cs_3_4.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate on channel 1 - just as an example Serial.begin(9600);
//initatialize readings array setting all values to 0
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
void loop() {
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = cs_3_4.capacitiveSensor(30);
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...wrap around to the beginning
if (readIndex >= numReadings) {
readIndex = 0;
}
// calculate the average:
average = total / numReadings;
// map the average value to the min and max we recorded above
newAverage = map(average, 0, 65, 0, 255);
//set brightness of LED to sensorValue (between 0-255)
// analogWrite(ledPin, newAverage);
if (newAverage <= 85) {
setColor(255, 0, 0); // Red Color
}
else if (newAverage > 85 && newAverage <= 170) {
setColor(0, 255, 0); // Green Color
}
else if (newAverage > 170) {
setColor(0, 0, 255); // Blue Color
}
SerialUSB.print("Old Value = ");
SerialUSB.print(average);
SerialUSB.print("\t"); // add a tab between the numbers
SerialUSB.print("New Value = ");
SerialUSB.println(newAverage);
delay(10); // arbitrary delay to limit data to serial port
}
void setColor(int redValue, int greenValue, int blueValue) {
analogWrite(redPin, redValue);
analogWrite(greenPin, greenValue);
analogWrite(bluePin, blueValue);
}
Drawing with Capacitive Sensor in Processing
I wanted to start of easy since it is my first time writing code in Processing. First I started building a circuit using a LDR, that was what the example code provided by the minor uses.
Inspiration
After looking at more and more tutorials I wanted to be able to create a painting or drawing with the sensor. Lots of Processing tutorials showed examples of being able to draw with your mouse, using the x- and y-axis of the mouse position. The YouTube channel thedotisblack creative coding has some cool examples.
At first I chose to recreate this video from thedotisblack creative coding. I'm not that advanced in coding so I searched for some tutorials. Bu while searching for tutorials I stumbled upon a nice example from Processing. When I saw this example I decided it was a better idea to use this and just change a few lines of code, to make it fit in with the swatches. The benefit from the example was that I didn't have to start from scratch. And another benefit was that the drawing is never finished, thats something the first idea didn't have. The idea that I wanted to try and recreate from the video had to be started over again if the canvas was filled.
Code from Processing example
Pointillism by Daniel Shiffman.
PImage img;
int smallPoint, largePoint;
void setup() {
size(640, 360);
img = loadImage("moonwalk.jpg");
smallPoint = 4;
largePoint = 40;
imageMode(CENTER);
noStroke();
background(255);
}
void draw() {
float pointillize = map(mouseX, 0, width, smallPoint, largePoint);
int x = int(random(img.width));
int y = int(random(img.height));
color pix = img.get(x, y);
fill(pix, 128);
ellipse(x, y, pointillize, pointillize);
}
Setup
I used a Seeeduino Lotus Cortex M0+ instead of a Arduino Uno.
Changing window size
The first thing I did was change the of the window. I wanted the window to be full screen. So I deleted the line size(600, 600); to fullScreen();.
As seen in the image above the dots were only appear in a box the exact same size as the original image used to pick the colors. So it treats the image as a canvas.
Resizing image to window size
Because the dots only appear in the image size I simply needed to resize the image to the whole window size. img.resize(width,height);
To make the output fit in with the others. I had to make two changes, use another picture with copper colors and use rectangles instead of ellipses to make a drawing. Both simple changes, I only had to change this line of code ellipse(x, y, pointillize, pointillize); to rect(x, y, pointillize, pointillize); and search a picture with nice black and copper colors.
Before swapping the ellipses to squares I thought I wouldn't like the squares as much as the ellipses.
End result
When seeing one of my classmates, Andrei, designs in Process I realized that my full screen design wasn't making it fit in with the other outputs. Thats when I chose to resize it to a square just like Andrei did.
So I swapped fullScreen(); back to size(600, 600); to make the window a square.
In the beginning of the week I ordered some 1M ohm resistances at tinytronics.nl. Unfortunately they haven't arrived yet. That's why I couldn't use my own capacitive sensor from week 6, because I didn't have any 1M ohm resistance to get some nice values out of my sensor.
Final code
Arduino IDE
//ARDUINO CODE FOR ANALOG SENSOR
int sensorValue = 0;
void setup() {
SerialUSB.begin(9600); //needs to match processing baudrate
}
void loop() {
//SerialUSB.println(analogRead(A0)); // for debugging only
sensorValue = analogRead(A0); // store value in sensorValue
SerialUSB.write(map(sensorValue, 0,1023,255,0)); // map to processing range
delay(50);
}
Processing
/*
DRAWING WITH CAPACITIVE SENSOR by Kaz Bison
Recources:
https://hello.processing.org/editor/ <- Nice for understanding the basics of Processing
https://processing.org/examples/pointillism.html <- Processing example I used
*/
import processing.serial.*;
Serial myPort;
int dataInput;
PImage img;
int smallPoint, largePoint;
void setup() {
println(Serial.list()); //use to find list of your port addresses
String portName = "/dev/cu.usbmodem141101"; //change to your own port address! (Arduino: Tools > Port)
myPort = new Serial(this, portName, 9600); //needs to match arduino baudrate
size(600, 600); // window size 600 x 600 px
img = loadImage("copper-on-black-pattern.jpg"); //image source (I removed the bottom part): https://cdn2.vectorstock.com/i/1000x1000/09/01/copper-rose-gold-foil-florals-on-black-pattern-vector-22540901.jpg
img.resize(width,height);
smallPoint = 4;
largePoint = 40;
noStroke();
background(255);
}
void draw() {
float pointillize = map(dataInput*20+70, 0, width, smallPoint, largePoint);
int x = int(random(width));
int y = int(random(height));
color pix = img.get(x, y);
fill(pix, 128); //uses color for ellipse from picture
rect(x, y, pointillize, pointillize);
println(dataInput); // data sent from Arduino in console
}
void serialEvent(Serial myPort) {
dataInput = myPort.read();
}
Reflection
Looking at the work of the classmates, at the show and tell, I'm able to notice some of the flaws in my design I didn't think of before. It's nice to have some fresh eyes and feedback at the show and tell, to improve my work.
I also noticed that I enjoyed coding in Processing.