本帖最后由 UerRob 于 2015-5-17 14:41 编辑
万能方法三:(什么都没有,仅有一种地址的模块)
原本买来六个ADXL345来读取不同地方的加速度信息,datasheet里说可以通过对某个引脚置高置低来选择其中一个地址。然而发现并不能改变地址!于是只好想出这样一个邪恶的方法。
用到的工具是模拟开关,楼主以CD4053为例,这货非常便宜,几元钱可以买一大把。
简单来说模拟开关相当于多个单刀双掷开关,可以通过IO口输出高低电平控制某两路连通。
我们知道I2C通信有 SCL和SDA两根线,我们通过调整模拟开关使仅有一个模块完整接入I2C BUS即可实现只对其中一个通信。
具体实施方式:
假设有模块1 2 3
CD4053的 ay by cy悬空 ax bx cx并接到单片机的SCL
将模块1的SCL口接CD4053的a口
将模块2的SCL口接CD4053的b口
将模块3的SCL口接CD4053的c口
这样只需将A置高,B、C置低,即可与模块1通信
将B置高,A、C置低,即可与模块2通信
将C置高,A、B置低,即可与模块3通信
亲测有效,读数稳定,
不过注意一定要将CD4053 VEE和VSS都接地,不然读数抖动不稳定,楼主在这里卡死了很久!{:soso_e105:}
上代码 以ADXL345为例:
- boolean x=true; //是否调试输出
- //CD4053的接入方式
- //INH口接地 aY->SCL1 bY->SCL2 cY->SCL3 a.b.c->SCL_Arduino
- #define CD4053_C 10
- #define CD4053_B 9
- #define CD4053_A 8
- //----------1
- //CBA 000 不接通
- //CBA 100 C接通
- //CBA 010 B接通
- //CBA 001 A接通
- //----------2
- //PIN
- #define PIN_SDA 20
- #define PIN_SCL 21
- //I2C (sparkfun breakout)
- #define Register_ID 0
- #define Register_2D 0x2D
- #define Register_X0 0x32
- #define Register_X1 0x33
- #define Register_Y0 0x34
- #define Register_Y1 0x35
- #define Register_Z0 0x36
- #define Register_Z1 0x37
- #include <Wire.h>
- int ADXAddress = 0x53; // the default 7-bit slave address
- int reading = 0;
- int val=0;
- int X0,X1,X_out;
- int Y0,Y1,Y_out;
- int Z1,Z0,Z_out;
- double Xg,Yg,Zg;
- int flag=1; //标志变量
- void Wire_Start(){
- Wire.beginTransmission(ADXAddress);
- Wire.write(Register_2D);
- Wire.write(8); //measuring enable
- Wire.endTransmission(); // stop transmitting
- }
- void Wire_Get(){
- //--------------X
- Wire.beginTransmission(ADXAddress); // transmit to device
- Wire.write(Register_X0);
- Wire.write(Register_X1);
- Wire.endTransmission();
- Wire.requestFrom(ADXAddress,2);
- if(Wire.available()<=2)
- {
- X0 = Wire.read();
- X1 = Wire.read();
- X1=X1<<8;
- X_out=X0+X1;
- }
- //------------------Y
- Wire.beginTransmission(ADXAddress); // transmit to device
- Wire.write(Register_Y0);
- Wire.write(Register_Y1);
- Wire.endTransmission();
- Wire.requestFrom(ADXAddress,2);
- if(Wire.available()<=2)
- {
- Y0 = Wire.read();
- Y1 = Wire.read();
- Y1=Y1<<8;
- Y_out=Y0+Y1;
- }
- //------------------Z
- Wire.beginTransmission(ADXAddress); // transmit to device
- Wire.write(Register_Z0);
- Wire.write(Register_Z1);
- Wire.endTransmission();
- Wire.requestFrom(ADXAddress,2);
- if(Wire.available()<=2)
- {
- Z0 = Wire.read();
- Z1 = Wire.read();
- Z1=Z1<<8;
- Z_out=Z0+Z1;
- }
- //----------------
- Xg=X_out/256.0;
- Yg=Y_out/256.0;
- Zg=Z_out/256.0;
- }
- void setup()
- {
- Wire.begin();
- if(x)
- Serial.begin(9600);
- delay(100);
-
- pinMode(CD4053_A,OUTPUT);
- pinMode(CD4053_B,OUTPUT);
- pinMode(CD4053_C,OUTPUT);
- // enable to measute g data
-
- digitalWrite(CD4053_A,HIGH);
- digitalWrite(CD4053_B,LOW);
- digitalWrite(CD4053_C,LOW);
- delay(10);
- Wire_Start(); //初始化模块1
- digitalWrite(CD4053_A,LOW);
- digitalWrite(CD4053_B,HIGH);
- delay(10);
- Wire_Start(); //初始化模块2
-
- digitalWrite(CD4053_B,LOW);
- digitalWrite(CD4053_C,HIGH);
- delay(10);
- Wire_Start(); //初始化模块3
- }
- void loop()
- {
- if(x){
- Serial.print("----");
- Serial.print((flag+0));
- Serial.println("----");}
- switch(flag){
- case 1: {
- digitalWrite(CD4053_A,HIGH);
- digitalWrite(CD4053_C,LOW);
- Wire_Get(); //读取模块1
- flag=2;
- break;
- }
- case 2:{
- digitalWrite(CD4053_B,HIGH);
- digitalWrite(CD4053_A,LOW);
- Wire_Get(); //读取模块2
- flag=3;
- break;
- }
- case 3:{
- digitalWrite(CD4053_C,HIGH);
- digitalWrite(CD4053_B,LOW);
- Wire_Get(); //读取模块3
- flag=1;
- break;
- }
- }
- if(x){
- Serial.print("X= ");
- Serial.print(Xg);
- Serial.print(" ");
- Serial.print("Y= ");
- Serial.print(Yg);
- Serial.print(" ");
- Serial.print("Z= ");
- Serial.println(Zg);
- }
- delay(33); //改变参数可以改变读取频率
- }
复制代码 |