My project uses a NANO (AT mega328). I Expect it to be running for days at a time in an outdoor enclosure, managing a pool pump, monitoring temerature and sunlight, and a few other things related to a solar heating system. I'd really like to be able to bring a laptop with the USB serial driver installed, plug in a serial monitor, and interrogate the system for some history without disturbing its opperation.
Unfortunately, opening a serial interface, or even just plugging in the device to a USB will cause the device to reset. I know I can periodically save some data to EEprom, but it would be nice if there were a way I could either prevent the reset, or at least cause a function within my project to be called when reset occurs, so I could save some key data before the program restarts.
If this isn't possible, I suppose I can just create an ordinary serial port which is open all the time, and just plug my laptop in with a USB based RS232 (or easier, RS485) adapter. But before going that route, is it possible to tame the NANO's USB port?
It is possible to prevent the reset by disconnecting the DTR pin of the USB chip from the reset pin of the ATmega328P. Usually Arduino boards have a "RESET-EN" solder jumper you can cut to do this but it looks like that is not the case with the Nano. You can remove the 0.1 uF capacitor that's connected between the DTR and reset pin. Here's a picture of the bottom of a Nano-ish clone board that has that capacitor labeled:
Note that the purpose of the reset is to enable the bootloader so you can upload a sketch to the microcontroller. With the auto-reset disabled you will need to manually reset the board at the right time during the upload process.
Use a USB-TTL cable to communicate with the Arduino without resetting it - just connect to Rx Tx and GND.
On some of my stripboard Arduino projects I have two connections for the USB-TTL cable - one makes all the connections needed for re-programming and the other just connects to Rx Tx and GND so I can get the output of Serial.print() without causing a reset.
pert:
It is possible to prevent the reset by disconnecting the DTR pin of the USB chip from the reset pin of the ATmega328P. Usually Arduino boards have a "RESET-EN" solder jumper you can cut to do this but it looks like that is not the case with the Nano. You can remove the 0.1 uF capacitor that's connected between the DTR and reset pin. Here's a picture of the bottom of a Nano-ish clone board that has that capacitor labeled:
Note that the purpose of the reset is to enable the bootloader so you can upload a sketch to the microcontroller. With the auto-reset disabled you will need to manually reset the board at the right time during the upload process.
Ah thanks so much for that! Thi is just the kind of solution a hacker like me loves! And I believe my NANO-ish clones are the same breed as the one pictured.
srnet:
Why not just leave an OpenLog permanently connected ?
Logs all serial output to a Micro SD card, small, cost around £3.50.
Good to know! Not enough history in my current project to warrant an SD card, but the time will come I'm sure. For now, if I can connect without resetting, I can leave a cheap laptop near overnight when necessary.
Robin2:
Use a USB-TTL cable to communicate with the Arduino without resetting it - just connect to Rx Tx and GND.
On some of my stripboard Arduino projects I have two connections for the USB-TTL cable - one makes all the connections needed for re-programming and the other just connects to Rx Tx and GND so I can get the output of Serial.print() without causing a reset.
...R
Oh so I wouldn't even have to do anything different code wise to monitor through the RX/TX pins? Thats good to know! Thanks!
pert:
It is possible to prevent the reset by disconnecting the DTR pin of the USB chip from the reset pin of the ATmega328P. Usually Arduino boards have a "RESET-EN" solder jumper you can cut to do this but it looks like that is not the case with the Nano. You can remove the 0.1 uF capacitor that's connected between the DTR and reset pin.
Hey Pert... I thought you'd find it amusing that I was able to lift one side of that tiny (605 size?) capacitor, sneak a pair of very fine wires from an old pair of earphones, and run it to a tiny switch. Now I can throw the switch to u/l new code, and leave it off for easy serial monitoring. Thanks again for figuring out this convenience!
Wow, nice work! That's definitely useful to be able to easily enable/disable that feature. My attempts at things like that have not turned out well. I've always thought it would have been better for them to put some holes for a two pin header on that solder jumper so that after cutting the jumper you can add the header and jumper the pins to easily enable/disable the auto reset. There should be plenty of room for that on the larger boards but the smaller boards are pretty cramped already so maybe that's not possible.
I'd like to re-open this topic again, for a slightly different reason, for the same project. Last time I mentioned this, I was just wrestling with the annoyance of the USB connection causing reset. I've got a good solution to that one, but now I really would like to hook a routine into the reset vector if at all possible.
Currently I'm able to detect when power is eminently failing, and take the opportunity to save a structure containing everything important. This allows me to completely recover machine states and timers, and resume all in-progress activities. But I have plenty of time to do this because a hefty power supply filter capacitor gives me at least a second to complete the EEPROM save. Plenty of time.
I've not measured exactly how long it takes to save about 60 bytes to EEPROM, so that may be a factor if I'm trying to upload a code change and I cause too long a delay. But If its not too difficult, I'd like to try taking that same 'save' action whenever a reset occurs. Possible?
The boot loader will destroy a lot of your data (if not all). So you have to get rid of that.
With a reset due to a power failure, there is a good chance that your data is corrupted before you manage to save it (if that's what the purpose of the exercise is).
So now the question: what are you trying to achieve?
PeterPan321:
But If its not too difficult, I'd like to try taking that same 'save' action whenever a reset occurs. Possible?
That sounds to me like you want to do something after the reset has been triggered. Isn't that too late?
If the reset is caused by some external signal applied to the reset pin then maybe you could add some extra hardware to detect the signal before it gets to the reset pin, save the data and then trigger the reset pin.
But all that brings me back to @sterretje's question "what are you trying to achieve?"
Dont know how you sense the power fail, I use the following procedure:
use an external power supply more than 12VDC (let say 18). From that power go with diode to a voltage regulator to ~8VDC . This powers arduino. [important : cut the 5Vusb connection to 5v output from onboard regulator) or use a "no power" usb cable when connecting to pc]
From initial power (18V) use a zener (about 14V) and a resistor to GND. There in the middle when everything is ok you have a 4V, thats a clear "high" which goes "low" when power drops to about 14-15V. Connectit to a digitalpin.
Attach interrupt (to that pin , downfunction, low)
void downfunction(void) {
EEPROM.write.....
...
}
You can use any size capacitor at input of 8V regulator (?diode current) so to have the time you need
sterretje:
With a reset due to a power failure, there is a good chance that your data is corrupted before you manage to save it (if that's what the purpose of the exercise is).
So now the question: what are you trying to achieve?
demkat1:
Dont know how you sense the power fail, I use the following procedure:
I'm sorry... I thought i explained that I was already able to save everything when a power failure happens. For the "how".. I have my 12V supply tied to a voltage divider going into a data pin with a small capacitor. It filters noise but drops rapidly when power fails. I also have a diode connected to the supply, isolating that power detect point, from a larger capacitor. That capacitor is then connected to VIN. So the sense pin drops very quickly , but the power to the NANO doesn't drop fo at leas a second. Plenty of time to save. Now...
Robin2:
But all that brings me back to @sterretje's question "what are you trying to achieve?"
...R
Exactly what I'm trying to accomplish is this: if a hardware RESET occurs (button pushed or serial chip interrupt... see response #1), I want my save procedure to run before the rest of the reset procedure completes. I'm hoping there is a reset vector somewhere which I can steal on power up, so that when reset occurs my procedure is done first, and then of course i would jump back to finish the boards reset normally. I'm looking for a programmable solution here, not an addition to the reset pin circuitry.
PeterPan321:
Exactly what I'm trying to accomplish is this: if a hardware RESET occurs (button pushed or serial chip interrupt... see response #1), I want my save procedure to run before the rest of the reset procedure completes.
That describes what but not WHY? - which is what my question was aimed at.
The button being pressed or a program being uploaded are both initiated by a person (you?) so why not just do the saving before you initiate the reset.
To my mind this is very different from dealing with a power-outage, not least because after a power outage one would expect to resume as previously. But one would not wish to resume as previously after new code was uploaded - why upload code unless it is different?
PeterPan321:
... so that when reset occurs my procedure is done first, and then of course i would jump back to finish the boards reset normally.
I don t understand this. If you want "initialisation" of variables to run first of all other "your" code, then simply put a statement [ie MyInitialise()] first in setup. In this function assign EEPROM values to your variables.
If you want to interfere the way resetcode executes, sorry, have no idea.
Robin2:
That describes what but not WHY? - which is what my question was aimed at.
...snip...
why upload code unless it is different?
...R
Correct. The code is different.No other reason to upload it. Its a reasonable complex (to me anyway) system with lots of user programmable behaviors and variations, and it is still being debugged and refined. So there are times when I'm going to make a change, bug fix, or improvement. In that case I'd like to upload that change and have everything resume as it was. My initialization recalls machine states from EEPROM, and my clock (RTC) tells the code where and how it should resume. So let's say there is a situation where the code is not taking the ideal action I want. When I believe I have a fix, I upload it. But in doing so, my save routine never gets to run. Therefore its more difficult to see if my "fix" has worked, until I cause the identical situation arises again.
Yes, I know that since my power loss save does work, I could turn off the power, turn it back on, and then as soon as things settle go ahead and upload new code. But it occurs to me that it would be better if I could make the save happen automatically on reset.
I'll grant that I can surely come up with a way around it. Make an easier way to just save states before uploading. But I'd still like to know if stealing the reset vector as I've described CAN be done, and if so how.
Probably a moderator question, but would it be a bad thing to delete my original post, and start it again to get some fresh viewpoints? The reason being, its an old post whose primary question was never addressed. Granted, I took the conversation off track early on with the discussion of preventing reset during serial events, and later with my power loss recovery scheme. But considering the original question, I think the discussion has gotten pretty far into the weeds, and I think its a question whose definitive answer would be useful to others too. Quite often someone with an answer may not chime in if they see there's already been a lot of responses.
PeterPan321:
So let's say there is a situation where the code is not taking the ideal action I want. When I believe I have a fix, I upload it. But in doing so, my save routine never gets to run. Therefore its more difficult to see if my "fix" has worked, until I cause the identical situation arises again.
If this is just for debugging why not rig up a pushbutton that signals the need to save the data and press that just before you upload the new code?
PeterPan321:
Probably a moderator question, but would it be a bad thing to delete my original post, and start it again to get some fresh viewpoints?
I strongly favour continuing with this Thread as it contains a lot of useful background info.