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运行效果:


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







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



     

  • 相关阅读:
    sql常用函数
    sql数据库查询
    数据库增删改查
    数据库基本概念
    C#总结
    C#结构体
    C#常用函数类
    初识函数
    C#冒泡排序 折半查找
    12月27日笔记
  • 原文地址:https://www.cnblogs.com/ouyangmail/p/14283020.html
Copyright © 2011-2022 走看看