I have multiple I2C anemometers that I'd like to read data from, but they all have the same base address. It is possible to change the addresses, but the data sheet doesn't make it super clear for how to do it using Arduino. I've attached the relevant pages and the code the sensor supplier provided for reading the sensor: F200-Digital-Airflow-Probe-Manual-pages-9-13.pdf (1.5 MB)
#include <Wire.h>
const unsigned int ADDR_STATUS = 66;
const unsigned int ADDR_VELOCITY = 67;
const unsigned int ADDR_TEMPERATURE = 71;
const int SLAVE_ADDR = 0xC0;
void setup() {
Wire.begin(); // Enable I2C communication as master
Serial.begin (19200); // Enable communication back to host PC at 19200 bps
}
void loop() {
// stream the sensor's Velocity, temperature and status
// to the host computer using the USB/Serial port
Serial.print ("Velocity: ");
Serial.print (GetVelocity(SLAVE_ADDR));
Serial.println (" m/s");
}
/*
* GetVelocity
* Summary: Requests the Velocity in meters per second at I2C address addr
* returns: A floating point value of the sensor's velocity reading in m/s
*/
float GetVelocity (int addr)
{
unsigned int result;;
// write the address being requested to the sensor
Wire.beginTransmission(addr>>1);
Wire.write(ADDR_VELOCITY); // request the velocity register
Wire.endTransmission();
// read back the two bytes at that address
Wire.requestFrom (addr>>1,2);
result = Wire.read(); // first byte read is LSB
result += (Wire.read() << 8); // second byte read is MSB
return ((float) result) / 1000.0;
}
The I2C address is not 0xC0.
Can you run a I2C Scanner sketch ? It should be 0x60.
There are a few more things in the datasheet that are misleading or incomplete.
When data is read via the I2C bus, I think a repeated start should be used.
Could you try this:
Wire.beginTransmission( 0x60);
int error = Wire.endTransmission();
if( error != 0)
{
Serial.println( "The sensor is not at 0x60");
}
else
{
Serial.println( "The sensor is found, changing I2C address");
Wire.beginTransmission( 0x60);
Wire.write( 0x53); // password register
Wire.write( 0xAA); // password
Wire.endTransmission();
delay(10); // not described somewhere, just for safety
Wire.beginTransmission( 0x60);
Wire.write( 0x00); // I2C address register
Wire.write( 0x50); // new I2C address
Wire.endTransmission();
}
Then turn off the power and turn on the power. Run a I2C Scanner sketch and check if the new I2C address is found.
The register contains the 8-bit version of the address so: Wire.write( 0x50 << 1); // new I2C address
How much current does the airflow sensor draw? If it's under 40 mA you can power it from an Arduino output pin. That would allow you to cycle the power (turn it off and on again). Then you can not only set a new address but test if it is working at the new address after the required power cycle.
If 'multiple' means some number above about 3, you might want to have your sketch get the desired addresses from a table or from Serial input. That way you don't have to edit and re-upload the sketch for each address you want to program.
The airflow sensors draws <35mA nominal, but I'm looked to run many of them (36) at once. I'm powering them from a separate power supply, but using the same I2C bus. Should I be concerned with the quantity of sensors I'm putting on the bus? Also, in reference to your comment about putting in values from a table, I'm gonna look into that now!
36 sensors means a lot of wires. The problem with the I2C bus is the wires.
Maybe the sensor has an internal pullup resistors. 36 pullup resistors might be too much.
When someone has a single small problem on the I2C bus and asks on this forum how to fix it, then I have to tell that he/she has many major problems with the I2C bus.
You have to do everything just right to be able to use 36 devices on a I2C bus.