diff --git a/.travis.yml b/.travis.yml
index 088f1c56cf7da34a206809c7bdb87d913417e32e..a493d9c236bf40016a0ac550ad33c5f227610858 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -121,6 +121,15 @@ script:
   - opt_enable_adv DUAL_X_CARRIAGE
   - build_marlin
   #
+  # Test SPEAKER with BOARD_BQ_ZUM_MEGA_3D and BQ_LCD_SMART_CONTROLLER
+  #
+  - restore_configs
+  - opt_set MOTHERBOARD BOARD_BQ_ZUM_MEGA_3D
+  - opt_set LCD_FEEDBACK_FREQUENCY_DURATION_MS 10
+  - opt_set LCD_FEEDBACK_FREQUENCY_HZ 100
+  - opt_enable BQ_LCD_SMART_CONTROLLER SPEAKER
+  - build_marlin
+  #
   ### LCDS ###
   #
   #
diff --git a/Marlin/Conditionals.h b/Marlin/Conditionals.h
index 54b111bb655aabe16be1896c8f73d4669909c654..74e0d1c3d223090890d006ca30c771664fb9f0f8 100644
--- a/Marlin/Conditionals.h
+++ b/Marlin/Conditionals.h
@@ -43,8 +43,7 @@
 #endif
 
 #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))
 
@@ -154,11 +153,6 @@
       #define ENCODER_STEPS_PER_MENU_ITEM 1
     #endif
 
-    #if ENABLED(LCD_USE_I2C_BUZZER)
-      #define LCD_FEEDBACK_FREQUENCY_HZ 1000
-      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
-    #endif
-
     #define ULTIPANEL
     #define NEWPANEL
   #endif
@@ -806,5 +800,27 @@
     #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 //CONDITIONALS_H
diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 7b275b0cb8d7014ae201b57d8e92656a65cca547..1a3a170c7b392098a714c2f50e131cc8f7798d63 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -373,4 +373,15 @@ extern uint8_t active_extruder;
 
 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
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 475dea4aa223cc598421b5a25c8215800a3c1cca..7142d968214dd7782855f934bc63fe116d1e1b8b 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -59,7 +59,6 @@
 #include "language.h"
 #include "pins_arduino.h"
 #include "math.h"
-#include "buzzer.h"
 
 #if ENABLED(USE_WATCHDOG)
   #include "watchdog.h"
@@ -354,6 +353,15 @@ static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL
   Stopwatch print_job_timer = Stopwatch();
 #endif
 
+// Buzzer
+#if HAS_BUZZER
+  #if ENABLED(SPEAKER)
+    Speaker buzzer;
+  #else
+    Buzzer buzzer;
+  #endif
+#endif
+
 static uint8_t target_extruder;
 
 #if ENABLED(AUTO_BED_LEVELING_FEATURE)
@@ -1233,7 +1241,7 @@ inline bool code_value_bool() { return code_value_byte() > 0; }
 
 #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
   inline void set_input_temp_units(TempUnit units) { input_temp_units = units; }
-  
+
   float code_value_temp_abs() {
     switch (input_temp_units) {
       case TEMPUNIT_C:
@@ -5689,10 +5697,13 @@ inline void gcode_M226() {
    * M300: Play beep sound S<frequency Hz> P<duration ms>
    */
   inline void gcode_M300() {
-    uint16_t beepS = code_seen('S') ? code_value_ushort() : 110;
-    uint32_t beepP = code_seen('P') ? code_value_ulong() : 1000;
-    if (beepP > 5000) beepP = 5000; // limit to 5 seconds
-    buzz(beepP, beepS);
+    uint16_t const frequency = code_seen('S') ? code_value_ushort() : 260;
+    uint16_t duration = code_seen('P') ? code_value_ushort() : 1000;
+
+    // Limits the tone duration to 0-5 seconds.
+    NOMORE(duration, 5000);
+
+    buzzer.tone(duration, frequency);
   }
 
 #endif // HAS_BUZZER
@@ -6173,7 +6184,7 @@ inline void gcode_M428() {
         SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
         LCD_ALERTMESSAGEPGM("Err: Too far!");
         #if HAS_BUZZER
-          buzz(200, 40);
+          buzzer.tone(200, 40);
         #endif
         err = true;
         break;
@@ -6190,8 +6201,8 @@ inline void gcode_M428() {
     report_current_position();
     LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED);
     #if HAS_BUZZER
-      buzz(200, 659);
-      buzz(200, 698);
+      buzzer.tone(200, 659);
+      buzzer.tone(200, 698);
     #endif
   }
 }
@@ -8076,17 +8087,23 @@ void idle(
     bool no_stepper_sleep/*=false*/
   #endif
 ) {
-  thermalManager.manage_heater();
+  lcd_update();
+  host_keepalive();
   manage_inactivity(
     #if ENABLED(FILAMENTCHANGEENABLE)
       no_stepper_sleep
     #endif
   );
-  host_keepalive();
-  lcd_update();
+
+  thermalManager.manage_heater();
+
   #if ENABLED(PRINTCOUNTER)
     print_job_timer.tick();
   #endif
+
+  #if HAS_BUZZER
+    buzzer.tick();
+  #endif
 }
 
 /**
diff --git a/Marlin/buzzer.cpp b/Marlin/buzzer.cpp
deleted file mode 100644
index 776ea4dfaedc9a3ff92a66399bb495aa394420b2..0000000000000000000000000000000000000000
--- a/Marlin/buzzer.cpp
+++ /dev/null
@@ -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
diff --git a/Marlin/buzzer.h b/Marlin/buzzer.h
index ec568ecd87da6fba11c9f2216ce951e87affe520..2e436259e46ff63fb1a55e8ac4f235646b28ba1c 100644
--- a/Marlin/buzzer.h
+++ b/Marlin/buzzer.h
@@ -20,11 +20,114 @@
  *
  */
 
-#ifndef BUZZER_H
-  #define BUZZER_H
+#ifndef __BUZZER_H__
+#define __BUZZER_H__
 
-  #if HAS_BUZZER
-    void buzz(long duration, uint16_t freq);
-  #endif
+#include "fastio.h"
+#include "watchdog.h"
+#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
diff --git a/Marlin/circularqueue.h b/Marlin/circularqueue.h
new file mode 100644
index 0000000000000000000000000000000000000000..99efd244efd3d9871d54f10322e62ce3fed31d26
--- /dev/null
+++ b/Marlin/circularqueue.h
@@ -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
diff --git a/Marlin/pins_BQ_ZUM_MEGA_3D.h b/Marlin/pins_BQ_ZUM_MEGA_3D.h
index c6b53d8703464d67a0350d96976dbd2b8250254c..13f81a9cedfef5e4e76f0aaa6f465105fa126756 100644
--- a/Marlin/pins_BQ_ZUM_MEGA_3D.h
+++ b/Marlin/pins_BQ_ZUM_MEGA_3D.h
@@ -59,23 +59,6 @@
 #undef PS_ON_PIN             // 12
 #define PS_ON_PIN         81 // External Power Supply
 
-#if ENABLED(BQ_LCD_SMART_CONTROLLER) // Most similar to REPRAP_DISCOUNT_SMART_CONTROLLER
-  #define KILL_PIN        41
-
-  #define BEEPER_PIN      37
-
-  #define BTN_EN1         31
-  #define BTN_EN2         33
-  #define BTN_ENC         35
-
-  #define LCD_PIN_BL      39
-  #define LCD_PINS_RS     16
-  #define LCD_PINS_ENABLE 17
-  #define LCD_PINS_D4     23
-
-  #define SD_DETECT_PIN   49
-#endif
-
 #if ENABLED(AUTO_BED_LEVELING_FEATURE)
   #undef Z_MIN_PIN
   #undef Z_MAX_PIN
diff --git a/Marlin/pins_MEGATRONICS.h b/Marlin/pins_MEGATRONICS.h
index 3cd467db86bc484e41f76739d60f09b7ffb83be8..b8022e642a4e31a5c34ad174ef91c6f0f7019a06 100644
--- a/Marlin/pins_MEGATRONICS.h
+++ b/Marlin/pins_MEGATRONICS.h
@@ -74,7 +74,8 @@
 #define TEMP_1_PIN         15   // 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)
 
diff --git a/Marlin/pins_MINIRAMBO.h b/Marlin/pins_MINIRAMBO.h
index 1485c72bc1552a157a21a189d9ed2c42fac9e5e7..29bc9dfb533352f79e1b57f5a4b38c601a177fe0 100644
--- a/Marlin/pins_MINIRAMBO.h
+++ b/Marlin/pins_MINIRAMBO.h
@@ -94,7 +94,9 @@
 
   #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_ENABLE 18
     #define LCD_PINS_D4     19
diff --git a/Marlin/pins_PRINTRBOARD.h b/Marlin/pins_PRINTRBOARD.h
index 5534589cb4f298d33fae93aff3663dfa1b1eb684..91455a615e4ece57821de864d97ddce9343b0195 100644
--- a/Marlin/pins_PRINTRBOARD.h
+++ b/Marlin/pins_PRINTRBOARD.h
@@ -121,7 +121,8 @@
 #endif // ULTRA_LCD && NEWPANEL
 
 #if ENABLED(VIKI2) || ENABLED(miniVIKI)
-  #define BEEPER_PIN 32 //FastIO
+  //FastIO
+  #define BEEPER_PIN 32
   // Pins for DOGM SPI LCD Support
   #define DOGLCD_A0  42 //Non-FastIO
   #define DOGLCD_CS  43 //Non-FastIO
diff --git a/Marlin/pins_RAMBO.h b/Marlin/pins_RAMBO.h
index a42731a1ad3391737d8cb19f0aa7ef7572b3410b..0e7c7aadee1a545ca366bf1b8f6f011d853a4dd4 100644
--- a/Marlin/pins_RAMBO.h
+++ b/Marlin/pins_RAMBO.h
@@ -112,7 +112,8 @@
 
   #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_ENABLE 71
@@ -134,7 +135,8 @@
 
   #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
     // Not wired yet
diff --git a/Marlin/pins_RAMPS_14.h b/Marlin/pins_RAMPS_14.h
index 9c8caa27c25978875eb37ddf87035345ec3477b4..32232af4b1752fe2a5b9cea9bc16b495db49d4bd 100644
--- a/Marlin/pins_RAMPS_14.h
+++ b/Marlin/pins_RAMPS_14.h
@@ -116,10 +116,6 @@
 
 #define PS_ON_PIN          12
 
-#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) || ENABLED(G3D_PANEL)
-  #define KILL_PIN         41
-#endif
-
 #if MB(RAMPS_14_EFF) || MB(RAMPS_13_EFF)
   #define HEATER_0_PIN      8
 #else
@@ -168,6 +164,12 @@
       #define BTN_ENC 35
 
       #define SD_DETECT_PIN 49
+      #define KILL_PIN 41
+
+      #if ENABLED(BQ_LCD_SMART_CONTROLLER)
+        #define LCD_PIN_BL 39
+      #endif
+
     #elif ENABLED(LCD_I2C_PANELOLU2)
       #define BTN_EN1 47  // reverse if the encoder turns the wrong way.
       #define BTN_EN2 43
@@ -218,7 +220,8 @@
 
     #else
 
-      #define BEEPER_PIN 33  // Beeper on AUX-4
+      // Beeper on AUX-4
+      #define BEEPER_PIN 33
 
       // buttons are directly attached using AUX-2
       #if ENABLED(REPRAPWORLD_KEYPAD)
@@ -240,6 +243,7 @@
 
       #if ENABLED(G3D_PANEL)
         #define SD_DETECT_PIN 49
+        #define KILL_PIN 41
       #else
         //        #define SD_DETECT_PIN -1  // Ramps doesn't use this
       #endif
@@ -247,7 +251,8 @@
     #endif
   #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
     // Not wired yet
@@ -280,7 +285,3 @@
   #define MISO_PIN         50
   #define MOSI_PIN         51
 #endif
-
-#ifndef KILL_PIN
-  //  #define KILL_PIN         -1
-#endif
diff --git a/Marlin/pins_SANGUINOLOLU_11.h b/Marlin/pins_SANGUINOLOLU_11.h
index bd77226403586c5c779e2e5293b3e29aa797e4f2..9b00788c30f649d1fcb000760004a174c55d894c 100644
--- a/Marlin/pins_SANGUINOLOLU_11.h
+++ b/Marlin/pins_SANGUINOLOLU_11.h
@@ -105,7 +105,10 @@
         #define LCD_PINS_RS     30 //CS chip select /SS chip slave select
         #define LCD_PINS_ENABLE 29 //SID (MOSI)
         #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
         #define LCD_PINS_RS      4
         #define LCD_PINS_ENABLE 17
diff --git a/Marlin/speaker.h b/Marlin/speaker.h
new file mode 100644
index 0000000000000000000000000000000000000000..93aa6f7361874559cb45bccf4bdfbc70cd785598
--- /dev/null
+++ b/Marlin/speaker.h
@@ -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
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index c59bffb6b3d5bcf25f96c48eacac68257885a904..0838c7604fd00d877c7a3d48a8ae9004105637e1 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -978,8 +978,8 @@ void lcd_cooldown() {
           lcd_return_to_status();
           //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE);
           #if HAS_BUZZER
-            buzz(200, 659);
-            buzz(200, 698);
+            buzzer.tone(200, 659);
+            buzzer.tone(200, 698);
           #endif
         }
         else {
@@ -1978,25 +1978,10 @@ void lcd_quick_feedback() {
   next_button_update_ms = millis() + 500;
 
   #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);
   #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
-    buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
+    buzzer.tone(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
   #else
-    #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
-      #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
-    #endif
     delay(LCD_FEEDBACK_FREQUENCY_DURATION_MS);
   #endif
 }