2

I'm using Arduino to look for I2C addresses, and half way through this new glitch appeared, and I don't know if it's the IDE or if I'm going insane.

I know most of this probably isn't important, but I don't know what is going on so here is my entire loop.

void loop(){

    byte error, address;
    int nDevices;

    Serial.println("Scanning...");

    nDevices = 0;
    for(address = 0; address <= 255; address++ )
    {

        Wire.beginTransmission(address);

        error = Wire.endTransmission();
        Serial.print(address);
        Serial.print("|");
        Serial.println(error);
        if (error == 0)
        {
            Serial.print("I2C device found at address 0x");
            if (address<16)
            Serial.print("0");
            Serial.print(address, HEX);
            Serial.println(" !");
            nDevices++;
        }
        else if (error==4)
        {
            Serial.print("Unknow error at address 0x");
            if (address<16)
                Serial.print("0");
            Serial.println(address,HEX);
        }
        delay(200);
        //Serial.println(address);
    }
    delay(150);
    Serial.println("Exiting");

    if (nDevices == 0)
        Serial.println("No I2C devices found\n");
    else
        Serial.println("done\n");

    delay(30000);

    exit(0);
}

As you can see in the picture I included the for loop returns to address=0 without printing anything after it, or before it in the loop(). Why is this happening?

Look at the output in the Serial

gre_gor
  • 6,669
  • 9
  • 47
  • 52
Sally Milson
  • 45
  • 1
  • 5

2 Answers2

4

I'm sure it has to do with you declaring address as a byte which is can be the integer 255 at max. What happens is if you add 1 to a byte value of 255, it loops around again to 0.

What happens when address = 255 and when the for loop goes back up to check the conditioning, 255 passes and address++ adds 1 to address so now address = 0.

https://www.arduino.cc/en/reference/byte

nugenjs
  • 155
  • 2
  • 10
  • Forgot to add an answer; use a different variable type. An `int` will solve your problem. `int` is good up to the number 32,767 on an Arduino Uno and 2,147,483,647 on Arduino Due and SAMD based boards. https://www.arduino.cc/en/reference/int – nugenjs May 04 '17 at 20:19
  • Thank you! It seems so obvious now. Of course it was the use of byte. – Sally Milson May 05 '17 at 17:44
1

Alternatively, you could use a while loop instead and increment the address counter at the very end of the loop, followed by a test to see if it has wrapped around to zero. On the first run through of the loop, the address counter will be 1, so the loop will continue until the counter has reached 255 when the increment will wrap it around to zero and execution reaches the break statement.

byte address = 0;

while( true ) // Creating an unconditional loop
{
    // Run your test here

    address++;

    if( !address ) // If address has wrapped around to 0, exit the loop
    {
        break;
    }
}

...or a do/while loop, which does the same thing but may be slightly larger in some cases.

byte address = 0;

do
{
    // Run your test here

    address++;
} while( address ); // The loop will continue until address becomes zero again

Depending on your microcontroller, this may take a few bytes more program space though it looks like the while-loop ends up the same size as the for-loop on an ATMega328. (YMMV, of course)

On 8-bit microcontrollers however, code to manipulate ints will be slower and take up more space, so depending on your code you may still be better off by being able to stick with using a byte for your address.

Erik HB
  • 61
  • 4