Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

esp32 tone #980

Closed
gemforce opened this issue Jan 8, 2018 · 7 comments · Fixed by #6402
Closed

esp32 tone #980

gemforce opened this issue Jan 8, 2018 · 7 comments · Fixed by #6402
Assignees

Comments

@gemforce
Copy link

gemforce commented Jan 8, 2018

Hi
Why not working tone in esp32 ?

   tone(SOUND_PIN, 1000, 1000);
   delay(1000);
    noTone(SOUND_PIN)
@lbernstone
Copy link
Contributor

I think tone() will be implemented in the ESP-IDF, rather than arduino. In the meantime, try https://techtutorialsx.com/2017/07/01/esp32-arduino-controlling-a-buzzer-with-pwm/

@copercini copercini added the Status: To be implemented Selected for Development label Jan 15, 2018
@ReanimationXP
Copy link

ReanimationXP commented Sep 8, 2018

This is part of the Arduino core library and needs to be implemented, as it causes the basic Examples > Digital > toneMelody example to not compile correctly.

@lbernstone
Copy link
Contributor

I don't think this is of a quality to be added to the code base, but it is a start, anyhow.
https:/lbernstone/Tone

@Thomascountz
Copy link

Although this functionality is unavailable in Espressif's arduino-esp32 library, members of the community have found various work-arounds such as using the native LED Control functions to generate PWM signals.

However, looking more closely at arduino-esp32 library, not only has Espressif provided a clean API for generating tones, they've provided an interface for generating specific PWM frequencies for specific notes on the chromatic scale in different octaves.

https:/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-ledc.c#L255-L266

double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
  const uint16_t noteFrequencyBase[12] = {
  //   C        C#       D        Eb       E        F       F#        G       G#        A       Bb        B
      4186,    4435,    4699,    4978,    5274,    5588,    5920,    6272,    6645,    7040,    7459,    7902
  };

  if(octave > 8 || note >= NOTE_MAX){
      return 0;
  }
  double noteFreq =  (double)noteFrequencyBase[note] / (double)(1 << (8-octave));
  return ledcWriteTone(chan, noteFreq);
}

Although not directly compatible with Arduino's tone(), the function allows for a clearer interface by providing named frequencies out of the box via the note_t type.

typedef enum {
    NOTE_C, NOTE_Cs, NOTE_D, NOTE_Eb, NOTE_E, NOTE_F, NOTE_Fs, NOTE_G, NOTE_Gs, NOTE_A, NOTE_Bb, NOTE_B, NOTE_MAX
} note_t;

Example Usage

Here is an example of generating PWM frequencies at 50% duty cycle to play the C-major scale.

void playScale(uint8_t pin, uint8_t channel) {
  ledcAttachPin(pin, channel);
  ledcWriteNote(pin, NOTE_C, 4);
  delay(500);
  ledcWriteNote(pin, NOTE_D, 4);
  delay(500);
  ledcWriteNote(pin, NOTE_E, 4);
  delay(500);
  ledcWriteNote(pin, NOTE_F, 4);
  delay(500);
  ledcWriteNote(pin, NOTE_G, 4);
  delay(500);
  ledcWriteNote(pin, NOTE_A, 4);
  delay(500);
  ledcWriteNote(pin, NOTE_B, 4);
  delay(500);
  ledcDetachPin(pin)
}

@lbernstone
Copy link
Contributor

analogWrite and tone are both available in the ESP32Servo library. This can be found in the Arduino Library Manager.

@mmackh
Copy link

mmackh commented Apr 18, 2021

For anyone coming across @Thomascountz Example Usage code, the first argument in ledcWriteNote is a channel, not the pin. So the code could look like:

void playScale(uint8_t pin, uint8_t channel) {
  uint8_t octave = 4;
  
  ledcAttachPin(pin, channel);
  ledcWriteNote(channel, NOTE_C, octave);
  delay(500);
  ledcWriteNote(channel, NOTE_D, octave);
  delay(500);
  ledcWriteNote(channel, NOTE_E, octave);
  delay(500);
  ledcWriteNote(channel, NOTE_F, octave);
  delay(500);
  ledcWriteNote(channel, NOTE_G, octave);
  delay(500);
  ledcWriteNote(channel, NOTE_A, octave);
  delay(500);
  ledcWriteNote(channel, NOTE_B, octave);
  delay(500);
  ledcDetachPin(pin);
}

@aldityarafi
Copy link

analogWrite and tone are both available in the ESP32Servo library. This can be found in the Arduino Library Manager.

hey man, you just saved me from depression because of this...buzzer . Thanks

@PilnyTomas PilnyTomas self-assigned this Mar 7, 2022
me-no-dev pushed a commit that referenced this issue Mar 10, 2022
* Implemented tone
* Tone uses queue; implemented setToneChannel
@VojtechBartoska VojtechBartoska added Status: Solved and removed Status: To be implemented Selected for Development labels Apr 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging a pull request may close this issue.

9 participants