3
\$\begingroup\$

I wrote this code for the Arduino Uno. It will count a variable every second and send that count to the serial terminal. The problem is when I close the terminal and reopen it, the count will start from 0 again. I am confused with this behavior. Please tell me why this is happening.

Here is the code:

#include "Arduino.h"

#include <avr/io.h>
#include <avr/interrupt.h>

#define setbit(x,y) x |= 1<<y

unsigned long newmillis(void);
void newdelay(int x);
void toggle_led(void);

unsigned long volatile _count = 0;
volatile char state = 1;
int count = 0;

ISR(TIMER0_COMPA_vect) {

    _count++;

}

unsigned long newmillis(void) {
    //toggle_led();
    return _count;

}

void newdelay(int x) {
    unsigned volatile long y = (unsigned long)x + newmillis() - 1;
    while (y>newmillis());
}


int main(void) {

    init();
    TCCR0B = 0b11;
    OCR0A = 249;
    TIMSK0 |= 0b10;
    sei();

    Serial.begin(9600);
    DDRB |= 1<<5;

    //int count = 0;

    for (;;) {

        Serial.println(count++);
        newdelay(1000);
        toggle_led();

    }
}

void toggle_led(void) {

    if (state==0) {
        state = 1;
        PORTB |= 1<<5;
    }
    else {
        state = 0;
        PORTB &= ~(1<<5);
    }
}
\$\endgroup\$

5 Answers 5

5
\$\begingroup\$

When you program the Arduino the microcontroller on the board has to be reset to enter the bootloader so you can upload the new software. Arduino, in their infinite wisdom, decided that this should be done automatically whenever you connect to the serial port. There are much better ways of doing it, but I guess that they decided on this with the first Arduino board before they really knew what they were doing (do they even now?) and are now stuck with it. Personally I would have used a different USB->RS232 chip right from the start - one that can do more than just serial comms, such as the MCP2200 which gives you both a CDC and a HID device in one, and 8 GPIO lines that you could use to trigger events on the board, like resetting, programatically.

However, I digress. There are two ways around the issue that I am aware of - one which damages the board permanently, and one which is far simpler and nicer.

  • The official way is a permanent mod to the board. I wouldn't recommend this way - there is a far nicer way (see below). Look for a little link on the front called RESET-EN and cut it with a very sharp knife. This will disconnect the serial chip from the reset pin and the board will never auto-reboot again. However, this will break the ability to program the board easily. From now on you will have to manually reset the board by pressing the reset button at the right time to program it.

enter image description here

  • The method I use is far simpler and less destructive. Connect a 22uF capacitor between RESET and GND (on the POWER header). You will need to disconnect it to program the board, but it doesn't involve breaking the board at all. Just plug it in between those two connections in the header, making sure the - side of the capacitor goes to ground. This works by holding the reset line high enough to stop the chip from resetting even when driven low by the USB chip. The reset switch should still work, but you may need to hold it in for a bit longer than normal.

enter image description here

On a side note, the ChipKIT™ UNO32™ has the same problem - they had to keep that functionality to maintain compatability with other Arduino products and methodologies. However, they have been much more sensible about it. They still have the little link to cut, but instead of it being between the pads of an 0805 footprint, they are between the plated through holes of a 0.1" 2-pin header. This way, you can cut the link, and install a normal jumper header. From then on you can enable and disable the reset functionality by just installing or removing a jumper.

\$\endgroup\$
2
\$\begingroup\$

It's normal, it's how the Arduino works. When you connect to the serial port via the FTDI chip (or the newer Atmega serial devices), it will reset your device.

So it's not in your software, just the hardware. It has bugged me before, .. just like a xbee shield resets the atmega chip when it's buffers is full (aargh).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ The XBee does that? That's just plain stupid! \$\endgroup\$
    – Majenko
    Jan 8, 2012 at 10:17
  • \$\begingroup\$ Yes it does. I have had a project where a sensor node was crashing when the coordinator went offline. Happened that the CTS pin is tied to the RESET pin of the controller. If CTS goes low, it will reset the controller, losing all of it environment settings, time, node addresses etc. The xbee wants redundant data transfer, so it continues buffering it data isn't transmitted properly. It seems like the new 'Wireless communication' shield doesn't have this 'issue', the original old shield had this. \$\endgroup\$
    – Hans
    Jan 8, 2012 at 13:04
0
\$\begingroup\$

In actuality, the reset is not caused by the act of connection itself, but rather by the default behavior of most host computer's operating systems to command activation of the DTR signal upon serial device connection and de-activation upon device closure.

That is behavior that can be configured in the host software serial API, and thus avoided.

\$\endgroup\$
0
\$\begingroup\$

Another option that requires no hardware modification (that @Chris_Stratton touched upon) is to connect to the Arduino with DTR disabled. Your host sending a DTR signal is what's causing the Arduino to reset, which is done by design to reload your sketch if the serial connection was being used for programming.

You don't mention what software you're using to connect with, but here's an example of how to disable DTR in Python.

\$\endgroup\$
0
\$\begingroup\$

Like stated it is normal behavior for the Arduino and disabling it gives some issues to reprogram the device. A hardware solution I use for this gives you software control on when the usb should or should not reset the device. While a bit more complicated then just scratching the line between the reset pads it only involves 2 components.

The idea is simply to block the reset pulse using an IO pin from the device. When your program loads, it initializes the IO pin low, enabling the USB reset and thereby the program mode. After some seconds push the pin high and block any further USB resets.

To do so I soldered a pnp transistor (e.g. BC857) before the 100nF capacitance in the reset line and connected the base with an 5K (exact value is not overly important) to an available IO line.

patch Arduino reset Notes:

  1. Due to the galvanic separation of C5, it won't work to place the pnp on the other side of C5 (yes, those pads look temping)
  2. With this patch the lowest value of the reset signal is just above the required specification. It works for me, but to further lower the signal you can add 10nF between base and collector of the pnp. (but more soldering)

Fix Mounted In practice I found it easiest to actually cut the wire within the reset pads, moved C5 (the 100nF) on those PADS and used the footprint of the C5 to attach the pnp. But there are many ways to patch this. It is easiest to ensure the Arduino puts the used IO pin low before patching, else you have to give a timely manual reset to reprogram the first time

Reset signal with pnp+5K Without 10nF (simulated with V3 which has an extra diode over RN1D)

Reset signal with additional 10nF With an additional 10nF to lower the peak of the reset signal

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.