0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« on: December 28, 2010, 04:40:18 am » |
I have a problem that after a small piece of code the Arduoino (UNO) does no reset. It resets only by uploading a new sketch or by power off.
In the code below I separated the problem to % operation. My idea was to give exact 1 second signal compared to last reset. I can go around the problem by other ways, but I'm worried about why this peace of code has a problem. Because I got the same problem in longer code but occasionally (when interrupt happens during %).
My guess is that if reset or interrupt happens during % then the board is somehow in unknown state and does not reset.
The problem can be repeated by code below and pressing the reset button repeatedly until led in line 13 remains blinking. Then the Arduiono is possible to reset only by new sketch or power on.
#include <Wire.h> #include <string.h>
#undef int #include <stdio.h>
const int dummyPort = 7;
void setup() { Serial.begin(115200); Serial.println("Start Arduino"); pinMode(dummyPort, OUTPUT); }
unsigned long n1000 = 0; int dOn = 0;
void loop() { n1000 = micros() % 1000000; if ( !dOn && n1000 >= 500000 ) { digitalWrite(dummyPort, 1); dOn = 1; } if ( dOn && n1000 < 500000 ) { digitalWrite(dummyPort, 0); dOn = 0; }
}
:o
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9403
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #1 on: December 28, 2010, 05:18:46 am » |
I have a problem that after a small piece of code the Arduino (UNO) does no reset. How should this code do a reset? as simple as the code is I do not understand how it should do a reset. some remarks: instead of - int dOn - use a boolean variable, is more clear imho I can imagine that the micros() wraps around quite fast - start with 0 again, maybe you should try millis() instead as it takes 1000 times as long before wrapping around. (code not tested) unsigned long n1000 = 0; boolean dOn = false;
void loop() { n1000 = millis() % 1000; if ( !dOn && n1000 >= 500 ) { digitalWrite(dummyPort, 1); dOn = true; } if ( dOn && n1000 < 500 ) { digitalWrite(dummyPort, 0); dOn = false; } }
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #2 on: December 28, 2010, 05:26:34 am » |
This code is not doing the reset. The problem is that if YOU do reset somehow during this code, the Aruino hangs and you can not do another reset. Why should you do the reset? When you start serial from PC it sinks the DTR and resets Arduino. So the problem is that when you have code like my example, you have good change to hang the Arduino when you connect it thru USB from PC. And to simulate that it is much faster to just press the reset button and see what happends. The micros is just OK for me, because millis is not accurate enough in my purpose. And dOn I admit that boolean is better in this case, but this was just a smallest peace of code from much much bigger case where a noticed the problem and tried to minimize the problem something that is easy to repeat. And the worst thing is that the same problem comes when some interrupt happens. And that is the main point, but I think Reset is more familiar for most people. 
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9403
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #3 on: December 28, 2010, 05:36:48 am » |
OK, so when you press the reset button the Arduino locks itself up in a permanent state. Sounds definitely as a hardware problem. If you have a voltmeter you could check if the reset switch is working correctly or if it blocks. Also check your board for small pieces that connect (bad soldering a bit of grease whatever). You could also circumvent the reset switch by resetting using the reset pin.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #4 on: December 28, 2010, 06:17:15 am » |
I have 3 Arduino Uno module and all behaves the same way. And the reset comes also from USB-serial line by DTR low and it has exactly same effect. So do external reset.
The difference in reset by reset button, external reset, serial start reset and uplod is that when upload is done, the rset signal stays 5 V, goes to 0 V and the over 7 V and then back to 5 V. All others just pull reset signal to 0 V and returns it 5 V.
The reset is one of my worries. The biggest is that WHY Arduino hangs when Reset or Interrupt is done during %-operation???
:-[
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9403
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #5 on: December 28, 2010, 05:04:16 pm » |
just observed this statement in your code
#undef int
What is its purpose? Does the problem exists when you remove that line?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #6 on: December 28, 2010, 06:12:41 pm » |
Actually I do not know why there is #undef int. I pick the code where I started somewhere and it was there.
But removing it does not help. Works exactly same way.
|
|
|
|
|
Logged
|
|
|
|
|
Huntsville, Alabama, USA
Offline
Sr. Member
Karma: 0
Posts: 327
Arduino rocks
|
 |
« Reply #7 on: December 29, 2010, 04:43:54 pm » |
I don't know about the reset problem, but your code may not work correctly unless you change some of your constants: 1000000 should be 1000000L and 50000 should be 50000L Regards, -Mike
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15314
Measurement changes behavior
|
 |
« Reply #8 on: December 29, 2010, 06:25:11 pm » |
the reset signal stays 5 V, goes to 0 V and the over 7 V and then back to 5 V. When the reset is being done via the DTR/RTS signal from the serial FTDI chip, by way to the Arduino IDE or any PC application that is opening or closing that comm port, it is capacitance coupled to the reset pin by a .1mfd cap, so the overshoot to +7vdc is just a transent pulse caused by the discharging of the cap and should not be a concern nor have any effect on the chip. The reset pin unlike all the other pins is rated for a much higher voltage, +12vdc I think, because that is the mechanism to allow the chip to utilize a different high voltage programming mode. All the ugly details are in the AVR datasheet for the chip. The biggest is that WHY Arduino hangs when Reset or Interrupt is done during %-operation??? This has nothing to do with the hardware reset circuitry, just some software mistake or error not yet solved by you or us.  Lefty
|
|
|
|
« Last Edit: December 29, 2010, 06:33:42 pm by retrolefty »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #9 on: December 29, 2010, 06:46:01 pm » |
.. +7vdc is just a transent pulse ...
Anyway, after reset button or normal reset from PC it does not reset correctly like it does when power on or upload program. And the signal from osciloscope is different between those two cases.
Still the buggest problem is that WHY Arduiono goes on that kind of state. No I'm not bold enough to use %-operator in my code...
And for Mike: for some reason it works same way (= correct when reset happens to work) if there is 500000 or 500000L. You are right that it should have L, but seems to be ok without also. Still this is not the biggest point of the problem.
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9403
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #10 on: December 30, 2010, 03:49:47 am » |
No I'm not bold enough to use %-operator in my code... It would suprise me if the % operator has anything todo with it. replace the line: n1000 = millis() % 1000; with unsigned long t1 = millis(); unsigned long t2 = t1 / 1000; n1000 = t1 - (t2 * 1000);
This is what the modulo does so now you can test the code without the % operator to see if it still behaves that way. Please post your results.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #11 on: December 30, 2010, 07:08:40 am » |
Now I have a code: #include <Wire.h> #include <string.h>
#include <stdio.h>
const int dummyPort = 7;
void setup() { Serial.begin(115200); Serial.println("Start Arduino"); pinMode(dummyPort, OUTPUT); }
unsigned long n1000 = 0; int dOn = 0;
void loop() {
unsigned long t1 = millis(); unsigned long t2 = t1 / 1000; n1000 = t1 - (t2 * 1000);
// n1000 = micros() % 1000000; if ( !dOn && n1000 >= 500 ) { digitalWrite(dummyPort, 1); dOn = 1; } if ( dOn && n1000 < 500 ) { digitalWrite(dummyPort, 0); dOn = 0; }
} And that woks exactly same way in all 3 Arduino Uno-modules. Pressing Rest button or starting Terminal hangs the Arduino. Upulod or Power on resets and led in 7 starts to blink once a second. Instead the code: #include <Wire.h> #include <string.h>
#include <stdio.h>
const int dummyPort = 7;
void setup() { Serial.begin(115200); Serial.println("Start Arduino"); pinMode(dummyPort, OUTPUT); }
unsigned long n1000 = 0; boolean dOn = true; unsigned long ms = 0; unsigned long msHigh = 0; unsigned long msgoal = 500000L; unsigned long msgoalHigh = 0;
void loop() {
ms = n1000; n1000 = micros(); if ( n1000 < ms ) msHigh++; if ( n1000 >= msgoal && msHigh >= msgoalHigh) { digitalWrite(dummyPort, dOn); dOn = !dOn; unsigned long newms = msgoal + 500000L; if ( newms < msgoal ) msgoalHigh++; msgoal = newms; } } works perfect in this form and also by lot of other stuff in loop or in interrupts. So what else I could suspect than division (or modulo)?
|
|
|
|
« Last Edit: December 30, 2010, 07:41:23 am by vesal »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #12 on: December 30, 2010, 07:38:20 am » |
Actually changing n1000 = micros() % 1000000; to n1000 = micros(); while ( n1000 > 1000000L) n1000 -= 1000000L;
(where is no sense after few minutes of course) makes the code work. So even more proofs against modulo % or division / ???
|
|
|
|
|
Logged
|
|
|
|
|
Austin, TX
Offline
Faraday Member
Karma: 41
Posts: 5170
CMiYC
|
 |
« Reply #13 on: December 30, 2010, 02:25:57 pm » |
Why is stdio.h included?
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15314
Measurement changes behavior
|
 |
« Reply #14 on: December 30, 2010, 03:55:06 pm » |
In your failing code example: // n1000 = micros() % 1000000; if ( !dOn && n1000 >= 500 ) { digitalWrite(dummyPort, 1); dOn = 1; } if ( dOn && n1000 < 500 ) { digitalWrite(dummyPort, 0); dOn = 0; } Software isn't my strong suit, but shouldn't it be: // n1000 = micros() % 1000000; if ( [glow]([/glow]!dOn && n1000[glow]) [/glow]>= 500 ) { digitalWrite(dummyPort, 1); dOn = 1; } if ( [glow]([/glow]dOn && n1000[glow]) [/glow]< 500 ) { digitalWrite(dummyPort, 0); dOn = 0; } Lefty
|
|
|
|
|
Logged
|
|
|
|
|
|