Society of Robots - Robot Forum
Electronics => Electronics => Topic started by: Admin on April 04, 2008, 01:53:35 PM
-
I have an AVR that keeps resetting and I don't know why. The time between resets is sometimes predictable, sometimes not (usually every 1-4 seconds). Sometimes it never resets. Sometimes I feel as if hitting the boards in just the right way might cause a reset, but not sure and its not consistent.
I have several boards made exactly the same, all with the same code, all with the same problem. The time to reset isn't consistent among each board.
The power supply is loaded with caps and a voltage regulator. The oscope says there is no power fluctuation at any time. The two major power draws on the board are just two LED's.
Between resets, everything works properly. That means voltages everywhere are correct.
What I've done to debug, but to no effect:
- I tried both an external crystal and an internal oscillator.
- Tried several batteries, all fully charged
- Tried several battery connector cables
- checked and rechecked soldering on all boards
- Tried several oscillator frequencies
- Turned off the LED's in code
- removed the on/off button
- used a 50x microscope to look for shorts between pins, found none
The last thing I can think of to do is remove the onboard CP2102 usb adaptor, but wanted other ideas first . . .
-
isnt it a coincidence iam also getting the same problem , my servo which iam controlling continously vibrates, may be due to resetting from left to right and right to left instead of taking full sweeps , may be there are power fluctuations , otherwise the mcu wont reset
-
Do you have a pull-up (or pull-down) resistor on the reset line, or is there just a power-up reset circuit ? I've seen similar problems on processor cards that were designed assuming a pull-up wasn't required, but that was a bad assumption.
-
i thought that a mcu can resetted by applying the gnd voltage to the reset pin, how do pull up registers help in resetting?
-
hmmmm I just assumed it wouldn't need one . . . so I don't have one there . . . but . . .
I just took a jumper cable and attached reset to ground, and the board stopped running (as its supposed to do).
Then I forced it to 5V, and the reset problem just continued like 'normal' . . .
The problem also occurs regardless of whether the programmer is attached or not.
So nope, thats not the problem unfortunately . . .
how do pull up registers help in resetting?
superchiku, a pull-up resistor prevents a floating voltage from causing it to reset on its own
-
I have several boards made exactly the same, all with the same code, all with the same problem.
1/try changing the code , totally, make another simple code and run it, this way you know its not your code making the problem
(i suppose there are bits in registers that may cause a reset condition(interrupt))
2/take the mcu out of the board and put it in a test board,run it and see if it resets there.
-
Maybe you set brown-out detection too high (4.3 V). So when the voltage to your AVR goes below a setpoint (i.e. fuse setting) the MCU resets?
[BEGIN EDIT]
I just re-read your post. I see you check the voltages already to make sure they are constant at 5 V.
[END EDIT]
-
you don't have WDT fuse bit enabled by mistake?
dunk.
-
Does that fuse matter ???
-
Does that fuse matter
yes. It is designed to reset the mcu when the watch dog timer overflows. unless the wdt is perodically set at 0x00 in code then it will overflow and reset the mcu.
-
oh.. that cleared my fundamentals..
-
Sounds like a Null pointer problem or a jump of the end of an array problem.
-
Did you check the noise levels in the area?
I knew some guy how even shielded his AVR for EMI caused by a motor or a relay... (I don't get to remember but it was an elevator project)
Also adding a pull up surely helps a lot...
Cheers!
Lefteris
-
I've run more experiments and it gets weirder. I'll explain that first, then address everyone's comments.
For some strange reason, if I send long data streams *into* the Rx port on my microcontroller, it causes a reset! A short datastream of just a few characters doesn't cause the reset.
During all my tests I've used the UART to detect resets. The status LED (programmed to turn on during power up) flickers a bit during resets, but its really hard to see.
try changing the code , totally, make another simple code and run it, this way you know its not your code making the problem
I'm already running simplified code . . .
Maybe you set brown-out detection too high (4.3 V). So when the voltage to your AVR goes below a setpoint (i.e. fuse setting) the MCU resets?
Oops forgot to mention that I already tried all the brown-out fuses, and I even disabled them. This was my first thought too!
take the mcu out of the board and put it in a test board,run it and see if it resets there.
its a surface mount, no can do :P
you don't have WDT fuse bit enabled by mistake?
Nope its not enabled. If it was the WDT, it would be predictable . . .
Sounds like a Null pointer problem or a jump of the end of an array problem.
this happens in very simple loops, such as:
while(1)
{
rprintf("output %d",output);
}
Now considering I'm starting to strongly believe it has something to do with uart, there is always the possiblity there is a problem with AVRlib - especially since I had to modify it to handle 4 uarts! I've uploaded the source if anyone is willing to look over it. The folks over at avrfreaks.net constantly rant at how the uart code for avrlib is terribly outdated.
I'll run another test tomorrow that doesn't use rprintf or uart, and I'll scope a digital output pin to hopefully detect resets.
Did you check the noise levels in the area?
I knew some guy how even shielded his AVR for EMI caused by a motor or a relay
I have no motors or other noisy components connected.
-
Did you try bypassing the voltage regulator and powering the circuit directly with 5V? Also, do you have .1uF ceramic caps going to ground at every power input to the chip?
-Scott
forgot you already looked at the power on the scope and saw no variation... still might be worth a try
-
Clock source fuse bits, if they are wrong, you will have predictable resets as you described
-
I would say check out their buffer implementation.
Also this looks suspicious if you are indeed using 4 uarts:
volatile u08 uartReadyTx[2];
volatile u08 uartBufferedTx[2];
// receive and transmit buffers
cBuffer uartRxBuffer[2];
cBuffer uartTxBuffer[2];
unsigned short uartRxOverflow[2];
// Omited for clarity
volatile static voidFuncPtru08 UartRxFunc[2];
As you can see the arrays are declared of size two and in other function like the init and what not they are referenced by index of 2 and 3. So I'd increase that to 4 if you are going to use all 4.
For example this function if called would access off the end of the arrays declared above: void uart2Init(void)
{
// initialize the buffers
uart2InitBuffers();
// initialize user receive handlers
UartRxFunc[2] = 0;
// enable RxD/TxD and interrupts
outb(UCSR2B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
// set default baud rate
uartSetBaudRate(2, UART2_DEFAULT_BAUD_RATE);
// initialize states
uartReadyTx[2] = TRUE;
uartBufferedTx[2] = FALSE;
// clear overflow count
uartRxOverflow[2] = 0;
// enable interrupts
sei();
}
-
You see Jesse, this is why I gave you green robots next to your name!!!
Problem solved!
(I never knew accessing data outside of an array could cause a hardware reset . . .)
I'd been struggling with this 8 hrs/day for the last 4 days . . . I'd kiss you if it wasn't highly inappropriate! :-*
Did you try bypassing the voltage regulator and powering the circuit directly with 5V? Also, do you have .1uF ceramic caps going to ground at every power input to the chip?
Just for fun I added ceramic caps and various resistor types across the voltage reg output, but it didn't solve this problem.
-
Hmmmm so the problem is still here, albeit a lot more rare now. :-\
Its no longer random, and now very predictable. Its this problem I mentioned earlier:
For some strange reason, if I send long data streams *into* the Rx port on my microcontroller, it causes a reset!
It still appears to be an improper access of memory, because sometimes it appears to jump in code - including to functions in my code thats never used! The compiler seems to be compiling unused code :-\ . . . It doesn't matter if its a long stream or short.
It occurs in this while loop:
rprintfInit(uart3SendByte);//define uart port
while(1)
{
temp=uart0GetByte();//returns -1 if no data present, takes data from uart port 0
//&0x0F strips ascii off to use in char strings
if (temp != -1)//if data received
rprintf("%c",temp&0x0F);//transmit to uart port 3
}
It waits for data, and whenever data is received, the reset happens. If no data received, no reset.
Also, in uart.h, I found another code error, but fixing it didn't solve the problem:
// define this key if you wish to use
// external RAM for the UART buffers
//#define UART_BUFFER_EXTERNAL_RAM
#ifdef UART_BUFFER_EXTERNAL_RAM
// absolute address of uart0 buffers
#define UART0_TX_BUFFER_ADDR 0x1000
#define UART0_RX_BUFFER_ADDR 0x1100
// absolute address of uart1 buffers
#define UART1_TX_BUFFER_ADDR 0x1200
#define UART1_RX_BUFFER_ADDR 0x1300
// absolute address of uart2 buffers
#define UART2_TX_BUFFER_ADDR 0x1400
#define UART2_RX_BUFFER_ADDR 0x1500
// absolute address of uart3 buffers
#define UART3_TX_BUFFER_ADDR 0x1600
#define UART3_RX_BUFFER_ADDR 0x1700
#endif
-
Hold on I'm being stupid.
I changed uart4.c and uart4.h in the wrong project folder!
I'll retry this sometime later tonight . . . ignore my last post for now.
-
Ok problem solved, no more resetting :)
I really need to keep my common files straight on all my bots . . .
-
Version control works great for that. CVS or SVN. At work we have one 'project' but 4 microcontrolers with about 75% common code.
You might think about setting up a Source Forge Project for SOR, it would help this kind of problem and also let people like me contribute in the familiar open source way... just a thought.
-
Yeah, having fully switched from PICs to AVRs, I am using my brother's repository (http://svn.hylands.org (http://svn.hylands.org)) organization for all my projects now. All the common files are shared...
- Jon
-
I've moved away from copying the .h and .c files from one project to another as it gets confusing, for a new project, which project you should copy the files from. Especially if you modify some of the clock specific stuff. Version control is one solution. Another is to have a project for all your utilities and then compile them into a new library rather than an elf. In your projects you can then add the new library onto the search path without copying files around at all. The only consideration with the library approach is if you are using lots of different mcus and/or different clock rates in which case you may generate different libraries for Mega8-1Mhz and Mega8-8Mhz etc and then its just a matter of changing the library search path to include the correct library.
-
(I never knew accessing data outside of an array could cause a hardware reset . . .)
how is it you are accessing data outside an array in your code?
the copiler always turns the c code into assembly before generating macine language so you can always check the assembled code
and see what causes the reset,, maybe its a compiler issue
-
Because he told it to ;)
volatile u08 uartReadyTx[2];See the size of the array? means it's two elements big. So that means the compiler makes room and you can access uartReadyTx[0] or uartReadyTx[1] But he Told it to access further down the array, which is nonexistent:
uartReadyTx[2] = TRUE;This might or might not cause a reset, it all depends on what you just overwrote. One scenario is if it happened to be a pointer to a function that just got set to 'TRUE' your code is going to bonkers after that and eventually reset depending on the rampage path it takes through crazy land.
-
thanks Jesse for makin this clear