Changes to integrate Week 3 Project:
I attempted to modify the circuit and include 2 switches, each switch sending one of the rhythms to one of the 2 additional LEDs according to the value of the potentiometer. I only kept 3 of the original rhythms and varied their speed so that they are more clearly distinguishable.
The schematics for the new circuit:
The code:
I wrote the rhythm sequences as functions in order to make reading the code easier and not having to paste them into every command I used them for.
//Program objectives:
//Use a series circuit of LEDs to generate 3 different rhythms,
1 going at a faster pace to allow easy distinction
//Vary the order of rhythms playing using a switch.
When the switch is on, mix up the order.
//Using another switch, play one of the rhythms
on an additional LED when the switch is on.
//The reading from a potentiometer dictates
which rhythm will play on the additional LED.
int yellow_switch = digitalRead(11); //initialize switches
int blue_switch = digitalRead(12);
int pot_meter = analogRead(A0); //initialize potentiometer
void setup() {
Serial.begin(9600);
pinMode(2, OUTPUT); //Declare output pins. Declare input pins for quick remembrance.
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(8, OUTPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
}
void loop() {
// set up conditions for green and red switch
// change potentiometer to call functions
// for loop to change return from red/green switch condition
int pot_meter = analogRead(A0);
Serial.println(pot_meter);
//int yellow_switch = digitalRead(11);
//int blue_switch = digitalRead(12);
if (yellow_switch == HIGH) {
/*digitalWrite(8, HIGH); //test red switch
delay(400);
digitalWrite(8, LOW);
delay(400);*/
for (int counter = 3; counter > 0; counter --) {
transfer_rhythms(8); //play rhythm on red LED 3 times
}
}
else if (blue_switch == HIGH) {
/*digitalWrite(9, HIGH);
delay(400);
digitalWrite(9, LOW);
delay(400);*/
rumba();
soukous();
clave_son();
}
else {
rumba();
clave_son();
soukous();
}
}
//functions make it easier to pass rhythms
to conditional statements in main loop
//intervals for 3 distinct rhythms
void clave_son() {
digitalWrite(2, HIGH);
delay(200);
digitalWrite(2, LOW);
delay(400);
digitalWrite(3, HIGH);
delay(200);
digitalWrite(3, LOW);
delay(400);
digitalWrite(4, HIGH);
delay(200);
digitalWrite(4, LOW);
delay(600);
digitalWrite(5, HIGH);
delay(200);
digitalWrite(5, LOW);
delay(200);
digitalWrite(6, HIGH);
delay(200);
digitalWrite(6, LOW);
delay(600);
}
void rumba() {
digitalWrite(2, HIGH);
delay(200);
digitalWrite(2, LOW);
delay(400);
digitalWrite(3, HIGH);
delay(200);
digitalWrite(3, LOW);
delay(600);
digitalWrite(4, HIGH);
delay(200);
digitalWrite(4, LOW);
delay(400);
digitalWrite(5, HIGH);
delay(200);
digitalWrite(5, LOW);
delay(200);
digitalWrite(6, HIGH);
delay(200);
digitalWrite(6, LOW);
delay(600);
}
void soukous() {
digitalWrite(2, HIGH);
delay(50);
digitalWrite(2, LOW);
delay(100);
digitalWrite(3, HIGH);
delay(50);
digitalWrite(3, LOW);
delay(100);
digitalWrite(4, HIGH);
delay(50);
digitalWrite(4, LOW);
delay(150);
digitalWrite(5, HIGH);
delay(50);
digitalWrite(5, LOW);
delay(10);
digitalWrite(6, HIGH);
delay(50);
digitalWrite(6, LOW);
delay(200);
}
int transfer_rhythms(int led) {
if (0 < pot_meter && pot_meter < 350) {
//varying the value of the reading from potentiometer
decides which rhythm to play on red LED
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(100);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(100);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(150);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(50);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(150);
}
else if (350 < pot_meter && pot_meter < 750) {
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(100);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(150);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(100);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(50);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(150);
}
else if (750 < pot_meter && pot_meter < 1023) {
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(100);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(100);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(150);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(10);
digitalWrite(led, HIGH);
delay(50);
digitalWrite(led, LOW);
delay(200);
}
return led;
}
And some pictures:
Unfortunately, this code didn’t work. I modified it many times and I could get the blue switch to work, but never the yellow one. Some of the other students checked my circuit and the connection between switches and the Arduino seemed right. I suspect it might be something with how I coded the last function but nor I or my helpers could debug it.
Idea: In my freshman year, I took a core class called Rhythm with Prof. Godfried Toussaint, which was about using computer science for the structural analysis of music, especially focusing on certain mathematical properties of rhythm such as geometry or divisiveness. The rhythms we examined first arrived in America at the dawn of the slave trade and have been inherited through many generations. They are still alive as part of African, African American as well as Latin American music. I imagined LEDs in a series circuit the same way the timelines of these rhythms are constructed, which gave me the idea to “play” these rhythms using an LED string.
I would like to thank Prof. Toussaint for researching these rhythms extensively and making them known for us. I will be playing them on my circuit as he taught them, without modification.
Objective: To build an electronic circuit which can play multiple rhythms at the same time at a given command.
***
To start, I looked an image of the six traditional rhythms from a slide Prof. Toussaint presented in class. An onset can be understood as a beat and pulse the sum of all beats and silences. The length of 1 pulse is the meter.
From a computer science perspective, these rhythms can be represented as:
1000101000101000, 1001001000101000, 1001001000110000, etc.
Therefore, they can also be played by blinking LEDs. Because these unique rhythms all have 5 onsets, I chose to play 5 rhythms with 5 LEDs: son, shiko, soukous, rumba and gahu.
I began the process of computing these rhythms by isolating just one of them, the son, and writing a program for one LED that would play it by blinking at certain intervals. Because pulses in these rhythms are of equal length (hence, playing every pulse gives the meter), I counted each 0 or 1 as a quantity P. Thus, every onset (blink) is P long, while the silences are products of P and the number of silent pulses.
I used the pinMode function in the Arduino to declare one digital pin as OUTPUT for each of the 5 LEDs.
I experimented with different values of P until I found the value I thought worked best for the blinking LEDs, P=200. So, every onset became 0.2 seconds long, and every silence between onsets calculated in multiplies of 0.2 seconds.
The code for the first blink would look like this:
I saved the code 5 times and modified it for each rhythm. Though I ended up with 5 codes, which is unnecessary from a programming point of view, I still felt the need to see how each one looked before I complicated the circuit further.
I then set up the circuit with 5 LEDs, 5 resistors and the Arduino.
It was the lamest and messiest circuit I’ve built so far.
But then I made it neater, improving the timing of the LEDs by allowing for clearer connections using fewer wires…
… and played all the rhythms with a white paper behind the LEDs to make them look pretty.
With this modification in the code, I could also play each rhythm on a distinct LED (See video).
To make the circuit interactive, I inserted a potentiometer be able to play multiple rhythms using the same code. Here is a schematic drawing and a photo of the new circuit:
For this, I reworked one of the examples from class and assigned an interval of the reading of the potentiometer to each output pin.
Now I can play each rhythm using the same code and setup by changing the direction of the arrow on the potentiometer and looking at the written output of the analogRead function. Though one has to pay close attention to the circuit to see when the rhythm changes, I am still happy with the way this circuit visualises these interesting rhythms.
(Disclaimer: It is a little hard to see when the rhythms change. The order of the rhythms is still the same: clave son, shiko, soukous, rumba and gahu. I left every rhythm to play 2-4 times.)
***
Evaluation and possible improvements:
Though my circuit was successful in that it looks engaging and because I achieved my goal, the result is still somewhat dull. One of the reasons is definitely the fact that these 5 rhythms are similar in structure. They are very interesting rhythms because of their popularity, but for this demonstration, more varied rhythms would have been more suitable. I didn’t have much reference material left from the Rhythm class, perhaps an improvement could be to make my own rhythms and play with them.
Another improvement would be to make the circuit even more interesting by synchronising the blinking LEDs as much as I can. I tried a few versions of code to achieve this, but sadly came nowhere. It would be easy to set up a loop for each LED and play them at the same time, but unfortunately as I learned from here,
https://arduino.stackexchange.com/questions/37684/can-i-make-multiple-void-loops-with-arduino-uno/37685
it is not possible.
I tried grouping the first onsets and silences, then the second ones, etc, like this:
But this didn’t get me closer to my second goal either and by now I ran out of time to try new solutions.
Overall, thought my circuit didn’t turn out as exciting and funky as I planned it to, it was still an interesting discovery and I enjoyed practicing building it and writing the code for it. Ultimately, I was left with many new lessons.