Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Pages: [1]   Go Down
Author Topic: piezo + leds  (Read 1148 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm doing a project where I'm trying to correspond a flashing led with a note made by my piezo element. I have 6 different notes and therefore 6 leds. Some leds will flash more than others depending on how many times that note is played in the song (twinkle twinkle little star)
I'm trying to add an if then statement in the loop but I do not know how to do one in this situation. I'm trying to say if note 'a' played led '3' high for example (not literal example in this code) but I do not know how to separate the piezo notes from their current 'i' increments
here is what i have so far
Code:
int speakerPin = 9;

int length = 15; // the number of notes
char notes[] = "ccggaagffeeddc "; // a space represents a rest
int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 300;
int ledPins[] = {2,3,4,5,6,7};

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
 
  // play the tone corresponding to the note name
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}

void setup() {
  pinMode(speakerPin, OUTPUT);
  pinMode(ledPins[0],OUTPUT);
  pinMode(ledPins[1],OUTPUT);
  pinMode(ledPins[2],OUTPUT);
  pinMode(ledPins[3],OUTPUT);
  pinMode(ledPins[4],OUTPUT);
  pinMode(ledPins[5],OUTPUT);
}

void loop() {
  for (int i = 0; i < length; i++) {
    if (notes[i] == ' ') {
      delay(beats[i] * tempo); // rest
    } else {
      playNote(notes[i], beats[i] * tempo);
     digitalWrite(ledPins[0], HIGH);
  delay (100);
  digitalWrite(ledPins[0], LOW); 
 
    }
   


Moderator edit: There are really, really good reasons we use [code] [/code] tags when posting code.
Did you read this before posting?
« Last Edit: May 11, 2012, 04:22:08 pm by AWOL » Logged

Sydney, Australia
Online Online
Edison Member
*
Karma: 33
Posts: 1288
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The delay() statement in the main loop will stop anything happening for 100ms. This is probably going to make your music sound jerky.

One solution is to turn the LED on before you ptay the note, play the note, and then turn it off afterwards. The LED is on while the note is playing and it sounds more seamless. Like this:
Code:
void loop() {
  for (int i = 0; i < length; i++) {
    if (notes == ' ') {
      delay(beats * tempo); // rest
    } else {
      digitalWrite(ledPins[0], HIGH);
      playNote(notes, beats * tempo);
     digitalWrite(ledPins[0], LOW); 
     }

Now to address which LED pin you should be using. I am not sure how you have one LED per note when you have 8 notes { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' } and only 6 LED pins {2,3,4,5,6,7}, so that is one problem you need to fix. However, the key for you is that in playNote() you work out the array index of the note. That can be used as the array index of the ledpins array BUT you need to be turning the LED on and off to the playNote function:

Code:
void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
 
  // play the tone corresponding to the note name
  for (int i = 0; i < (sizeof(names)/sizeof(char)); i++) {
    if (names[i] == note) {
      digitalWrite(ledPins[i], HIGH);
      playTone(tones[i], duration);
      digitalWrite(ledPins[i], LOW); 
    }
  }
}

You'll note I have also changed some other stuff in the function - 'magic' numbers like 8 are always a problem in code when you come back later in life, so writing a formula to work out the size is more maintainable (you may want to think about length = 15 in the same way). Also, the comparison needs to be to names indexed by i, not names - a big clue is if you are doing a loop and are not using the loop index anywhere in the loop then you may have a issue with the code. You have the same problem with the notes variable in the main loop, but I will let you discover and fix it for yourself  smiley

Clearly if you are using this new function you need to remove turning the LED on in the main loop:
Code:
void loop() {
  for (int i = 0; i < length; i++) {
    if (notes == ' ') {
      delay(beats * tempo); // rest
    } else {
      playNote(notes, beats * tempo);
    }

« Last Edit: May 11, 2012, 04:03:13 pm by marco_c » Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Offline Offline
Full Member
***
Karma: 1
Posts: 209
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hay nmuturi,

Did you ever get this to work. I am trying to do the same thing but with El Wire. I tool you code that you had posted. (Hope that’s ok) and modified it a bit.

I got it to work. Well I got sound and things light up that is.  But not the way I would like to. Right now it’s light up a different El wire per tone not note.

If you worked it out can you post the code.

I am working on it but, I just started playing with Arduion a few days ago and I am just learning the code.

Thanks
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 209
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

HI sydney.

Like I was saying in my last post I am just starting out with all of this.  I needed a hobby.

Can you explain what you mean by "you work out the array index of the note" and maybe point me in the right direction


Thanks
Logged

Pages: [1]   Go Up
Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Jump to: