how to use the AVR watchdog

Go To Last Post
37 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have scanned through the first number of tutorial pages, and did a google search on avrfreaks on using the watchdog, but I come up empty  on a tutorial on watchdog usage.

Is there a tutorial on the use of the watchdog?

 

what I want to do is:

during normal program execution the watchdog is off. there are no things blocking so at this point I think I do not need it there.

But I have a couple of possible crash situations were I want to enable the watchdog and let that trigger a HW reset.

example 1 is my main for loop that should never ever exit, but if it does... turn on watchdog and that will never be reset so it will trigger a complete system restart.

second is when I want to power off the system. If for some reason the power off does not work I want the watchdog to get triggered and then let that give a system reset.

 

I have never worked with the watchdog and before I start asking a lot of questions that most likely will be answered in a tutorial I want to have read that first.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Calculate you max execution time in main and select an appropriate WDT timeout. Just before you go into your While loop start the WDT, and put a WDT Reset at the end of the loop. As long as your code hits the reset the WDT will stay in its doghouse, if the reset is not hit the WDT will bark and reset the AVR.

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which compliler you have using?

If AVRGCC then it's for you smiley

For wiki: http://microchipdeveloper.com/8a...
For <avr/wdt.h>: https://www.nongnu.org/avr-libc/...

And https://www.pocketmagic.net/avr-...

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

#include <avr/wdt.h> /*Watchdog timer handling*/

int main(void)
{
	/*First step is Enable Watchdog*/
	wdt_enable(WDTO_8S); /*Watchdog Reset after 8Sec*/
			     /*WDTO_15MS , WDTO_30MS..etc for deffernt time*/
				/*for more time*/
			     /*https://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html */

	while(1)
	{
		/*Here your code executing*/
		/*Then second step for Watchdog is Reset you Watchdog timer*/
		wdt_reset();
	}
}

 

শূন্য  - The ZeRo

Last Edited: Sun. Feb 3, 2019 - 06:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't know of a tutorial....

 

If you need the watchdog in your project, then

keep it on all the time.  Turning it on and off

just when you think it might be needed will

probably cause more problems.

 

Your code just needs to regularly reset the

watchdog timer to avoid a watchdog reset.

The timer period can be as long as 8 seconds

on some AVR models (and 2 seconds on older

chips) which is quite a long time for an MCU.

 

So in your main function, add enough calls to

wdt_reset() to ensure the watchdog timeout

period will not be exceeded.  (This C function

generates a single wdr assembler instruction.)

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

+1 to what Mike just said.

 

But note that in all but the most trivial program watchdog is not something you bolt on at the end when  everything else is done and then you think "I think I'll throw in a bit of last minute protection".

 

Watchdog should be something you design in from the start and every subsequent design decision is predicated on "how will this interact with the watchdog?"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

+1 to Cliff's comment.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use the watchdog in an M328P much as you describe. In my case, I have it as a failsafe for sleep, in case the wakeup event fails to happen while it is sleeping (it could, possibly happen other times, and never wake it up). So, I do turn it on and off. It works fine. 

 

The important thing to remember about watchdog is that you have to pet it just right. It takes TWO operations (within, I think, 4 MCU clock cycles) to change the operating mode and maybe the timeout interval. 

 

For a failsafe like this, you really never need to reset it. You start it, just before the operation to be guarded, begins. You stop it when that operation is over. BUT, be very careful about that remote possibility that the watchdog might time out and get hungry. So, you need to make sure that you do, or don't ( depending on the MCU you use ) have the interrupt service routine and that you have the necessary control bits set so that it all does what you want.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you need the watchdog in your project, then keep it on all the time.

Some of the newer processors only let you change the watchdog configuration once (ie "turn it on at boot time"), so you don't have much choice in the matter.  I guess the idea is that it's primarily a "bad code path" detector, and you wouldn't want to have people die just because your bad code happened to turn off the watchdog...  (I think it's a bit over-protective, given the other protections usually wrapped around changing the WD status, but... worth considering.)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jack Ganssle has written some nice documentation / tutorials about effective use of watchdog timers.

https://duckduckgo.com/html?q=jack+ganssle+watchdog+tutorial

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note the default value of the WDT is 16ms on most mega's, so if you use a longer period, be sure you handle the timeout pretty quickly in your start up code as a reset will 'reset' your timeout to this short period!

If not handled properly and quickly, will lead to a "hung" micro that resets - wdt timeout- reset - wdt timeout - reset, don't ask me how I know this!  sad

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all the great replies.

I am using a AtMega1281 in the project that I want to be using the Watchdog in.

 

I have really never ever used the watchdog but it seems to be straight forward in usage.

I always have event based systems and in general make sure these events do not take to long to process, so that seems to be the way to go with using the watchdog.

 

From what I understand so far is that at initial power on the watchdog is disabled by default ( note that I never program the watchdog fuse)

So then it is not important what is done to it, but after a watchdog generated reset it seems to be such that the watchdog is not turned off, but changes to the shortest interval time possible. Which as said will cause problems if you do not take that into account.

So this means that the second thing I have to do (first is setting the IO ports to a after reset state, just plain PORT & DDR registers writing) is either turn the watchdog off, or set it to a very long time interval.

At this point I think I will opt for leaving/turning it on and setting it to 8seconds time-out which will be way more than needed.

Then I will do the full system initialization and when that is done change the watchdog to 2 seconds. an event should never last longer than a second anyway or the system might run into memory problems. so 2 seconds between ticks should be more than enough. Then I can choose in the special situations to speed up or just let the timer be.

 

Interestingly while looking at the AVRgcc documentation the wdt library does not have a standard function call to turn the watchdog off.

you call wdt_enable for turning it on and set the interval ( assume that when I want to change the interval I also call this function). and a wdt_reset that you have to cal regularly to not trigger the watchdog.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
So this means that the second thing I have to do (first is setting the IO ports to a after reset state, just plain PORT & DDR registers writing) is either turn the watchdog off, or set it to a very long time interval.
It'll depend on your C compiler but most have a way to intercept the early C startup so you can service the watchdog even before the loops that set up BSS and .data. For example in avr-gcc one would use a .init3 routine to achieve this.
meslomp wrote:
Interestingly while looking at the AVRgcc documentation the wdt library does not have a standard function call to turn the watchdog off.
as noted above the idea of switching it off is a bit of anathema - either you use it or you don't. If you do then you simply enable it by the fuse or by a call to configure it as early as possible. Once on it stays on. Interesting to see Bill's comment in #8 - so some new AVR don't give you a choice - it's a one way switch.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have made a file with 4 functions:

1: function to turn watchdog ON

void WDT_Turn_On(const uint8_t a_time)
{
	wdt_enable(a_time);
}

 

2: function to change the interval

void WDT_Set_Interval(const uint8_t a_time)
{
	wdt_enable(a_time);
}

 

3: a function that will reset the watchdog

void WDT_Do_Reset(void)
{
	wdt_reset();
}

4: a function that will turn off the watchdog

void WDT_Turn_Off(void)
{
	uint8_t l_Sreg;
		
	l_Sreg = SREG;						// store SREG state specially for global interrupt enable
	cli();								// turn off interrupts
	wdt_reset();						// reset watchdog
	MCUSR &= ~(1<<WDRF);				// make sure WDRF is cleared in MCU status reg or else watchdog cannot be turned off
	WDTCSR |= (1<<WDCE) | (1<<WDE);		// send special value to command register enabling it to be editted
	WDTCSR = 0x00;						// turn off watchdog by clearing WDE & WDIE plus all the rest
	SREG = l_Sreg;						// restore SREG. if interrupts were enabled they will be again
}

 

now the first 2 are the same, but when you go through the code it is clear what the function is actually doing.

 

in fact the first 3 are just re-definitions of the functions in the avr/wdt library and are a shell for me to in now and a year to still understand what is going on.

 

the 4th function I copied from the datasheet

 

I am just wondering if I need to reset the watchdog myself before changing the interval or if that is done inside the library.

And personally I am still in doubt if I not going to make the "turn on" function turn the wdt on always at 8 seconds, and then use the set interval to change it later on in the process.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:

Interestingly while looking at the AVRgcc documentation the wdt library does not have a standard function call to turn the watchdog off.

 

My include/avr/wdt.h file has wdt_disable() with

a few variations for different chips.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

My include/avr/wdt.h file has wdt_disable() with

a few variations for different chips.

 

--Mike

 

That is interesting as the documentation does not mention it.

it only mentions a macro define for the reset command, a couple of defines for the interval time setting and an enable function.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
That is interesting as the documentation does not mention it.
Sort of:

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The watchdog isn’t there to catch bad code - although it tends to do that. Even with defect free software (!) the watchdog is there to catch situations that can’t be detected (not without special hardware) like an ESD event flipping a bit in a register or ram that sends the micro off the rails. Having the watchdog interrupt is next to useless - if it fired the train has already crashed. The stack pointer might be out the window, so whilst you might beable to enter the isr, don’t try calling any functions or relying onthe ram to be sensible.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Having the watchdog interrupt is next to useless
Well yes and no - it does give the opportunity to get the outputs into a "safe" state (like stopping motors and stuff).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hardware should take care of that.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

meslomp wrote:
That is interesting as the documentation does not mention it.
Sort of:

 

Indeed did not notice that.

 

kartman,

 

one thing I want to protect is my main loop, which technically is a for(;;){code}

if it ever exits then I want the watchdog to kick in, simply as then indeed things are terribly wrong.

there is a second place and that is when I want to power down.

At this moment I put everything in a power down state and then cut power(should be suicide)

If for some reason that does not go right I would need to technically go through reset to restart the system so could just start executing from address 0 again. But I want all the peripherals to also be reset to their reset state and using the watchdog seems to be the simplest way to do that, specially as I now want to have it for code protection.

I do not plan on using the interrupt, although I might also use that during debugging ( trigger interrupt to spit out debug data before dying. but that will not be there in the code I want to eventually use. watchdog is just plain reset as indeed registers or anything can be corrupt so the data is no longer trusted to be correct.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
which technically is a for(;;){code} if it ever exits
Go on. How can an infinite loop ever exit (unless a deliberate "break;" is performed) ?? If you write:

int main(void) {
    while(1) {
        PORTB = rand();
    }
    PORTB = 0x55;
}

I bet the compiler will even warn you about "unreachable code". There is no way that PORTB = 0x55 line can ever be reached. Of course if I wrote:

int main(void) {
    while(1) {
        PORTB = rand();
        if (somecondition) break;
    }
    PORTB = 0x55;
}

then there is a chance that it could be.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It has been a while since I had some time to do some coding and check things.

Clawson, you are right. I think it has been some left over code from another project were there was a posibility for the code to break out of the for loop when something in the system went wrong. There I just did a pc jump to reset and the system woudl start running again. 

 

I have tested the posted code and it works fine.... to good actually, hahahahah

was testing some things were if I pressed a button I would display data on my LCD and freeze the program to be able to do some measurements.

I normally use a for(;;) loop to achieve that when possible.

Took me a while to figure out why the bloody thing would reset after I did a couple measurements as I always ended up at the same pin to measure, then to realize I had enabled the watchdog, but forgot to reset it inside that for loop. So the reset on each pass of the normal operational loop was OK.

After disabling the watchdog through my routine all went OK. I still have to check if the undocumented wdt_disable function actually is there I did not have time to do that.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
I normally use a for(;;) loop to achieve that when possible.
If you are going to "retrofit" watchdog support (rather than design it in from the start) then you need to analyse every code path in your code and consider where the intentional "long loops" are then sprinkle liberally with WDRs

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

Kartman wrote:
Having the watchdog interrupt is next to useless - if it fired the train has already crashed.

I don't think I'm the only 'Freak here that uses the watchdog as a wakeup timer.  Especially in deep-sleep apps that are battery powered.

 

So I certainly cannot agree with "useless".  But

1)  The power budget for watch crystal and timer2 async clocking on some/many modern AVR8 models is about the same as the WD, in power-down.  So a case could be made for not using the WD for that.

1a)  And that will have better accuracy than WD, if that is important to the app.

2)  When using it for periodic wakeup, one must carefully code to use it as a real watchdog also.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

meslomp wrote:
I normally use a for(;;) loop to achieve that when possible.
If you are going to "retrofit" watchdog support (rather than design it in from the start) then you need to analyse every code path in your code and consider where the intentional "long loops" are then sprinkle liberally with WDRs

I have set the watchdog to 8 seconds for now as I already thought I needed to do that, but at this moment seems to be a lot of work and I want to finish to a certain state in not to long.

I have already done a couple of multi hour tests with he watchdog running and all seemed to be OK, I have not seen resets occur. If that was to happen the device would power down, so no way to miss it as I found out while halting my program.

 

what I have is an event driven system. before checking if there are new events I reset the watchdog. then handle the event and start again with clearing the timer. as there are a couple of events that should be handled within a second of occurring or things might go bad ( have not seen that happening) for now I think it is safe to say that setting the watchdog at 8 seconds and being sure that at least a reset is given every 2seconds I should be OK for now.

It does not take away the fact though that I will have and will be going to check how long events are actually taking, but as said I now first want to have my code in a usable state in not to long a time as I want to do some practical testing in a couple of weeks when we are on holiday.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@eRony I wanted to test the code you wrote. I configured watchdog for 4 second and gave a delay of 5 second inside the while loop to test the code. But processor is resetting continuously after that. I cannot even program the controller and I have to remove the power to the board. I am using arduino nano board (atmega328P). I also tried to test the code by not calling wdt_reset() and without adding 5 second delay. Even in this case, controller resets continuously. What needs to be done?

int main(void)
{
   wdt_enable(WDTO_4S);
   // Initialize port pins for LEDs
   initializeLEDTest();

    while(1)
    {
        wdt_reset();
        digitalInvert(LED1);
        digitalInvert(LED2);
        _delay_ms(5000);
    }
	return(0);
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

joneewheelock wrote:
atmega328P
Then no doubt you have read this:

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html

 

and specifically this:

 

Note that for newer devices (ATmega88 and newer, effectively any AVR that has the option to also generate interrupts), the watchdog timer remains active even after a system reset (except a power-on condition), using the fastest prescaler value (approximately 15 ms). It is therefore required to turn off the watchdog early during program startup, the datasheet recommends a sequence like the following:

#include <stdint.h>

#include <avr/wdt.h>

uint8_t mcusr_mirror __attribute__ ((section (".noinit")));

void get_mcusr(void) \
     __attribute__((naked)) \
     __attribute__((section(".init3")));
void get_mcusr(void)
{
    mcusr_mirror = MCUSR;

    MCUSR = 0;

    wdt_disable();

}

Saving the value of MCUSR in mcusr_mirror is only needed if the application later wants to examine the reset source, but in particular, clearing the watchdog reset flag before disabling the watchdog is required, according to the datasheet.

Your 328 is in the aforementioned family of mega88 etc. 

 

Bottom line - switch it off in early start up code.

 

EDIT: and now I just read the whole thread and not just the recent posts. So #16 already said this ?!?! If you read that why did you post?

Last Edited: Mon. Oct 28, 2019 - 04:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried this now, but still no luck. Just now I found the same problem reported in the below link. I guess I need to change the boot loader and I need to look for an USBASP programmer to do that.

https://arduino.stackexchange.com/questions/2922/watchdog-timer-stuck-in-restart-loop-green-led-flashing

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Obviously the first code that runs after power on has to be the code to disable the watchdog in the limited time window available. So, yes, if a bootloader is involved it has to be part of your watchdog strategy. I would implore you to reread this entire thread. The point was already made that watchdog use is something that should be designed in at the very core of your design from the outset. It's not a thing where you can really finish the main project then, as an afterthought, you think "OK, now to add a bit of watchdog" at the end. If you had approached the design like this it would probably have a bearing on whether you use a bootloader at all and, if you do, continuation of watchdog handling would be part of its initial design.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arduinos use a bootloader that runs after each rese - it runs for about 1s looking for attempted uploading.  Older versions of the bootloader used on the Arduino Nano did not properly reset the WDT, so if you enable the WDT in the application,, the next reset will result in a WDT loop (every 15ms) ALL INSIDE THE BOOTLOADER.

This was fixed a LONG time ago, but unforunately many of the "nano" derivatives that one can buy on eBay and etc still ship with the older, broken, bootloader.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Done, I grabbed USBASP and changed boot loader to optiboot and now watchdog works as expected.

My personal opinion: Not disabling watchdog on watchdog reset may be a bad feature of Atmega328P. Any specific reason why this may be a desired feature for others? I am just a level 0 hobby developer in embedded and may not be able to comment much on this. I have not worked on any other controllers and hence cannot compare with other chips.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Disabling watchdog on watchdog reset" would defeat the whole purpose of the watchdog.

 

The whole idea is that the "dog" needs to be "petted" at a regular interval for everything to continue running properly. If the mcu gets stuck somewhere and cannot reach the watchdog in time, then it will be reset to reboot. That could happen if you do not figure the worst case time properly. Or, it could happen waiting for something external that never comes. 

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Sun. Nov 3, 2019 - 03:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The whole point of any watchdog is to prevent against faulty software.

 

If the watchdog could be disabled by software, then faulty software could (accidentally or otherwise) disable it when it shouldn't.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If that is the case why watchdog timer is reset to default value? They could have retained user set timeout value.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

The whole point of any watchdog is to prevent against faulty software.

 

 

I'd suggest the main reason for a watchdog is to recover from hardware related problems - transients etc upsetting the processor state or memory. It is a 'bandaid' for environmental factors we can't easily control. Using it as a 'bandaid' for software defects is not the best idea.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When the watchdog is reset by software (e.g. "petted"), the watchdog timer is reloaded with its initial value that depends on the timeout interval. It down-counts to zero. If it reaches that point, the MCU is reset. Perhaps I was not very clear when I wrote "then it will be reset to reboot". The intended "it" in that sentence is the MCU. There are two resets happening, here. One involves the watchdog timer and the other involves the MCU. The watchdog's reset reloads the timeout value into the watchdog timer. The MCU watchdog reset does pretty much what pulsing the reset pin would do (which is not exactly what a power-up boot does).

 

Sorry.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Mon. Nov 4, 2019 - 01:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
I'd suggest the main reason for a watchdog is to recover from hardware related problems - transients etc upsetting the processor state or memory.

But that still leads to the same reasoning for why it should not be easy/possible for software to disable it once has been enabled.

 

 

Using it as a 'bandaid' for software defects is not the best idea.

For software defects, it's sensible to use it as a "last resort" protection - better than having the possibility of software defects that could lock-up the system in an unrecoverable state!

 

Of course, good practice is to have the Watchdog record diagnostic information, and give indication that it fired - so that the cause can be investigated, found, and fixed.

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...