zoukankan      html  css  js  c++  java
  • openmv4arduino_spi_slave 从设备

    # Arduino 作为SPI主设备, OpenMV作为SPI从设备。
    
    # 请把OpenMV和Arduino Uno按照下面连线:
    # OpenMV Cam Master Out Slave In (P0) - Arduino Uno MOSI (11)
    # OpenMV Cam Master In Slave Out (P1) - Arduino Uno MISO (12)
    # OpenMV Cam Serial Clock        (P2) - Arduino Uno SCK  (13)
    # OpenMV Cam Slave Select        (P3) - Arduino Uno SS   (10)
    # OpenMV Cam Ground                   - Arduino Ground

    # 请把OpenMV和Arduino 2560按照下面连线:
    # OpenMV Cam Master Out Slave In (P0) - Arduino Uno MOSI (51)
    # OpenMV Cam Master In Slave Out (P1) - Arduino Uno MISO (50)
    # OpenMV Cam Serial Clock        (P2) - Arduino Uno SCK  (52)
    # OpenMV Cam Slave Select        (P3) - Arduino Uno SS   (53)
    # OpenMV Cam Ground                   - Arduino Ground


    openmv4IDE代码:
    import pyb, ustruct, time
    
    text = "Hello World!
    "
    data = ustruct.pack("<bi%ds" % len(text), 85, len(text), text) # 85 is a sync char.
    
    # 使用 "ustruct" 来生成需要发送的数据包
    # "<" 把数据以小端序放进struct中
    # "b" 把一个 signed char 放进数据流
    # "i" 把一个 signed integer 放进数据流
    # "%ds" 把字符串放进数据流,比如:"13s" 对应的 "Hello World!
    " (13 chars).
    # 详见 https://docs.python.org/3/library/struct.html
    
    
    # 零填充数据为4字节加4字节的倍数。
    data += "x00" * (4 + (len(data) % 4))
    
    # READ ME!!!
    #
    # 请理解,当您的OpenMV摄像头不是SPI主设备,所以不管是使用中断回调,
    # 还是下方的轮循,都可能会错过响应发送数据给主机。处于这点,
    # 你必须设计你的通信协议,比如从设备(OpenMV)没有及时调用"spi.send()"回应,
    # 那么SPI读取到的垃圾数据应该被丢弃。为了达到这个目的,我们使用一个85
    # (二进制01010101)的同步字符,Arduino将把它看作是第一个读取的字节。
    # 如果它没有看到这个,那么它会中止SPI事务,然后再试一次。 其次,
    # 为了清除SPI外设状态,我们总是发送四个字节的倍数和一个额外的四个零字节,
    # 以确保SPI外设不会保存可能为85的任何陈旧数据。注意,OpenMV可能会随机
    # 错过调用 "spi.send()",因为中断服务程序。当你连接到电脑的时候,中断
    # 可能会发生很多次。
    
    # OpenMV上的硬件SPI总线都是2
    # polarity = 0 -> clock 闲时为低
    # phase = 0 -> 取样数据在clock上升沿,输出数据在下降沿。
    spi = pyb.SPI(2, pyb.SPI.SLAVE, polarity=0, phase=0)
    
    # NSS callback.
    def nss_callback(line):
        global spi, data
        try:
            spi.send(data, timeout=1000)
            # 如果同步第一帧失败,我们再一次同步
            print("Sent Data!") # 没有遇到错误时,会显示
        except OSError as err:
            pass # 不用担心遇到错误,会跳过
            # 请注意,有3个可能的错误。 超时错误(timeout error),
            # 通用错误(general purpose error)或繁忙错误
            #(busy error)。 “err.arg[0]”的错误代码分别
            # 为116,5,16。
    
    # 在IRQ模式中配置NSS/CS,以便在主机请求时发送数据
    pyb.ExtInt(pyb.Pin("P3"), pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, nss_callback)
    
    while(True):
        time.sleep(1)

    arduino代码:

    #include <SPI.h>
    #define SS_PIN 53           //10引脚得改为53管脚
    #define BAUD_RATE 19200
    #define CHAR_BUF 128
    
    int temp;
    
    void setup() {
      pinMode(SS_PIN, OUTPUT);
      Serial.begin(BAUD_RATE);
      SPI.begin();
      SPI.setBitOrder(MSBFIRST);
      SPI.setClockDivider(SPI_CLOCK_DIV16);
      SPI.setDataMode(SPI_MODE0);
      delay(1000); // 给OpenMV摄像头启动的时间
    }
    
    void loop(){
      int32_t len = 0;
      char buff[CHAR_BUF] = {0};
      digitalWrite(SS_PIN, LOW);
      delay(1); // 给OpenMV摄像头一些时间来设置发送数据
    
      if (SPI.transfer(1) == 85) { // saw sync char?
        SPI.transfer(&len, 4); // get length
        if (len) {
          SPI.transfer(&buff, min(len, CHAR_BUF));
          temp -= min(len, CHAR_BUF);
        }
        while (len--) SPI.transfer(0); // eat any remaining bytes
      }
    
      digitalWrite(SS_PIN, HIGH);
      Serial.print(buff);
      delay(1); // 延时一点时间,不要马上循环
    }

    openmv4运行效果:


    arduuno运行效果:


     
    本文章实现了主从设备的发送与接受数据!







    正是步行者,一步步登峰!



     

  • 相关阅读:
    【反射】Java反射机制
    Composer教程之常用命令
    Composer教程之基础用法
    Composer教程之初识Composer
    Composer 的结构详解
    现代 PHP 新特性系列(七) —— 内置的 HTTP 服务器
    现代 PHP 新特性系列(一) —— 命名空间
    现代 PHP 新特性系列(二) —— 善用接口
    现代 PHP 新特性系列(三) —— Trait 概览
    现代 PHP 新特性系列(四) —— 生成器的创建和使用
  • 原文地址:https://www.cnblogs.com/ouyangmail/p/14283020.html
Copyright © 2011-2022 走看看