Problem with modulo (%) and reset

just observed this statement in your code

#undef int

What is its purpose?
Does the problem exists when you remove that line?

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.

I don't know about the reset problem, but your code may not work correctly unless you change some of your constants:
1000000should be1000000Land50000should be50000L

Regards,

-Mike

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. :wink:

Lefty

.. +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.

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.

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)?

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 / ???

Why is stdio.h included?

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

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.

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 Google Code Archive - Long-term storage for Google Code Project Hosting.

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

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. :wink:

Lefty

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...

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. :wink:

Lefty

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.

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.

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 :smiley:

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)

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. :wink:

Lefty