Sunday, 2 March 2014

c - Arduino resetting while reconnecting the serial terminal


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
#include

#define setbit(x,y) x |= 1<
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);
}
}

Answer



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.


No comments:

Post a Comment

arduino - Can I use TI&#39;s cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...