Example6_Change_I2C_Address.ino not working

I am trying to change the I2C address on a qwiic relay, SparkFun Qwiic Single Relay COM-15093 using the example program Example6_Change_I2C_Address.ino. Here is the console output which says it changed but when I call the i2c scanner it still shows the default address of 0x18. I am using the qwiic relay library v 1.2.0 w arduino ide 1.8.10

18:15:43.091 → Scanning…

18:15:43.091 → I2C device found at address 0x18 !

18:15:43.091 → done

18:15:43.091 →

18:15:43.091 → Ready to flip some switches.

18:15:43.138 → Address changed successfully.

18:15:45.132 → Scanning…

18:15:45.132 → I2C device found at address 0x18 !

18:15:45.132 → done

18:15:45.132 →

/*
  This example code demonstrates how to change the address of the Single or
  Quad Qwiic Relay to one of your choosing. There is a set range of available
  addresses from 0x07 to 0x78, so make sure your chosen address falls within
  this range. The next thing to note is that when you change the address you'll
  need to call an instance of the Qwiic_Relay class that includes your new
  address: "Qwiic_Relay relay(YOUR_NEW_ADDRESS_HERE);" so that the new address
  is fed to all the available functions. Finally if for some reason you've
  forgotten your new address. No big deal, load up the I2C scanner example code
  and find out where your product's address is at. 
  By: Elias Santistevan
  SparkFun Electronics
  Date: July 2019

  License: This code is public domain but you buy me a beer if you use 
	this and we meet someday (Beerware license).
*/

#include <Wire.h>
#include "SparkFun_Qwiic_Relay.h"

// All available product addresses labeled below. Close the onboard jumpers if
// you want to access the alternate addresses. 
#define SINGLE_DEFAULT_ADDR 0x18 // Alternate jumper address 0x19
//#define QUAD_DEFAULT_ADDR 0x6D // Alternate jumper address 0x6C

#define NEW_ADDR 0x19
// After changing the address you'll need to apply that address to a new
// instance of the Qwiic_Relay class: "Qwiic_Relay relay(YOUR_NEW_ADDRESS_HERE)".
Qwiic_Relay relay(SINGLE_DEFAULT_ADDR); // Change to Single Relay Address if using Quad Relay

void setup()
{
  Wire.begin(); 
  Serial.begin(115200);
   I2Cscanner();
  // Let's see.....
  if(relay.begin())
    Serial.println("Ready to flip some switches.");
  else
    Serial.println("Check connections to Qwiic Relay.");

  // There is a not so limited but still limited range of
  // addresses that are available to you 0x07 -> 0x78.
  if(relay.changeAddress(NEW_ADDR)) // Put the address you want here. 
    Serial.println("Address changed successfully."); 
  else
    Serial.println("Address change failed...");
  
  delay(2000);

  I2Cscanner();

  
}

void loop()
{
}

void I2Cscanner()
{
    byte error, address;
    byte nDevices;
    
    Serial.println("Scanning...");
    
    nDevices = 0;
    for(address = 1; address < 127; address++ ) 
    {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    
    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);
    } 
    }
    if (nDevices == 0)
    Serial.println("No I2C devices found\n");
    else
    Serial.println("done\n");


}

Thanks for reaching out to us on this.

Newer documentation for this process exists here (which corrects some errors): https://learn.sparkfun.com/tutorials/qw … ample-code

Hope this helps, and happy sparking!

that tutorial does not show any sample code for changing the address, just passing a parm if it was already changed as far as I could tell. I am looking for code to change the default i2c address from say 0x18 to 0x19 . The download had a sample script in the examples folder that I mentioned above but does not seem to work. I bought several relays and need to give each one a unique address.

I misunderstood.

You initially change the address to 0x19 via the jumper pads , which is mentioned in the example https://github.com/sparkfun/SparkFun_Qw … ddress.ino

If you need to become familiar with how to use jumpers, here’s a link to that: https://learn.sparkfun.com/tutorials/ho … s-a-jumper

After doing so, the example mentions: // After changing the address you’ll need to apply that address to a new

// instance of the Qwiic_Relay class: “Qwiic_Relay relay(YOUR_NEW_ADDRESS_HERE)”.

Place your new specified address and you should be good to upload and re-scan i2c for the new address.

Best of luck!

I am not using the jumper pads, I am try to change the address using the program provided in the download “Example6_Change_I2C_Address.ino”

I did some searching on goggle and found some sample code I think was from when this product was released as sparkx product that works.

#include <Wire.h>
#define COMMAND_RELAY_OFF 0x00
#define COMMAND_RELAY_ON 0x01
#define COMMAND_CHANGE_ADDRESS 0x03
volatile byte qwiicRelayAddress = 0x18; //Default Address


void setup()
{
 Serial.begin(115200);
 Serial.println("Qwiic Relay Master Awake");
 Wire.begin(); // join the I2C Bus
 Wire.beginTransmission(qwiicRelayAddress); // transmit to device
 //check here for an ACK from the slave
 if (Wire.endTransmission() != 0 ) {
 Serial.println("Check Connections. Slave not found.");
 }
 else {
 Serial.println("Qwiic Relay found!");
 }

 I2Cscanner();

 boolean error = changeAddress(0x19); // Change the Relay's address to 0x19
if (error != true) {
 Serial.println("!!!!! invalid address" );
 }
 else {
 Serial.println("success");
 }

  I2Cscanner();

 
}

void loop()
{
  
}

boolean changeAddress(byte address) {
 Wire.beginTransmission(qwiicRelayAddress);
 //check here for an ACK from the slave
 if (Wire.endTransmission() != 0) {
 Serial.println("Check Connections. No slave found.");
 return (false);
 }
 //check if valid address.
 if (address < 0x07 || address > 0x78) {
 Serial.println("Invalid I2C address");
 return (false);
 }
 //valid address
 Wire.beginTransmission(qwiicRelayAddress);
 Wire.write(COMMAND_CHANGE_ADDRESS);
 qwiicRelayAddress = address;
 Wire.write(qwiicRelayAddress);
 Wire.endTransmission();
 return (true); //Success!
}


void I2Cscanner()
{
    byte error, address;
    byte nDevices;
    
    Serial.println("Scanning...");
    
    nDevices = 0;
    for(address = 1; address < 127; address++ ) 
    {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    
    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);
    } 
    }
    if (nDevices == 0)
    Serial.println("No I2C devices found\n");
    else
    Serial.println("done\n");


}

Excellent!

Thanks for sharing! This worked to reprogram the address for me too.

Here is some code snippets that let you control 2 relays independently:

in setup:

#define RELAY_ADDR 0x18 // Default address

#define NEW_ADDR 0x19 // Reprogrammed using Change_I2C_Address

Qwiic_Relay relay1(RELAY_ADDR);

Qwiic_Relay relay2(NEW_ADDR);

Can then control relay1 and relay 2 individually:

relay1.turnRelayOn();

relay2.turnRelayOn();

…etc.

jimk123:
I did some searching on goggle and found some sample code I think was from when this product was released as sparkx product that works.

#include <Wire.h>

#define COMMAND_RELAY_OFF 0x00
#define COMMAND_RELAY_ON 0x01
#define COMMAND_CHANGE_ADDRESS 0x03
volatile byte qwiicRelayAddress = 0x18; //Default Address

void setup()
{
Serial.begin(115200);
Serial.println(“Qwiic Relay Master Awake”);
Wire.begin(); // join the I2C Bus
Wire.beginTransmission(qwiicRelayAddress); // transmit to device
//check here for an ACK from the slave
if (Wire.endTransmission() != 0 ) {
Serial.println(“Check Connections. Slave not found.”);
}
else {
Serial.println(“Qwiic Relay found!”);
}

I2Cscanner();

boolean error = changeAddress(0x19); // Change the Relay’s address to 0x19
if (error != true) {
Serial.println(“!!! invalid address” );
}
else {
Serial.println(“success”);
}

I2Cscanner();

}

void loop()
{

}

boolean changeAddress(byte address) {
Wire.beginTransmission(qwiicRelayAddress);
//check here for an ACK from the slave
if (Wire.endTransmission() != 0) {
Serial.println(“Check Connections. No slave found.”);
return (false);
}
//check if valid address.
if (address < 0x07 || address > 0x78) {
Serial.println(“Invalid I2C address”);
return (false);
}
//valid address
Wire.beginTransmission(qwiicRelayAddress);
Wire.write(COMMAND_CHANGE_ADDRESS);
qwiicRelayAddress = address;
Wire.write(qwiicRelayAddress);
Wire.endTransmission();
return (true); //Success!
}

void I2Cscanner()
{
byte error, address;
byte nDevices;

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

nDevices = 0;
for(address = 1; address < 127; address++ ) 
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();

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);
} 
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");

}

When I run this code, it cannot find the I2C device address, It just returns a lot of them.

Any idea how to read the correct I2C device address?

12:02:41.359 → success

12:02:41.359 → Scanning…

12:02:41.359 → I2C device found at address 0x01 !

12:02:41.359 → I2C device found at address 0x02 !

12:02:41.359 → I2C device found at address 0x03 !

12:02:41.359 → I2C device found at address 0x04 !

12:02:41.359 → I2C device found at address 0x05 !

12:02:41.359 → I2C device found at address 0x06 !

12:02:41.359 → I2C device found at address 0x07 !

12:02:41.359 → I2C device found at address 0x08 !

12:02:41.359 → I2C device found at address 0x09 !

12:02:41.359 → I2C device found at address 0x0A !

12:02:41.359 → I2C device found at address 0x0B !

12:02:41.359 → I2C device found at address 0x0C !

12:02:41.405 → I2C device found at address 0x0D !

12:02:41.405 → I2C device found at address 0x0E !

12:02:41.405 → I2C device found at address 0x0F !

12:02:41.405 → I2C device found at address 0x10 !

12:02:41.405 → I2C device found at address 0x11 !

12:02:41.405 → I2C device found at address 0x12 !

12:02:41.405 → I2C device found at address 0x13 !

12:02:41.405 → I2C device found at address 0x14 !

12:02:41.405 → I2C device found at address 0x15 !

12:02:41.405 → I2C device found at address 0x16 !

12:02:41.405 → I2C device found at address 0x17 !

12:02:41.405 → I2C device found at address 0x18 !

12:02:41.405 → I2C device found at address 0x19 !

12:02:41.405 → I2C device found at address 0x1A !

12:02:41.405 → I2C device found at address 0x1B !

12:02:41.451 → I2C device found at address 0x1C !

12:02:41.451 → I2C device found at address 0x1D !

12:02:41.451 → I2C device found at address 0x1E !

12:02:41.451 → I2C device found at address 0x1F !

12:02:41.451 → I2C device found at address 0x20 !

12:02:41.451 → I2C device found at address 0x21 !

12:02:41.451 → I2C device found at address 0x22 !

12:02:41.451 → I2C device found at address 0x23 !

12:02:41.451 → I2C device found at address 0x24 !

12:02:41.451 → I2C device found at address 0x25 !

12:02:41.451 → I2C device found at address 0x26 !

12:02:41.451 → I2C device found at address 0x27 !

12:02:41.451 → I2C device found at address 0x28 !

12:02:41.451 → I2C device found at address 0x29 !

12:02:41.496 → I2C device found at address 0x2A !

12:02:41.496 → I2C device found at address 0x2B !

12:02:41.496 → I2C device found at address 0x2C !

12:02:41.496 → I2C device found at address 0x2D !

12:02:41.496 → I2C device found at address 0x2E !

12:02:41.496 → I2C device found at address 0x2F !

12:02:41.496 → I2C device found at address 0x30 !

12:02:41.496 → I2C device found at address 0x31 !

12:02:41.496 → I2C device found at address 0x32 !

12:02:41.496 → I2C device found at address 0x33 !

12:02:41.496 → I2C device found at address 0x34 !

12:02:41.496 → I2C device found at address 0x35 !

12:02:41.496 → I2C device found at address 0x36 !

12:02:41.496 → I2C device found at address 0x37 !

12:02:41.496 → I2C device found at address 0x38 !

12:02:41.541 → I2C device found at address 0x39 !

12:02:41.541 → I2C device found at address 0x3A !

12:02:41.541 → I2C device found at address 0x3B !

12:02:41.541 → I2C device found at address 0x3C !

12:02:41.541 → I2C device found at address 0x3D !

12:02:41.541 → I2C device found at address 0x3E !

12:02:41.541 → I2C device found at address 0x3F !

12:02:41.541 → done

jimk123:
I did some searching on goggle and found some sample code I think was from when this product was released as sparkx product that works.

#include <Wire.h>

#define COMMAND_RELAY_OFF 0x00
#define COMMAND_RELAY_ON 0x01
#define COMMAND_CHANGE_ADDRESS 0x03
volatile byte qwiicRelayAddress = 0x18; //Default Address

void setup()
{
Serial.begin(115200);
Serial.println(“Qwiic Relay Master Awake”);
Wire.begin(); // join the I2C Bus
Wire.beginTransmission(qwiicRelayAddress); // transmit to device
//check here for an ACK from the slave
if (Wire.endTransmission() != 0 ) {
Serial.println(“Check Connections. Slave not found.”);
}
else {
Serial.println(“Qwiic Relay found!”);
}

I2Cscanner();

boolean error = changeAddress(0x19); // Change the Relay’s address to 0x19
if (error != true) {
Serial.println(“!!! invalid address” );
}
else {
Serial.println(“success”);
}

I2Cscanner();

}

void loop()
{

}

boolean changeAddress(byte address) {
Wire.beginTransmission(qwiicRelayAddress);
//check here for an ACK from the slave
if (Wire.endTransmission() != 0) {
Serial.println(“Check Connections. No slave found.”);
return (false);
}
//check if valid address.
if (address < 0x07 || address > 0x78) {
Serial.println(“Invalid I2C address”);
return (false);
}
//valid address
Wire.beginTransmission(qwiicRelayAddress);
Wire.write(COMMAND_CHANGE_ADDRESS);
qwiicRelayAddress = address;
Wire.write(qwiicRelayAddress);
Wire.endTransmission();
return (true); //Success!
}

void I2Cscanner()
{
byte error, address;
byte nDevices;

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

nDevices = 0;
for(address = 1; address < 127; address++ ) 
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();

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);
} 
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");

}

Some boards with devices that use clock-stretch need a write between

Wire.beginTransmission(address);
    error = Wire.endTransmission();

like

Wire.beginTransmission(address);
Wire.write(0x01);   // or a valid register for the device
error = Wire.endTransmission();

Give it a try and see