Enabling Ultratronics Pro v1.0 Buzzer


I need some help making M300 : Play beep sound GCode work with Ultratronics Pro v1.0. 

I defined BEEPER_PIN 27 in pins.h under Ultratronics Board section. Before adding this line I was getting unknown command error. Now printer accepts the command, but there is no sound. 

The buzzer is located on the mainboard, not on LCD board. In fact, this is newly built printer and at the moment it does not even have display, so FEATURE_CONTROLLER in configuration.h file is set to NO_CONTROLLER. Can this be the issue? 

The printer runs on the latest 1.x Development version of firmware downloaded from here https://github.com/repetier/Repetier-Firmware/tree/development



  • No, beeper is independent from display. Display may override pin variable if it has a beeper defined as well.

    Does it make a sound with M42 P27 S255
    and disables with M42 P27 S0 ?
  • Yes, M42 P27 S255 makes sound even without power (only USB connected to RPI)! I could use M42 instead of M300; the downside is M42 does not allow to change tone frequency.

  • I rechecked the code and just having BEEPER_PIN > -1 should activate the function. It calls a ton function that activates a timer. Need to test that when I get more time. Maybe the timer function is not working as expected. Does not look like your error so far.
  • I did further research and even contacted Ultratronics support. While I still don't know the reason why buzzer does not work as expected, here is what I've learned so far:

    As per explanation given here https://www.cuidevices.com/product-spotlight/piezo-and-magnetic-buzzers

    There are two types of piezo buzzers - transducers and indicators. Transducers consist of a casing, a piezoceramic element and a terminal. In order to operate a transducer, the user must send a square wave signal to the buzzer. Indicators consist of a casing, a piezoceramic element, a circuit board and a terminal. In order to operate an indicator, the user must send the buzzer a specified dc voltage  

    So, transducers can generate tones with different frequencies matching the frequency of square signal they get. Indicators just beep with fixed frequency of built in generator. 

    If Ultratronics' buzzer is Indicator, then it works as it should, however if it has Transducer, then there may be a problem. 

    I checked the code of Ultratronics test firmware and, if I read it right, it generates several beeps with 1 sec interval using the following code

      digitalWrite(27, LOW);
      digitalWrite(27, HIGH);
      digitalWrite(27, LOW);
      digitalWrite(27, HIGH);
      digitalWrite(27, HIGH);
      digitalWrite(27, LOW);
      digitalWrite(27, HIGH);
      digitalWrite(27, LOW);

    This is the way one would control Indicator, but not Transducers. 

    Here is the reply I got from Ultratronics technical support:

    I did some testing and I guess you are right, wasn't able to get anything other than a beep from it. Not sure if it is the beeper (KXG0905C) itself or the mosfet controlling it. Looking up the hardware I would say it should be a Transducer, so why it is not working I am confused about. 

    KXG0905C datasheet is available from here http://www.farnell.com/datasheets/97486.pdf

    It does not mention Transducer or Indicator, but says that KXG0905C has resonant frequency 2730 +/- 300 Hz.


  • Can you run the simple test also with tone like described here:


    On due we use a interrupt to generate a frequency as well. So question is if it is not switching pin due to some error or does it not work with that piezo. If the tone example works the error would be in firmware tone handling.
  • Can you run the simple test also with tone like described here

    I am out of town until the end of next week. Will try this once I am back.


  • I tested the code posted in reply #2 here https://forum.arduino.cc/index.php?topic=136500.0 and in worked!! Just changed the pin number from 8 to 27. Ultratronics played a melody with different tones, which means the board works as advertised.
    Pasting below the exact code I used. SD card was removed during this test and Ultratronics was powered only via programming USB port.
      Melody on pin 8 of DUE
      **** Pin 27 on Ultratronics Pro ****
    #define BEEPER_PIN 27 // 8
    // notes in the melody:
    int melody[] = { 262,196, 196, 220, 196, 0,  247, 262
      /*NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4*/ };
    // note durations: 4 = quarter note, 8 = eighth note, etc.:
    int noteDurations[] = {
      4, 8, 8, 4,4,4,4,4 };
    void setup() {
    void loop() {
      // iterate over the notes of the melody:
      for (int thisNote = 0; thisNote < 8; thisNote++) {
        // to calculate the note duration, take one second
        // divided by the note type.
        //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
        int noteDuration = 1000/noteDurations[thisNote];
        tone(BEEPER_PIN, melody[thisNote],noteDuration);
        // to distinguish the notes, set a minimum time between them.
        // the note's duration + 30% seems to work well:
        int pauseBetweenNotes = noteDuration * 1.30;
        // stop the tone playing:
    Tone generator
    v1  use timer, and toggle any digital pin in ISR
       funky duration from arduino version
       TODO use FindMckDivisor?
       timer selected will preclude using associated pins for PWM etc.
        could also do timer/pwm hardware toggle where caller controls duration
    // timers TC0 TC1 TC2   channels 0-2 ids 0-2  3-5  6-8     AB 0 1
    // use TC1 channel 0
    #define TONE_TIMER TC1
    #define TONE_CHNL 0
    #define TONE_IRQ TC3_IRQn
    // TIMER_CLOCK4   84MHz/128 with 16 bit counter give 10 Hz to 656KHz
    //  piano 27Hz to 4KHz
    static uint8_t pinEnabled[PINS_COUNT];
    static uint8_t TCChanEnabled = 0;
    static boolean pin_state = false ;
    static Tc *chTC = TONE_TIMER;
    static uint32_t chNo = TONE_CHNL;
    volatile static int32_t toggle_count;
    static uint32_t tone_pin;
    // frequency (in hertz) and duration (in milliseconds).
    void tone(uint32_t ulPin, uint32_t frequency, int32_t duration)
    		const uint32_t rc = VARIANT_MCK / 256 / frequency;
    		tone_pin = ulPin;
    		toggle_count = 0;  // strange  wipe out previous duration
    		if (duration > 0 ) toggle_count = 2 * frequency * duration / 1000;
    		 else toggle_count = -1;
    		if (!TCChanEnabled) {
    			TC_Configure(chTC, chNo,
    				TC_CMR_WAVE |         // Waveform mode
    				TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC
    			chTC->TC_CHANNEL[chNo].TC_IER=TC_IER_CPCS;  // RC compare interrupt
                             TCChanEnabled = 1;
    		if (!pinEnabled[ulPin]) {
    			pinMode(ulPin, OUTPUT);
    			pinEnabled[ulPin] = 1;
    		TC_Stop(chTC, chNo);
                    TC_SetRC(chTC, chNo, rc);    // set frequency
    		TC_Start(chTC, chNo);
    void noTone(uint32_t ulPin)
    	TC_Stop(chTC, chNo);  // stop timer
    	digitalWrite(ulPin,LOW);  // no signal on pin
    // timer ISR  TC1 ch 0
    void TC3_Handler ( void ) {
    	TC_GetStatus(TC1, 0);
    	if (toggle_count != 0){
    		// toggle pin  TODO  better
    		digitalWrite(tone_pin,pin_state= !pin_state);
    		if (toggle_count > 0) toggle_count--;
    	} else {
  • Thanks. I have updated dev version with a HAL that creates sounds on my ultratronics as well. Seems like WRITE_VAR was not working.
  • Just tested latest HAL files with the following GCode:
    M300 S262 P200
    M300 S0 P50
    M300 S196 P400
    M300 S0 P50
    M300 S196 P400
    M300 S0 P50
    M300 S220 P200
    M300 S0 P50
    M300 S196 P200
    M300 S0 P250
    M300 S247 P200
    M300 S0 P50
    M300 S262 P200
    Worked perfectly!!

    @Repetier Thanks for outstanding support!!
Sign In or Register to comment.