【學習筆記】OpenMV與arduino通訊

吾本虛無發表於2018-09-03

官網的教程是這樣的:http://book.openmv.cc/MCU/serial2.html
http://book.openmv.cc/example/02-Board-Control/arduino-i2c-slave.html
連線方式:
這裡寫圖片描述
在這裡插入圖片描述

使用OpenMV IDE執行下面的程式:

# Arduino 作為I2C主裝置, OpenMV作為I2C從裝置。
#
# 請把OpenMV和Arduino按照下面連線:
#
# OpenMV Cam Master I2C Data  (P5) - Arduino Uno Data  (A4)
# OpenMV Cam Master I2C Clock (P4) - Arduino Uno Clock (A5)
# OpenMV Cam Ground                - Arduino Ground

import pyb, ustruct

text = "Hello World!\n"
data = ustruct.pack("<%ds" % len(text), text)
# 使用 "ustruct" 來生成需要傳送的資料包
# "<" 把資料以小端序放進struct中
# "%ds" 把字串放進資料流,比如:"13s" 對應的 "Hello World!\n" (13 chars).
# 詳見 https://docs.python.org/3/library/struct.html

# READ ME!!!
#
# 請理解,當您的OpenMV攝像頭不是I2C主裝置,所以不管是使用中斷回撥,
# 還是下方的輪循,都可能會錯過響應傳送資料給主機。當這種情況發生時,
# Arduino會獲得NAK,並且不得不從OpenMV再次讀資料。請注意,
# OpenMV和Arduino都不擅長解決I2C的錯誤。在OpenMV和Arduino中,
# 你可以通過釋放I2C外設,再重新初始化外設,來恢復功能。

# OpenMV上的硬體I2C匯流排都是2
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
bus.deinit() # 完全關閉裝置
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
print("Waiting for Arduino...")



# 請注意,為了正常同步工作,OpenMV Cam必須 在Arduino輪詢資料之前執行此指令碼。
# 否則,I2C位元組幀會變得亂七八糟。所以,保持Arduino在reset狀態,
# 直到OpenMV顯示“Waiting for Arduino...”。


while(True):
    try:
        bus.send(ustruct.pack("<h", len(data)), timeout=10000) # 首先傳送長度 (16-bits).
        try:
            bus.send(data, timeout=10000) # 然後傳送資料
            print("Sent Data!") # 沒有遇到錯誤時,會顯示
        except OSError as err:
            pass # 不用擔心遇到錯誤,會跳過
            # 請注意,有3個可能的錯誤。 超時錯誤(timeout error),
            # 通用錯誤(general purpose error)或繁忙錯誤
            #(busy error)。 “err.arg[0]”的錯誤程式碼分別
            # 為116,5,16。
    except OSError as err:
        pass # 不用擔心遇到錯誤,會跳過
        # 請注意,有3個可能的錯誤。 超時錯誤(timeout error),
        # 通用錯誤(general purpose error)或繁忙錯誤
        #(busy error)。 “err.arg[0]”的錯誤程式碼分別
        # 為116,5,16。

用Arduino執行以下程式:

// Arduino Code

include <Wire.h>
#define BAUD_RATE 19200
#define CHAR_BUF 128

void setup() {
  Serial.begin(BAUD_RATE);
  Wire.begin();
  delay(1000); // 給OpenMV一個啟動的時間
}

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.
}

插播一波,如果感興趣的童鞋們可以加入技術交流群~
在這裡插入圖片描述

相關文章