1
1
#include < Arduino.h>
2
2
#include " esp32-hal-ledc.h"
3
+ #include " freertos/task.h"
4
+ #include " freertos/queue.h"
5
+ #include " freertos/semphr.h"
6
+
7
+ static TaskHandle_t _tone_task = NULL ;
8
+ static QueueHandle_t _tone_queue = NULL ;
9
+ static QueueHandle_t _tone_mutex = NULL ;
10
+ static uint8_t _channel = 0 ;
11
+
12
+ typedef enum {
13
+ TONE_START,
14
+ TONE_END,
15
+ TONE_SET_CHANNEL
16
+ } tone_cmd_t ;
17
+
18
+ typedef struct {
19
+ tone_cmd_t tone_cmd;
20
+ uint8_t pin;
21
+ unsigned int frequency;
22
+ unsigned long duration;
23
+ uint8_t channel;
24
+ } tone_msg_t ;
25
+
26
+ static void tone_task (void *){
27
+ tone_msg_t tone_msg;
28
+ while (1 ){
29
+ xQueueReceive (_tone_queue, &tone_msg, portMAX_DELAY);
30
+ switch (tone_msg.tone_cmd ){
31
+ case TONE_START:
32
+ log_d (" Task received from queue TONE_START: _pin=%d, frequency=%u Hz, duration=%u ms" , tone_msg.pin , tone_msg.frequency , tone_msg.duration );
33
+ if (xSemaphoreTake (_tone_mutex, portMAX_DELAY) != pdTRUE ){
34
+ log_e (" Tone mutex take returned with error" );
35
+ break ;
36
+ }
37
+ log_d (" Setup LED controll on channel %d" , _channel);
38
+ ledcSetup (_channel, tone_msg.frequency , 11 );
39
+ ledcAttachPin (tone_msg.pin , _channel);
40
+ ledcWrite (_channel, 1024 );
41
+ if (xSemaphoreGive (_tone_mutex) != pdTRUE){
42
+ log_e (" Tone mutex give returned with error" );
43
+ }
44
+
45
+ if (tone_msg.duration ){
46
+ vTaskDelay (pdMS_TO_TICKS (tone_msg.duration ));
47
+ ledcDetachPin (tone_msg.pin );
48
+ }
49
+ break ;
50
+
51
+ case TONE_END:
52
+ log_d (" Task received from queue TONE_END: pin=%d" , tone_msg.pin );
53
+ ledcDetachPin (tone_msg.pin );
54
+ break ;
55
+
56
+ case TONE_SET_CHANNEL:
57
+ _channel = tone_msg.channel ;
58
+ break ;
59
+
60
+ default : ; // do nothing
61
+ } // switch
62
+ } // infinite loop
63
+ }
64
+
65
+ static int tone_init (){
66
+ if (_tone_mutex == NULL ){
67
+ log_v (" Creating tone mutex" );
68
+ _tone_mutex = xSemaphoreCreateMutex ();
69
+ if (_tone_mutex == NULL ){
70
+ log_e (" Could not create tone mutex" );
71
+ return 0 ; // ERR
72
+ }
73
+ log_v (" Tone mutex created" );
74
+ }
75
+
76
+
77
+ if (_tone_queue == NULL ){
78
+ log_v (" Creating tone queue" );
79
+ _tone_queue = xQueueCreate (128 , sizeof (tone_msg_t ));
80
+ if (_tone_queue == NULL ){
81
+ log_e (" Could not create tone queue" );
82
+ return 0 ; // ERR
83
+ }
84
+ log_v (" Tone queue created" );
85
+ }
86
+
87
+ if (_tone_task == NULL ){
88
+ log_v (" Creating tone task" );
89
+ xTaskCreate (
90
+ tone_task, // Function to implement the task
91
+ " toneTask" , // Name of the task
92
+ 3500 , // Stack size in words
93
+ NULL , // Task input parameter
94
+ 1 , // Priority of the task
95
+ &_tone_task // Task handle.
96
+ );
97
+ if (_tone_task == NULL ){
98
+ log_e (" Could not create tone task" );
99
+ return 0 ; // ERR
100
+ }
101
+ log_v (" Tone task created" );
102
+ }
103
+ return 1 ; // OK
104
+ }
105
+
106
+ void setToneChannel (uint8_t channel){
107
+ log_d (" channel=%d" , channel);
108
+ if (tone_init ()){
109
+ tone_msg_t tone_msg = {
110
+ .tone_cmd = TONE_SET_CHANNEL,
111
+ .channel = channel
112
+ };
113
+ xQueueSend (_tone_queue, &tone_msg, portMAX_DELAY);
114
+ }
115
+ }
3
116
4
117
void noTone (uint8_t _pin){
5
- ledcDetachPin (_pin);
118
+ log_d (" noTone was called" );
119
+ if (tone_init ()){
120
+ tone_msg_t tone_msg = {
121
+ .tone_cmd = TONE_END,
122
+ .pin = _pin
123
+ };
124
+ xQueueSend (_tone_queue, &tone_msg, portMAX_DELAY);
125
+ }
6
126
}
7
127
8
128
// parameters:
@@ -11,12 +131,14 @@ void noTone(uint8_t _pin){
11
131
// duration - time in ms - how long will the signal be outputted.
12
132
// If not provided, or 0 you must manually call noTone to end output
13
133
void tone (uint8_t _pin, unsigned int frequency, unsigned long duration){
14
- ledcSetup (0 , frequency, 11 );
15
- ledcAttachPin (_pin, 0 );
16
-
17
- ledcWrite (0 , 1024 );
18
- if (duration){
19
- vTaskDelay (pdMS_TO_TICKS (duration));
20
- noTone (_pin);
134
+ log_d (" _pin=%d, frequency=%u Hz, duration=%u ms" , _pin, frequency, duration);
135
+ if (tone_init ()){
136
+ tone_msg_t tone_msg = {
137
+ .tone_cmd = TONE_START,
138
+ .pin = _pin,
139
+ .frequency = frequency,
140
+ .duration = duration
141
+ };
142
+ xQueueSend (_tone_queue, &tone_msg, portMAX_DELAY);
21
143
}
22
144
}
0 commit comments