0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #15 on: December 30, 2010, 05:16:26 pm » |
Why is stdio.h included? It was just from the bigger program I tried to split to smallest one where the error still exists and I forgot include there. If I remove all includes, it still works same way wrong. Software isn't my strong suit, but shouldn't it be: if ( (!dOn && n1000) >= 500 ) {
Does not matter, because && has stronger precedence than >=. In case of clarity this would of course be better. Still none of the above is the problem. The problem is that something weird is with division.
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, USA
Offline
Sr. Member
Karma: 4
Posts: 499
Sometimes I just can't help myself.
|
 |
« Reply #16 on: December 30, 2010, 06:23:34 pm » |
Pardon me for coming late to the party. Vesal: Are you by any chance using Linux? There are some known problems with the UNO Boot loader and /dev/ttyACM0 on Linux systems. (If you are not using Linux, then: Never Mind.) Here's what I did: I took your original program without the superfluous and confusing (to us mere humans) stuff: I added a delay of 1 millisecond in the loop. Here's the code: const int dummyPort = 13; // I use pin 13 since it already has an LED
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; } delay(1); }
When I do this, I see the three-blink bootloader sequence and then the LED blinks on and off with a period of about a second, which, I perceive, was your intent. I can reset by opening a terminal and I can reset by pressing button. All is Good on my Centos 5.5 system with Arduino version 0022 , avr-gcc version 4.3.4 built from source and with the latest version of the Optiboot boot loader from http://code.google.com/p/optiboot/However, if I delete the delay() statement, it repeatedly does the bootloader three-blink thing on the LED on pin 13 whenever I hit the button or when I open a terminal, and never gets to the code in the sketch. If you are using Windows, then never mind (but I already said that). Maybe some of the other helpers can come up with something. The code itself works just swell on Duemilanove boards as well as the UNO with my Linux system, although I might have written it a little differently. With the Duemilanove boards it doesn't need the delay() statement. The problem is that something weird is with division. I can state unequivocally (and I am unanimous in that) that it has nothing do do with division. Regards, Dave
|
|
|
|
« Last Edit: December 30, 2010, 06:39:01 pm by davekw7x »
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15316
Measurement changes behavior
|
 |
« Reply #17 on: December 30, 2010, 06:39:24 pm » |
I can state unequivocally (and I am unanimous in that) that it has nothing do do with division. But that's what he is saying, division is do do.  Lefty
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, USA
Offline
Sr. Member
Karma: 4
Posts: 499
Sometimes I just can't help myself.
|
 |
« Reply #18 on: December 30, 2010, 06:48:14 pm » |
Hmmm... I was just testing whether the forum's swear filter would let me say "do do" on the Internet. (That's my story and I'm sticking with it.)
I mean, it does its damndest to keep us from saying "damn," right? Really.
Regards,
Dave
Footnote: If you hadn't been so fast on the trigger, I might have caught it and done a sneaky, silent edit to change it. I really wish I hadn't had to lay off my proofreader and editor. Oh, well...
|
|
|
|
« Last Edit: December 30, 2010, 06:53:11 pm by davekw7x »
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15316
Measurement changes behavior
|
 |
« Reply #19 on: December 30, 2010, 06:55:53 pm » |
Footnote: If you hadn't been so fast on the trigger, I might have caught it and done a sneaky, silent edit to change it. I really wish I hadn't had to lay off my proofreader and editor. Oh, well... Somehow I think you will get over it.  Lefty
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #20 on: December 31, 2010, 05:03:46 am » |
Thanks to try my code. ...Linux... No, I'm using Windows 7 64 bit. But this is not the bootloader problem, because the code works if it happens to reset correctly. I added a delay of 1 millisecond in the loop. Here's the code: I tried that also and forget to tell. I thought that it helped, but if you are passioned enough to press the reset button, then the problem comes anyway. And why? Because the 1 ms loop takes the most of the time from the main loop, so the certainty to press the reset while in division goes minimal. That it the thing it took me so long to find that division is the problem. Originally I had so much larger main loop and the problem game very seldom, I even ignored it at the beginning. And my real concern is that if everybody that has division in his code has the same problem. Normally people do not press the the reset button all the time, but I think also interrupt in the same case hangs the Arduino. And that is the main concern.
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, USA
Offline
Sr. Member
Karma: 4
Posts: 499
Sometimes I just can't help myself.
|
 |
« Reply #21 on: December 31, 2010, 09:05:56 am » |
Windows 7 64 bit Generally speaking, I think it's really important for posters to tell us exactly what system they are using. Sometimes it makes a difference to people who would like to help. One final question, and then I am done for this thread: Does the symptom persist if you unplug the UNO's USB connection and power it externally? Anyhow... I'm sorry to have wasted the board's bandwidth on something that couldn't help you. But: See Footnote. Regards, Dave Footnote:Putting in the delay() that keeps away from micros() is, at best, a Band-Aid that masks the real problem: A system bug that causes the Bad Thing to happen. What I forgot to mention is that the UNO was absolutely unusable on my Linux system until I updated the firmware in the USB interface chip. That made it "almost good enough" for casual testing, but it still has problems that I simply can't reproduce with the FTDI interface on Duemilanove boards or other designs that use the FT232 chip for the USB interface. For Linux users, I still think it's a matter of interaction between the Bootloader and the Operating System's treatment of /dev/ttyACM0. Whether it can be fixed with a new load of the bootloader or updating firmware in the ATmega8U2 USB chip on the UNO or a change in the Operating System's handling of USB with /dev/ttyACM0 is still awaiting discovery and fix.
|
|
|
|
« Last Edit: December 31, 2010, 09:25:15 am by davekw7x »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #22 on: December 31, 2010, 09:25:04 am » |
I'm sorry to have wasted the board's bandwidth on something that couldn't help. You did not waste the band. You was the only one who really tried the code and showed to me that the problem can be repeated elsewhere than in my environment. So lot of thanks and Happy New Year 
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 0
Posts: 92
|
 |
« Reply #23 on: December 31, 2010, 09:30:07 pm » |
Does not matter, because && has stronger precedence than >=. In case of clarity this would of course be better. no. >= is evaluated first then && At least according to Kernighan and Ritchie so, ( (!dOn && n1000) >= 500 ) != (!dOn && n1000 >= 500)
EDIT: also, (!dOn && n1000) >= 500 doesn't make a lot of sense because it is always false ( (!dOn && n1000) evaluates to either 0 or 1, which is always strictly smaller than 500)
|
|
|
|
« Last Edit: December 31, 2010, 09:32:42 pm by cnt »
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15316
Measurement changes behavior
|
 |
« Reply #24 on: December 31, 2010, 11:48:20 pm » |
Ah Ha, I knew something was mangled in those if statements, but what do I know I'm just a hardware guy faking the programming stuff.  Lefty
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #25 on: January 02, 2011, 04:36:28 am » |
Sorry. Of course >= is evaluated before &&. I just get confused when retrolefty suggested parenthesis and I just thought the original code was ok without (as it was) and did not notice the false suggest. So !dOn && ( n1000 >= 500000L ) == !dOn && n1000 >= 500000L as it was in the original code. Here is the code as whole with all the mods requested: const int dummyPort = 7;
void setup() { Serial.begin(115200); Serial.println("Start Arduino"); pinMode(dummyPort, OUTPUT); }
unsigned long n1000 = 0; boolean dOn = false;
void loop() {
//n1000 = micros(); //while ( n1000 > 1000000L) n1000 -= 1000000L; // This works n1000 = micros() % 1000000L; // This hangs Arduino while pressing reset if ( !dOn && ( n1000 >= 500000L ) ) { digitalWrite(dummyPort, 1); dOn = true; } if ( dOn && ( n1000 < 500000L ) ) { digitalWrite(dummyPort, 0); dOn = false; }
}
And the real problem still exist on that code: Reseting while in modulo hangs the Arduino 
|
|
|
|
« Last Edit: January 02, 2011, 05:15:23 am by vesal »
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9393
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #26 on: January 02, 2011, 05:04:44 am » |
n1000 = micros() % 1000000[glow]L[/glow] Think that one needs an L for long too. Otherwise still no clue
Update: I confirm that the code without the L does behave "strange" on my UNO too. * adding the L does not solve it * adding UL does not solve it n1000 = micros(); n1000 %= 1000000UL; still has the problem. Diving into - http://www.nongnu.org/avr-libc/user-manual/stdlib_8h_source.html - brings up : 00068 typedef struct { 00069 int quot; /**< The Quotient. */ 00070 int rem; /**< The Remainder. */ 00071 } div_t; 00072 00073 /** Result type for function ldiv(). */ 00074 typedef struct { 00075 long quot; /**< The Quotient. */ 00076 long rem; /**< The Remainder. */ 00077 } ldiv_t; ... 00153 /** 00154 The ldiv() function computes the value \c num/denom and returns 00155 the quotient and remainder in a structure named \c ldiv_t that 00156 contains two long integer members named \c quot and \c rem. 00157 */ 00158 extern ldiv_t ldiv(long __num, long __denom) __asm__("__divmodsi4") __ATTR_CONST__;
Assuming that the compiler uses ldiv() for both % and / , it brings us to the same assembly call ; that "explains" why both % and / have same behavior. Still strange ...
|
|
|
|
« Last Edit: January 02, 2011, 06:09:57 am by robtillaart »
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9393
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #27 on: January 02, 2011, 05:57:18 am » |
void loop() {
//n1000 = micros(); //while ( n1000 > 1000000L) n1000 -= 1000000L; // This works // n1000 = micros() % 1000000UL; // This hangs Arduino while pressing reset n1000 = micros(); n1000 %= 1000000UL; if ( !dOn && ( n1000 >= 500000L ) ) { digitalWrite(dummyPort, 1); dOn = true; } if ( dOn && ( n1000 < 500000L ) ) { digitalWrite(dummyPort, 0); dOn = false; } [glow] delay(1);[/glow] } Adding shortest delay seems to make it more stable ... what does micro() do low level as that is also a constant factor in the code?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #28 on: January 02, 2011, 06:10:58 am » |
Adding shortest delay seems to make it more stable Yes it helps, because then you minimize the change to hit reset during modulo (%). But still it is possible to hang if you are patient enough pressing the reset button. So this is not a way to replace this, one only hides the real problem. ... what does micros() do low level as that is also a constant factor in the code? it gives the microseconds from the last restart. And notice that if one uncomments the two lines: n1000 = micros(); while ( n1000 > 1000000L) n1000 -= 1000000L; // This works
and comments the modulo line // n1000 = micros() % 1000000L; // This hangs Arduino while pressing reset
then the code works just perfect and does the same thing. So the % is the only one (what I can see) that has effect. And as in earlier posts also division (/) has the same (not working) effect.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 23
Arduino rocks
|
 |
« Reply #29 on: January 02, 2011, 06:17:54 am » |
Minimal code that hangs Arduino: unsigned long n1000 = 0; unsigned long m = 0;
void setup() { }
void loop() { n1000 = m++; n1000 %= 1000000L; // This hangs Arduino while pressing reset }
|
|
|
|
|
Logged
|
|
|
|
|
|