WT901 Multiple I2C

Hello so Im haveing trouble finding a way to change the I2C address for a WT901 im sure you can do it but i cant seem to find it online and im kinda new to the coding world. the data sheet says the IICADDR is 0x1a and it only uses b and c then jumps to 0x30 when i look at the code i have its just the basic code sample you get for this sensor i find they set the addr to 0x50 and on the data sheet thats the gps so there has to be a way to change it im sure ive said this wrong but i just want multiple of these sensors on the i2c so i can make a leg

Manufacturer's page of the WT901: https://www.wit-motion.com/gyroscope-module/Witmotion-wt901-ttl-i2c.html.
Scroll down that page for the documents

Github: https://github.com/WITMOTION/WT901
The manual and datasheet are also on that Github page
The Arduino code is in the file "Sample Code.zip".

It seems that the I2C address can be changed with register 0x1A.
I have been reading it a few times, but it is hard to understand.
It seems that writing the new address to register 0x1A followed by a restart is enough.

Can you run a I2C Scanner sketch ? Use the found I2C address.

Try to change it:

void setup()
{
  delay( 2000);

  Wire.beginTransmission( 0x50);
  Wire.write( 0x1A);
  Wire.write( 0x49);
  Wire.endTransmission();
}

void loop()
{
}

Wait a few seconds, disconnect it or remove the USB cable if that is used to power it.
Then run the I2C Scanner sketch again.

I think that the sensor and the M0 processor run at 3.3V. That means it has a 3.3V I2C bus.

yea i have the manual and data sheet printed out and i dont understand it full and i agree with you. ive never ran an i2c scanner sketch ill do that and do the code and get back to you in just a moment
thank you for the response so much

so the i2c scanner on arduino doesnt work right it doesnt give reults at all just stays blank but with the wire thing according to the data sheet i have to save it afterwords and the data sheet has a save code would i have to put that at the bottom of your setup ?

The datasheet is talking about the program on the computer, about the serial communication and about I2C. Trying to untangle them, I came up with only that short sketch. The datasheet of the sensor is indeed a confusing bunch of information, so I'm just guessing.

The first thing to do is to have a I2C Scanner running. If that does not work, then there is no need to try something else.
Here is the I2C Scanner by Nick Gammon: http://www.gammon.com.au/forum/?id=10896&reply=6#reply6.
There is also one in the menu of the Arduino IDE: File / Examples / Wire / i2c_scanner.

Which Arduino board do yo have ?
What is the output to the Serial Monitor when you run a I2C Scanner sketch ?
There should be at least something.

If you don't see anything at all, then start with the Blink example. Did you use your Arduino board before or is this the first time ?

Ok so I got the i2c scanner to work would it work in the sketch if I put the wire address change that you gave if I start the sensor start the scanner give it a delay change the address and run the scanner again in the same sketch? It says once I change the address and save the configuration will the registry I just power cycle but if I run the i2c scanner twice in the sketch before and after the address change I should see the change in the monitor right?

#include "Wire.h"
#include "WT901.h"
extern "C" {
#include "utility/twi.h" // from Wire library, so we can do bus scanning
}

// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr,
void(*callback)(byte address, byte result) )
{
byte rc;
byte data = 0; // not used, just an address to feed to twi_writeTo()
for( byte addr = from_addr; addr <= to_addr; addr++ ) {
rc = twi_writeTo(addr, &data, 0, 1, 0);
callback( addr, rc );
}
}

// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
Serial.print("addr: ");
Serial.print(addr,DEC);
Serial.print( (result==0) ? " found!":" ");
Serial.print( (addr%4) ? "\t":"\n");
}

byte start_address = 8; // lower addresses are reserved to prevent conflicts with other protocols
byte end_address = 119; // higher addresses unlock other modes, like 10-bit addressing

// standard Arduino setup()

void setup()
{

WT901.startIIC();

Serial.begin(9600);                   // Changed from 19200 to 9600 which seems to be default for Arduino serial monitor
Serial.println("\nI2CScanner ready!");

Serial.print("starting scanning of I2C bus from ");
Serial.print(start_address,DEC);
Serial.print(" to ");
Serial.print(end_address,DEC);
Serial.println("...");

// start the scan, will call "scanFunc()" on result from each address
scanI2CBus( start_address, end_address, scanFunc );

Serial.println("\ndone");

delay(5000);

Wire.beginTransmission( 0x50);
Wire.write( 0x1A);
Wire.write( 0x49);
Wire.endTransmission();

delay(2000);

Serial.println("\nI2CScanner ready!");
Serial.print("starting scanner of I2C bus from");
Serial.print("start_address, DEC);
Serial.print(" to ");
Serial.print("end_address,DEC");
Serial.print("...");

scanI2CBus( start_address, end_address, scanFunc );

Serial.println("\ndone");

}

void loop() {}

What am I doing wrong here it only says there is a ) before; that shouldn't be

#include <Wire.h>
#include <WT901.h>
void setup() {
WT901.startIIC(0x50);
Wire.begin();
Serial.begin(9600);
Wire.beginTransmission(0x50);
Wire.write(0x1a);
Wire.write(0x49);
Wire.endTransmission(0x49);
WT901.saveConf();

Serial.println("\nI2C Scanner");

byte error, address;
int 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");
delay(2000);
Wire.beginTransmission(0x50);
Wire.write(0x1A);
Wire.write(0x49);
Wire.endTransmission();
}

void loop(){}
Ok so this is what I got but it doesn't change the addr

When you show a sketch, please put it between lines with three backware-single-quotes or use the </> button.

```
Your sketch
```

It is normal to have a few difference test-sketches before the final sketch is made. You were not supposed to put the I2C Scanner into your sketch.
Can you try once more as I described in reply #2 ?

Can you copy the text from the I2C Scanner and show it here ? Both before and after the small sketch to change the address.

At this moment I don't even know if you are actually communicating with the WT901. If the I2C Scanner finds 0x50, then we can make the next step.

 #include <Wire.h> 
 
 void setup()   {
  Wire.begin();  
  Serial.begin(9600);  
    Wire.beginTransmission(0x50);
Wire.write(0xFF);
Wire.write(0xAA);
    Wire.write(0x1A);
    Wire.write(0x49);
Wire.write(0x00);
    Wire.endTransmission();
    }
  
void loop(){
        Serial.println("\nI2C Scanner");  
 
  byte error, address;  
  int 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");  
  delay(2000);  
  
 }  

This is a what I have since it was 5 arguments in the data sheet we came up with this and the i2c sensor shows back as 0x50

The i2c scanner reading just says sensor found and 0x50 is sensor addr

It is not about what you came up with, because I think you are mixing a few things together (computer, serial, I2C). Those 5 arguments are not in the datasheet for I2C. If you think they are, then please tell me where that is or make a screendump of that part of the datasheet.

Please use the I2C Scanner sketch on its own, and my small sketch on its own.
You have to make a new sketch with only those few lines of reply #2.

If you can not run a I2C Scanner sketch on its own and not my sketch of reply #2 on its own, then I have to bail out.

image

image

thats where i get my idea of five arguments but i could be very wrong and here we go. i did everything you mentioned up to now i ran line my library code just to check if it was working first and get this which the things that come back as zero i dont have this is just the example code

Time:200-0-0 0:3:21.27
Acc:0.81 -0.41 0.36
Gyro:-1.16 -0.24 -0.18
Angle:-48.36 -55.89 -6.09
Mag:-254 306 164
Pressure:0 0.00
DStatus:1628 785 517 459
Longitude:0Deg0.00m Lattitude:0Deg0.00m
GPSHeight:0.00m GPSYaw:0.00Deg GPSV:0.00km/h

then i ran the i2c scanner and get this back

Scanning...
I2C device found at address 0x50 !
done

then i ran your line 2 code as is and it did not change it i tried to tweak it and do this

#include <Wire.h>
#include <JY901.h>
void setup()
{
  JY901.StartIIC();
  delay( 2000);

  Wire.beginTransmission( 0x50);
  Wire.write( 0x1A);
  Wire.write( 0x49);
  Wire.endTransmission();
  SAVE;
}

void loop()
{
}

it unfortunatly came back as 0x50 on the scanner still after the restart i then went so far as tried

     Wire.beginTransmission(0x50);
Wire.write(0xFF);
Wire.write(0xAA);
    Wire.write(0x1A);
    Wire.write(0x49);
Wire.write(0x00);
    Wire.endTransmission();

it still did nothing i even tried to add the start and save as i did with my modded line#2 code you sent but with or without the starting and saveing of the sensor the results come back as 0x50 still
i hope ive explained myself and did the things you asked correctly so we maybe can get a little closer to an answer

to fully clarify i ran your code the first time as you wrote it i did have to include the wire.h library but thats the only thing i did to it one the first 2 tries i did with your code. i then restarted after and ran the i2c scanner separate

:point_right: Can you give a link to which datasheet you are using ? I'm looking at a different one, which does not have chapter 7.

The part about "connect to PC", reply #13, is for the program on the computer.

The part about "7.2.32 Set IIC Address", reply #14, is for the serial/UART communication.
The Serial/UART uses a standard byte pattern with the extra bytes. Go to the beginning of chapter 7, you see that is for Serial/UART.

This is not you fault. Most sensors that can change their address cause a lot of troubles. Some sensors don't store the new address and it has to be set at startup, some have a whole sequence of commands. There are Arduino users that give up and fix it with a hardware I2C multiplexer. I even think there are bugs in the datasheet when explaining the I2C protocol.

I'm just as confused as you. They say this: "The length of each address are 16bits, two bytes". They are talking about the register address. But then they say that the data is 16 bits, and the picture shows a single byte for the register address and two bytes for the data.

Perhaps a even I2C address works better and a odd I2C address.
That means it could be this:

void setup()
{
  delay( 2000);

  Wire.beginTransmission( 0x50);  // I2C address
  Wire.write( 0x1A);   // register address
  Wire.write( 0x48);   // low byte of 16-bits data
  Wire.write( 0x00);   // high byte of 16-bits data
  Wire.endTransmission();
}

void loop()
{
}

I still have to figure out if there is a "save" or "store" I2C command, and maybe a "restart" I2C command. I don't think so, but I could be wrong.

WT901 - Google Drive
here is the entire drive they have for what i have it doesnt have chapter 7 either i got that snip from discord with a guy i was talking to but look at chapter 6 in the data sheet i think it is saying how to change the bus address in there i just am haveing trouble reading it he may have been looking in one of the other datasheets and after careful looking there isnt a chapter 7 for mine but the read and write sectons of chapter 6 in the data sheet there is something there

This is what the DEV just sent me for additional commands on changing the address he said it is very possible to do in i2c coding but he was not sure how it was done and sent me these command other stuff is for gyro mag etc I can give a link if you want but other than what I posted it doesn't say anything related to our topic.

That picture is for the Serial/UART communication.

I would like you to run my sketch from reply #17. Sorry that I missed that the data is two bytes.

If that does not work, then we can go one step further with the save command.

void setup()
{
  delay( 2000);

  Wire.beginTransmission( 0x50);  // I2C address
  Wire.write( 0x1A);   // register address
  Wire.write( 0x48);   // low byte of 16-bits data
  Wire.write( 0x00);   // high byte of 16-bits data
  Wire.endTransmission();

  delay( 1000);

  Wire.beginTransmission( 0x50);  // I2C address
  Wire.write( 0x00);   // register address of SAVE command
  Wire.write( 0x00);   // low byte of 16-bits data, zero for SAVE command
  Wire.write( 0x00);   // high byte of 16-bits data, zero for SAVE command
  Wire.endTransmission();
}

void loop()
{
}