Example: 07-Interface-Library/00-Arduino/arduino_i2c_slave.py

# 本作品采用MIT许可证授权。
# 版权所有 (c) 2013-2023 OpenMV LLC。保留所有权利。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# 以Arduino为主设备,OpenMV Cam为从设备的I2C通信。
#
# 请按如下方式将您的OpenMV Cam连接到Arduino:
#
# OpenMV Cam主I2C数据线(P5) - Arduino Uno数据线(A4)
# OpenMV Cam主I2C时钟线(P4) - Arduino Uno时钟线(A5)
# OpenMV Cam地线                - Arduino地线

import pyb
import struct

text = "Hello World!\n"
data = struct.pack("<%ds" % len(text), text)
# 使用“struct”构建要发送的数据包。
# “<”将结构中的数据按小端序排列。
# “%ds”在数据流中放入一个字符串。例如,“13s”对应“Hello World!\n”(13个字符)。
# 参见 https://docs.python.org/3/library/struct.html

# 请阅读!!!
#
# 请注意,当您的OpenMV Cam不是I2C主设备时,它可能会错过响应
# 作为I2C从设备发送数据,无论您是在中断回调中还是在下方的
# 主循环中调用“i2c.send()”。当这种情况发生时,Arduino将收到NAK并需要尝试再次从
# OpenMV Cam读取数据。请注意,Arduino和OpenMV Cam的I2C驱动在遇到任何I2C错误后
# 都不擅长恢复。在OpenMV Cam和Arduino上,您可以通过以下方式恢复:
# 解除初始化并重新初始化I2C外设。

# 您的OpenMV Cam硬件I2C总线始终为I2C总线2。
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
bus.deinit()  # 完全重置I2C设备中...
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
print("Waiting for Arduino...")

# 请注意,为确保同步功能正常运作,OpenMV Cam必须在此脚本运行后,
# Arduino才开始轮询OpenMV Cam获取数据。否则I2C字节帧会混乱,
# 等等。因此,在OpenMV Cam显示“等待Arduino...”之前,请保持Arduino处于复位状态。

while True:
    try:
        bus.send(
            struct.pack("<h", len(data)), timeout=10000
        )  # 先发送长度(16位)。
        try:
            bus.send(data, timeout=10000)  # 随后发送数据。
            print("Sent Data!")  # 仅在无错误时到达此步骤。
        except OSError as err:
            pass  # 不要在意错误 - 所以跳过。
            # 请注意,有3种可能的错误。超时错误、通用错误或
            # 忙碌错误。错误代码分别为116、5、16,对应"err.arg[0]"。
    except OSError as err:
        pass  # 不要在意错误 - 所以跳过。
        # 请注意,有3种可能的错误。超时错误、通用错误或
        # 忙碌错误。错误代码分别为116、5、16,对应"err.arg[0]"。

###################################################################################################
# Arduino代码
###################################################################################################
#
# #include <Wire.h>
# #define BAUD_RATE 19200
# #define CHAR_BUF 128
#
# void setup() {
#   Serial.begin(BAUD_RATE);
#   Wire.begin();
#   delay(1000); // Give the OpenMV Cam time to bootup.
# }
#
# void loop() {
#   int32_t temp = 0;
#   char buff[CHAR_BUF] = {0};
#
#   Wire.requestFrom(0x12, 2);
#   if(Wire.available() == 2) { // got length?
#
#     temp = Wire.read() | (Wire.read() << 8);
#     delay(1); // Give some setup time...
#
#     Wire.requestFrom(0x12, temp);
#     if(Wire.available() == temp) { // got full message?
#
#       temp = 0;
#       while(Wire.available()) buff[temp++] = Wire.read();
#
#     } else {
#       while(Wire.available()) Wire.read(); // Toss garbage bytes.
#     }
#   } else {
#     while(Wire.available()) Wire.read(); // Toss garbage bytes.
#   }
#
#   Serial.print(buff);
#   delay(1); // Don't loop to quickly.
# }

results matching ""

    No results matching ""