Browse Source

Non-blocking buzzer

João Brázio 8 years ago
parent
commit
5b5aa1572b

+ 23
- 7
Marlin/Conditionals.h View File

@@ -43,8 +43,7 @@
43 43
 #endif
44 44
 
45 45
 #ifndef CONFIGURATION_LCD // Get the LCD defines which are needed first
46
-
47
-  #define CONFIGURATION_LCD
46
+#define CONFIGURATION_LCD
48 47
 
49 48
   #define LCD_HAS_DIRECTIONAL_BUTTONS (BUTTON_EXISTS(UP) || BUTTON_EXISTS(DWN) || BUTTON_EXISTS(LFT) || BUTTON_EXISTS(RT))
50 49
 
@@ -154,11 +153,6 @@
154 153
       #define ENCODER_STEPS_PER_MENU_ITEM 1
155 154
     #endif
156 155
 
157
-    #if ENABLED(LCD_USE_I2C_BUZZER)
158
-      #define LCD_FEEDBACK_FREQUENCY_HZ 1000
159
-      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
160
-    #endif
161
-
162 156
     #define ULTIPANEL
163 157
     #define NEWPANEL
164 158
   #endif
@@ -806,5 +800,27 @@
806 800
     #endif
807 801
   #endif
808 802
 
803
+  /**
804
+   * Buzzer/Speaker
805
+   */
806
+  #if ENABLED(LCD_USE_I2C_BUZZER)
807
+    #ifndef LCD_FEEDBACK_FREQUENCY_HZ
808
+      #define LCD_FEEDBACK_FREQUENCY_HZ 1000
809
+    #endif
810
+    #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
811
+      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
812
+    #endif
813
+  #elif PIN_EXISTS(BEEPER)
814
+    #ifndef LCD_FEEDBACK_FREQUENCY_HZ
815
+      #define LCD_FEEDBACK_FREQUENCY_HZ 5000
816
+    #endif
817
+    #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
818
+      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
819
+    #endif
820
+  #else
821
+    #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
822
+      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
823
+    #endif
824
+  #endif
809 825
 #endif //CONFIGURATION_LCD
810 826
 #endif //CONDITIONALS_H

+ 11
- 0
Marlin/Marlin.h View File

@@ -373,4 +373,15 @@ extern uint8_t active_extruder;
373 373
 
374 374
 void calculate_volumetric_multipliers();
375 375
 
376
+// Buzzer
377
+#if HAS_BUZZER
378
+  #if ENABLED(SPEAKER)
379
+    #include "speaker.h"
380
+    extern Speaker buzzer;
381
+  #else
382
+    #include "buzzer.h"
383
+    extern Buzzer buzzer;
384
+  #endif
385
+#endif
386
+
376 387
 #endif //MARLIN_H

+ 29
- 12
Marlin/Marlin_main.cpp View File

@@ -59,7 +59,6 @@
59 59
 #include "language.h"
60 60
 #include "pins_arduino.h"
61 61
 #include "math.h"
62
-#include "buzzer.h"
63 62
 
64 63
 #if ENABLED(USE_WATCHDOG)
65 64
   #include "watchdog.h"
@@ -354,6 +353,15 @@ static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL
354 353
   Stopwatch print_job_timer = Stopwatch();
355 354
 #endif
356 355
 
356
+// Buzzer
357
+#if HAS_BUZZER
358
+  #if ENABLED(SPEAKER)
359
+    Speaker buzzer;
360
+  #else
361
+    Buzzer buzzer;
362
+  #endif
363
+#endif
364
+
357 365
 static uint8_t target_extruder;
358 366
 
359 367
 #if ENABLED(AUTO_BED_LEVELING_FEATURE)
@@ -1233,7 +1241,7 @@ inline bool code_value_bool() { return code_value_byte() > 0; }
1233 1241
 
1234 1242
 #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
1235 1243
   inline void set_input_temp_units(TempUnit units) { input_temp_units = units; }
1236
-  
1244
+
1237 1245
   float code_value_temp_abs() {
1238 1246
     switch (input_temp_units) {
1239 1247
       case TEMPUNIT_C:
@@ -5689,10 +5697,13 @@ inline void gcode_M226() {
5689 5697
    * M300: Play beep sound S<frequency Hz> P<duration ms>
5690 5698
    */
5691 5699
   inline void gcode_M300() {
5692
-    uint16_t beepS = code_seen('S') ? code_value_ushort() : 110;
5693
-    uint32_t beepP = code_seen('P') ? code_value_ulong() : 1000;
5694
-    if (beepP > 5000) beepP = 5000; // limit to 5 seconds
5695
-    buzz(beepP, beepS);
5700
+    uint16_t const frequency = code_seen('S') ? code_value_ushort() : 260;
5701
+    uint16_t duration = code_seen('P') ? code_value_ushort() : 1000;
5702
+
5703
+    // Limits the tone duration to 0-5 seconds.
5704
+    NOMORE(duration, 5000);
5705
+
5706
+    buzzer.tone(duration, frequency);
5696 5707
   }
5697 5708
 
5698 5709
 #endif // HAS_BUZZER
@@ -6173,7 +6184,7 @@ inline void gcode_M428() {
6173 6184
         SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
6174 6185
         LCD_ALERTMESSAGEPGM("Err: Too far!");
6175 6186
         #if HAS_BUZZER
6176
-          buzz(200, 40);
6187
+          buzzer.tone(200, 40);
6177 6188
         #endif
6178 6189
         err = true;
6179 6190
         break;
@@ -6190,8 +6201,8 @@ inline void gcode_M428() {
6190 6201
     report_current_position();
6191 6202
     LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED);
6192 6203
     #if HAS_BUZZER
6193
-      buzz(200, 659);
6194
-      buzz(200, 698);
6204
+      buzzer.tone(200, 659);
6205
+      buzzer.tone(200, 698);
6195 6206
     #endif
6196 6207
   }
6197 6208
 }
@@ -8076,17 +8087,23 @@ void idle(
8076 8087
     bool no_stepper_sleep/*=false*/
8077 8088
   #endif
8078 8089
 ) {
8079
-  thermalManager.manage_heater();
8090
+  lcd_update();
8091
+  host_keepalive();
8080 8092
   manage_inactivity(
8081 8093
     #if ENABLED(FILAMENTCHANGEENABLE)
8082 8094
       no_stepper_sleep
8083 8095
     #endif
8084 8096
   );
8085
-  host_keepalive();
8086
-  lcd_update();
8097
+
8098
+  thermalManager.manage_heater();
8099
+
8087 8100
   #if ENABLED(PRINTCOUNTER)
8088 8101
     print_job_timer.tick();
8089 8102
   #endif
8103
+
8104
+  #if HAS_BUZZER
8105
+    buzzer.tick();
8106
+  #endif
8090 8107
 }
8091 8108
 
8092 8109
 /**

+ 0
- 57
Marlin/buzzer.cpp View File

@@ -1,57 +0,0 @@
1
-/**
2
- * Marlin 3D Printer Firmware
3
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
- *
5
- * Based on Sprinter and grbl.
6
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
- *
8
- * This program is free software: you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation, either version 3 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
- *
21
- */
22
-
23
-#include "Marlin.h"
24
-#if HAS_BUZZER
25
-  #include "buzzer.h"
26
-  #include "ultralcd.h"
27
-
28
-  void buzz(long duration, uint16_t freq) {
29
-    if (freq > 0) {
30
-      #if ENABLED(LCD_USE_I2C_BUZZER)
31
-        lcd_buzz(duration, freq);
32
-      #elif PIN_EXISTS(BEEPER) // on-board buzzers have no further condition
33
-        SET_OUTPUT(BEEPER_PIN);
34
-        #if ENABLED(SPEAKER) // a speaker needs a AC ore a pulsed DC
35
-          //tone(BEEPER_PIN, freq, duration); // needs a PWMable pin
36
-          unsigned int delay = 1000000 / freq / 2;
37
-          int i = duration * freq / 1000;
38
-          while (i--) {
39
-            WRITE(BEEPER_PIN, HIGH);
40
-            delayMicroseconds(delay);
41
-            WRITE(BEEPER_PIN, LOW);
42
-            delayMicroseconds(delay);
43
-           }
44
-        #else // buzzer has its own resonator - needs a DC
45
-          WRITE(BEEPER_PIN, HIGH);
46
-          delay(duration);
47
-          WRITE(BEEPER_PIN, LOW);
48
-        #endif
49
-      #else
50
-        delay(duration);
51
-      #endif
52
-    }
53
-    else {
54
-      delay(duration);
55
-    }
56
-  }
57
-#endif

+ 109
- 6
Marlin/buzzer.h View File

@@ -20,11 +20,114 @@
20 20
  *
21 21
  */
22 22
 
23
-#ifndef BUZZER_H
24
-  #define BUZZER_H
23
+#ifndef __BUZZER_H__
24
+#define __BUZZER_H__
25 25
 
26
-  #if HAS_BUZZER
27
-    void buzz(long duration, uint16_t freq);
28
-  #endif
26
+#include "fastio.h"
27
+#include "watchdog.h"
28
+#include "circularqueue.h"
29 29
 
30
-#endif //BUZZER_H
30
+#define TONE_QUEUE_LENGTH 4
31
+
32
+/**
33
+ * @brief Tone structure
34
+ * @details Simple abstration of a tone based on a duration and a frequency.
35
+ *
36
+ */
37
+struct tone_t {
38
+  uint16_t duration;
39
+  uint16_t frequency;
40
+};
41
+
42
+/**
43
+ * @brief Buzzer class
44
+ */
45
+class Buzzer {
46
+  private:
47
+    struct state_t {
48
+      tone_t   tone;
49
+      uint32_t timestamp;
50
+    } state;
51
+
52
+  protected:
53
+    CircularQueue<tone_t, TONE_QUEUE_LENGTH> buffer;
54
+
55
+    /**
56
+     * @brief Inverts the sate of a digital PIN
57
+     * @details This will invert the current state of an digital IO pin.
58
+     */
59
+    void invert() {
60
+      WRITE(BEEPER_PIN, !READ(BEEPER_PIN));
61
+    }
62
+
63
+    /**
64
+     * @brief Turn off a digital PIN
65
+     * @details Alias of digitalWrite(PIN, LOW) using FastIO
66
+     */
67
+    void off() {
68
+      WRITE(BEEPER_PIN, LOW);
69
+    }
70
+
71
+    /**
72
+     * @brief Turn on a digital PIN
73
+     * @details Alias of digitalWrite(PIN, HIGH) using FastIO
74
+     */
75
+    void on() {
76
+      WRITE(BEEPER_PIN, HIGH);
77
+    }
78
+
79
+    /**
80
+     * @brief Resets the state of the class
81
+     * @details Brings the class state to a known one.
82
+     */
83
+    void reset() {
84
+      this->off();
85
+      this->state.timestamp = 0;
86
+    }
87
+
88
+  public:
89
+    /**
90
+     * @brief Class constructor
91
+     */
92
+    Buzzer() {
93
+      SET_OUTPUT(BEEPER_PIN);
94
+      this->reset();
95
+    }
96
+
97
+    /**
98
+     * @brief Add a tone to the queue
99
+     * @details Adds a tone_t structure to the ring buffer, will block IO if the
100
+     * queue is full waiting for one slot to get available.
101
+     *
102
+     * @param duration Duration of the tone in milliseconds
103
+     * @param frequency Frequency of the tone in hertz
104
+     */
105
+    void tone(uint16_t const &duration, uint16_t const &frequency = 0) {
106
+      while (buffer.isFull()) {
107
+        delay(5);
108
+        this->tick();
109
+        #if ENABLED(USE_WATCHDOG)
110
+          watchdog_reset();
111
+        #endif
112
+      }
113
+      this->buffer.enqueue((tone_t) { duration, frequency });
114
+    }
115
+
116
+    /**
117
+     * @brief Loop function
118
+     * @details This function should be called at loop, it will take care of
119
+     * playing the tones in the queue.
120
+     */
121
+    virtual void tick() {
122
+      if (!this->state.timestamp) {
123
+        if (this->buffer.isEmpty()) return;
124
+
125
+        this->state.tone = this->buffer.dequeue();
126
+        this->state.timestamp = millis() + this->state.tone.duration;
127
+        if (this->state.tone.frequency > 0) this->on();
128
+      }
129
+      else if (millis() >= this->state.timestamp) this->reset();
130
+    }
131
+};
132
+
133
+#endif

+ 146
- 0
Marlin/circularqueue.h View File

@@ -0,0 +1,146 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#ifndef __CIRCULARQUEUE_H__
24
+#define __CIRCULARQUEUE_H__
25
+
26
+#include <Arduino.h>
27
+
28
+/**
29
+ * @brief Circular Queue class
30
+ * @details Implementation of the classic ring buffer data structure
31
+ */
32
+template<typename T, int N>
33
+class CircularQueue {
34
+  private:
35
+
36
+    /**
37
+     * @brief Buffer structure
38
+     * @details This structure consolidates all the overhead required to handle
39
+     * a circular queue such as the pointers and the buffer vector.
40
+     */
41
+    struct buffer_t {
42
+      uint8_t head;
43
+      uint8_t tail;
44
+      uint8_t size;
45
+      uint8_t length;
46
+      T queue[N];
47
+    } buffer;
48
+
49
+  public:
50
+    /**
51
+     * @brief Class constructor
52
+     * @details This class requires two template parameters, T defines the type
53
+     * of the items this queue will handle and N defines the maximum number of
54
+     * items that can be stored on the queue.
55
+     */
56
+    CircularQueue<T, N>() {
57
+      this->buffer.length = N;
58
+      this->buffer.size = this->buffer.head = this->buffer.tail = 0;
59
+    }
60
+
61
+    /**
62
+     * @brief Removes and returns a item from the queue
63
+     * @details Removes the oldest item on the queue which is pointed by the
64
+     * buffer_t head variable, this item is then returned to the caller.
65
+     * @return type T item
66
+     */
67
+    T dequeue() {
68
+      if (this->isEmpty()) return T();
69
+
70
+      T const item = this->buffer.queue[this->buffer.head++];
71
+      --this->buffer.size;
72
+
73
+      if (this->buffer.head == this->buffer.length)
74
+        this->buffer.head = 0;
75
+
76
+      return item;
77
+    }
78
+
79
+    /**
80
+     * @brief Adds an item to the queue
81
+     * @details Adds a item to the queue on the location pointed by the buffer_t
82
+     * tail vairable, will return false if there is no queue space available.
83
+     *
84
+     * @param item Item to be added to the queue
85
+     * @return true if the operation was successfull
86
+     */
87
+    bool enqueue(T const &item) {
88
+      if (this->isFull()) return false;
89
+
90
+      this->buffer.queue[this->buffer.tail++] = item;
91
+      ++this->buffer.size;
92
+
93
+      if (this->buffer.tail == this->buffer.length)
94
+        this->buffer.tail = 0;
95
+
96
+      return true;
97
+    }
98
+
99
+    /**
100
+     * @brief Checks if the queue has no items
101
+     * @details Returns true if there are no items on the queue, false otherwise.
102
+     * @return true if queue is empty
103
+     */
104
+    bool isEmpty() {
105
+      return this->buffer.size == 0;
106
+    }
107
+
108
+    /**
109
+     * @brief Checks if the queue is full
110
+     * @details Returns true if the queue is full, false otherwise.
111
+     * @return true if queue is full
112
+     */
113
+    bool isFull() {
114
+      return this->buffer.size == this->buffer.length;
115
+    }
116
+
117
+    /**
118
+     * @brief Gets the queue size
119
+     * @details Returns the maximum number of items a queue can have.
120
+     * @return the queue lenght
121
+     */
122
+    uint8_t length() {
123
+      return this->buffer.length;
124
+    }
125
+
126
+    /**
127
+     * @brief Gets the next item from the queue without removing it
128
+     * @details Returns the next item on the queue but the item is not removed
129
+     * from the queue nor the pointers updated.
130
+     * @return the queue size
131
+     */
132
+    uint8_t peek() {
133
+      return this->buffer.queue[this->buffer.head];
134
+    }
135
+
136
+    /**
137
+     * @brief Gets the number of items on the queue
138
+     * @details Returns the current number of items stored on the queue.
139
+     * @return type T item
140
+     */
141
+    uint8_t size() {
142
+      return this->buffer.size;
143
+    }
144
+};
145
+
146
+#endif

+ 2
- 1
Marlin/pins_MEGATRONICS.h View File

@@ -74,7 +74,8 @@
74 74
 #define TEMP_1_PIN         15   // ANALOG NUMBERING
75 75
 #define TEMP_BED_PIN       14   // ANALOG NUMBERING
76 76
 
77
-#define BEEPER_PIN         33   // AUX-4
77
+// AUX-4
78
+#define BEEPER_PIN         33
78 79
 
79 80
 #if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)
80 81
 

+ 3
- 1
Marlin/pins_MINIRAMBO.h View File

@@ -94,7 +94,9 @@
94 94
 
95 95
   #if ENABLED(NEWPANEL)
96 96
 
97
-    #define BEEPER_PIN      84  // Beeper on AUX-4
97
+    // Beeper on AUX-4
98
+    #define BEEPER_PIN      84
99
+
98 100
     #define LCD_PINS_RS     82
99 101
     #define LCD_PINS_ENABLE 18
100 102
     #define LCD_PINS_D4     19

+ 2
- 1
Marlin/pins_PRINTRBOARD.h View File

@@ -121,7 +121,8 @@
121 121
 #endif // ULTRA_LCD && NEWPANEL
122 122
 
123 123
 #if ENABLED(VIKI2) || ENABLED(miniVIKI)
124
-  #define BEEPER_PIN 32 //FastIO
124
+  //FastIO
125
+  #define BEEPER_PIN 32
125 126
   // Pins for DOGM SPI LCD Support
126 127
   #define DOGLCD_A0  42 //Non-FastIO
127 128
   #define DOGLCD_CS  43 //Non-FastIO

+ 4
- 2
Marlin/pins_RAMBO.h View File

@@ -112,7 +112,8 @@
112 112
 
113 113
   #if ENABLED(NEWPANEL)
114 114
 
115
-    #define BEEPER_PIN 79      // Beeper on AUX-4
115
+    // Beeper on AUX-4
116
+    #define BEEPER_PIN 79
116 117
 
117 118
     #define LCD_PINS_RS 70
118 119
     #define LCD_PINS_ENABLE 71
@@ -134,7 +135,8 @@
134 135
 
135 136
   #else //!NEWPANEL - old style panel with shift register
136 137
 
137
-    #define BEEPER_PIN 33    // No Beeper added
138
+    // No Beeper added
139
+    #define BEEPER_PIN 33
138 140
 
139 141
     //buttons are attached to a shift register
140 142
     // Not wired yet

+ 4
- 2
Marlin/pins_RAMPS_14.h View File

@@ -218,7 +218,8 @@
218 218
 
219 219
     #else
220 220
 
221
-      #define BEEPER_PIN 33  // Beeper on AUX-4
221
+      // Beeper on AUX-4
222
+      #define BEEPER_PIN 33
222 223
 
223 224
       // buttons are directly attached using AUX-2
224 225
       #if ENABLED(REPRAPWORLD_KEYPAD)
@@ -247,7 +248,8 @@
247 248
     #endif
248 249
   #else // !NEWPANEL (Old-style panel with shift register)
249 250
 
250
-    #define BEEPER_PIN 33   // No Beeper added
251
+    // No Beeper added
252
+    #define BEEPER_PIN 33
251 253
 
252 254
     // Buttons are attached to a shift register
253 255
     // Not wired yet

+ 4
- 1
Marlin/pins_SANGUINOLOLU_11.h View File

@@ -105,7 +105,10 @@
105 105
         #define LCD_PINS_RS     30 //CS chip select /SS chip slave select
106 106
         #define LCD_PINS_ENABLE 29 //SID (MOSI)
107 107
         #define LCD_PINS_D4     17 //SCK (CLK) clock
108
-        #define BEEPER_PIN      27 // Pin 27 is taken by LED_PIN, but Melzi LED does nothing with Marlin so this can be used for BEEPER_PIN. You can use this pin with M42 instead of BEEPER_PIN.
108
+        // Pin 27 is taken by LED_PIN, but Melzi LED does nothing with
109
+        // Marlin so this can be used for BEEPER_PIN. You can use this pin
110
+        // with M42 instead of BEEPER_PIN.
111
+        #define BEEPER_PIN      27
109 112
       #else         // Sanguinololu 1.3
110 113
         #define LCD_PINS_RS      4
111 114
         #define LCD_PINS_ENABLE 17

+ 92
- 0
Marlin/speaker.h View File

@@ -0,0 +1,92 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#ifndef __SPEAKER_H__
24
+#define __SPEAKER_H__
25
+
26
+#include "buzzer.h"
27
+
28
+class Speaker: public Buzzer {
29
+  private:
30
+    typedef Buzzer super;
31
+
32
+    struct state_t {
33
+      tone_t   tone;
34
+      uint16_t period;
35
+      uint16_t cycles;
36
+    } state;
37
+
38
+  protected:
39
+    /**
40
+     * @brief Resets the state of the class
41
+     * @details Brings the class state to a known one.
42
+     */
43
+    void reset() {
44
+      super::reset();
45
+      this->state.period = 0;
46
+      this->state.cycles = 0;
47
+    }
48
+
49
+  public:
50
+    /**
51
+     * @brief Class constructor
52
+     */
53
+    Speaker() {
54
+      this->reset();
55
+    }
56
+
57
+    /**
58
+     * @brief Loop function
59
+     * @details This function should be called at loop, it will take care of
60
+     * playing the tones in the queue.
61
+     */
62
+    virtual void tick() {
63
+      if (!this->state.cycles) {
64
+        if (this->buffer.isEmpty()) return;
65
+
66
+        this->reset();
67
+        this->state.tone = this->buffer.dequeue();
68
+
69
+        // Period is uint16, min frequency will be ~16Hz
70
+        this->state.period = 1000000UL / this->state.tone.frequency;
71
+
72
+        this->state.cycles =
73
+          (this->state.tone.duration * 1000L) / this->state.period;
74
+
75
+        this->state.period >>= 1;
76
+        this->state.cycles <<= 1;
77
+
78
+      }
79
+      else {
80
+        uint32_t const us = micros();
81
+        static uint32_t next = us + this->state.period;
82
+
83
+        if (us >= next) {
84
+          --this->state.cycles;
85
+          next = us + this->state.period;
86
+          if (this->state.tone.frequency > 0) this->invert();
87
+        }
88
+      }
89
+    }
90
+};
91
+
92
+#endif

+ 3
- 18
Marlin/ultralcd.cpp View File

@@ -978,8 +978,8 @@ void lcd_cooldown() {
978 978
           lcd_return_to_status();
979 979
           //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE);
980 980
           #if HAS_BUZZER
981
-            buzz(200, 659);
982
-            buzz(200, 698);
981
+            buzzer.tone(200, 659);
982
+            buzzer.tone(200, 698);
983 983
           #endif
984 984
         }
985 985
         else {
@@ -1978,25 +1978,10 @@ void lcd_quick_feedback() {
1978 1978
   next_button_update_ms = millis() + 500;
1979 1979
 
1980 1980
   #if ENABLED(LCD_USE_I2C_BUZZER)
1981
-    #ifndef LCD_FEEDBACK_FREQUENCY_HZ
1982
-      #define LCD_FEEDBACK_FREQUENCY_HZ 100
1983
-    #endif
1984
-    #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
1985
-      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS (1000/6)
1986
-    #endif
1987 1981
     lcd.buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
1988 1982
   #elif PIN_EXISTS(BEEPER)
1989
-    #ifndef LCD_FEEDBACK_FREQUENCY_HZ
1990
-      #define LCD_FEEDBACK_FREQUENCY_HZ 5000
1991
-    #endif
1992
-    #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
1993
-      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
1994
-    #endif
1995
-    buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
1983
+    buzzer.tone(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
1996 1984
   #else
1997
-    #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
1998
-      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
1999
-    #endif
2000 1985
     delay(LCD_FEEDBACK_FREQUENCY_DURATION_MS);
2001 1986
   #endif
2002 1987
 }

Loading…
Cancel
Save