Skip to content

Commit 4b973dc

Browse files
committed
Added ESP32 port based on MCPWM unit
1 parent 0a94d5c commit 4b973dc

File tree

7 files changed

+83
-16
lines changed

7 files changed

+83
-16
lines changed

README.creole

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Replacement to the standard tone library with many advantages:
1212
* Can set not only the frequency but also the sound volume
1313
* Less stress on the speaker so it will last longer and sound better
1414
15-
Disadvantages are that it must use certain pins and it uses two pins instead of one. But, if you're flexible with your pin choices, this is a great upgrade. It also uses timer 1 instead of timer 2, which may free up a conflict you have with the tone library. It exclusively uses port registers for the fastest and smallest code possible (which also makes it **ONLY compatible with ATmega microcontrollers**).
15+
Disadvantages are that it must use certain pins and it uses two pins instead of one. But, if you're flexible with your pin choices, this is a great upgrade. In case of ATmega microcontrollers, it uses timer 1 instead of timer 2, which may free up a conflict you have with the tone library. It exclusively uses port registers for the fastest and smallest code possible.
1616

17-
== Difference between toneAC and toneAC2 ==
17+
== Difference between toneAC and toneAC2 (ATmega) ==
1818

1919
First off, toneAC is **SUPERIOR** to [[https://bitbucket.org/teckel12/arduino-toneac2/wiki/Home|toneAC2]]. It's called [[https://bitbucket.org/teckel12/arduino-toneac2/wiki/Home|toneAC2]] only because it uses timer 2, not because it's a newer version of toneAC. [[https://bitbucket.org/teckel12/arduino-toneac2/wiki/Home|toneAC2]] is an alternate but **INFERIOR** version of toneAC that uses timer 2 instead of timer 1 and allows for any two pins to be used. You should use toneAC instead of [[https://bitbucket.org/teckel12/arduino-toneac2/wiki/Home|toneAC2]] if at all possible because toneAC is more accurate, higher quality, allows for higher frequencies, uses fewer CPU cycles, and creates smaller code. However, if you're having a conflict with timer 1, or just can't use the default PWM pins for timer 1, then [[https://bitbucket.org/teckel12/arduino-toneac2/wiki/Home|toneAC2]] may be your answer.
2020

@@ -49,19 +49,19 @@ Help future development by making a small donation (the [email protected] payee is
4949
5050
== Compatibility ==
5151

52-
toneAC is written specifically for the ATmega AVR platform as it uses timer events that only exist with this platform. Compatibility includes the following platforms/microcontrollers:
52+
Compatibility includes the following platforms/microcontrollers:
5353

54-
* ATmega328, ATmega128, ATmega640, ATmega8, Uno, Leonardo, ATmega2560/2561, ATmega1280/1281, Mega, ATmega1284P, ATmega644, Teensy 2.0, Teensy++ 2.0
54+
* ATmega328, ATmega128, ATmega640, ATmega8, Uno, Leonardo, ATmega2560/2561, ATmega1280/1281, Mega, ATmega1284P, ATmega644, Teensy 2.0, Teensy++ 2.0, ESP32
5555
5656
== Connection Example ==
5757

58-
Connection is very similar to a piezo or standard speaker. Except, instead of connecting one speaker wire to ground you connect both speaker wires to Arduino pins. The pins you connect to are specific, as toneAC lets the ATmega microcontroller do all the pin timing and switching. This is important due to the high switching speed possible with toneAC and to make sure the pins are alyways perfectly out of phase with each other (push/pull). See the below list for which pins to use for different Arduinos. Just as usual when connecting a speaker, make sure you add an inline 100 ohm resistor between one of the pins and the speaker wire.
58+
Connection is very similar to a piezo or standard speaker. Except, instead of connecting one speaker wire to ground you connect both speaker wires to Arduino pins. The pins you connect to are specific, as toneAC lets the microcontroller do all the pin timing and switching. This is important due to the high switching speed possible with toneAC and to make sure the pins are alyways perfectly out of phase with each other (push/pull). See the below list for which pins to use for different Arduinos. Just as usual when connecting a speaker, make sure you add an inline 100 ohm resistor between one of the pins and the speaker wire.
5959

6060
* **Pins 9 & 10** - ATmega328, ATmega128, ATmega640, ATmega8, Uno, Leonardo, etc.
6161
* **Pins 11 & 12** - ATmega2560/2561, ATmega1280/1281, Mega
6262
* **Ping 12 & 13** - ATmega1284P, ATmega644
6363
* **Pins 14 & 15** - Teensy 2.0
64-
* **Pins 25 & 26** - Teensy++ 2.0
64+
* **Pins 25 & 26** - Teensy++ 2.0, ESP32
6565
6666
{{https://bitbucket.org/repo/Kg6beL/images/3490992041-toneAC3.png|toneAC3.png}}
6767

@@ -117,7 +117,7 @@ void loop() {
117117

118118
The library is named toneAC because it produces an alternating push/pull between two pins. It's not really AC (alternating current) as in-wall electrical wiring because it's a square wave and never produces a negative voltage. However, the effect of the alternating push/pull creates an effective double voltage differential which produces the higher volume level.
119119

120-
The ATmega's PWM takes care of the alternating push/pull so the accuracy is exact. When you send a tone to a speaker with the standard tone library, the loudest is at 50% duty cycle (only on half the time). Which at 5 volts, is like sending only 2.5v to the speaker. With toneAC, we're sending out of phase signals on two pins. So in effect, the speaker is getting 5 volts instead of 2.5, making it nearly twice as loud.
120+
The ATmega's PWM and ESP32 MCPWM take care of the alternating push/pull so the accuracy is exact. When you send a tone to a speaker with the standard tone library, the loudest is at 50% duty cycle (only on half the time). Which at 5 volts, is like sending only 2.5v to the speaker. With toneAC, we're sending out of phase signals on two pins. So in effect, the speaker is getting 5 volts instead of 2.5, making it nearly twice as loud.
121121

122122
The sound quality difference has to do with allowing the Arduino's PWM to take care of everything and careful programming. Longer piezo life happens because instead of driving the transducer disc only ever in one direction (deforming the disc and reducing sound and quality), it drives it in both directions keeping the disc uniform.
123123

examples/toneAC_demo/toneAC_demo.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Connect a piezo buzzer (without internal oscillator) or speaker to these pins:
44
Pins 11 & 12 - ATmega2560/2561, ATmega1280/1281, Mega
55
Pins 12 & 13 - ATmega1284P, ATmega644
66
Pins 14 & 15 - Teensy 2.0
7-
Pins 25 & 26 - Teensy++ 2.0
7+
Pins 25 & 26 - Teensy++ 2.0, ESP32
88
Be sure to include an inline 100 ohm resistor on one pin as you normally do when connecting a piezo or speaker.
99
--------------------------------------------------------------------------- */
1010

@@ -32,4 +32,4 @@ void loop() {
3232
}
3333

3434
while(1); // Stop (so it doesn't repeat forever driving you crazy--you're welcome).
35-
}
35+
}

examples/toneAC_dual_LED/toneAC_dual_LED.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Connect a two-pin dual LED to the following pins with inline 220 ohm resistor.
44
Pins 11 & 12 - ATmega2560/2561, ATmega1280/1281, Mega
55
Pins 12 & 13 - ATmega1284P, ATmega644
66
Pins 14 & 15 - Teensy 2.0
7-
Pins 25 & 26 - Teensy++ 2.0
7+
Pins 25 & 26 - Teensy++ 2.0, ESP32
88
Connect the center lead of a potentiometer to analog pin A0 and the other two leads to +5V and ground.
99
--------------------------------------------------------------------------- */
1010

@@ -22,4 +22,4 @@ void loop() {
2222
toneAC(freq, 10, 0, true); // Set the frequency and have it run forever in the background (next event should take over in 500 ms).
2323
}
2424
/* Do a bunch of other stuff here, it won't affect toneAC doing its thing. */
25-
}
25+
}

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ sentence=Replacement to the standard tone library with many advantages
66
paragraph=Replacement to the standard tone library with many advantages
77
category=Signal Input/Output
88
url=https://github.com/teckel12/arduino-toneac
9-
architectures=avr
10-
includes=toneAC.h
9+
architectures=avr,esp32
10+
includes=toneAC.h

src/toneAC.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ uses port registers for the fastest and smallest code possible.
2727
Connection is very similar to a piezo or standard speaker. Except, instead
2828
of connecting one speaker wire to ground you connect both speaker wires to
2929
Arduino pins. The pins you connect to are specific, as toneAC lets the
30-
ATmega microcontroller do all the pin timing and switching. This is
30+
ATmega/ESP32 microcontroller do all the pin timing and switching. This is
3131
important due to the high switching speed possible with toneAC and to make
3232
sure the pins are alyways perfectly out of phase with each other
3333
(push/pull). See the below CONNECTION section for which pins to use for
@@ -39,7 +39,7 @@ add an inline 100 ohm resistor between one of the pins and the speaker wire.
3939
Pins 11 & 12 - ATmega2560/2561, ATmega1280/1281, Mega
4040
Pins 12 & 13 - ATmega1284P, ATmega644
4141
Pins 14 & 15 - Teensy 2.0
42-
Pins 25 & 26 - Teensy++ 2.0
42+
Pins 25 & 26 - Teensy++ 2.0, ESP32
4343
4444
SYNTAX:
4545
toneAC( frequency [, volume [, length [, background ]]] ) - Play a note.

src/toneAC_esp32.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* ---------------------------------------------------------------------------
2+
Created by Tim Eckel - [email protected]
3+
Copyright 2019 License: GNU GPL v3 http://www.gnu.org/licenses/gpl-3.0.html
4+
5+
See "toneAC.h" for purpose, syntax, version history, links, and more.
6+
--------------------------------------------------------------------------- */
7+
8+
#include "toneAC_internal.h"
9+
10+
#if defined(ESP32)
11+
12+
#include <mutex>
13+
#include <esp32-hal-cpu.h>
14+
#include <driver/mcpwm.h>
15+
16+
#define MCPWM0APIN 25
17+
#define MCPWM0BPIN 26
18+
19+
static hw_timer_t *_tAC_timer = NULL;
20+
static void IRAM_ATTR onTimer();
21+
22+
static std::once_flag _tAC_init;
23+
24+
void toneAC_init() {
25+
std::call_once(_tAC_init, [](){
26+
// Initialize MCPWM
27+
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, MCPWM0APIN);
28+
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, MCPWM0BPIN);
29+
mcpwm_config_t pwm_config;
30+
pwm_config.frequency = 1;
31+
pwm_config.cmpr_a = 0.0;
32+
pwm_config.cmpr_b = 0.0;
33+
pwm_config.counter_mode = MCPWM_UP_COUNTER;
34+
pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
35+
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);
36+
mcpwm_deadtime_enable(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, 0, 0);
37+
mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
38+
// Initialize timer
39+
_tAC_timer = timerBegin(0, ESP.getCpuFreqMHz(), true);
40+
timerAttachInterrupt(_tAC_timer, &onTimer, true);
41+
});
42+
}
43+
44+
void toneAC_playNote(unsigned long frequency, uint8_t volume) {
45+
float duty = 100.0 / _tAC_volume[volume - 1];
46+
mcpwm_set_frequency(MCPWM_UNIT_0, MCPWM_TIMER_0, frequency);
47+
mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, duty);
48+
mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B, duty);
49+
mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
50+
}
51+
52+
void noToneAC() {
53+
timerAlarmDisable(_tAC_timer);
54+
mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
55+
}
56+
57+
void noToneAC_setTimer(unsigned long delay) {
58+
timerAlarmWrite(_tAC_timer, delay * 1000, false);
59+
timerRestart(_tAC_timer);
60+
timerAlarmEnable(_tAC_timer);
61+
}
62+
63+
static void IRAM_ATTR onTimer() {
64+
noToneAC();
65+
}
66+
67+
#endif

src/toneAC_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ See "toneAC.h" for purpose, syntax, version history, links, and more.
1010

1111
#include "toneAC.h"
1212

13-
#if !defined(__AVR__)
13+
#if !defined(__AVR__) && !defined(ESP32)
1414
#error Unsupported architecture
1515
#endif
1616

0 commit comments

Comments
 (0)