8 | Untoolkit: Electronic Outputs

Zine

Capacitive sensor + RGB LED

//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);

Swapping mouse position with sensor values

float pointillize = map(mouseX, 0, width, smallPoint, largePoint);
float pointillize = map(dataInput, 0, width, smallPoint, largePoint);

Fitting in with the other outputs

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.

Last updated