MegaCore using ATMega128 and delay(); not playing nice together

So i've been working on something using the ATMega2560 dev board and everything works great, no issues. I wanted to convert it down to the ATMega128 (MegaCore based). I can bootload the ATMega128 with no issues and load the sketch to it as well. I did change all the pinouts to match/correspond and everything works as it should, except the delay(): function, but for some odd reason, it only seems to be afftected while using an analogWrite(); function. The output is controlling a small 5v piezo buzzer.

What happens, is that the function processes, but when it comes to the delay for the beeping to stay on or off, the buzzer just chirps and doesnt run for the delay time while on. I've even raised the time and no change, also tried as a digitalWrite(); function and still no change. Here is a sample of the code that calls for 3 beeps (and when using the same code on the ATMega2560, it works as it should)...

void beep() {
  for (int x = 0; x < 3; x++) {  
    analogWrite(Beep3, 200);     
    delay(200);                  
    analogWrite(Beep3, 0);       
    delay(200);                  
  }
  digitalWrite(back_light, LOW);  
  lcd.clear();                    
  delay(5000);
}

Pin assigments...

#define interruptPin 18  //D2 Pin 25 The interrupt pin on the main controller 1 0f 4 MCU
#define LCD_ADC A0       //A0 Pin 61  Buttons/Membrane
#define back_light A1    //A1 Pin 60  LCD Backlight
#define reset_tiny A2    //A2 Pin 59  Reset the Tiny85
#define Beep3 A3         //A3 Pin 58  Piezo Buzzer VCC
#define RX A4            //A4 Pin 57  NOT USED
#define TX A5            //A5 Pin 56  Tiny85 communication
#define power_pin 15     //D13 Pin 17  This pin controls the QV251

Setup...

void setup() {

  //Initializes serial communication
  pinMode(interruptPin, INPUT_PULLUP);  //D2 Pin  used as interrupt used for long press force sleep
  pinMode(reset_tiny, OUTPUT);          //A2 Pin  Reset the Tiny85
  pinMode(power_pin, OUTPUT);           //D13 Pin  This pin controls the QV251
  pinMode(RX, INPUT_PULLUP);            //A4 Pin  NOT USED
  pinMode(TX, OUTPUT);                  //A5 Pin  Tiny85 communication
  pinMode(Beep3, OUTPUT);               //A3 Pin  Piezo Buzzer VCC
  pinMode(back_light, OUTPUT);          //A1 Pin  LCD Backlight

  Serial.begin(57600);   //Use USB to UART adapter for troubleshooting
  mySerial.begin(9600);  //Software serial for attiny85
  startTime = millis();

  //Initializes and clears the LCD screen
  lcd.begin(8, 2);  //(8,2) LCD
  lcd.clear();      //Clears LCD

  //Creates the byte for the 3 custom characters
  lcd.createChar(0, menuCursor);  //Creates cursor and sets first position

  //Unit powers up in sleep mode
  delay(100);                     //Delay for power on
  digitalWrite(power_pin, LOW);   //LCD and Tiny85 powered off
  digitalWrite(reset_tiny, LOW);  //Resets Tiny85
  digitalWrite(TX, LOW);          //Disable Tiny85 communication
  Going_To_Sleep();               //Goes to sleep
}

It's a long sketch, but can pull out a lot if need be to post it entirely (just by removing all the menu items and such. My guess is theres maybe a fault with how MegaCore uses the delay(); function or perhaps an interrupt issue? either way, I've been looking and testing and looking and testing for quite some time with no luck.

Any help is appreciated :slight_smile:

SoftwareSerial may be your problem.

You try to make the buzzer beep by applying a PWM-voltage
with the function-call analogWrite().

It might be that the ATMega128 uses a different frequency than the Mega 2560
post a datasheet of your buzzer.
What type of buzzer is it?
Is it a passive one which requires to have power switched on/off with the frequency the buzzer shall buzz?
or
is it an active one that just needs to be switched on and has its own internal onboard-oscillator for creating the buzzing?

If it is a passive one you would setup a different PWM-frequency or use a timer-interrupt to switch the IO-pin on/off

If you look up the reference for the function analogWrite()

there you can read which pins can do analogWrite (PWM) and which ones not

For Mega: IO-pins 2 - 13, 44 - 46 490 Hz (pins 4 and 13: 980 Hz)

You are using IO-pin A3 so I guess IO-pin A3 is not capable of creating a PWM-signal in the way the function analogWrite() does it.

So you have to either change the IO-pin or to use a timer-interrupt

best regards Stefan

1 Like

Just out of curiousity, why would that be an issue? Thats the communication baudrate to additional ATTiny controllers that hold frequency generation. These are working and have no issue, the issue is with the output for running a buzzer, which is controlled by the main ATMega128.

Thanks for your reply :slight_smile:

Yes, it's an active piezo with an internal oscillator, so only requires voltage. I've also tried with using the digitalWrite(); function as well and same issue, along with other pins on the ATMega128, including pins that are verified working with other controls like the lcd backlight. It's only when the delay(); function is added that the issue happens, it's really strange.

what issue happends then?

As far as I have understood the problem
running the code and the buzzer on a Mega 2560 works
running the code and the buzzer on a Mega 128 does not work

Now you are talking vague about a delay() that causes - what? - issue?

another shot into the fog:
how much current does your buzzer draw and how much current can a Mega128-IO-pin deliver?

Yes, running on the 2560, everything is fully functional. The delay(); in the buzzer sniplet works as it should with the proper delays for on/off periods.

on the 128, everything is functional except the buzzer. It doesn't read the delay(); properly. So instead of the normal operation like the 2560 and the buzzer output, with the 128, it's almost like the just does a quick chirp, like its reading the delay, but not the time. So basically a quick on/off.

I had thought about the current draw issue, but pins on both the 2560 and 128 are max rated at 40mA and the buzzer is drawing 20mA. I've even tested with the pin driving the base pin on a transistor and running resistor to limit the current, same issue.

Only different between the 2 is that the 2560 is an arduino avr board and the 128 is megacore...

what exactly is a "megacore" ????

if you have an oscilloscope I would measure the voltage-level
for pure digitals a 8 ch 24 MHz logic analyser might do

without oscilloscope you could use a second microcontroller to measure the time
of the high-pulse with an interrupt mode change
with first change store micros() in a variable "start"
with second change store micros() in a second variable "stop"

then printing the difference to the serial monitor

a. with buzzer connected
b. with buzzer dis-connected

to see if this makes a difference

best regards Stefan

MegaCore is the arduino core for multiple avr chips that werent adopted by arduino, but can be utilized in the arduino IDE...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.