极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14316|回复: 8

以ADXL345为例 三种方法让你在I2C通信中同时和多个从机通信

[复制链接]
发表于 2015-5-17 14:38:01 | 显示全部楼层 |阅读模式
对于不同地址的模块就不用多说了,直接分别对其地址进行通信即可。那么若拿到相同地址的模块,或者直接是相同的多个模块怎么办呢?
经过楼主对adxl345的苦苦摸索,这里给大家分享三种方法。{:soso_e104:}

楼主纯手打+原创
到游弋吧uer8.com发了一次 不过里面都是大学生
转过来给更多人分享一下
回复

使用道具 举报

 楼主| 发表于 2015-5-17 14:38:32 | 显示全部楼层
本帖最后由 UerRob 于 2015-5-17 14:42 编辑

方法一:(内置了两种地址的模块
对于内置了两种地址的模块,可以通过对某个引脚置高或置低来选择其中一个地址,现假设置高为A,置低为B。
假设你有三个模块要同时通信,首先将模块1置高,模块2、模块3的地址选择口置低,这样仅有模块1在地址A,然后对地址A进行通信即可防止其他模块干扰。接下来将模块1置低,模块2置高,即可对模块2通信。循环下去即可实现同时对三个模块通信。

方法二:(具有使能端的模块
若你手中的模块某个引脚必须拉低或拉高才能正常使用,那么仿照方法一,对其中一个使能,其他均处于非使能状态,如此便可以仅对其中一个模块通信咯。


如adxl345中的ALT ADDRESS口即是地址选择口

如果以上都不行,那就只能方法三了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-17 14:39:31 | 显示全部楼层
本帖最后由 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为例:



  1. boolean x=true;   //是否调试输出

  2. //CD4053的接入方式
  3. //INH口接地  aY->SCL1 bY->SCL2 cY->SCL3 a.b.c->SCL_Arduino

  4. #define CD4053_C 10
  5. #define CD4053_B 9
  6. #define CD4053_A 8

  7.   //----------1
  8.   //CBA 000  不接通
  9.   //CBA 100  C接通
  10.   //CBA 010  B接通
  11.   //CBA 001  A接通

  12.   //----------2

  13. //PIN
  14. #define PIN_SDA 20
  15. #define PIN_SCL 21


  16. //I2C (sparkfun breakout)
  17. #define Register_ID 0
  18. #define Register_2D 0x2D
  19. #define Register_X0 0x32
  20. #define Register_X1 0x33
  21. #define Register_Y0 0x34
  22. #define Register_Y1 0x35
  23. #define Register_Z0 0x36
  24. #define Register_Z1 0x37

  25. #include <Wire.h>
  26. int ADXAddress = 0x53; // the default 7-bit slave address
  27. int reading = 0;
  28. int val=0;
  29. int X0,X1,X_out;
  30. int Y0,Y1,Y_out;
  31. int Z1,Z0,Z_out;
  32. double Xg,Yg,Zg;
  33. int flag=1;   //标志变量

  34. void Wire_Start(){
  35.   Wire.beginTransmission(ADXAddress);
  36.   Wire.write(Register_2D);
  37.   Wire.write(8); //measuring enable
  38.   Wire.endTransmission(); // stop transmitting
  39. }

  40. void Wire_Get(){
  41.     //--------------X
  42.     Wire.beginTransmission(ADXAddress); // transmit to device
  43.     Wire.write(Register_X0);
  44.     Wire.write(Register_X1);
  45.     Wire.endTransmission();
  46.     Wire.requestFrom(ADXAddress,2);
  47.     if(Wire.available()<=2)
  48.     {
  49.     X0 = Wire.read();
  50.     X1 = Wire.read();
  51.     X1=X1<<8;
  52.     X_out=X0+X1;
  53.     }
  54.     //------------------Y
  55.     Wire.beginTransmission(ADXAddress); // transmit to device
  56.     Wire.write(Register_Y0);
  57.     Wire.write(Register_Y1);
  58.     Wire.endTransmission();
  59.     Wire.requestFrom(ADXAddress,2);
  60.     if(Wire.available()<=2)
  61.     {
  62.     Y0 = Wire.read();
  63.     Y1 = Wire.read();
  64.     Y1=Y1<<8;
  65.     Y_out=Y0+Y1;
  66.     }
  67.     //------------------Z
  68.     Wire.beginTransmission(ADXAddress); // transmit to device
  69.     Wire.write(Register_Z0);
  70.     Wire.write(Register_Z1);
  71.     Wire.endTransmission();
  72.     Wire.requestFrom(ADXAddress,2);
  73.     if(Wire.available()<=2)
  74.     {
  75.     Z0 = Wire.read();
  76.     Z1 = Wire.read();
  77.     Z1=Z1<<8;
  78.     Z_out=Z0+Z1;
  79.     }
  80.     //----------------
  81.     Xg=X_out/256.0;
  82.     Yg=Y_out/256.0;
  83.     Zg=Z_out/256.0;
  84. }

  85. void setup()
  86. {
  87.   Wire.begin();
  88.   if(x)
  89.   Serial.begin(9600);
  90.   delay(100);
  91.   
  92.   pinMode(CD4053_A,OUTPUT);
  93.   pinMode(CD4053_B,OUTPUT);
  94.   pinMode(CD4053_C,OUTPUT);
  95.   // enable to measute g data
  96.   

  97.   digitalWrite(CD4053_A,HIGH);
  98.   digitalWrite(CD4053_B,LOW);
  99.   digitalWrite(CD4053_C,LOW);
  100.   delay(10);
  101.   Wire_Start();   //初始化模块1

  102.   digitalWrite(CD4053_A,LOW);
  103.   digitalWrite(CD4053_B,HIGH);
  104.   delay(10);
  105.   Wire_Start();   //初始化模块2
  106.   
  107. digitalWrite(CD4053_B,LOW);
  108.   digitalWrite(CD4053_C,HIGH);
  109.   delay(10);
  110.   Wire_Start();  //初始化模块3

  111. }
  112. void loop()
  113. {  
  114.   if(x){  
  115.   Serial.print("----");
  116.   Serial.print((flag+0));
  117.   Serial.println("----");}
  118.   switch(flag){
  119.     case 1: {              
  120.       digitalWrite(CD4053_A,HIGH);
  121.       digitalWrite(CD4053_C,LOW);
  122.       Wire_Get();     //读取模块1
  123.       flag=2;
  124.       break;
  125.     }
  126.     case 2:{

  127.       digitalWrite(CD4053_B,HIGH);
  128.       digitalWrite(CD4053_A,LOW);
  129.       Wire_Get();         //读取模块2
  130.       flag=3;
  131.       break;
  132.     }   
  133.     case 3:{

  134.       digitalWrite(CD4053_C,HIGH);
  135.       digitalWrite(CD4053_B,LOW);
  136.       Wire_Get();         //读取模块3
  137.       flag=1;
  138.       break;
  139.     }
  140.   }  

  141.   if(x){  
  142.   Serial.print("X= ");
  143.   Serial.print(Xg);
  144.   Serial.print(" ");
  145.   Serial.print("Y= ");
  146.   Serial.print(Yg);
  147.   Serial.print(" ");
  148.   Serial.print("Z= ");
  149.   Serial.println(Zg);
  150.   }
  151.   delay(33); //改变参数可以改变读取频率
  152. }

复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2015-5-17 15:52:22 | 显示全部楼层
牛,学习了,是个好方法。
回复 支持 反对

使用道具 举报

发表于 2015-5-17 20:27:10 | 显示全部楼层
这方法不错,可惜我的345 Z轴是坏的
回复 支持 反对

使用道具 举报

发表于 2015-5-17 21:59:42 | 显示全部楼层
UerRob 发表于 2015-5-17 14:39
万能方法三:(什么都没有,仅有一种地址的模块)
原本买来六个ADXL345来读取不同地方的加速度信息,datas ...

不错,对于初学者有很大的参考价值,感谢楼主贡献资料,有了加速度计的资料,陀螺仪的照着也可以自己写了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-6-2 17:47:19 | 显示全部楼层
azh7138m 发表于 2015-5-17 20:27
这方法不错,可惜我的345 Z轴是坏的

反正345挺便宜 换一个呗   个人用起来感觉灵敏度挺高的
回复 支持 反对

使用道具 举报

发表于 2015-7-4 17:55:20 | 显示全部楼层
lz我是萌新,你的帖子很有帮助。但可不可以提供一个较为详细的CD4053的接线方式,小白不懂,谢谢。
回复 支持 反对

使用道具 举报

发表于 2015-7-4 17:57:40 | 显示全部楼层
zhanghe390 发表于 2015-7-4 17:55
lz我是萌新,你的帖子很有帮助。但可不可以提供一个较为详细的CD4053的接线方式,小白不懂,谢谢。

哦对,能不能再问一下。我要用6个ADXL345该怎么弄,谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-5-3 17:19 , Processed in 0.043107 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表