查看: 3283|回复: 6

用小小的滚轮,丈量你周围的“天下”

[复制链接]
  • TA的每日心情

    2018-1-11 13:58
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2017-9-14 15:41 | 显示全部楼层 |阅读模式
    Arduino UNO——小型测距轮
    现在打开百度地图,输入起点和终点,两地之间的距离马上显示在手机屏幕上。相比以往的地图,现在的电子地图,地理信息量更大。距离计算的更加精确。可这么大的面积,是怎么测量出来的呢?卫星、卷尺还是其他的。卫星能勘探地形、地面资源。但所测距离的精确度不高;卷尺灵活性不够,所测的距离不够长。排除以上两种还有其他测距工具吗?前段时间在马路上看见有人手持一个滚轮沿着马路边滚动,觉得很是新奇,上前询问,原来他是地图工作者,现在正在绘制路线,并测量两地之间的距离。原来他所用的就是用测距轮。这种测距工具,方便携带,灵活性高,测量精准度高。回来之后自己也制作了一个小型的测距轮。






    测距轮相比传统的卷尺,可以随意滑动,可测正负(向左滑动为正,向右滑动负)。
    下面就来看看做的怎么样吧。


    【配件图】


    【主要配件】


    测距轮的主板我采用的DFRobot最新推出的DFRduino UNO R3的主板,他完全兼容Arduino UNO R3版本。性价比也比较高,相比之下,我更钟意DFRduino UNOR3。因为它采用沉金工艺,外观精致,在追求质量的同时,也提高了颜值 。制作测距尺,还需要一个强大的配件,那就是编码器,这样才能计数。


    在这里我采用增量式光电旋转编码器,它能有效的兼容Arduino,PLC等各类主控器。它具有AB两相输出,可以通过旋转的光栅盘和光耦产生可识别方向的计数脉冲信号。其电路输出的类型为NPN集电极开路输出,这样的输出类型可以和内部带上拉电阻的单片机连接,然后实现转速、角度、角速度等数据的测量。
    注意:编码器在不接设备的情况下,集电极开路输出,在没有上拉电阻的时候,是没有电压输出的,如要要示波器示波请在AB两相输出上加上两个上拉电阻。如果实际运用,就不需要加上拉电阻了。

    示波器信号

    【部分配件】
    【电路接线图】


    实物连接图


    【效果图】
    Reset:此模式为复位模式,切换到此模式,可以清零所测的数据。这样又可以重新开始测距取值了。

    Detection:此模式为测距模式,切换到此模式,可以开始你的表演了,随意测距,上下左右随便滚动,完全无压力。往左滚测得是数值为正,往右滑数值为负(当测距数值为正得时候,往右滑可以看见数值随着减小)。



    Lock:此模式为锁定,当你测得一定的距离后,选择到此模式可以锁定数据,随意你怎么滚动,数据都不会改变了,这样你就可以记录数据了。方便吧,按三下按键就可以了哦。



    为了让携带方便,外观漂亮。我用3D打印机打印了外壳。方方正正的,是不是看起来有点呆板。没办法,我能想到的只是如此了。相信朋友们肯定有更好的创意。3D打印的文件我以附件的形式放在文末了。
    注意:因为自己找的轮毂尺寸都不合适,后面自己用3D打印机制作了一个80mm的轮毂。而轮胎还是用的高品质环保ABS硅胶车轮外的轮胎


    程序:

    kittenblock中小学创客名师推荐的图形化编程软件

    #include <Wire.h>
    #include "DFRobot_RGBLCD.h"
     
    DFRobot_RGBLCD lcd(16, 2);
     
     
    //rgb_lcd lcd;
     
    #define A 3
    #define B 4
    #define Key  12//key
     
    #define D 79 //Diameter 79mm
     
    float C = 0; //perimeter
    unsigned int Distance;
    int VA = 0;
    int VB = 0;
    unsigned long Count = 0;//count
    unsigned int Count_1 = 0; //Negative count
    unsigned char flag = 1, Mark = 0;
    unsigned long lasttime = 0, Modetime = 0;
     
    //Length measurement range is ± 6 M
    void setup()
    {
      Serial.begin(9600);
      lcd.init();
      lcd.setRGB(255, 255,0);
      lcd.setCursor(2, 0 );
      lcd.print("M:");
      lcd.setCursor(2, 1 );
      lcd.print("D:");
      lcd.setCursor(12, 1 );
      lcd.print("cm");
      pinMode(A, INPUT_PULLUP); //Pull-up input
      pinMode(B, INPUT_PULLUP);
      pinMode(Key, INPUT);
      attachInterrupt(1, interrupt, RISING);
      C = D * PI;
    }
     
    void loop()
    {
      if (millis() - 150 > lasttime)//Detect keys once every 150ms
      {
        if (digitalRead(Key) == HIGH)
          if (digitalRead(Key) == HIGH)
            Mark += 1;
        if (Mark > 2)
          Mark = 0;
     
        while (digitalRead(Key) == HIGH);
        lasttime = millis();
      }
     
      if (millis() - 100 > Modetime)//Refresh the data every 100ms
      {
        if (Mark == 0) //Cleared
        {
          lcd.setCursor(6, 0 );
          lcd.print("Reset    ");
          Distance = C * Count / 40;
          flag = 3;
          lcd.setCursor(11, 0 );
          lcd.print("     ");
        }
     
        if (Mark == 1) //Calculate the measured value
        {
          lcd.setCursor(6, 0 );
          lcd.print("Detection");//
          lcd.setCursor(4, 1 );
          if (Count > 0 && Count < 0xffff)//Determine whether the length is positive
          {
            lcd.print('-');//The length is negative
            Distance = C * Count / 40;
          }
     
          else if (Count == 0 && Count_1 == 0 )//Determine whether the length is zero
          {
            lcd.setCursor(4, 1 );
            lcd.print(' ');
            Distance = C * Count / 40;
          }
     
          else//Length is positive
          {
            lcd.print('+');
            Distance = Count_1 * C  / 40;
          }
        }
     
        else if (Mark == 2) //lock
        {
          lcd.setCursor(6, 0 );
          lcd.print("Lock     ");
          Count = 0;
          Count_1 = 0;
        }
     
        Modetime = millis();
      }
     
     
     
      lcd.setCursor(5, 1 );//Displays the value of Distance
      lcd.print(Distance / 10000);
      lcd.print((Distance / 1000) % 10);
      lcd.print((Distance / 100) % 10);
      lcd.print('.');
      lcd.print((Distance / 10) % 10);
      lcd.print(Distance % 10);
    }
     
    void interrupt()//Interrupt handler
    {
      VB = digitalRead(B);
      if (Mark == 1)//Detects whether the current mode is a measurement
      {
        if (VB == 1)//To determine whether the positive measurement
        {
          flag = 1;
           
          if (Count > 0xffff)
          {
            Count_1 -= 1;
          }
     
          Count += 1;
        }
         
        else//Reverse measurement
        {
          flag = 0;
          Count -= 1;
           
          if (Count > 0xFFFF)
          {
            Count_1 += 1;
          }
        }
         
        //Count is cleared over the range
        if (Count < 0xFFFF && Count > 0x294A)
          Count = 0;
     
        else if (Count < 0xFFFFD6B5 && Count > 0xFFFF)
          Count = 0;
      }
    }


    测距尺的3D文件.rar (327.89 KB, 下载次数: 6)
    打赏作者鼓励一下!
  • TA的每日心情
    开心
    2018-1-15 23:35
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2018-1-15 23:42 | 显示全部楼层

    感谢您的分享!

    该用户从未签到

    发表于 2018-5-20 22:46 | 显示全部楼层
    楼主的电路连接图和实物图上都没有用到uno板子吗? 直接用扩展板?

    该用户从未签到

    发表于 2018-5-23 21:26 | 显示全部楼层
    楼主可以给个联系方式吗。有点小问题需要咨询一下
  • TA的每日心情
    开心
    2018-12-12 11:46
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2018-11-20 13:38 | 显示全部楼层
    创意非常好,只是做为一个优秀的程序员不写注释的话,成果减半哈哈。小声说,看不懂啊
  • TA的每日心情

    2018-1-11 13:58
  • 签到天数: 8 天

    [LV.3]偶尔看看II

     楼主| 发表于 2018-11-21 10:45 | 显示全部楼层
    qhdyang 发表于 2018-11-20 13:38
    创意非常好,只是做为一个优秀的程序员不写注释的话,成果减半哈哈。小声说,看不懂啊 ...

    我也假装看不懂……咔咔咔,我相信你可以的
    打赏作者鼓励一下!
  • TA的每日心情

    2018-1-11 13:58
  • 签到天数: 8 天

    [LV.3]偶尔看看II

     楼主| 发表于 2018-11-21 10:54 | 显示全部楼层
    1223640900 发表于 2018-5-23 21:26
    楼主可以给个联系方式吗。有点小问题需要咨询一下

    你加一下作者微信哦,zcl2009031081,备注一下 arduinoCN
    打赏作者鼓励一下!
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    【项目】基于Arduino Nano的多功能桌面感应垃圾桶
    【项目】基于Arduino Nano
    基于Arduino Nano的多功能桌面感应垃圾桶随着大学生活不断往前迈进,宿舍桌面上的杂物
    智能物联网花盆
    智能物联网花盆
    打坏了一个费时5小时 3D打印的花盆,耗时22小时 下载:Kittenblock软件,安装、运
    呼吸灯实验
    呼吸灯实验
    本文节选自《Arduino程序设计基础》 之前的章节已经介绍了多种方法控制LED,但单是开
    为开发板 Generic ESP8266 Module 编译时出错
    为开发板 Generic ESP8266
    第一次尝试Arduino UNO软串口通信,编译一直通不过,错误信息 “开发板 generic (平
    Arduino Uno 无法上传程序
    Arduino Uno 无法上传程序
    原来可以正常使用的Arduino Uno 板子突然不能上传程序了,硬件驱动正常,TX和RX指示灯
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表