极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12575|回复: 6

总线传输数据出了问题

[复制链接]
发表于 2014-3-4 01:26:00 | 显示全部楼层 |阅读模式
本帖最后由 shihaipeng04 于 2014-3-5 10:45 编辑

我还是不绕弯了, 就是i2c怎么读int型的数据?




I2C是个好玩的东西,可以让多个arduino之间通讯,让一个主机控制很多个从机协同工作,比如控制100个LED各种亮虽然有脱裤子放屁的嫌疑。。。

今天试验了一下,1个uno板子GND,SDA(A4),SCL(A5) 3线连到一个Mirco板子的 GND,SDA(2),SCL(3)。
此图找了很久才知道 mirco的sda是哪条腿。

连好后,让uno做主机,mirco做从机,主机发指令让从机返回一个随机数,然后主机按返回的数值控制led亮度。 程序很顺利。

主机程序
  1. #include <Wire.h> //声明I2C库文件
  2. void setup()
  3. {
  4.   Serial.begin(9600);
  5.   Wire.begin(); // 加入 i2c 总线,作为主机
  6. }

  7. void loop()
  8. {

  9.   Wire.requestFrom(0x97, 1);    //通知从机上传1个字节
  10.   while(Wire.available()>0)    // 当主机接收到从机数据时
  11.   {
  12.     byte c = Wire.read(); //接收一个字节赋值给c
  13.     analogWrite(9,c); //pin9有个led灯
  14.      Serial.println(c);
  15.   }
  16.   delay(1000);//延时1s
  17. }
复制代码


从机程序
  1. #include <Wire.h>

  2. void setup()
  3. {
  4.   Wire.begin(0x97);                // 加入 i2c 总线,设置从机地址为 #0x97
  5.   Wire.onReceive(receiveEvent); //注册接收到主机字符的事件
  6.   Wire.onRequest(requestEvent); // 注册主机通知从机上传数据的事件
  7.   Serial.begin(9600);           //设置串口波特率
  8. }

  9. void loop()
  10. {
  11. }

  12. void receiveEvent(int howMany)
  13. {
  14.   //接收函数无内容
  15. }


  16. //当主机通知从机上传数据,执行该事件
  17. void requestEvent()
  18. {
  19.   //产生一随机数上传给主机
  20.   byte q = random(255);
  21.   Wire.write(q); //将q返回主机
  22.   Serial.println(q); //监视检测用
  23. }
复制代码



上面2段代码运行的很顺利,后来想研究一下更复杂数据的传输,比如int或long型的数据,改动如下

从机requestEvent函数代码
  1. void requestEvent()
  2. {
  3.   //产生一随机数上传给主机
  4.   int q = random(32768);
  5.   Wire.write(q); // <<---直接返回int型数据,后来又试验过,分2次write2个byte数据
  6.   Serial.println(q); //监视检测用
  7. }
复制代码


主机代码改动也不大
  1. void loop()
  2. {

  3.   Wire.requestFrom(0x97, 2);    //《--- 此处有改动,一次读取2个字节,long型就读取4个字节
  4.   while(Wire.available()>0)    //  <---读取字节超过1个就会循环执行,直到全部读取完毕
  5.   {
  6.     byte c = Wire.read(); //接收int型数据的一半
  7.     Serial.println(c,HEX); //分2部分读取一个int,并将结果直接打印
  8.   }
  9.   delay(1000);//延时1s
  10. }
复制代码

主机只是分2次读取那个int的上下2部分,并直接打印到串口。但是结果不正确。 如果从机显示 0x"1234",而主机的结果是34 FF,只能读取后半截。后来又试验过,修改从机,不发送int数,而是连续write2次发送byte型数据,也是同样的结果。不知道是从机发送的不对?还是主机的读取方式不正确? 而long型数据也是失败告终。

最后测字符串到是很成功,只要字符串长度确认,就没有任何问题。请高人指点一下。后来代码是哪的错误?

本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 2014-3-4 08:46:50 | 显示全部楼层
目的在于测试IIC通讯 和“脱裤子放屁”没半毛钱关系

可以尝试通讯其他IIC设备 比如运动轨迹传感器等其他传感器
还有就是IIC作为一个多设备总线 还是有很大的优势的  对于并非需要大数据量但设备较多的状况很有价值。 试想即便是2560的所有其他口加起来也就那么点,但是一个IIC能通讯127个设备(某些设备的IIC地址只能2选1  所以最多只能2个 但是不会影响其他设备的)。还是很强悍的。
回复 支持 反对

使用道具 举报

发表于 2014-3-4 18:34:55 | 显示全部楼层
如果要单纯的控制IO或者RGB彩色LED的话,都有专门的IIC总线IO模块或者PWM模块的,没必要摆一堆Arduino的。可以搜搜“ IIC IO扩展” 或者 “IIC LED模块”

“脱裤子放屁” 然后走人,呵呵。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-4 23:40:42 | 显示全部楼层
幻生幻灭 发表于 2014-3-4 18:34
如果要单纯的控制IO或者RGB彩色LED的话,都有专门的IIC总线IO模块或者PWM模块的,没必要摆一堆Arduino的。可 ...

服了~~ 我回传的数据总得有个去处吧。弄个led直观点而已,我是研究i2c咋用。不是led好吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-5 10:45:18 来自手机 | 显示全部楼层
darkorigin 发表于 2014-3-4 08:46
目的在于测试IIC通讯 和“脱裤子放屁”没半毛钱关系

可以尝试通讯其他IIC设备 比如运动轨迹传感器等其他 ...

哪个啥,我主要是想问问I2c传输int型数咋搞?
回复 支持 反对

使用道具 举报

发表于 2014-3-5 11:11:06 | 显示全部楼层
shihaipeng04 发表于 2014-3-5 10:45
哪个啥,我主要是想问问I2c传输int型数咋搞?

传输出来的默认就是数值啊
字符是按照ASCII传输的
整型也是数值类型的一个子集嘛  

IIC传输建议你看看精华区的几个帖子
1是2个ARDUINO用IIC进行通讯的例子
2是IIC地址扫描程序
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-5 11:41:43 | 显示全部楼层
本帖最后由 shihaipeng04 于 2014-3-5 11:46 编辑
darkorigin 发表于 2014-3-5 11:11
传输出来的默认就是数值啊
字符是按照ASCII传输的
整型也是数值类型的一个子集嘛  


主机只是分2次读取那个int的上下2部分,并直接打印到串口。但是结果不正确。 如果从机显示 0x"1234",而主机的结果是34 FF,只能读取后半截。后来又试验过,修改从机,不发送int数,而是连续write2次发送byte型数据,也是同样的结果。不知道是从机发送的不对?还是主机的读取方式不正确?


地址扫描的那个我看到了,前天还发了个新的程序呢,1.5可以运行的,原来帖子里的程序1.5已经不能编译了,需要修改。

你说的通讯的那个例子,我似乎没找到。
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-5 13:49 , Processed in 0.042088 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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