W4 Lab

Discover & share this Animated GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.

Analog output

1.LED dimmer controlled with analog output

Code:

// connect resistor and LED from PWM pin 5 to ground

int brightness; void setup() { pinMode(5, OUTPUT); }

void loop() { for (int brightness = 0; brightness < 256; brightness++) { analogWrite(5, brightness); delay(30); }

for (int brightness = 255; brightness >= 0; brightness--) { analogWrite(5, brightness); delay(30); } delay(1000); }

Discover & share this Animated GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.

2.Servo Motor with FSR

Code:

#include <Servo.h> //attach FSR to analog input A0 //attach servo to pin 5 Servo myServo;

void setup() { myServo.attach(5); Serial.begin(9600); }

void loop() { int analogVal = analogRead(A0); Serial.println(analogVal); int angle=map(analogVal,0,1023,0,179); myServo.write(angle); delay(20); }

Troubleshoot:

First time when I ran the code, it didn't work, and I didn't see any analogVal being printed in serial monitor. So I double checked my circuit connections with the schematic diagram, and I found out that my analog read skipped over the FSR, instead, I was supposed to measure the analog input voltage from +5V across the FSR to analog pin A0. so I moved the yellow wire up a grid to connect the other side of FSR and it worked.

3. Speaker controlled by photocell to generate tone

Code:

int frequency; int analogVal;

void setup() { pinMode(9,OUTPUT); Serial.begin(9600); }

void loop() { analogVal = analogRead(A0); Serial.println(analogVal); frequency = map(analogVal,0,100 ,100,1000); tone(9,frequency); delay(30); }

Application

To apply all the topics we covered in the past two weeks, I came up with a 4/4 servo metronome which applies the concepts of digital output, analog input and analog output(PWM), tone() and servo.

The metronome is in 4/4 meter, with a BPM range of 60-160 controlled by a potentiometer. Each measure has 4 quarter-note beats generated by a piezo speaker. (1st beat is accented with higher note E3 and the rest three notes are C3). 4 LEDs correspond to which beat we are at in each measure, red LED is the 1st(accent) beat, green LEDs are the rest 3 beats. Each servo movement in one direction indicates one beat, just like how a real mechanical metronome works.

Code:

#include "pitches.h"

#include <Servo.h> int BPM; //beats per minute

int potValue;

int angle[]= {20, 160, 20, 160}; //servo pulsing between 20 -160 degrees

int melody[] = {NOTE_E3, NOTE_C3, NOTE_C3, NOTE_C3}; //notes E(accent)-C-C-C Servo myServo;

void setup() {

pinMode(2, OUTPUT); //red LED (1st beat)

pinMode(3, OUTPUT); //green LED (2nd beat)

pinMode(4, OUTPUT); //green LED (3rd beat)

pinMode(5, OUTPUT); //green LED (4th beat)

myServo.attach(9); //servo attached to pin 9 Serial.begin(9600); }

void loop() {

potValue = analogRead(A0); //analog input reading from potentiometer

BPM = map (potValue, 0, 1023, 60, 160); //map potValue to 60-160 BPM range

Serial.println("potValue:");

Serial.println(potValue);

Serial.println("BPM");

Serial.println(BPM);

//note duration converted from BPM (60000ms/min)/(number of beats/min)

int noteDuration = 60000 / BPM;

for (int thisNote = 0; thisNote < 4; thisNote++) {

//play tone E3 or C3 from speaker (pin 6) tone(6, melody[thisNote]);

//move servo by alternating direction at angle 20 and 160 each cycle through loop/each //beat is played

myServo.write(angle[thisNote]);

if (thisNote == 0) {  //At 1st beat, red LED on

digitalWrite(2, HIGH);

digitalWrite(3, LOW);

digitalWrite(4, LOW);

digitalWrite(5, LOW);

} else if (thisNote == 1) { //At 2nd beat, 1 st green LED on

digitalWrite(2, LOW);

digitalWrite(3, HIGH);

digitalWrite(4, LOW);

digitalWrite(5, LOW);

} else if (thisNote == 2) { //At 3rd beat, 2nd green LED on

digitalWrite(2, LOW);

digitalWrite(3, LOW);

digitalWrite(4, HIGH);

digitalWrite(5, LOW);

} else if (thisNote == 3) { //At 4th beat, 3rd green LED on

digitalWrite(2, LOW);

digitalWrite(3, LOW);

digitalWrite(4, LOW);

digitalWrite(5, HIGH); }

//stops the program for noteDuration ms before next beat plays

delay(noteDuration);

}

}

Challenge:

I had two major problems I couldn't figure out to get the program running, so I reached out to resident Mithru and he was extremely smart and helpful. I was so impressed by how fast he identified my problems. Huge thanks to Mithru here.

One of the challenges was the note duration. As I know with tone() I can pass in 3 parameters: pin, frequency, duration. So I calculated noteDuration from BPM value converted from potentiometer reading, and passed in that noteDuration value into tone().  However, no matter how I changed the potentiometer's reading, it wouldn't affect the noteDuration at all. When I first ran it, the servo would jitter really fast in really small angles and I can barely tell the beats from each other. It just sounded like a consecutive C note. Then I changed the delay(20) after tone() and myServo.write() to delay(100) and to delay (500), and to delay(1000), I noticed the milliseconds in delay() is what actually affecting the speed of the beats. So I passed noteDuration into delay() and it worked, and the speaker was playing beats accurately at the BPM printed on serial monitor. Though I still do no know why passing in noteDuration doesn't change anything. If I can just add a delay() to pulse the notes, what does the duration in tone(pin, frequency, duration) do?

Another problem I encountered was that although the LEDs were lit in synch with the beats, the order of the color being lit did not match the order of the beats being played. The order of lighting is lagging 1 beat behind the notes. As opposed to notes E-C-C-C corresponding to LED R-G-G-G. It was behaving as notes E-C-C-C corresponding to LED G-R-G-G.  Then I noticed it was because I had delay(noteDuration) placed ahead of the codes for LED, therefore resulting in LEDs lagging one beat behind the corresponding notes. I fixed the problem by placing delay after LED code at the end of for loop.