There is a lot of discussion on this forum about this function pointing to 0x0000. It restarts your code but it won't reset all registers and internal counters. If you search for "reset function" (upper right) you find several threads e.g. - http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235780325

Thanks for the pointers, I now have read quite a bit more, and perhaps I understand some more.

I understand the comments from others in the past - that a software reset() is not really a good thing to seek out...

But given the sorts of things that I want to ask my poor micro controller to do (tack my model boat, and get the sails on the right side pulling, and head a certain direction, ...)And that I want that to be done in combinations of interrupt code and other peoples PID code and etc...

I am sure that a fast - start from the very beggining() - method is worth having .

All that said, what I understand is required is:

Set all the device registers to the initial states documented in the datasheet

TWDR = 0xff ; // this write might not suceed. Is only writeable when TWI is not shifting a byte. // maybe should disable twi as early as possible, so more chance this instruction works. // could need to delay for >1 milliSec for byte to be sent. // I do not use TWI (yet) so can perhaps ignore this.

TWAR = ~(_BV(TWGCE)) ; // all bits except TWGCE set. TWAMR = 0 ;

// analog comparator ADCSRB = 0 ; ACSR = 0 ; DIDR1 = 0 ;

// ADC ADMUX = 0 ; ADCSRA = 0 ; ADCSRB = 0 ; DIDR0 = 0 ;

// ADCL = 0 ; // read only and the output of a conversion, not really a problem if not 0 on restart. // ADCH = 0 ; // read only

Ok... i haven't cleared the cpu registers yet - and there are IO registers that are read only withvalues defined at startup - so sketchRestart() is never going to be a 100% reset,but all the periperals that I care about are done/ for a 168 or a 368.

It sort of works, [glow]except that the output of the first print is corrupted after the reset.[/glow]

I am guessing that the hardware serial code is assuming some control value has been set in the boot loader.

That will be a problem for tomorrow.

And then the register clear.

And then the same stuff for a Mega 1280.

Maybe I am optimistic... but I think that then we will have a sketchReset() that is fast and reliable 8-)

Maybe I am optimistic... but I think that then we will have a sketchReset() that is fast and reliable

Well the point that sold me on not having/using a 'softReset' function is that it is usually just a lack of imagination and/or experience at program structure.

When someone can explain why they must have that function and that there is not other way for s/he's program to function without it, then maybe I will stand in that line. Until then, color me meh...

I think I would rather learn how to master better program structure. Learning software skills has been frustrating to me at times, but I do feel I'm making steady progress. Mostly because I stay away from that nasty C++ stuff and just swim in the C part of the pool.

Lots more comments as I have read more detail about how the USART works in the 328 and the 168.

Clears registers .

The corruption on the serial port is reduced a bit.

if you send 'ccccccccccccccccccccccccpr' as one string then the last character of the printed data is not properlyflushed through the usart when the reset happens, and the next time i send a 'p' a garbage character is printed in place of the newline.

if (UCSR0B & (1<<TXEN0)) // if transmit enabled {// Try to to drain the transmit fifo; sometimes we do not succeed, we leave the data// in the shift register and change the settings, leading to garbage on the line.// This code is not sure to work, as it is not possible to reliably tell if// there is data in the trasmit shift register.// The bit TXC0 is cleared after a transmit interrupt is sent, and can be cleared by code.// If the TXC0 bit is clear, it could mean that there is data waiting to be sent or that there isn't.// If the TXC0 bit is set, there is no data to send.// The only reliable signal that there is more data to send is the UDRE0 bit which indicates that one and// a part characters are waiting to be sent. if ((UCSR0A & (1<<UDRE0)) == 0) // there is a byte in the transmit fifo { while ((UCSR0A & (1<<UDRE0)) == 0) // while transmit queue is not empty ; // drain the transmit buffer while ((UCSR0A & (1<<TXC0)) == 0) // transmit of last character not yet complete ; // and wait for the transmit shift buffer to empty } }

// the UDR0 register supplys the data for both input and output side of UART comms..// UDR0 = 0 ; // would be transmitting a null :( - leads to corruption because we are about to set the speed to 1M Bit/second.// if I put this back the garbage is much more :)

UCSR0A = 0 ; // RXC0 bit is clear due to read queue draining above // TXC0 bit is cleared by assinment to 0. // UDRE0 bit is read only, and 1 according the restart normal logic // UDRE0 bit should be 1 if transmit was enabled because of the transmit fifo draining above. // FE0 (frame error) is cleared by draining the read queue // DOR0 (data over run) is cleared by draining read queue // UPE0 (usart parity error) is cleared by draining the read queue // U2X0 (double baud rate) is set to zero by assignment of 0 // MPCM0 (multi-processor communication mode) cleared by to zero by assignment of 0

Since I will already be in panic mode when i go for the reset, the extra delay is likely to panic me more.

16 milliseconds is going to panic you more? Will that extra 16 milliseconds make that much of a difference on a sailboat? Would you even be able to tell the difference between zero delay and a 16 millisecond delay?

In my experience, less code = fewer bugs. You're adding quite a bit of code to "reset" the processor. Does your plan include a method for identifying bugs in your reset code? What if your reset code does not work correctly? Will you have a "reset squared" in case your "reset" fails to work?

16ms is the watchdog timeout, the rest of the time after the watchdog RESET is the bootloader.Once you have proved your software, put it direct into a fresh AVR without a bootloader.Hopefully by then, you'll have tested your software so well, you won't actually need the watchdog.

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.Do not send technical questions via personal messaging - they will be ignored.

I see where you are coming from - I can replace the bootloader code, so I shouldn't fuss with the reset.

That is probably the correct low risk approach as my simulated reset is never going to be quite right (as otherwise ATMEL would have a doc on their site saying how to do it).

But I am treating it as a learning exercise, to better understand the processor, while also preserving the ability to bootload the code.

My eventual objective is that I will be able to build quite complex strategies into the top level controller - with no need to have the logic that reverts each path back to a known starting point.

This is an extension of a well known approach in application development - called "Crash only software" http://lwn.net/Articles/191059/ - which states that you know your program will fail, so design for it to fail and recover gracefully, and quickly.

If you get it right (like I hope to) then you are free to actively use the fail & recovery path to simplify your system...

So for example, I will only code the control algorithms to a position that is defined in terms of the current position.

All the commands that request a change to a position determined from the boot up state will be saved in a EEPROM location and executed after restart.

This is an extension of a well known approach in application development - called "Crash only software" http://lwn.net/Articles/191059/ - which states that you know your program will fail, so design for it to fail and recover gracefully, and quickly.

(sorry i hit tab in the editor and then return which posted while i was still working on it)

I will try to sketch out the reasoning for the software sketchReset() for you and explain how it is just a bit different to a Watch-Dog-Timer...

First picture a program structure in loop() that implements various tasks in functions, and each task-function breaks its steps into lower level functions..

So there might be a function which called tack() to sail the boat onto the other side of the wind... that is if the wind is on the left of the boat at the start, it should be on the right at the end - and the boat should move forwards at all times...

while (currentSpeed() < 0 || startTack == currentTack()) // while not moving forwards or not on the new tack { // work to fix these issues

while (speed() < 0) // sailing backwards { try_to_sail_forwards() ; // this is pretty complex in of itself - and will take some time to fix. // in a real boat can break things by sailing backwards. }

// we are sailing forwards - is a good start :)

// have to start a tack with some boat speed, because sailing through the wind slows us down - we can end out stopped // head to the wind - 'in irons' is the old term. // we will drift backwards with the wind and then need the try_to_sail_forwards() ...

// we are sailing forwards while (currentTack() == startTack) // we are still on the wrong tack { // work to sail fast enough to tack while (currentSpeed() < GOOD_STEERAGE_WAY) // while not going fast enough to turn into the wind and across to the other tack { // work to sail faster try_to_sail_faster() ; }

while (sailsPulling()) // still under power from wind { while (currentSpeed() > GOOD_STEERAGE_WAY) // still fast enough to manoeuvre { headUpALittle() ; /// steer into the wind trimSails() ; // adjust the sails so they keep pulling } } // sails not pulling - to close to the wind to sail.. while (currentTack() == startTack && headingVersusWind() < currentSpeed() * CLUDGE_FACTOR) // not tacked and still moving { // we should be able to continue through wind onto other tack loosenSails() ; // reduce drag from wind on the boat headUpALittle() ; // steer into the wind, not too much or rudder will act like a brake } // either on the right tack or are too slow }// on the right tack now, but the tack is not complete until you are moving with STEERAGE_WAY while (currentSpeed() < GOOD_STEERAGE_WAY) // while not going fast enough { // work to sail faster try_to_sail_faster() ; }return ; // on the right tack now.}

The thing to notice is almost all the commands are relative adjustments to controls or policy...And that each function trimSails(), as an extreme example, could be as involved as the above.

If every thing is working then the boat should smoothly sail up to close to the wind, let the sails loose and then continue to glide through the wind onto the other tack, and then trim the sails in and sail away on the other tack.

If it goes wrong... then the control software will not know how to move to a better state.

For example, if the wind shifts by 50 degrees, then the boat could be caught head to wind, and just think that the wind has died....

At that point, I by remote control, would send boat the command to do the wake-up and gain control sequence - ie the power on sequence.

I know that there are finite state machine approaches to control software that might allow this stuff to be written differently, with different classes of special cases that are difficult to deal with...

But this is the sort of way I think when I attempt to explain sailing...