Coding
The software used for coding are VSCode for building the site, Arduino IDE for programming the boards and Processing for interfacing and networking.
In order to program the FabDuino, I decided in
week 16 to get started and learning how to connect Arduino IDE with Processing.
Through testing and looking at existing sketches, I was able to use the Arduino Capacitive Sensor library, the Serial library to interface with Processing.
Coding the sensors
In order to assign the controller pin and the sensor pin I used the A1 pin for sending en digital pin 5-10 for recieving.
The naming convention, I left at default. CapacitiveSensorC_x_x = CapacitiveSensor(x,x)
CapacitiveSensor cs_A1_5 = CapacitiveSensor(A1, 5); // 10M resistor between pins A1 & 5, pin A1 is send pin, pin 5 is sensor pin
CapacitiveSensor cs_A1_6 = CapacitiveSensor(A1, 6);
CapacitiveSensor cs_A1_7 = CapacitiveSensor(A1, 7);
CapacitiveSensor cs_A1_8 = CapacitiveSensor(A1, 8);
CapacitiveSensor cs_A1_9 = CapacitiveSensor(A1, 9);
CapacitiveSensor cs_A1_10 = CapacitiveSensor(A1, 10);
Initialization of the sensors. Though I now understand that it only can be written once, for cleaner code, I made it simple and defined each sensor individually.
void setup()
{
cs_A1_5.set_CS_AutocaL_Millis(0xFFFFFFFF); //Calibrate the sensor...
cs_A1_6.set_CS_AutocaL_Millis(0xFFFFFFFF);
cs_A1_7.set_CS_AutocaL_Millis(0xFFFFFFFF);
cs_A1_8.set_CS_AutocaL_Millis(0xFFFFFFFF);
cs_A1_9.set_CS_AutocaL_Millis(0xFFFFFFFF);
cs_A1_10.set_CS_AutocaL_Millis(0xFFFFFFFF);
Serial.begin(115200);
}
In order to define the threshold, samples and debounce of the sensors I used the #define
component to give the names to constants.
For the threshold I defined it as total
, which is given in the tutrial
here.
The other were named sensor
and replay
.
With these constants I could calibrate the sensitivity of the sensors. TBH I thouhgt at first that I needed to define the threshold with the set_CS_AutocaL_Millis, but after looking it up, I realised the #define
was what I was looking for.
For the loop, I used the datatype long capacitiveSensor(byte samples)
in order to sense or unsense the capacitance. The control structures if, else
are used to read the states
of the thresholds and the boolean operators >, ==, &&
for comparing the values.
Do note that short int
is used for debouncing purposes.
int state = HIGH;
boolean yes1;
boolean previous1 = false;
boolean yes2;
boolean previous2 = false;
boolean yes3;
boolean previous3 = false;
boolean yes4;
boolean previous4 = false;
boolean yes5;
boolean previous5 = false;
boolean yes6;
boolean previous6 = false;
short int a = 1, a1 = 0, b = 1, b1 = 0, c = 1, c1 = 0, d = 1, d1 = 0, e = 1, e1 = 0, f = 1, f1 = 0, g = 1, g1 = 0, h = 1, h1 = 0, i = 1, i1 = 0, j = 1, j1 = 0; //for debounce purpose
void loop()
{
long total1 = cs_A1_5.capacitiveSensor(sensor);
long total2 = cs_A1_6.capacitiveSensor(sensor);
long total3 = cs_A1_7.capacitiveSensor(sensor);
long total4 = cs_A1_8.capacitiveSensor(sensor);
long total5 = cs_A1_9.capacitiveSensor(sensor);
long total6 = cs_A1_10.capacitiveSensor(sensor);
if (total1 > total) {yes1 = true;}
else {yes1 = false;}
if (total2 > total) {yes2 = true;}
else {yes2 = false;}
if (total3 > total) {yes3 = true;}
else {yes3 = false;}
if (total4 > total) {yes4 = true;}
else {yes4 = false;}
if (total5 > total) {yes5 = true;}
else {yes5 = false;}
if (total6 > total) {yes6 = true;}
else {yes6 = false;}
if (yes1 == true && previous1 == false && e)
{
The part for reading and prinnting to serial is defined here.
if (state == LOW) {
state = HIGH;
}
else
state = LOW;
a = 0;
a1 = 0;
// Serial.print(total1);
// Serial.print("\t");
Serial.println('e');
}
if (yes1 == false && previous1 == false)
a1++;
else
a1 = 0;
if (a1 == replay)
{
a = 1;
a1 = 0;
}
The Serial.println
gives a variable corresponding the E2 tone of the guitar tuning, made so to make it easier to read.
This piece of code is then repeated for the A2, D3, G3, B3 and E4 (which i called f in the serial line print).
Processing
As stated in Week 16 I used simple methods to draw simple grpahics and used the serial read to read the data created by the sensors and play a WAV sound.
In order to achieve this, I imported the MINI-M and serial library. Defined the WAV files and created a "data" folder , containing the WAV files.
The
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;
import ddf.minim.signals.*;
import ddf.minim.spi.*;
import ddf.minim.ugens.*;
import processing.serial.*;
Minim minim;
AudioPlayer E2;
AudioPlayer A2;
AudioPlayer D3;
AudioPlayer G3;
AudioPlayer B3;
AudioPlayer E4;
Serial myPort; // Create object from Serial class
String val; // Data received from the serial port
int r=0;
int m=1;
void setup()
{
minim = new Minim(this);
E2 = minim.loadFile("acoustic1_e2.wav");
A2 = minim.loadFile("acoustic2_a2.wav");
D3 = minim.loadFile("acoustic3_d3.wav");
G3 = minim.loadFile("acoustic4_g3.wav");
B3 = minim.loadFile("acoustic5_b3.wav");
E4 = minim.loadFile("acoustic6_e4.wav");
String portName = "COM5"; //Change COM to the port number that your Arduino is connected, you can check the port number from arduino program.
myPort = new Serial(this, portName, 115200);
size(160, 160);
background(0);
}
void draw()
{
if ( myPort.available() > 0 )
{ // If data is available,
val = myPort.readStringUntil('\n');
if(val!=null)
{print(val);
if(val.charAt(0)=='e')
{
E2.rewind();
E2.play();
fill(0, 0, 0);
rect(0, 0, 160, 160);
fill(255, 255, 255);
textAlign(CENTER);
textSize(50);
text("E2", 80, 90);
}
The void draw()
is repeated for every note.
Here are the test results:
Testing it with the Arduino Mega 2560.