2

First of all, I know the problem with the code and how to get it to work. I'm mainly looking for an explanation why my output is what it is.

The following piece of code replicates the behaviour:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("start");
  for(int i = 0; i < 70000; i++) {
    if((i % 2000) == 0)
      Serial.println(i);
  }
}

Obviously the for loop will run forever because i will overflow at 32,767. I would expect it to overflow and print -32000.

Expected|   Actually printed
0       |   0                                       
2000    |   2000                                    
4000    |   4000                                    
...     |   ...                                     
30000   |   30000                                   
32000   |   32000                                   
-32000  |   33536                                   
-30000  |   35536       

It looks like it prints the actual iterations, since if you overflow and count to -32000 you would have 33536 iterations, but I can't figure out how it's able to print the 33536.

The same thing happens every 65536 iterations:

95536   |   161072  |   226608  |   292144  |   357680
97536   |   163072  |   228608  |   294144  |   359680
99072   |   164608  |   230144  |   295680  |   361216
101072  |   166608  |   232144  |   297680  |   363216

EDIT

When I change the loop to add 10.000 every iteration and only print every 1.000.000 to speed it up the Arduino crashes (or at least, the prints stop) at '2.147.000.000'. Which seems to point to the 32-bit idea of svtag**

EDIT2

The edits I made for the 2.147.000.000-check:

void loop() {
  Serial.println("start");
  for(int i = 0; i < 70000; i+=10000) {
    if((i % 1000000) == 0)
      Serial.println(i);
  }
}

They work in the same trend with the previous example, printing 0, 1000000, 2000000,...

However, when I update the AVR package from 1.6.17 to the latest 1.6.23 I get only 0's. The original example (% 2000 & i++) still gives the same output.

gre_gor
  • 6,669
  • 9
  • 47
  • 52
Lonefish
  • 647
  • 2
  • 11
  • 32
  • This can be because of the difference in `int` definition on the Arduino and PC. Serially Arduino will send the binary equivalent of (int)33536 in 16bit, but if your PC interpret it as 32bit, then you should get the actual number. Just a hypothesis, I will check it as soon as i get the hardware. – svtag Nov 15 '18 at 15:21
  • I've also been thinking something along those lines, but then it shouldn't be able to print numbers larger than 65535. Because in 16 bit that would be the max value the arduino could output. Somehow it has some sort of shadowcopy that is 32bit it seems.. – Lonefish Nov 15 '18 at 15:50
  • 1
    what Arduino board? you are on some 32bit board – Juraj Nov 15 '18 at 16:05
  • I'm using an Arduino UNO – Lonefish Nov 15 '18 at 16:10
  • somehow the compiler used the long version of `print`. perhaps it always uses the long. I am surprised that int version exists – Juraj Nov 15 '18 at 16:13
  • I get that part, but it also manages to count beyond the limits of a 16bit. Yet the evaluation in the for loop uses the 16bit value. – Lonefish Nov 15 '18 at 16:16
  • which version of Arduino IDE you use? or better which version of Arduino AVR package? – Juraj Nov 15 '18 at 16:20
  • Read the return value of `Serial.println(i);`. It returns number of bytes written on the port. This should give some insight. – svtag Nov 15 '18 at 16:21
  • 1
    @svtag, please. it would be number of digits. the conversion to text is done on MCU – Juraj Nov 15 '18 at 16:22
  • @Juraj, according to Arduino documentation on [`Serial.println()`](https://www.arduino.cc/en/Serial/Println), it reruns number of bytes written. – svtag Nov 15 '18 at 16:25
  • 1
    written to Serial. in case of number, after conversion to text. number of digits. +2 for \r\n – Juraj Nov 15 '18 at 16:27
  • It is indeed the number of digits+2 (for the carriage return). Using Arduino IDE 1.8.1, no idea about the AVR package version, how would I check that? – Lonefish Nov 15 '18 at 16:27
  • Board Manager in IDE in board selection menu. filter by 'Installed' – Juraj Nov 15 '18 at 16:28
  • Arduino AVR Boards v1.6.17, updating and testing it now. – Lonefish Nov 15 '18 at 16:29
  • Added an edit. It's just getting stranger and stranger – Lonefish Nov 15 '18 at 16:57
  • the compiler optimizes the code and things on edge can fall to either side. turn on warnings – Juraj Nov 19 '18 at 10:39

1 Answers1

0

The compiler may have automatically casted the i to usigned int when you are doing the println or the value is going to the wrong overload. Try using Serial.println((int)i);

  • It manages to count beyond 65535, it counts until 2.147.000.000 (printing only millions), so it's a 32bit value somehow.. – Lonefish Nov 15 '18 at 16:33