7246|7

128

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

i2c的write、writeto、write_mem分别适用于什么场合? [复制链接]

  本帖最后由 9zhmke 于 2018-2-22 00:52 编辑

绕晕了,编个小程序来使用个红外定位传感器,需要先传一串初使化信息过去,老出错报OSError: [Errno 19] ENODEV,偶尔又是对的。
1、用i2c.write我都不知道它会写到哪里去,我没有先指定从机地址的时候它能找到吗?
2、用i2c.writeto则是后面那个参数不知道怎么写老报错,i2c.writeto(设备地址,chr(我的数值),False),后面那个stop=False或者stop=True,只能加成False或者True,不能加前面的“stop=”字样,即便如此,第二次用就出错,不加又不行。
3、i2cwrite_mem看上去应该是EPROM之类用的吧,普通传感器能用么?

请大师多指点下,百度了很久,反复试了两天仍然没有过这一关。附上写的源程序:

我改的程序:

  1. import time
  2. from machine import Pin,I2C
  3. i2c=I2C(-1, sda=Pin(4), scl=Pin(5), freq=100000)  #scl=1脚绿线,sda=2脚黄线
  4. buf = buf_bak = bytes(16) #准备放取出的红外定位传感器数据
  5. x=[4] #准备放x轴地址
  6. y=[4] #准备放y轴地址
  7. tmp=0 #很随意个变量

  8. i2c_init=[0x30,0x01,0x30,0x08,0x06,0x90,0x08,0xC0,0x1A,0x40,0x33,0x33] #看上去要传这一串到传感器去
  9. i2c.start()
  10. for i in range(0,12,2):
  11.     time.sleep_ms(10)
  12.     i2c.write(chr(i2c_init[i]))     #i2c.writeto(0x58,chr(i2c_init[i]),False) #i2c.scan实测地址为0x58,与厂标相同
  13.     time.sleep_ms(5)
  14.     i2c.write(chr(i2c_init[i+1]))   #官方示例Arduino程序是一对一对发送的,间隔10ms
  15. time.sleep_ms(100)

  16. def Read_Ir():
  17.     global buf,buf_bak
  18.     buf_bak=buf   #先备份之关数据
  19.     buf=bytes(16) #清空,下一句读出与之前数据相同、为空、没数据(xFF)或者出错均重新再取,直到取出与之前不相同的内容
  20.     while(buf==buf_bak or buf==bytes(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') or buf==bytes(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')):
  21.         time.sleep_ms(3)
  22.         i2c.write(chr(0x36)) #看上去0x36是取数据前置信号
  23.         try:
  24.             time.sleep_ms(5)
  25.             buf=i2c.readfrom(i2c_address[0],16,True)
  26.         except Exception as e:
  27.             print("Err")
  28.     return
  29. #==========================开始==========================
  30. #while(True):
  31. for i in range(0,10):
  32.     Read_Ir()
  33.     print(i,end=" ")
  34.     print("buf",end=":")
  35.     print (buf)
  36.     print(i,end=" ")
  37.     print ("Bak",end=":")
  38.     print (buf_bak)

复制代码



再附上厂家原版的Arduino程序:

  1. // Wii Remote IR sensor  test sample code  by kako [url=http://www.kako.com]http://www.kako.com[/url]
  2. // modified output for Wii-BlobTrack program by RobotFreak [url=http://www.letsmakerobots.com/user/1433]http://www.letsmakerobots.com/user/1433[/url]
  3. // modified for [url=http://DFRobot.com]http://DFRobot.com[/url] by Lumi, Jan. 2014
  4. // 对位置的调整可参考英文版:[url=http://wiibrew.org/wiki/Wiimote/Pointing]http://wiibrew.org/wiki/Wiimote/Pointing[/url]
  5. // 维客:[url=http://wiibrew.org/wiki/Wiimote#IR_Camera]http://wiibrew.org/wiki/Wiimote#IR_Camera[/url]

  6. #include <Wire.h>

  7. int IRsensorAddress = 0xB0;
  8. //int IRsensorAddress = 0x58;
  9. int slaveAddress;
  10. int ledPin = 13;
  11. boolean ledState = false;
  12. byte data_buf[16];
  13. int i;

  14. int Ix[4];
  15. int Iy[4];
  16. int s;

  17. void Write_2bytes(byte d1, byte d2)
  18. {
  19.     Wire.beginTransmission(slaveAddress);
  20.     Wire.write(d1); Wire.write(d2);
  21.     Wire.endTransmission();
  22. }

  23. void setup()
  24. {
  25.     slaveAddress = IRsensorAddress >> 1;   // This results in 0x21 as the address to pass to TWI
  26.     Serial.begin(19200);
  27.     pinMode(ledPin, OUTPUT);      // Set the LED pin as output
  28.     Wire.begin();
  29.     // IR sensor initialize
  30.     Write_2bytes(0x30,0x01); delay(10);
  31.     Write_2bytes(0x30,0x08); delay(10);
  32.     Write_2bytes(0x06,0x90); delay(10);
  33.     Write_2bytes(0x08,0xC0); delay(10);
  34.     Write_2bytes(0x1A,0x40); delay(10);
  35.     Write_2bytes(0x33,0x33); delay(10);
  36.     delay(100);
  37. }
  38. void loop()
  39. {
  40.     ledState = !ledState;
  41.     if (ledState) { digitalWrite(ledPin,HIGH); } else { digitalWrite(ledPin,LOW); }

  42.     //IR sensor read
  43.     Wire.beginTransmission(slaveAddress);
  44.     Wire.write(0x36);
  45.     Wire.endTransmission();

  46.     Wire.requestFrom(slaveAddress, 16);        // Request the 2 byte heading (MSB comes first)
  47.     for (i=0;i<16;i++) { data_buf[i]=0; }
  48.     i=0;
  49.     while(Wire.available() && i < 16) {
  50.         data_buf[i] = Wire.read();
  51.         i++;
  52.     }

  53.     Ix[0] = data_buf[1];
  54.     Iy[0] = data_buf[2];
  55.     s   = data_buf[3];
  56.     Ix[0] += (s & 0x30) <<4;
  57.     Iy[0] += (s & 0xC0) <<2;

  58.     Ix[1] = data_buf[4];
  59.     Iy[1] = data_buf[5];
  60.     s   = data_buf[6];
  61.     Ix[1] += (s & 0x30) <<4;
  62.     Iy[1] += (s & 0xC0) <<2;

  63.     Ix[2] = data_buf[7];
  64.     Iy[2] = data_buf[8];
  65.     s   = data_buf[9];
  66.     Ix[2] += (s & 0x30) <<4;
  67.     Iy[2] += (s & 0xC0) <<2;

  68.     Ix[3] = data_buf[10];
  69.     Iy[3] = data_buf[11];
  70.     s   = data_buf[12];
  71.     Ix[3] += (s & 0x30) <<4;
  72.     Iy[3] += (s & 0xC0) <<2;

  73.     for(i=0; i<4; i++)
  74.     {
  75.       if (Ix[i] < 1000)
  76.         Serial.print("");
  77.       if (Ix[i] < 100)  
  78.         Serial.print("");
  79.       if (Ix[i] < 10)  
  80.         Serial.print("");
  81.       Serial.print( int(Ix[i]) );
  82.       Serial.print(",");
  83.       if (Iy[i] < 1000)
  84.         Serial.print("");
  85.       if (Iy[i] < 100)  
  86.         Serial.print("");
  87.       if (Iy[i] < 10)  
  88.         Serial.print("");
  89.       Serial.print( int(Iy[i]) );
  90.       if (i<3)
  91.         Serial.print(",");
  92.     }
  93.     Serial.println("");
  94.     delay(15);
  95. }


复制代码

最新回复

*,代表参数的个数可变。 buf必须是bytearray类型,类似C语言的数组。 True和False也可以用1或0代替  详情 回复 发表于 2018-2-23 23:24
点赞 关注
 
 

回复
举报

1万

帖子

24

TA的资源

版主

沙发
 
I2C的几种函数其实是差不多的,只是封装成不同形式。都是往总线上发送数据,I2C.write()是最基础的方法,通常第一个字节是寄存器地址,后面是数据。

我习惯将I2C的函数再次封装成下面的函数,用于读写寄存器。如:

    # set reg
    def        setReg(self, reg, dat):
        self.i2c.writeto(BMP280_I2C_ADDR, bytearray([reg, dat]))
               
    # get reg
    def        getReg(self, reg):
        self.i2c.writeto(BMP280_I2C_ADDR, bytearray([reg]))
        t =        self.i2c.readfrom(BMP280_I2C_ADDR, 1)
        return t[0]
       
    # get two reg
    def        get2Reg(self, reg):
        self.i2c.writeto(BMP280_I2C_ADDR, bytearray([reg]))
        t =        self.i2c.readfrom(BMP280_I2C_ADDR, 2)
        return t[0] + t[1]*256


点评

我以为writeto的数据是str型的,才知道居然是bytearray型的。 再继续请教下: writeto后面的reg是什么?dat是要发送的数据吧? 听说writeto的结尾可以带个标志表达是否发送完所有数据,似乎def里没有使用? 那  详情 回复 发表于 2018-2-22 11:28
 
 
 

回复

128

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
dcexpert 发表于 2018-2-22 09:40
I2C的几种函数其实是差不多的,只是封装成不同形式。都是往总线上发送数据,I2C.write()是最基础的方法,通 ...

我以为writeto的数据是str型的,才知道居然是bytearray型的。

再继续请教下:
writeto后面的reg是什么?dat是要发送的数据吧?
听说writeto的结尾可以带个标志表达是否发送完所有数据,似乎def里没有使用?
那怎么使用后面的这个标志位呢?

点评

没有看到有这样的标志位啊。  详情 回复 发表于 2018-2-23 09:50
 
 
 

回复

1万

帖子

24

TA的资源

版主

4
 
9zhmke 发表于 2018-2-22 11:28
我以为writeto的数据是str型的,才知道居然是bytearray型的。

再继续请教下:
writeto后面的reg是什 ...

没有看到有这样的标志位啊。

点评

邵子杨老师在《MicroPython入门指南》一书133页描述特别库时,对machine中的I2C模块基本操作(134页)这么写的: (2)标准总线操作 下面方法执行了标准的I2C主设备读写功能。 I2C.readfrom(addr,nbytes,stop=Tru  详情 回复 发表于 2018-2-23 11:26
 
 
 

回复

128

帖子

0

TA的资源

一粒金砂(中级)

5
 
dcexpert 发表于 2018-2-23 09:50
没有看到有这样的标志位啊。

邵子杨老师在《MicroPython入门指南》一书133页描述特别库时,对machine中的I2C模块基本操作(134页)这么写的:
(2)标准总线操作
下面方法执行了标准的I2C主设备读写功能。
I2C.readfrom(addr,nbytes,stop=True)
从指定地址读取nbytes字节数据,返回的数据是bytes对象。如果stop是true,在最后将发送一个STOP信号。
I2C.readfrom_into(addr, buf,stop=True)
从地址addr读取数据到缓存buf,读取数据的数量等于buf的长度。如果stop是true,在最后将发送一个STOP信号。这个函数无返回值。
I2C.writeto(addr, buf, *, stop=True)
写入缓存buf的数据到地址是addr的设备。如果在写操作后收到NACK信号,剩余的数据将不会被发送。如果stop是True,在最后将产生一个STOP信号,即使收到NACK也会发送STOP信号。返回值是收到的ACK信号数量。
...
此外,您在这里也提到了关于I2C.writeto(addr, buf, *, stop=True):   https://bbs.eeworld.com.cn/thread-496449-1-1.html
这里也是有个stop=True的。

点评

I2C.writeto(addr, buf, *, stop=True) 就代表默认会自动发送STOP,如果希望不发可以将它改为False。  详情 回复 发表于 2018-2-23 21:12
 
 
 

回复

1万

帖子

24

TA的资源

版主

6
 
9zhmke 发表于 2018-2-23 11:26
邵子杨老师在《MicroPython入门指南》一书133页描述特别库时,对machine中的I2C模块基本操作(134页)这 ...

I2C.writeto(addr, buf, *, stop=True) 就代表默认会自动发送STOP,如果希望不发可以将它改为False。

点评

刚接触到MicroPython,底子差问题多,谢谢版主的指导了,但还有点细节不清楚: 第三个参数*是什么意思呢?之前资料上没写这个 第一个参数要求是数字型,后面两个参数分别要求是什么类型的呢?是必须在同一个数组里  详情 回复 发表于 2018-2-23 22:15
 
 
 

回复

128

帖子

0

TA的资源

一粒金砂(中级)

7
 
闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣捣閻棗銆掑锝呬壕濡ょ姷鍋為悧鐘汇€侀弴銏犖ч柛鈩冦仦缁剝淇婇悙顏勨偓鏍礉瑜忕划濠氬箣閻樺樊妫滈梺绉嗗嫷娈曢柣鎾存礋閺岀喖鏌囬敃鈧悘閬嶆煕閵堝拋鍎旈柡灞诲€濆鍫曞箰鎼粹€叉樊闂備礁鎼張顒傜矙閹达箑鐓″璺号堥弸搴ㄦ煙闁箑鏋ら柍璇茬箻濮婅櫣鎷犻幓鎺濆妷闂佺厧缍婄粻鏍婵炴潙鍚嬪ḿ娆愵攰闂備礁鎲″ú锕傚垂閹殿喚涓嶉柟鎯板Г閻撴洟鏌嶉埡浣告殧濞寸媴绠戦…璺ㄦ喆閸曨剛顦紓浣介哺閹瑰洤鐣烽幒鎴旀瀻闁瑰瓨绻傞‖澶嬩繆閻愵亜鈧垿宕濈仦杞挎稑鈹戠€n亝鐎梺鍛婂姦閸犳牠锝為崨瀛樼厽婵☆垵娅f禒娑欑箾閸喎鍔ら柍瑙勫灦楠炲﹪鏌涙繝鍐╃妤犵偛锕ラ幆鏃堝閻樻彃顫婇梻鍌氬€搁崐椋庣矆娓氣偓閹潡宕惰濞存牠鏌曟繛褍鎳愰悞鍏肩箾鏉堝墽绉い顐㈩樀瀹曪綀绠涘☉娆戝帾闂佸壊鍋呯换宥呂hぐ鎺撶厽闁规崘娉涢弸娑㈡煛瀹€瀣埌妞ゎ偅绮撻崺鈧い鎺嶈兌椤╂煡鎮规潪鎷岊劅闁诲骸鐖奸弻锝夊箣閿濆憛鎾绘煟閹惧瓨绀嬮柡宀嬬節瀹曟帒鈹戦崶鈹库偓濠勭磽娴e搫啸缂侇噮鍨舵俊鐢稿礋椤栨凹娼婇梺鎸庣☉鐎氼參宕抽弶璇炬棃鎮╅棃娑楃捕濡炪倖鍨甸ˇ闈涱嚕椤愶箑纾奸柣鎰綑濞堢喖姊洪棃娑辨濠碘€虫穿閵囨劙濡搁埡鍌楁嫼闁荤姴娲﹂悡锟狀敁濡ゅ懏鐓曟俊顖濆吹閻帞鈧娲橀崹鍧楃嵁濡偐纾兼俊顖滃帶楠炲牓姊绘担鍝ョШ闁稿锕畷銏$附缁嬭法顦梺闈涚墕濡稓绮绘ィ鍐╃厱妞ゆ劦鍋勬晶顖炴倵濮樼偓瀚�闂傚倸鍊搁崐鎼佸磹閹间礁纾圭€瑰嫭鍣磋ぐ鎺戠倞妞ゆ帊绀侀崜顓烆渻閵堝棗濮х紒鐘冲灴閻涱噣濮€閵堝棛鍘撻柡澶屽仦婢瑰棝宕濆鍡愪簻闁哄倸鐏濋顐ょ磼鏉堛劍宕岀€规洘甯掗~婵嬵敄閽樺澹曢梺鍛婄缚閸庢娊鎯屽▎鎾寸厱闁哄洢鍔岄悘鐘电磼閻欌偓閸ㄥ爼寮婚妸鈺傚亞闁稿本绋戦锟�闂傚倸鍊搁崐鎼佸磹閹间礁纾归柣鎴eГ閸ゅ嫰鏌涢锝嗙缂佺姷濞€閺岀喖宕滆鐢盯鏌涚€c劌鈧繈寮婚弴鐔虹闁绘劦鍓氶悵鏇㈡⒑缁嬫鍎忔い鎴濐樀瀵鏁愭径濠勭杸濡炪倖甯婇悞锕傚磿閹剧粯鈷戠紓浣姑粭鎺楁煟韫囨柨鍝哄┑锛勬暬瀹曠喖顢涘槌栧敽闂備浇顫夐幆宀勫垂闁秴鏋佸Δ锝呭暞閻撶喖骞栧ǎ顒€鐏柛鐔哥叀閺岀喖宕欓妶鍡楊伓濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌熼梻瀵割槮缁惧墽绮换娑㈠箣閺冣偓閸ゅ秹鏌涢妷顔煎⒒闁轰礁娲弻鏇$疀閺囩倫銉︺亜閿旇娅嶉柟顔筋殜瀹曟寰勬繝浣割棜闂傚倷绀侀幉鈥趁洪敃鍌氱;濠㈣埖鍔曢弰銉╂煟閹邦喖鍔嬮柍閿嬪灴閹綊骞侀幒鎴濐瀳濠电偛鎳忛崝娆撳蓟閻旂厧绀勯柕鍫濇椤忥拷

点评

*,代表参数的个数可变。 buf必须是bytearray类型,类似C语言的数组。 True和False也可以用1或0代替  详情 回复 发表于 2018-2-23 23:24
 
 
 

回复

1万

帖子

24

TA的资源

版主

8
 
闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣捣閻棗銆掑锝呬壕濡ょ姷鍋為悧鐘汇€侀弴銏犖ч柛鈩冦仦缁剝淇婇悙顏勨偓鏍礉瑜忕划濠氬箣閻樺樊妫滈梺绉嗗嫷娈曢柣鎾存礋閺岀喖鏌囬敃鈧悘閬嶆煕閵堝拋鍎旈柡灞诲€濆鍫曞箰鎼粹€叉樊闂備礁鎼張顒傜矙閹达箑鐓″璺号堥弸搴ㄦ煙闁箑鏋ら柍璇茬箻濮婅櫣鎷犻幓鎺濆妷闂佺厧缍婄粻鏍婵炴潙鍚嬪ḿ娆愵攰闂備礁鎲″ú锕傚垂閹殿喚涓嶉柟鎯板Г閻撴洟鏌嶉埡浣告殧濞寸媴绠戦…璺ㄦ喆閸曨剛顦紓浣介哺閹瑰洤鐣烽幒鎴旀瀻闁瑰瓨绻傞‖澶嬩繆閻愵亜鈧垿宕濈仦杞挎稑鈹戠€n亝鐎梺鍛婂姦閸犳牠锝為崨瀛樼厽婵☆垵娅f禒娑欑箾閸喎鍔ら柍瑙勫灦楠炲﹪鏌涙繝鍐╃妤犵偛锕ラ幆鏃堝閻樻彃顫婇梻鍌氬€搁崐椋庣矆娓氣偓閹潡宕惰濞存牠鏌曟繛褍鎳愰悞鍏肩箾鏉堝墽绉い顐㈩樀瀹曪綀绠涘☉娆戝帾闂佸壊鍋呯换宥呂hぐ鎺撶厽闁规崘娉涢弸娑㈡煛瀹€瀣埌妞ゎ偅绮撻崺鈧い鎺嶈兌椤╂煡鎮规潪鎷岊劅闁诲骸鐖奸弻锝夊箣閿濆憛鎾绘煟閹惧瓨绀嬮柡宀嬬節瀹曟帒鈹戦崶鈹库偓濠勭磽娴e搫啸缂侇噮鍨舵俊鐢稿礋椤栨凹娼婇梺鎸庣☉鐎氼參宕抽弶璇炬棃鎮╅棃娑楃捕濡炪倖鍨甸ˇ闈涱嚕椤愶箑纾奸柣鎰綑濞堢喖姊洪棃娑辨濠碘€虫穿閵囨劙濡搁埡鍌楁嫼闁荤姴娲﹂悡锟狀敁濡ゅ懏鐓曟俊顖濆吹閻帞鈧娲橀崹鍧楃嵁濡偐纾兼俊顖滃帶楠炲牓姊绘担鍝ョШ闁稿锕畷銏$附缁嬭法顦梺闈涚墕濡稓绮绘ィ鍐╃厱妞ゆ劦鍋勬晶顖炴倵濮樼偓瀚�闂傚倸鍊搁崐鎼佸磹閹间礁纾圭€瑰嫭鍣磋ぐ鎺戠倞妞ゆ帊绀侀崜顓烆渻閵堝棗濮х紒鐘冲灴閻涱噣濮€閵堝棛鍘撻柡澶屽仦婢瑰棝宕濆鍡愪簻闁哄倸鐏濋顐ょ磼鏉堛劍宕岀€规洘甯掗~婵嬵敄閽樺澹曢梺鍛婄缚閸庢娊鎯屽▎鎾寸厱闁哄洢鍔岄悘鐘电磼閻欌偓閸ㄥ爼寮婚妸鈺傚亞闁稿本绋戦锟�闂傚倸鍊搁崐鎼佸磹閹间礁纾归柣鎴eГ閸ゅ嫰鏌涢锝嗙缂佺姷濞€閺岀喖宕滆鐢盯鏌涚€c劌鈧繈寮婚弴鐔虹闁绘劦鍓氶悵鏇㈡⒑缁嬫鍎忔い鎴濐樀瀵鏁愭径濠勭杸濡炪倖甯婇悞锕傚磿閹剧粯鈷戠紓浣姑粭鎺楁煟韫囨柨鍝哄┑锛勬暬瀹曠喖顢涘槌栧敽闂備浇顫夐幆宀勫垂闁秴鏋佸Δ锝呭暞閻撶喖骞栧ǎ顒€鐏柛鐔哥叀閺岀喖宕欓妶鍡楊伓濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌熼梻瀵割槮缁惧墽绮换娑㈠箣閺冣偓閸ゅ秹鏌涢妷顔煎⒒闁轰礁娲弻鏇$疀閺囩倫銉︺亜閿旇娅嶉柟顔筋殜瀹曟寰勬繝浣割棜闂傚倷绀侀幉鈥趁洪敃鍌氱;濠㈣埖鍔曢弰銉╂煟閹邦喖鍔嬮柍閿嬪灴閹綊骞侀幒鎴濐瀳濠电偛鎳忛崝娆撳蓟閻旂厧绀勯柕鍫濇椤忥拷
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
Vicor 有奖下载 | 在48V架构中使用高密度功率转换器构建更好的机器人
活动时间:即日起-4月28日
活动奖励:螺丝刀套装、充电套装、电风扇

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 4

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表