Go Down

Topic: How to program using USBASP and keep bootloader (Read 2352 times) previous topic - next topic

freeborn

Hi,
I am a newbie, I try to upload program using usbasp and it works fine
unfortunately I find that my arduino become no bootloader.
The problem is without bootloader, watchdog does not work.
I use barbone arduino board with atmega328.

Please let me know, how to program using usbasp and still keep bootloader.

Thanks in advance,

johnwasser

I just uploaded this watchdog timer sketch to my Arduino UNO (R2) using a USBasp programmer.  It works just fine.  Perhaps your sketch is missing something.
Code: [Select]

//  Watchdog Timer Example
#include <avr/wdt.h>

unsigned long ToggleDelay;  //  When this delay grows to longer than the WDT interval the WDT resets the Arduino

const int LEDpin = 13;

void toggle_led()
{
  digitalWrite(LEDpin, !digitalRead(LEDpin));
}

void setup()
{
  wdt_disable();
  ToggleDelay = 1;   // Start with a very short delay
  pinMode(LEDpin, OUTPUT);
  wdt_enable(WDTO_250MS);  // Set watchdog to 1/4 second
}

void loop()
{
  wdt_reset();
  toggle_led();   // Blinking goes slower and slower until the WDT causes reset, then starts over.
  delay(ToggleDelay);
  ToggleDelay += 5;   // Increase the delay by 5 milliseconds.
}
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

dc42

#2
Oct 12, 2012, 11:33 pm Last Edit: Oct 13, 2012, 12:53 am by dc42 Reason: 1
As johnwasser says, you don't need the bootloader to use the watchdog timer. HOWEVER, there is a problem you may have run into that the bootloader "solves". The problem is that when the watchdog timer expires and causes a reset, the watchdog is still enabled. The processor needs to complete the data initialization that occurs before setup() is called, before the timer expires again. Otherwise the watchdog will cause another reset, and this will repeat so that your sketch never gets the chance to reset the timer. The bootloader "solves" this by disabling the watchdog.

So it comes down to what you have in your sketch whose static initialization takes longer than the watchdog interval. The usual culprit is the LiquidCrystal library, which has a totally unnecessary "begin" call in its constructor, taking 60ms to execute (longer than the longest available watchdog interval). If you are using the LiquidCrystal library in your sketch, you need to remove this call from the LiquidCrystal library source code, otherwise you can't use the watchdog timer.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

johnwasser


The usual culprit is the LiquidCrystal library, which has a totally unnecessary "begin" call in its constructor, taking 60ms to execute (longer than the longest available watchdog interval).


Did you mean "longer than the TWO SHORTEST available watchdog intervals"?  The interval an be set as high as 8 seconds:
Code: [Select]

#define WDTO_15MS   0
#define WDTO_30MS   1
#define WDTO_60MS   2
#define WDTO_120MS   3
#define WDTO_250MS   4
#define WDTO_500MS   5
#define WDTO_1S   6
#define WDTO_2S   7
#define WDTO_4S   8
#define WDTO_8S   9
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

dc42

#4
Oct 13, 2012, 12:54 am Last Edit: Oct 13, 2012, 10:37 am by dc42 Reason: 1
Yes, my mistake! [although the 60ms setting would be likely to fail too.]
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

westfw

Quote
how to program using usbasp and still keep bootloader.

You can't, BTW.

(well, if you're using something outside of Arduino, you can merge the .hex files for the bootloader and your application.  Or you can set things up so that you burn the bootloader and then burn the app, or vis-versa, but overwriting an existing application always involves an "Erase all" step that will wipe out the bootloader.)

frank26080115


Quote
how to program using usbasp and still keep bootloader.

You can't, BTW.

(well, if you're using something outside of Arduino, you can merge the .hex files for the bootloader and your application.  Or you can set things up so that you burn the bootloader and then burn the app, or vis-versa, but overwriting an existing application always involves an "Erase all" step that will wipe out the bootloader.)



also just to follow up on this comment, if you do decide to merge the two hex files together, the programming process will take very long and get annoying.
Freelance engineer, consultant, contractor. Graduated from UW in 2013.

freeborn

Thanks, I finally find that without bootloader watchdog still work.
Anyway please see what worng with my code that causes watchdog stop working.
I know that it will work if I just comment out blink led in setup,
but I do not know why.

Code: [Select]

#include <avr/wdt.h>

void setup()
{
  wdt_disable();
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);   // without this line, work fine
  delay(100);                      // without this line, work fine
  digitalWrite(13, LOW);    // without this line, work fine
  delay(100);                      // without this line, work fine
  wdt_enable(WDTO_4S);
  wdt_reset();
}

void loop()
{
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);   // set the LED off
  delay(1000);              // wait for a second       
  wdt_reset();
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);   // set the LED off
  delay(1000);              // wait for a second         
  wdt_reset();
  digitalWrite(13, HIGH);   // set the LED on
  delay(5000);              // wait for 5 second to test watchdog
  wdt_reset();
}

freeborn


As johnwasser says, you don't need the bootloader to use the watchdog timer. HOWEVER, there is a problem you may have run into that the bootloader "solves". The problem is that when the watchdog timer expires and causes a reset, the watchdog is still enabled. The processor needs to complete the data initialization that occurs before setup() is called, before the timer expires again. Otherwise the watchdog will cause another reset, and this will repeat so that your sketch never gets the chance to reset the timer. The bootloader "solves" this by disabling the watchdog.

So it comes down to what you have in your sketch whose static initialization takes longer than the watchdog interval. The usual culprit is the LiquidCrystal library, which has a totally unnecessary "begin" call in its constructor, taking 60ms to execute (longer than the longest available watchdog interval). If you are using the LiquidCrystal library in your sketch, you need to remove this call from the LiquidCrystal library source code, otherwise you can't use the watchdog timer.


Your answer make me clear, Thanks you so much.
Anyway I think there will be no watchdog interval left if it start working (it start because it reach the interval, am I right?),
In this case, what is the longest time left for me to use?
The problem is I need time not only for liquidcrystal but eeprom initializing as well.

dc42

Atmel recommends that you always reset the watchdog before disabling it. Possibly the wdt_disable function does this already, but try inserting a call to wdt_reset before the call to wdt_disable, in case it doesn't.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

freeborn


Atmel recommends that you always reset the watchdog before disabling it. Possibly the wdt_disable function does this already, but try inserting a call to wdt_reset before the call to wdt_disable, in case it doesn't.


Still no luck even if I did that, thank you anyway.

freeborn

I have tested 4 atmega328 chips with various delay values and I found that
watchdog stopped working when used delay value between 17 - 18.
(2 chips fail when use delay(17) and the others fail when use delay(18))
here is my code.

Code: [Select]

#include <avr/wdt.h>

void setup()
{
  wdt_reset();
  wdt_disable();
  pinMode(13, OUTPUT);
//  digitalWrite(13, HIGH);   
//  delay(100);             
//  digitalWrite(13, LOW);   
  delay(16);  // watchdog stop working when delay between 17 - 18
  wdt_enable(WDTO_4S);
  wdt_reset();
}

void loop()
{
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);   // set the LED off
  delay(1000);              // wait for a second       
  wdt_reset();
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);   // set the LED off
  delay(1000);              // wait for a second         
  wdt_reset();
  digitalWrite(13, HIGH);   // set the LED on
  delay(5000);              // wait for 5 second to test watchdog
  wdt_reset();
}


BTW there was no problem even included liquidcrystal library and initialized it.
For safety, operating time in setup function shall not longer than 15 ms for watchdog to work properly.
Hope this will help someone who have same problem as mine.

dc42

It sounds as though the wdt_disable call isn't working and the wdt_enable call is setting the wrong timeout. This is the code I use to disable the watchdog:

Code: [Select]

  // Turn off watchdog timer
  cli();
  wdt_reset();
  MCUSR = 0;    // clear watchdog reset flag
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = 0x00;
  sei();
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

freeborn


It sounds as though the wdt_disable call isn't working and the wdt_enable call is setting the wrong timeout. This is the code I use to disable the watchdog:

Code: [Select]

  // Turn off watchdog timer
  cli();
  wdt_reset();
  MCUSR = 0;    // clear watchdog reset flag
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = 0x00;
  sei();





Thanks you so much, it works like a charm.

Go Up