QQ登录

只需一步,快速开始

热门帖子
  • 出租,哈大院内三居室整租

    出租,哈大院内三居室整租

    0 人关注

  • 哈大西门仁泰家园精装三居室电梯楼

    哈大西门仁泰家园精装三居室电梯楼

    209 人关注

  • 西门外二十米精装一室出租

    西门外二十米精装一室出租

    686 人关注

热心居民
    查看: 68699|回复: 18

    关于大一年度项目的一点帮助。。

    [复制链接]
    发表于 2019-3-10 16:50:26 | 显示全部楼层 |阅读模式
    Arduino单片机+L293D电机驱动板+HC-SR04超声波模块/3-6路光电对管/红外遥控模块 小车新手指南。。
    本人也是大一萌新。。开学之前花了一个寒假的时间去搞这个,总算明白了一点,希望对同学们(大佬除外)有帮助
    关于Arduino的介绍我就不说了。。可以自行上网了解。
    1、电脑端程序
    Arduino IDE,免费软件,win10应用商店或Arduino官网即可下载。这个软件操作界面非常简洁,左上角是常规操作区,右上角有个放大镜标志是串口监测器,这个的功能之后会说。
    用IDE编程也很简单,除了自定义函数之外只有两个函数void setup()和void loop(),第一个里面的东西只在单片机开始运行后执行一次,第二个会在setup执行完后循环执行,如果不需要使用额外的库的话没有头文件。
    2、L293D电机驱动板
    这块板子是和其它扩展板一样,是整个插在Arduino主板上使用的,可以驱动最多4个直流电机或两个步进电机。
    驱动板插在Arduino主板上能够得到主板的电力供应,但这点电流是根本无法带动电机的。所以必须外接电源。外接电源接在图中黄圈位置,特别注意正负极接反了要烧板子的  接外接电源时要把旁边的黄色跳帽拿掉。
    主板上的引脚被它全部占住,但并不是都被其使用
    首先,所有的六个模拟输入引脚都是可用的(引脚14到19),数字引脚2和13可用。
        下面的引脚只有在下面提到的直流或者步进电机工作时才会被用到
           数字引脚11: 1号直流电机或者1号步进电机
           数字引脚3: 2号直流电机或者1号步进电机
           数字引脚5: 3号直流电机或者2号步进电机
           数字引脚6:4号直流电机或者2号步进电机
        下面的引脚只有在下面的直流或者步进电机工作时才会被用到
           数字信号4,7,8,和12通过74hc595(serial-to-parallel)来驱动直流或者步进电机
        下面的引脚只有在舵机工作时才会被用到
           数字信号9:1号舵机
           数字信号10: 2号舵机
    所以只要相应的引脚没被L293D驱动板使用到,也是可以拿来用的但前提是得自己焊出引脚来。
    电机就接在左右两边画红圈的位置,板子上两两为一组分成了M1,M2,M3,M4,其中中间的为GND接线处一般不使用。可以接四个直流电机或两个步进电机。






    评分

    参与人数 2金币 +20 收起 理由
    Mini敏 + 10 赞一个!
    桃乐丝 + 10 不错,值得鼓励~

    查看全部评分

     楼主| 发表于 2019-3-10 16:52:13 | 显示全部楼层



    回复 来自苹果客户端来自苹果客户端

    使用道具 举报

     楼主| 发表于 2019-3-10 17:12:54 | 显示全部楼层
    3、HC-SR04超声波模块
    工作原理:除了5V和GND引脚外HC-SR04还有trig引脚和echo引脚,当trig引脚检测到高电平时会发出一个15us的方波,这个方波在被反射回来后echo引脚会接收这个方波并输出高电平,只要计算发出和接收之间的时间就可以根据声速计算出距离。有效距离2cm~5m,工作角度15度,工作时要尽量避免噪音。
    4、光电对管
    工作原理:探测头有一个红外线发出头和一个红外线接收头(不用担心互相干扰问题,这个本人一开始也担心过,后来发现完全没问题,不用套黑纸),当检测到黑线时,指示灯熄灭,引脚输出高电平(有些光电对管输出低电平,看具体类型),未检测到时,指示灯常亮,输出低电平。
    5、红外遥控模块
    需要红外遥控库文件(这里用IRremote库)
    遥控器随便,能发出红外信号就行(之后会按遥控器调整程序)
    工作原理就是将接收到的红外信号发送给单片机,由单片机进行解码。
    回复

    使用道具 举报

     楼主| 发表于 2019-3-10 17:13:55 | 显示全部楼层


    回复 来自苹果客户端来自苹果客户端

    使用道具 举报

     楼主| 发表于 2019-3-10 18:49:56 | 显示全部楼层
    已经上传了所需两个库文件,IRremote和AFMotor,直接放入文档/Arduino/libraries就可以了,注意不要两个一起用!!!这两个库有timer2定时器冲突!之后会介绍如何改掉的,但是最好别一起用,因为本人改完发现好像还有些问题
    6、电机驱动这里需要AFMotor库
    1.确认你导入#include <AFMotor.h>
    2.建立AF_DCMotor(motor#,frequency)函数,其中第一参数motor#示意你的电机连到了1,2,3或者4中的哪个端口;frequency则代表了信号控制的频率。如果连接电机1和2,可以选择MOTOR12_64KHZ,MOTOR12_8KHZ,MOTOR12_2KHZ,或者MOTOR12_1KHZ。像64KHZ这么高的频率不会发出噪声,但是低频率会有效降低电源。电机3和4只能以1KHZ运行,并且会忽略任何给定的设置。
    3.使用setSpeed(speed)函数来设置电机的速度,speed参数的范围从0(停止)到255(全速)。可以在这个范围内任意设定。
    4.想让电机转动,需要调用run(direction),其中direction参数可以是FORWARD(向前),BACKWARD(向后),RELEASE(停止)。当然Arduino并不知道哪个方向是正向,哪个是反向,所以如果运转的方向与你设定的相反,你只需要将电机接在驱动板上的两个线反向连接,或者将程序改成反向。
    示例程序如图1

    以上可以实现对一个电机的控制,对于多个电机,使用如图2方法(两个电机控制,小黄车的话可以直接同侧两个电机接一个电机口)

    以上用到了这个函数
    AF_DCMotor motorname(portnum,freq)
    这是一个建立一个直流电机的函数。在程序中需要声明每个电机各一次。像下面的例子中一样,每个电机必须使用不同的名字。
    参数:
    port num - 选择你的电机连接到电机驱动板上的接口(1-4)
    freq - 选择PWM频率。如果你没有选择这个选项,默认设置为1KHZ。
    适用于通道1和2的频率:
    MOTOR12_64KHZ
    MOTOR12_8KHZ
    MOTOR12_2KHZ
    MOTOR12_1KHZ
    适用于通道3和4的频率:
    MOTOR34_64KHZ
    MOTOR34_8KHZ
    MOTOR34_1KHZ
    注意:更高的频率会减小电机在运动过程中的噪音,但同时也会降低扭矩。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?加入观海听涛

    x
    回复

    使用道具 举报

     楼主| 发表于 2019-3-10 18:50:38 | 显示全部楼层
    图1,2


    回复 来自苹果客户端来自苹果客户端

    使用道具 举报

     楼主| 发表于 2019-3-11 22:01:48 | 显示全部楼层
    7、HC-SR04超声波模块测距
    这里只给出测距方法,至于避障功能相信大家可以以测距为基础做出来。
    首先除了5V和GND引脚连接到指定位置外,还需要定义两个接口来连接trig和echo引脚

    const(不可更改数值类型)int trig=8
    8号引脚
    const int echo =9
    9号引脚
    然后在setup函数中设置8号引脚为输出,9号引脚为输入就可以
    函数为pinMode(num#,INPUT/OUTPUT)

    pinMode(8,OUTPUT)
    8号引脚设置为输出
    loop函数
    digitalWrite函数可以用来设置一个引脚的电平高低
    用法
    digitalWrite(num#,0/1)0为低电平1为高电平
    由于发送超声波时间是15us,所以需要这个函数
    delayMicroseconds(us)us可以改成自己需要的数值
    在延时结束后一定别忘了把trig引脚的电平置低
    pulseIn(num#,HIGH)
    这个函数的功能是测出发送到接收的时间,单位是us
    这个结果÷58就可以得出结果,单位cm
    明天会贴上程序

    回复

    使用道具 举报

     楼主| 发表于 2019-3-12 08:52:10 | 显示全部楼层


    回复 来自苹果客户端来自苹果客户端

    使用道具 举报

     楼主| 发表于 2019-3-12 08:56:16 | 显示全部楼层
    刚才发的程序有问题,再发一遍

    回复 来自苹果客户端来自苹果客户端

    使用道具 举报

     楼主| 发表于 2019-3-16 10:38:23 | 显示全部楼层
    首先。。。实在抱歉。。之前发的程序发了两遍还是发错了。。distance我打成了diatance。。被自己蠢哭了。
    8、红外光电对管因为L293D电机驱动板上可以引出6路模拟信号引脚A0-A5,所以在这里使用6路光电对管(需要使用ADC功能)
    首先我们需要定义所有需要使用的模拟引脚
    这里使用const变量防止被引脚号被改动
    ——const int analogInPin[6]={A0,A1,A2,A3,A4,A5};
    定义一个数组,存储所有需要用到的引脚序号
    int states[6];
    定义一个数组来存储各路读取的光电对管状态
    这里介绍一下,模拟引脚读取信号并由ADC转换成数字信号后产生的是一个在0-1023(也可是1024?)之间的数字,这个数字代表电平的状态,即0位最低电位(一般为GND),1023为最高电位,但我们不需要如此细分的数值,因为光电对管只会输出两种信号:0(最低电位)和1(最高电位),所以在读取数字信号后,只需要判断是否大于512(最好取中间值,防止误差吧,但理论上只要大于0小于1023就可以)就可以判断出状态,从而调整车的方向。
    int i;
    for(i=0;i<6;i++)
    states=analogRead(analogInPin);
    读取各个引脚状态
    for(i=0;i<6;i++)
    if(states<500)
          states = 0;
        else
          states = 1;

    转换成0/1信号
    然后就可以根据各路对管状态来控制车的路线了
    对于各个功能的结合最后说。
    回复

    使用道具 举报

    发表于 2019-3-17 10:48:52 | 显示全部楼层
    萝北太强了吧
    回复 来自安卓客户端来自安卓客户端

    使用道具 举报

     楼主| 发表于 2019-3-18 08:25:12 | 显示全部楼层
    9、红外遥控模块
    这里使用的是那种简单的3个引脚的红外遥控模块,即VCC、GND、信号输出3个引脚。
    关于VCC和GND就不多说,注意信号输出引脚需要接到单片机的数字引脚上(即带有“~”的接口)一般使用9或11号引脚。
    准备一个红外遥控器(样式随意,不影响)
    首先需要引用IRremote库
    #include <IRremote.h>
    定义红外引脚(这里用了9号)
    int RECV_PIN=9;
    初始化相应端口接收
    IRrecv irrecv(RECV_PIN);
    定义存储编码结果的对象
    decode_results results;
    void setup()
    {
    Serial.begin (9600);
    初始化红外解码
    irrecv.enableIRIn();
    }
    void loop()
    {
    如果接收到信号
    if(irrecv.decode(&results))
    16进制输出解码完的信号
    Serial.println(results.value,HEX);
    接收下一个编码
    irrecv.resume();
    }
    此时打开串口监视器,并向用遥控器向模块发送红外信号,应该就能在串口监视器里看到遥控器各个按键对应的编码,如果想要实现遥控功能的话,就可以根据这些键位对应的编码很方便的写出遥控程序(以下仅供参考)
    switch(results.value)
      {
        case 0xFF18E7:
        {Serial.println("前进");
        break;}
        case 0xFF10EF:
        {Serial.println("左转");
        break;}
        case 0xFF38C7:
        {Serial.println("停止");
        break;}
        case 0xFF5AA5:
        {Serial.println("右转");
        break;}
        case 0xFF4AB5:
        { Serial.println("后退");
        break;}
        default:
        Serial.println("请输入有效信息");
      }

    回复

    使用道具 举报

     楼主| 发表于 2019-3-20 17:52:57 | 显示全部楼层
    10、HC-05蓝牙模块实现串口通信
    这个之前没有提到过,不过考虑到其实还是挺多项目需要用到蓝牙模块的,就在这里加上。
    蓝牙模块的引脚有四个,VCC和GND不多说,另外两个TX和RX引脚,单片机的0号和1号引脚分别是RX和TX引脚,按照RX接TX的方式连接起来就行。(注意是TX接RX!!)
    单片机的程序也很简单。
    首先还是初始化串口通讯
    void setup()
    {
    Serial.begin(9600);
    }
    void loop()
    {
    当检测到串口有数据传输时
    while(Serial.available())
    {
    读取数据并输出到串口监测器
    char c=Serial.read();
    Serial.println(c);
    }
    }
    然后启动并用手机或电脑连接蓝牙模块,再用串口调试助手(网上有很多)发送数据即可在串口监视器里看到发送结果。
    基本模块讲到这里就差不多了,之后应该就是各个模块的结合应用了。
    回复

    使用道具 举报

     楼主| 发表于 2019-3-26 13:20:37 | 显示全部楼层
    11、综合应用:红外光电对管和L293D电驱板控制小车循迹
    相信了解了各个模块的原理及程序之后模块的结合对于同学们来说不是难事。
    这里就简单的给个例子而已,实际使用需要调试的。
    关于初始化啥的就不多说了。(这里是两个电机,6个光电对管的程序)
    设置初速度(0-255之间,但不是这个数值和速度不是线性关系)
      LS=120;
      RS=120;
    读取光电对管状态
      for(i=0;i<6;i++)
        states[i] = analogRead(analogInPin[i]);
    识别状态
      for(i=0;i<6;i++)
        if(states[i]<500)
          outstates[i] = 0;
        else
          outstates[i] = 1;
    根据状态对速度进行调整
        if(outstates[0]==1)
        {LS-=60;RS+=60;}
        if(outstates[1]==1)
        {LS-=30;RS+=30;}
        if(outstates[2]==1)
        {LS-=20;RS+=20;}
        if(outstates[3]==1)
        {LS+=20;RS-=20;}
        if(outstates[4]==1)
        {LS+=30;RS-=30;}
        if(outstates[5]==1)
        {LS+=60;RS-=60;}
    输出速度
    motor1.setSpeed(LS);
    motor2.setSpeed(RS);
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    回复

    使用道具 举报

     楼主| 发表于 2019-3-26 13:28:48 | 显示全部楼层
    12、红外遥控模块和L293D控制小车(有库函数冲突)
    首先由于两个模块所使用的库有定时器冲突,首先需要改库函数。
    首先打开Documents\Arduino\libraries\IRremote,找到IRremoteInt.h这个文件,然后把第67行的#define IR_USE_TIMER2注释掉,把66行的#define IR_USE_TIMER1取消注释,保存。(如果还是不行那就算了,本人的小车这样改完了也经常失控。。)
    首先按照之前的方法获取遥控器的信号代码,然后就可以根据这个编码去写控制小车的程序了。
    (以下仅供参考)
    if (irrecv.decode(&results))
    {
      Serial.println(results.value,HEX);
       motor1.setSpeed(200);
       motor2.setSpeed(200);
      switch(results.value)
      {
        case 0xFF18E7:
        {Serial.println("前进");
                  motor1.run(RELEASE);
                  motor2.run(RELEASE);
                  delay(30);
                  motor1.run(FORWARD);
                  motor2.run(FORWARD);
        break;}
        case 0xFF10EF:
        {Serial.println("左转");
                  motor1.run(RELEASE);
                  motor2.run(RELEASE);
                  delay(30);
                  motor1.run(BACKWARD);
                  motor2.run(FORWARD);
        break;}
        case 0xFF38C7:
        {Serial.println("停止");
                  motor1.run(RELEASE);
                  motor2.run(RELEASE);
        break;}
        case 0xFF5AA5:
        {Serial.println("右转");
                  motor1.run(RELEASE);
                  motor2.run(RELEASE);
                  delay(30);
                  motor1.run(FORWARD);
                  motor2.run(BACKWARD);
        break;}
        case 0xFF4AB5:
        { Serial.println("后退");
                  motor1.run(RELEASE);
                  motor2.run(RELEASE);
                  delay(30);
                  motor1.run(BACKWARD);
                  motor2.run(BACKWARD);
        break;}
        default:
        Serial.println("请输入有效信息");
      }
      irrecv.resume(); // 接收下一个编码
    }
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入观海听涛

    本版积分规则

    联系我们

    Powered by Discuz! X3.4 © 2001-2013 Comsenz Inc.

    Archiver|手机版|观海听涛论坛   

    GMT+8, 2022-6-26 03:42 , Processed in 0.103949 second(s), 40 queries , Gzip On, MemCache On.

    快速回复 返回顶部 返回列表