Python中的SMBus / I2C在请求读取时保持触发接收回调

时间:2015-01-22 10:29:31

标签: python arduino i2c

我试图通过从我的PC发送读取请求从Arduino微控制器读取一些值,但是不是触发请求回调而是触发接收,这根本没有意义?我正在运行I2C,因此SMBus似乎要慢得多。

Arduino代码:

void dataReceive() {
    Serial.println("Receive");
}


void dataRequest() {
    Serial.println("Request");
    Wire.write(1);
}

void setup()
{
    Wire.begin(4);
    Wire.onReceive(dataReceive);
    Wire.onRequest(dataRequest);
}

PC代码:

import smbus
bus = smbus.SMBus(1)

data = bus.read_i2c_block_data(0x04, 0x09, 1)
print data

我也得到以下错误:

Traceback (most recent call last):
  File "./i2ctest.py", line 16, in <module>
    data = bus.read_i2c_block_data(0x04, 0x09, 1)
IOError: [Errno 11] Resource temporarily unavailable

虽然我能够在Arduino串口监视器中看到dataReceive回调被触发。

1 个答案:

答案 0 :(得分:1)

Arduino在Wire.h库中没有重复的启动信号。您的解决方案是这样的:

在Arduino方面:

void dataReceive() {
    x = 0;
    for (int i = 0; i < byteCount; i++) {
        if (i==0) {
            x = Wire.read();
            cmd = ""
        } else {
            char c = Wire.read();
            cmd = cmd + c;
        }
    }
    if (x == 0x09) {
        // Do something arduinoish here with cmd if you need no answer
        // or result from Arduino
        x = 0;
        cmd = ""
    }
}

这会将收到的第一个字符存储为&#34;命令&#34;然后其余的将成为争论的一部分。在你的情况下,命令是0x09,参数是1。

在PC端,python命令是这样的:

bus.write_i2c_block_data(0x05,0x09,buff)

buff是&#34; 1&#34;。

您可能需要datarequest事件:

void dataRequest() {
    x = 0;
    Wire.write(0xFF);
}

这将发回一个简单的FF。

如果你需要从arduino回答,那么在这里处理cmd参数。在这种情况下,在python方面你需要更多:

bus.write_i2c_block_data(0x05,0x09,buff)
tl = bus.read_byte(0x05)

这发送&#34; 1&#34;进入命令&#34; 0x09&#34;设备&#34; 0x05&#34;。然后,您将使用读取命令从设备&#34; 0x05&#34;获取答案。