zoukankan      html  css  js  c++  java
  • Arduino-蓝牙小车


    语言

    编程语言 脚本语言 标记语言 图形化编程语言
    机器语言 Arduino IDE(IDE集成开发环境)
    汇编语言
    高级语言C/C++
    应用语言


    开发板基础

    名词
    IC 集成电路
    MCU 微控制单元/单片机
    PLC可编程逻辑控制器
    常见单片机开发板
    51单片机
    STM32
    Arduino
    树莓派(自带操作系统)
    ESP8266/ESP32(带wifi)
    micropython开发板

    开发板简介

    开发板布局分析Fritzing
    Digital数字信号(13个数字接口)、analog模拟信号(6个模拟接口)
    PWM输出连续变化的信号:3、5、6、9、10、11接口(~)
    电平(电压):数字——低0V,高5V; 模拟——0~5V

    语法简介
    setup:初始化
    loop:循环
    serial库
    Serial.begin(speed); 用于设置串口波特率。

    Serial.print(); 函数用于将数据写入到串口中。

    Serial.println(); 函数用于将数据(包括' ')写入到串口中。

    Serial.available(); 返回串口接收到的数据量,一般用于判断串口缓冲区是否有数据输入。

    Serial.read(); 用于将数据写入到串口中(读取串口缓存中的一个字节并清除)。

    wire库(需要再稍微了解I2C)

    Wire.begin();
    begin 函数用于初始化 Wrie Library 并以 Master 或 Slave 的身份加入 I2C 总线上。begin 函数没有返回值。调用 begin 函数有两种形式:
    begin():无输入参数,表示以 Master 形式加入总线。
    begin(address):有输入参数,表示以从机形式加入总线,设备地址为address(7-bit)。

    Wire.beginTransmission();
    beginTransmission 函数用于启动一次 Master write to Slave 操作。值得注意的是这个函数的调用并不会产生 Start 信号 和发送 Slave Address,仅是实现通知 Arduino后要启动 Master write to Slave 操作。
    beginTransmission 函数调用后,(再调用 write 函数进行数据写入), 最后再调用 endTransmission 函数方能产生 Start 信号 和发送 Slave Address 及通讯时序。
    beginTransmission 函数调用形式:
    beginTransmission(address)

    Wire.endTransmission();
    endTransmission 函数用于结束一次 Master write to Slave 操作。前面在介绍 beginTransmission 的时候也介绍过了,如果不在后面使用 endTransmission 函数, 总线上会产生 Master write to Slave 的时序。
    endTransmission(0):当输入参数为 0 时,将在通讯结束后,不产生 STOP 信号。
    endTransmission(!0):当输入参数为 !0 时,在通讯结束后,生成 STOP 信号。(释放总线)
    endTransmission():当无输入参数时,在通讯结束后,产生 STOP 信号。(释放总线)
    同时,endTransmission 函数时具有返回值的:
    0:success
    1:data too long to fit in transmit buffer
    2:received NACK on transmit of address
    3:received NACK on transmit of data
    4:other error
    有个地方需要注意的:当通讯过程中,出现异常后,异常后的 write 操作将被终止,直接结束通讯,具体的是否出现异常,只需要看 endTransmission 的返回值即可。

    Wire.write();
    write 函数用于向 Slave 写入数据。共有 3 种调用形式:
    write(value) :写入单字节
    write(string) :写入字符串
    write(data, length) :写入 length 个字节

    Wire.requrstFrom();
    requestFrom 函数用于实现 Master Read From Slave 操作。调用形式有 2 种:
    requestFrom(address, quantity):从 address 设备读取 quantity 个字节,结束后,产生 STOP 信号
    requestFrom(address, quantity, stop) :从 address 设备读取 quantity 个字节,结束后,依据 stop 的值确定是否产生 STOP 信号。
    stop = 0:不产生 STOP 信号
    stop != 0:产生 STOP 信号
    requestFrom 函数具有返回值(表示从 address 设备读取到的字节数)。

    Wire.available();
    用于统计 Master Read From Slave 操作后, read 缓存区剩余的字节数。每当缓存区的数据被读走 1 个字节,available 函数的返回值减一。通常 available 函数会搭配着 read 函数使用。

    Wire.read();
    用于在 Master Read From Slave 操作后,读取缓存区的数据。

    I2C

    I2C 是一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。简单说就是 只需要4根线(电源正、GND、SDA线和SCL线)就可以让单片机和单片机或其他设备(多达100多个设备)通讯,也就是说100多个设备互相通讯只用4根线就可以了,所以说他是串行总线。
    具体来说,SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路为开漏输出。需通过上拉电阻接电源VCC。当总线空闲时,两根线都是高电平,连接总线的外同器件都是CMOS器件,输出级也是开漏电路,在总线上消耗的电流很小,因此总线上扩展的器件数量主要由电容负载来决定,因为每个器件的总线接口都有一定的等效电容,而线路中电容会影响总线传输速度。当电容过大时,有可能造成传输错误。所以,其负载能力为400pF,因此可以估算出总线允许长度和所接器件数量。
    主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件。然后主机接收从器件发送的数据最后由主机终止接收过程。在这种情况下主机负责产生定时时钟和终止数据传送。

    arduino 的iic库

    arduino 的iic库是Wire
    该库使您可以与I2C / TWI设备进行通信。

    APP

    SPP/蓝牙串口助手/自己做一个APP

    串口通讯

    Arduino 与蓝牙模块主要有以下的引脚需要连接:
    VCC : 接3.3v电源(或5v)
    GND :接地
    RX : 与 Arduino TX 引脚连接
    TX : 与 Arduino RX 引脚连接

    程序

    int p1 = 3;
    int p2 = 5;
    int p3 = 6;
    int p4 = 9;
    
    void pin_init(){
      pinMode(p1, OUTPUT); 
      pinMode(p2, OUTPUT);
      pinMode(p3, OUTPUT);
      pinMode(p4, OUTPUT);
    }
    void car_go(){
      digitalWrite(p1,HIGH);
      digitalWrite(p2,LOW);
      digitalWrite(p3,HIGH);
      digitalWrite(p4,LOW);
    }
    void car_back(){
      digitalWrite(p1,LOW);
      digitalWrite(p2,HIGH);
      digitalWrite(p3,LOW);
      digitalWrite(p4,HIGH);
    }
    void car_left(){
      digitalWrite(p1,LOW);
      digitalWrite(p2,HIGH);
      digitalWrite(p3,HIGH);
      digitalWrite(p4,LOW);
    }
    void car_right(){
      digitalWrite(p1,HIGH);
      digitalWrite(p2,LOW);
      digitalWrite(p3,LOW);
      digitalWrite(p4,HIGH);
    }
    void car_stop(){
      digitalWrite(p1,LOW);
      digitalWrite(p2,LOW);
      digitalWrite(p3,LOW);
      digitalWrite(p4,LOW);
    }
    void setup(){
      Serial.begin(9600);
      pin_init();
    }
    void loop() {
      if(Serial.available()>0){
        char value = Serial.read();//读取蓝牙模块发送到串口的数据
        switch(value){
          case 'f':
            car_go();
            break;
          case 'b':
            car_back();
            break;
           case 'l':
            car_left();
            break;
           case 'r':
            car_right();
            break;
           case 's':
            car_stop();
            break;
        }
      }
    }
    

    问题

    ​Serial.begin()中的波特率大小根据什么来填写?
    wire库用来干什么的,百度一下没看明白。

  • 相关阅读:
    航班查询http://www.variflight.com/
    打印串口日志
    驱动天使 360驱动大师好用2020
    mysqldMY-010457] [Server] --initialize specified but the data directory has files in it. Aborting. 2020-12
    拖拽刻录
    traceroute排查网络故障 www.qq.com排查网络故障网络不通 先ping自己
    tigervnc报错
    java axis调用带有soap头(soapheader)的.net webservice
    java 调用WebService【转】
    List<String>转换为实体类的属性【转】
  • 原文地址:https://www.cnblogs.com/hanser/p/12952607.html
Copyright © 2011-2022 走看看