Non-blocking buzzer
This commit is contained in:
		
							parent
							
								
									26f8f54c56
								
							
						
					
					
						commit
						5b5aa1572b
					
				| @ -43,8 +43,7 @@ | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifndef CONFIGURATION_LCD // Get the LCD defines which are needed first
 | #ifndef CONFIGURATION_LCD // Get the LCD defines which are needed first
 | ||||||
| 
 | #define CONFIGURATION_LCD | ||||||
|   #define CONFIGURATION_LCD |  | ||||||
| 
 | 
 | ||||||
|   #define LCD_HAS_DIRECTIONAL_BUTTONS (BUTTON_EXISTS(UP) || BUTTON_EXISTS(DWN) || BUTTON_EXISTS(LFT) || BUTTON_EXISTS(RT)) |   #define LCD_HAS_DIRECTIONAL_BUTTONS (BUTTON_EXISTS(UP) || BUTTON_EXISTS(DWN) || BUTTON_EXISTS(LFT) || BUTTON_EXISTS(RT)) | ||||||
| 
 | 
 | ||||||
| @ -154,11 +153,6 @@ | |||||||
|       #define ENCODER_STEPS_PER_MENU_ITEM 1 |       #define ENCODER_STEPS_PER_MENU_ITEM 1 | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|     #if ENABLED(LCD_USE_I2C_BUZZER) |  | ||||||
|       #define LCD_FEEDBACK_FREQUENCY_HZ 1000 |  | ||||||
|       #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 |  | ||||||
|     #endif |  | ||||||
| 
 |  | ||||||
|     #define ULTIPANEL |     #define ULTIPANEL | ||||||
|     #define NEWPANEL |     #define NEWPANEL | ||||||
|   #endif |   #endif | ||||||
| @ -806,5 +800,27 @@ | |||||||
|     #endif |     #endif | ||||||
|   #endif |   #endif | ||||||
| 
 | 
 | ||||||
|  |   /**
 | ||||||
|  |    * Buzzer/Speaker | ||||||
|  |    */ | ||||||
|  |   #if ENABLED(LCD_USE_I2C_BUZZER) | ||||||
|  |     #ifndef LCD_FEEDBACK_FREQUENCY_HZ | ||||||
|  |       #define LCD_FEEDBACK_FREQUENCY_HZ 1000 | ||||||
|  |     #endif | ||||||
|  |     #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS | ||||||
|  |       #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 | ||||||
|  |     #endif | ||||||
|  |   #elif PIN_EXISTS(BEEPER) | ||||||
|  |     #ifndef LCD_FEEDBACK_FREQUENCY_HZ | ||||||
|  |       #define LCD_FEEDBACK_FREQUENCY_HZ 5000 | ||||||
|  |     #endif | ||||||
|  |     #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS | ||||||
|  |       #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 | ||||||
|  |     #endif | ||||||
|  |   #else | ||||||
|  |     #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS | ||||||
|  |       #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 | ||||||
|  |     #endif | ||||||
|  |   #endif | ||||||
| #endif //CONFIGURATION_LCD
 | #endif //CONFIGURATION_LCD
 | ||||||
| #endif //CONDITIONALS_H
 | #endif //CONDITIONALS_H
 | ||||||
|  | |||||||
| @ -373,4 +373,15 @@ extern uint8_t active_extruder; | |||||||
| 
 | 
 | ||||||
| void calculate_volumetric_multipliers(); | void calculate_volumetric_multipliers(); | ||||||
| 
 | 
 | ||||||
|  | // Buzzer
 | ||||||
|  | #if HAS_BUZZER | ||||||
|  |   #if ENABLED(SPEAKER) | ||||||
|  |     #include "speaker.h" | ||||||
|  |     extern Speaker buzzer; | ||||||
|  |   #else | ||||||
|  |     #include "buzzer.h" | ||||||
|  |     extern Buzzer buzzer; | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #endif //MARLIN_H
 | #endif //MARLIN_H
 | ||||||
|  | |||||||
| @ -59,7 +59,6 @@ | |||||||
| #include "language.h" | #include "language.h" | ||||||
| #include "pins_arduino.h" | #include "pins_arduino.h" | ||||||
| #include "math.h" | #include "math.h" | ||||||
| #include "buzzer.h" |  | ||||||
| 
 | 
 | ||||||
| #if ENABLED(USE_WATCHDOG) | #if ENABLED(USE_WATCHDOG) | ||||||
|   #include "watchdog.h" |   #include "watchdog.h" | ||||||
| @ -354,6 +353,15 @@ static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL | |||||||
|   Stopwatch print_job_timer = Stopwatch(); |   Stopwatch print_job_timer = Stopwatch(); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | // Buzzer
 | ||||||
|  | #if HAS_BUZZER | ||||||
|  |   #if ENABLED(SPEAKER) | ||||||
|  |     Speaker buzzer; | ||||||
|  |   #else | ||||||
|  |     Buzzer buzzer; | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| static uint8_t target_extruder; | static uint8_t target_extruder; | ||||||
| 
 | 
 | ||||||
| #if ENABLED(AUTO_BED_LEVELING_FEATURE) | #if ENABLED(AUTO_BED_LEVELING_FEATURE) | ||||||
| @ -5689,10 +5697,13 @@ inline void gcode_M226() { | |||||||
|    * M300: Play beep sound S<frequency Hz> P<duration ms> |    * M300: Play beep sound S<frequency Hz> P<duration ms> | ||||||
|    */ |    */ | ||||||
|   inline void gcode_M300() { |   inline void gcode_M300() { | ||||||
|     uint16_t beepS = code_seen('S') ? code_value_ushort() : 110; |     uint16_t const frequency = code_seen('S') ? code_value_ushort() : 260; | ||||||
|     uint32_t beepP = code_seen('P') ? code_value_ulong() : 1000; |     uint16_t duration = code_seen('P') ? code_value_ushort() : 1000; | ||||||
|     if (beepP > 5000) beepP = 5000; // limit to 5 seconds
 | 
 | ||||||
|     buzz(beepP, beepS); |     // Limits the tone duration to 0-5 seconds.
 | ||||||
|  |     NOMORE(duration, 5000); | ||||||
|  | 
 | ||||||
|  |     buzzer.tone(duration, frequency); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| #endif // HAS_BUZZER
 | #endif // HAS_BUZZER
 | ||||||
| @ -6173,7 +6184,7 @@ inline void gcode_M428() { | |||||||
|         SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR); |         SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR); | ||||||
|         LCD_ALERTMESSAGEPGM("Err: Too far!"); |         LCD_ALERTMESSAGEPGM("Err: Too far!"); | ||||||
|         #if HAS_BUZZER |         #if HAS_BUZZER | ||||||
|           buzz(200, 40); |           buzzer.tone(200, 40); | ||||||
|         #endif |         #endif | ||||||
|         err = true; |         err = true; | ||||||
|         break; |         break; | ||||||
| @ -6190,8 +6201,8 @@ inline void gcode_M428() { | |||||||
|     report_current_position(); |     report_current_position(); | ||||||
|     LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED); |     LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED); | ||||||
|     #if HAS_BUZZER |     #if HAS_BUZZER | ||||||
|       buzz(200, 659); |       buzzer.tone(200, 659); | ||||||
|       buzz(200, 698); |       buzzer.tone(200, 698); | ||||||
|     #endif |     #endif | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -8076,17 +8087,23 @@ void idle( | |||||||
|     bool no_stepper_sleep/*=false*/ |     bool no_stepper_sleep/*=false*/ | ||||||
|   #endif |   #endif | ||||||
| ) { | ) { | ||||||
|   thermalManager.manage_heater(); |   lcd_update(); | ||||||
|  |   host_keepalive(); | ||||||
|   manage_inactivity( |   manage_inactivity( | ||||||
|     #if ENABLED(FILAMENTCHANGEENABLE) |     #if ENABLED(FILAMENTCHANGEENABLE) | ||||||
|       no_stepper_sleep |       no_stepper_sleep | ||||||
|     #endif |     #endif | ||||||
|   ); |   ); | ||||||
|   host_keepalive(); | 
 | ||||||
|   lcd_update(); |   thermalManager.manage_heater(); | ||||||
|  | 
 | ||||||
|   #if ENABLED(PRINTCOUNTER) |   #if ENABLED(PRINTCOUNTER) | ||||||
|     print_job_timer.tick(); |     print_job_timer.tick(); | ||||||
|   #endif |   #endif | ||||||
|  | 
 | ||||||
|  |   #if HAS_BUZZER | ||||||
|  |     buzzer.tick(); | ||||||
|  |   #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | |||||||
| @ -1,57 +0,0 @@ | |||||||
| /**
 |  | ||||||
|  * Marlin 3D Printer Firmware |  | ||||||
|  * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
 |  | ||||||
|  * |  | ||||||
|  * Based on Sprinter and grbl. |  | ||||||
|  * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU General Public License as published by |  | ||||||
|  * the Free Software Foundation, either version 3 of the License, or |  | ||||||
|  * (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU General Public License |  | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include "Marlin.h" |  | ||||||
| #if HAS_BUZZER |  | ||||||
|   #include "buzzer.h" |  | ||||||
|   #include "ultralcd.h" |  | ||||||
| 
 |  | ||||||
|   void buzz(long duration, uint16_t freq) { |  | ||||||
|     if (freq > 0) { |  | ||||||
|       #if ENABLED(LCD_USE_I2C_BUZZER) |  | ||||||
|         lcd_buzz(duration, freq); |  | ||||||
|       #elif PIN_EXISTS(BEEPER) // on-board buzzers have no further condition
 |  | ||||||
|         SET_OUTPUT(BEEPER_PIN); |  | ||||||
|         #if ENABLED(SPEAKER) // a speaker needs a AC ore a pulsed DC
 |  | ||||||
|           //tone(BEEPER_PIN, freq, duration); // needs a PWMable pin
 |  | ||||||
|           unsigned int delay = 1000000 / freq / 2; |  | ||||||
|           int i = duration * freq / 1000; |  | ||||||
|           while (i--) { |  | ||||||
|             WRITE(BEEPER_PIN, HIGH); |  | ||||||
|             delayMicroseconds(delay); |  | ||||||
|             WRITE(BEEPER_PIN, LOW); |  | ||||||
|             delayMicroseconds(delay); |  | ||||||
|            } |  | ||||||
|         #else // buzzer has its own resonator - needs a DC
 |  | ||||||
|           WRITE(BEEPER_PIN, HIGH); |  | ||||||
|           delay(duration); |  | ||||||
|           WRITE(BEEPER_PIN, LOW); |  | ||||||
|         #endif |  | ||||||
|       #else |  | ||||||
|         delay(duration); |  | ||||||
|       #endif |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       delay(duration); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| #endif |  | ||||||
							
								
								
									
										115
									
								
								Marlin/buzzer.h
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								Marlin/buzzer.h
									
									
									
									
									
								
							| @ -20,11 +20,114 @@ | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef BUZZER_H | #ifndef __BUZZER_H__ | ||||||
|   #define BUZZER_H | #define __BUZZER_H__ | ||||||
| 
 | 
 | ||||||
|   #if HAS_BUZZER | #include "fastio.h" | ||||||
|     void buzz(long duration, uint16_t freq); | #include "watchdog.h" | ||||||
|   #endif | #include "circularqueue.h" | ||||||
| 
 | 
 | ||||||
| #endif //BUZZER_H
 | #define TONE_QUEUE_LENGTH 4 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Tone structure | ||||||
|  |  * @details Simple abstration of a tone based on a duration and a frequency. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | struct tone_t { | ||||||
|  |   uint16_t duration; | ||||||
|  |   uint16_t frequency; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Buzzer class | ||||||
|  |  */ | ||||||
|  | class Buzzer { | ||||||
|  |   private: | ||||||
|  |     struct state_t { | ||||||
|  |       tone_t   tone; | ||||||
|  |       uint32_t timestamp; | ||||||
|  |     } state; | ||||||
|  | 
 | ||||||
|  |   protected: | ||||||
|  |     CircularQueue<tone_t, TONE_QUEUE_LENGTH> buffer; | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Inverts the sate of a digital PIN | ||||||
|  |      * @details This will invert the current state of an digital IO pin. | ||||||
|  |      */ | ||||||
|  |     void invert() { | ||||||
|  |       WRITE(BEEPER_PIN, !READ(BEEPER_PIN)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Turn off a digital PIN | ||||||
|  |      * @details Alias of digitalWrite(PIN, LOW) using FastIO | ||||||
|  |      */ | ||||||
|  |     void off() { | ||||||
|  |       WRITE(BEEPER_PIN, LOW); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Turn on a digital PIN | ||||||
|  |      * @details Alias of digitalWrite(PIN, HIGH) using FastIO | ||||||
|  |      */ | ||||||
|  |     void on() { | ||||||
|  |       WRITE(BEEPER_PIN, HIGH); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Resets the state of the class | ||||||
|  |      * @details Brings the class state to a known one. | ||||||
|  |      */ | ||||||
|  |     void reset() { | ||||||
|  |       this->off(); | ||||||
|  |       this->state.timestamp = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     /**
 | ||||||
|  |      * @brief Class constructor | ||||||
|  |      */ | ||||||
|  |     Buzzer() { | ||||||
|  |       SET_OUTPUT(BEEPER_PIN); | ||||||
|  |       this->reset(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Add a tone to the queue | ||||||
|  |      * @details Adds a tone_t structure to the ring buffer, will block IO if the | ||||||
|  |      * queue is full waiting for one slot to get available. | ||||||
|  |      * | ||||||
|  |      * @param duration Duration of the tone in milliseconds | ||||||
|  |      * @param frequency Frequency of the tone in hertz | ||||||
|  |      */ | ||||||
|  |     void tone(uint16_t const &duration, uint16_t const &frequency = 0) { | ||||||
|  |       while (buffer.isFull()) { | ||||||
|  |         delay(5); | ||||||
|  |         this->tick(); | ||||||
|  |         #if ENABLED(USE_WATCHDOG) | ||||||
|  |           watchdog_reset(); | ||||||
|  |         #endif | ||||||
|  |       } | ||||||
|  |       this->buffer.enqueue((tone_t) { duration, frequency }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Loop function | ||||||
|  |      * @details This function should be called at loop, it will take care of | ||||||
|  |      * playing the tones in the queue. | ||||||
|  |      */ | ||||||
|  |     virtual void tick() { | ||||||
|  |       if (!this->state.timestamp) { | ||||||
|  |         if (this->buffer.isEmpty()) return; | ||||||
|  | 
 | ||||||
|  |         this->state.tone = this->buffer.dequeue(); | ||||||
|  |         this->state.timestamp = millis() + this->state.tone.duration; | ||||||
|  |         if (this->state.tone.frequency > 0) this->on(); | ||||||
|  |       } | ||||||
|  |       else if (millis() >= this->state.timestamp) this->reset(); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | |||||||
							
								
								
									
										146
									
								
								Marlin/circularqueue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								Marlin/circularqueue.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,146 @@ | |||||||
|  | /**
 | ||||||
|  |  * Marlin 3D Printer Firmware | ||||||
|  |  * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
 | ||||||
|  |  * | ||||||
|  |  * Based on Sprinter and grbl. | ||||||
|  |  * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CIRCULARQUEUE_H__ | ||||||
|  | #define __CIRCULARQUEUE_H__ | ||||||
|  | 
 | ||||||
|  | #include <Arduino.h> | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Circular Queue class | ||||||
|  |  * @details Implementation of the classic ring buffer data structure | ||||||
|  |  */ | ||||||
|  | template<typename T, int N> | ||||||
|  | class CircularQueue { | ||||||
|  |   private: | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Buffer structure | ||||||
|  |      * @details This structure consolidates all the overhead required to handle | ||||||
|  |      * a circular queue such as the pointers and the buffer vector. | ||||||
|  |      */ | ||||||
|  |     struct buffer_t { | ||||||
|  |       uint8_t head; | ||||||
|  |       uint8_t tail; | ||||||
|  |       uint8_t size; | ||||||
|  |       uint8_t length; | ||||||
|  |       T queue[N]; | ||||||
|  |     } buffer; | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     /**
 | ||||||
|  |      * @brief Class constructor | ||||||
|  |      * @details This class requires two template parameters, T defines the type | ||||||
|  |      * of the items this queue will handle and N defines the maximum number of | ||||||
|  |      * items that can be stored on the queue. | ||||||
|  |      */ | ||||||
|  |     CircularQueue<T, N>() { | ||||||
|  |       this->buffer.length = N; | ||||||
|  |       this->buffer.size = this->buffer.head = this->buffer.tail = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Removes and returns a item from the queue | ||||||
|  |      * @details Removes the oldest item on the queue which is pointed by the | ||||||
|  |      * buffer_t head variable, this item is then returned to the caller. | ||||||
|  |      * @return type T item | ||||||
|  |      */ | ||||||
|  |     T dequeue() { | ||||||
|  |       if (this->isEmpty()) return T(); | ||||||
|  | 
 | ||||||
|  |       T const item = this->buffer.queue[this->buffer.head++]; | ||||||
|  |       --this->buffer.size; | ||||||
|  | 
 | ||||||
|  |       if (this->buffer.head == this->buffer.length) | ||||||
|  |         this->buffer.head = 0; | ||||||
|  | 
 | ||||||
|  |       return item; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Adds an item to the queue | ||||||
|  |      * @details Adds a item to the queue on the location pointed by the buffer_t | ||||||
|  |      * tail vairable, will return false if there is no queue space available. | ||||||
|  |      * | ||||||
|  |      * @param item Item to be added to the queue | ||||||
|  |      * @return true if the operation was successfull | ||||||
|  |      */ | ||||||
|  |     bool enqueue(T const &item) { | ||||||
|  |       if (this->isFull()) return false; | ||||||
|  | 
 | ||||||
|  |       this->buffer.queue[this->buffer.tail++] = item; | ||||||
|  |       ++this->buffer.size; | ||||||
|  | 
 | ||||||
|  |       if (this->buffer.tail == this->buffer.length) | ||||||
|  |         this->buffer.tail = 0; | ||||||
|  | 
 | ||||||
|  |       return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Checks if the queue has no items | ||||||
|  |      * @details Returns true if there are no items on the queue, false otherwise. | ||||||
|  |      * @return true if queue is empty | ||||||
|  |      */ | ||||||
|  |     bool isEmpty() { | ||||||
|  |       return this->buffer.size == 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Checks if the queue is full | ||||||
|  |      * @details Returns true if the queue is full, false otherwise. | ||||||
|  |      * @return true if queue is full | ||||||
|  |      */ | ||||||
|  |     bool isFull() { | ||||||
|  |       return this->buffer.size == this->buffer.length; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Gets the queue size | ||||||
|  |      * @details Returns the maximum number of items a queue can have. | ||||||
|  |      * @return the queue lenght | ||||||
|  |      */ | ||||||
|  |     uint8_t length() { | ||||||
|  |       return this->buffer.length; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Gets the next item from the queue without removing it | ||||||
|  |      * @details Returns the next item on the queue but the item is not removed | ||||||
|  |      * from the queue nor the pointers updated. | ||||||
|  |      * @return the queue size | ||||||
|  |      */ | ||||||
|  |     uint8_t peek() { | ||||||
|  |       return this->buffer.queue[this->buffer.head]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Gets the number of items on the queue | ||||||
|  |      * @details Returns the current number of items stored on the queue. | ||||||
|  |      * @return type T item | ||||||
|  |      */ | ||||||
|  |     uint8_t size() { | ||||||
|  |       return this->buffer.size; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -74,7 +74,8 @@ | |||||||
| #define TEMP_1_PIN         15   // ANALOG NUMBERING
 | #define TEMP_1_PIN         15   // ANALOG NUMBERING
 | ||||||
| #define TEMP_BED_PIN       14   // ANALOG NUMBERING
 | #define TEMP_BED_PIN       14   // ANALOG NUMBERING
 | ||||||
| 
 | 
 | ||||||
| #define BEEPER_PIN         33   // AUX-4
 | // AUX-4
 | ||||||
|  | #define BEEPER_PIN         33 | ||||||
| 
 | 
 | ||||||
| #if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) | #if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -94,7 +94,9 @@ | |||||||
| 
 | 
 | ||||||
|   #if ENABLED(NEWPANEL) |   #if ENABLED(NEWPANEL) | ||||||
| 
 | 
 | ||||||
|     #define BEEPER_PIN      84  // Beeper on AUX-4
 |     // Beeper on AUX-4
 | ||||||
|  |     #define BEEPER_PIN      84 | ||||||
|  | 
 | ||||||
|     #define LCD_PINS_RS     82 |     #define LCD_PINS_RS     82 | ||||||
|     #define LCD_PINS_ENABLE 18 |     #define LCD_PINS_ENABLE 18 | ||||||
|     #define LCD_PINS_D4     19 |     #define LCD_PINS_D4     19 | ||||||
|  | |||||||
| @ -121,7 +121,8 @@ | |||||||
| #endif // ULTRA_LCD && NEWPANEL
 | #endif // ULTRA_LCD && NEWPANEL
 | ||||||
| 
 | 
 | ||||||
| #if ENABLED(VIKI2) || ENABLED(miniVIKI) | #if ENABLED(VIKI2) || ENABLED(miniVIKI) | ||||||
|   #define BEEPER_PIN 32 //FastIO
 |   //FastIO
 | ||||||
|  |   #define BEEPER_PIN 32 | ||||||
|   // Pins for DOGM SPI LCD Support
 |   // Pins for DOGM SPI LCD Support
 | ||||||
|   #define DOGLCD_A0  42 //Non-FastIO
 |   #define DOGLCD_A0  42 //Non-FastIO
 | ||||||
|   #define DOGLCD_CS  43 //Non-FastIO
 |   #define DOGLCD_CS  43 //Non-FastIO
 | ||||||
|  | |||||||
| @ -112,7 +112,8 @@ | |||||||
| 
 | 
 | ||||||
|   #if ENABLED(NEWPANEL) |   #if ENABLED(NEWPANEL) | ||||||
| 
 | 
 | ||||||
|     #define BEEPER_PIN 79      // Beeper on AUX-4
 |     // Beeper on AUX-4
 | ||||||
|  |     #define BEEPER_PIN 79 | ||||||
| 
 | 
 | ||||||
|     #define LCD_PINS_RS 70 |     #define LCD_PINS_RS 70 | ||||||
|     #define LCD_PINS_ENABLE 71 |     #define LCD_PINS_ENABLE 71 | ||||||
| @ -134,7 +135,8 @@ | |||||||
| 
 | 
 | ||||||
|   #else //!NEWPANEL - old style panel with shift register
 |   #else //!NEWPANEL - old style panel with shift register
 | ||||||
| 
 | 
 | ||||||
|     #define BEEPER_PIN 33    // No Beeper added
 |     // No Beeper added
 | ||||||
|  |     #define BEEPER_PIN 33 | ||||||
| 
 | 
 | ||||||
|     //buttons are attached to a shift register
 |     //buttons are attached to a shift register
 | ||||||
|     // Not wired yet
 |     // Not wired yet
 | ||||||
|  | |||||||
| @ -218,7 +218,8 @@ | |||||||
| 
 | 
 | ||||||
|     #else |     #else | ||||||
| 
 | 
 | ||||||
|       #define BEEPER_PIN 33  // Beeper on AUX-4
 |       // Beeper on AUX-4
 | ||||||
|  |       #define BEEPER_PIN 33 | ||||||
| 
 | 
 | ||||||
|       // buttons are directly attached using AUX-2
 |       // buttons are directly attached using AUX-2
 | ||||||
|       #if ENABLED(REPRAPWORLD_KEYPAD) |       #if ENABLED(REPRAPWORLD_KEYPAD) | ||||||
| @ -247,7 +248,8 @@ | |||||||
|     #endif |     #endif | ||||||
|   #else // !NEWPANEL (Old-style panel with shift register)
 |   #else // !NEWPANEL (Old-style panel with shift register)
 | ||||||
| 
 | 
 | ||||||
|     #define BEEPER_PIN 33   // No Beeper added
 |     // No Beeper added
 | ||||||
|  |     #define BEEPER_PIN 33 | ||||||
| 
 | 
 | ||||||
|     // Buttons are attached to a shift register
 |     // Buttons are attached to a shift register
 | ||||||
|     // Not wired yet
 |     // Not wired yet
 | ||||||
|  | |||||||
| @ -105,7 +105,10 @@ | |||||||
|         #define LCD_PINS_RS     30 //CS chip select /SS chip slave select
 |         #define LCD_PINS_RS     30 //CS chip select /SS chip slave select
 | ||||||
|         #define LCD_PINS_ENABLE 29 //SID (MOSI)
 |         #define LCD_PINS_ENABLE 29 //SID (MOSI)
 | ||||||
|         #define LCD_PINS_D4     17 //SCK (CLK) clock
 |         #define LCD_PINS_D4     17 //SCK (CLK) clock
 | ||||||
|         #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.
 |         // 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.
 | ||||||
|  |         #define BEEPER_PIN      27 | ||||||
|       #else         // Sanguinololu 1.3
 |       #else         // Sanguinololu 1.3
 | ||||||
|         #define LCD_PINS_RS      4 |         #define LCD_PINS_RS      4 | ||||||
|         #define LCD_PINS_ENABLE 17 |         #define LCD_PINS_ENABLE 17 | ||||||
|  | |||||||
							
								
								
									
										92
									
								
								Marlin/speaker.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								Marlin/speaker.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,92 @@ | |||||||
|  | /**
 | ||||||
|  |  * Marlin 3D Printer Firmware | ||||||
|  |  * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
 | ||||||
|  |  * | ||||||
|  |  * Based on Sprinter and grbl. | ||||||
|  |  * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __SPEAKER_H__ | ||||||
|  | #define __SPEAKER_H__ | ||||||
|  | 
 | ||||||
|  | #include "buzzer.h" | ||||||
|  | 
 | ||||||
|  | class Speaker: public Buzzer { | ||||||
|  |   private: | ||||||
|  |     typedef Buzzer super; | ||||||
|  | 
 | ||||||
|  |     struct state_t { | ||||||
|  |       tone_t   tone; | ||||||
|  |       uint16_t period; | ||||||
|  |       uint16_t cycles; | ||||||
|  |     } state; | ||||||
|  | 
 | ||||||
|  |   protected: | ||||||
|  |     /**
 | ||||||
|  |      * @brief Resets the state of the class | ||||||
|  |      * @details Brings the class state to a known one. | ||||||
|  |      */ | ||||||
|  |     void reset() { | ||||||
|  |       super::reset(); | ||||||
|  |       this->state.period = 0; | ||||||
|  |       this->state.cycles = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     /**
 | ||||||
|  |      * @brief Class constructor | ||||||
|  |      */ | ||||||
|  |     Speaker() { | ||||||
|  |       this->reset(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Loop function | ||||||
|  |      * @details This function should be called at loop, it will take care of | ||||||
|  |      * playing the tones in the queue. | ||||||
|  |      */ | ||||||
|  |     virtual void tick() { | ||||||
|  |       if (!this->state.cycles) { | ||||||
|  |         if (this->buffer.isEmpty()) return; | ||||||
|  | 
 | ||||||
|  |         this->reset(); | ||||||
|  |         this->state.tone = this->buffer.dequeue(); | ||||||
|  | 
 | ||||||
|  |         // Period is uint16, min frequency will be ~16Hz
 | ||||||
|  |         this->state.period = 1000000UL / this->state.tone.frequency; | ||||||
|  | 
 | ||||||
|  |         this->state.cycles = | ||||||
|  |           (this->state.tone.duration * 1000L) / this->state.period; | ||||||
|  | 
 | ||||||
|  |         this->state.period >>= 1; | ||||||
|  |         this->state.cycles <<= 1; | ||||||
|  | 
 | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         uint32_t const us = micros(); | ||||||
|  |         static uint32_t next = us + this->state.period; | ||||||
|  | 
 | ||||||
|  |         if (us >= next) { | ||||||
|  |           --this->state.cycles; | ||||||
|  |           next = us + this->state.period; | ||||||
|  |           if (this->state.tone.frequency > 0) this->invert(); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -978,8 +978,8 @@ void lcd_cooldown() { | |||||||
|           lcd_return_to_status(); |           lcd_return_to_status(); | ||||||
|           //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE);
 |           //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE);
 | ||||||
|           #if HAS_BUZZER |           #if HAS_BUZZER | ||||||
|             buzz(200, 659); |             buzzer.tone(200, 659); | ||||||
|             buzz(200, 698); |             buzzer.tone(200, 698); | ||||||
|           #endif |           #endif | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
| @ -1978,25 +1978,10 @@ void lcd_quick_feedback() { | |||||||
|   next_button_update_ms = millis() + 500; |   next_button_update_ms = millis() + 500; | ||||||
| 
 | 
 | ||||||
|   #if ENABLED(LCD_USE_I2C_BUZZER) |   #if ENABLED(LCD_USE_I2C_BUZZER) | ||||||
|     #ifndef LCD_FEEDBACK_FREQUENCY_HZ |  | ||||||
|       #define LCD_FEEDBACK_FREQUENCY_HZ 100 |  | ||||||
|     #endif |  | ||||||
|     #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS |  | ||||||
|       #define LCD_FEEDBACK_FREQUENCY_DURATION_MS (1000/6) |  | ||||||
|     #endif |  | ||||||
|     lcd.buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); |     lcd.buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); | ||||||
|   #elif PIN_EXISTS(BEEPER) |   #elif PIN_EXISTS(BEEPER) | ||||||
|     #ifndef LCD_FEEDBACK_FREQUENCY_HZ |     buzzer.tone(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); | ||||||
|       #define LCD_FEEDBACK_FREQUENCY_HZ 5000 |  | ||||||
|     #endif |  | ||||||
|     #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS |  | ||||||
|       #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 |  | ||||||
|     #endif |  | ||||||
|     buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); |  | ||||||
|   #else |   #else | ||||||
|     #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS |  | ||||||
|       #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 |  | ||||||
|     #endif |  | ||||||
|     delay(LCD_FEEDBACK_FREQUENCY_DURATION_MS); |     delay(LCD_FEEDBACK_FREQUENCY_DURATION_MS); | ||||||
|   #endif |   #endif | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user