PlatformIO Community

Serial port timing on arduino mega2560

Hi, I have come across a problem in a device driver I am writing. The problem is that when I open a serial port and connect in the driver code, there needs to be a time interval before the Arduino (USB Serial) will respond to serial comms. By experimenting in the driver code, introducing a 3 second delay using Thread.Sleep(3000) between the code which connects the port and the code which transmits a serial string seems to be a reliable minimum.

In another forum it has been suggested that the delay may be because of the Arduino bootloader and the MCU resetting when a serial connection is made.

So my question is a) is there a good source of info about how the bootloader may cause a delay before serial comms will work and b) What is a good way to manage this?

Currently I’m managing the situation by causing a delay in my code as described above.
thanks for help.

Correct. Opening the serial port with standard settings will make the USB-UART adapter (which is ATmega8u2 on the mega2560 board) assert the DTR (data terminal ready) line, which is connected to the nreset of the Mega2560 via a capacitor (AC-coupled signal). See schematics.

image

So opening the serial port with standard settings (assert DTR on port open) will reset the Mega2560.

When it is reset, oscillator will be started according to its fuse settings (this may take a tiny time). The first piece of code that will execute is the bootloader. The Mega2560 is flashed with the STK500v2 bootloader.

It has a timeout for acceping UART bootloader commands for flashing. If no flashing commands are coming in, the MCU will boot your actual application after the timeout.

The value for this timeout is 1 second.

Once the application is booted, it will start execution by running the reset vector (provided by avr-gcc) and then it finally enters the main function of the Arduino core, which after some initialization goes into your setup() function. So, there’s a lot of time that passes until you get the chance to execute your first command in setup() – if Serial.begin(..) isn’t the first one, more time will pass until the serial is initialized and ready to accept commands (at least writing them in the serial RX buffer, processing them is then up to your application).

You can exactly measure how much time is passing by using a oscilloscope or a logic analyzer and tracing the RESET signal (available on header) and an arbitrary GPIO pin which you pinMode(..,OUTPUT); digitalWrite(..,HIGH); high as the first commands in your setup(). The time passing between reset being activated and the GPIO pin going high is then the time it takes to enter the setup() function.

1 Like

If you don’t want to have static delays in your application, make your firmware send out some “READY” string via UART right before accepting commands. Your application can then just open the port, wait for the READY string (with some maximum timeout to be safe) and go on with its logic.

thanks for a very comprehensive reply, much appreciated.

Afternoon Gentlemen,

I’m not a mega2560 guru, but I do have one, somewhere!

On the Duemilanove and Uno, which I’m more au-fait with, you can get rid of the bootloader by programming your sketch with an ICSP device – I use the usbTiny – and this completely overwrites the bootloader when uploading a sketch. This gives a little bit of extra space in Flash RAM for your sketch code, and gets rid of any bootloader specific delays.

I needed to get rid of the bootloader on my Duemilanove board when I was experimenting with the watchdog reset. The default bootloader for that board takes too long between restarting and disabling the watchdog, so the watchdog resets after the minimum period of 16 milliseconds – which is how it is configured after a WDT reset – and we enter a watchdog reset loop where the board constantly resets.

Just a though, if you can live without the bootloader.

Cheers,
Norm.

thanks for reply, I usually use the AVR4809 mcu which has no bootloader, so the mega2560 caught me out with this delay and reset on opening the port. I guess I should read more datasheets…what if I don’t want the processor to be reset when I open the port? - no need to answer that one.

1 Like