×

手势控制机器人开源分享

消耗积分:0 | 格式:zip | 大小:0.11 MB | 2022-11-16

贾虎世

分享资料个

描述

介绍

该项目旨在构建一个手势控制机器人,可用于医院、商店、酒店、家庭等,在这些地方需要非接触式交付,以便在 Covid-19 情况下严格遵守社交距离。

项目概况

该项目基本上包含两个电路,一个发射器电路和一个接收器电路。手势通过 MPU6050 加速度计传感器转换为电信号,Arduino Nano 处理传入的信号并将其发送到射频发射器。在接收端,这些信号被射频接收器接收并发送到Arduino Uno进行解码。Arduino Uno 在接收到信号后,通过电机驱动器驱动电机。

第一步:传输电路

发射电路由一个 MPU6050 加速度传感器、一个 Arduino Nano、一个 433 MHz 射频发射器和一个 9V 电池组成。电池用于为 Arduino 供电,而传感器和发射器可以由 Arduino 供电。这是因为,Arduino 可以接受 5V 至 12V 的电压,而传感器必须由 5V 电源供电。Arduino 的代码已在本项目的后面部分提供。组件放置在面包板上,并根据下图给出了连接。

pYYBAGNy7VyAV3ibAAIDC6MBEdI248.png
发射器电路
 

完成必要的连接后,它看起来应该是这样的。在这里,我使用了移动电源而不是 9V 电池。

poYBAGNy7V-AHWPlAABSmtI6QHo024.png
 

第二步:接收电路

接收电路由一个 Arduino Uno、一个 433MHz 射频接收器、一个 L298N H 桥电机驱动器、两个直流电机和四个 18650 锂离子电池组成。电池为电机驱动器供电,电机驱动器为 Arduino 供电,射频接收器由 Arduino 供电。Arduino 的代码已在项目的后期部分提供。组件放置在机器人底盘上,并根据下图给出连接。

pYYBAGNy7WOAJpRcAAI24pQRRPo371.png
接收电路
 

电机及其轮子和脚轮应安装在底盘底部。组件应用胶带固定在顶部。如果它是像我这样的金属底盘,则用一层绝缘材料(如纸)将顶部绝缘。完成必要的连接后,机器人应类似于下图。在这里,我为电机和 Arduino 使用了单独的电源。

poYBAGNy7WWAculkAABRjg6RAKo207.png
机器人上的接收器电路
 

第三步:逻辑

MPU6050 传感器具有加速度计和陀螺仪。对于这个项目,加速度计值是从传感器获得的。

  • 如果沿 x 轴的加速度值在 20 到 60 之间,则机器人应该向前移动
  • 如果沿 x 轴的加速度值介于 -20 和 -60 之间,则机器人应该向后移动
  • 如果沿 y 轴的加速度值在 20 到 60 之间,则机器人应向左转
  • 如果沿 y 轴的加速度值介于 -20 和 -60 之间,则机器人应向右转
  • 如果以上条件均不满足,则机器人应停止。

第 4 步:对发射器进行编程

首先,包括必要的库。分别为 GY6050 和 RH_ASK 类创建实例,即 acc 和 driver。0x68 代表传感器的 I2C 地址。

#include <RH_ASK.h>
#include <Wire.h>
#include <GY6050.h>

GY6050 acc(0x68);
RH_ASK driver;
char* msg="100";

在 setup 函数中,首先初始化加速度传感器。然后开始串行通信,以 9600 的波特率显示串行监视器中的值。然后,检查 RH_ASK 驱动程序是否已正确初始化。

void setup()
{
    acc.initialisation();
    Serial.begin(9600);
    if (!driver.init())
    Serial.println("init failed");
}

在循环函数中,声明一个名为 msg 的变量,用于将消息发送给接收者。将必要的参数传递给刷新函数以获取两个轴的加速度计值,并将它们存储在两个变量中。

void loop()
{
    const char *msg = "hello";
    int AcX=acc.refresh('A', 'X');
    int AcY=acc.refresh('A', 'Y');
    delay(25);
  • 如果 AcX 的值介于 20 和 60 之间,则在串行监视器中打印 Front 并将值 Front 存储在 msg 中。
  • 如果 AcX 的值介于 -20 和 -60 之间,则在串行监视器中打印 Back 并将值 Back 存储在 msg 中。
  • 如果 AcY 的值介于 20 和 60 之间,则在串行监视器中打印 Left 并将值 Left 存储在 msg 中。
  • 如果 AcY 的值介于 -20 和 -60 之间,则在串行监视器中打印 Right 并将值 Right 存储在 msg 中。
  • 如果上述条件都不满足,则将值 Stop 存储在 msg 中并在串行监视器中打印 Stop。
if(AcX>=20 && AcX<=60)
    {
        Serial.println("Front");
        msg="Front";
    }
    else if(AcX<=-20 && AcX>=-60)
    {
        Serial.println("Back");
        msg="Back";
    }
    else if(AcY>=20&&AcY<60)
    {
        Serial.println("Left");
        msg="Left";
    }
    else if(AcY>=-60&&AcY<-20)
    {
        Serial.println("Right");
        msg="Right";
    }
    else
    {
        Serial.println("Stop");
        msg="Stop";
    }
    delay(100);

然后通过 send 函数发送消息并等待任何先前的消息传输完成。

driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
delay(200);
}

第 5 步:对接收器进行编程

首先,包含必要的库并分别为 RH_ASK 和 String 类创建实例。

#include 
RH_ASK driver;
String str;

在 setup 函数中,以 9600 的波特率启动串行通信,并检查 RH_ASK 驱动程序是否已正确初始化。

void setup()
{
    Serial.begin(9600);
    if (!driver.init())
    Serial.println("init failed");
}

在循环函数内部,创建一个缓冲区来存储从发送器接收到的值。然后将缓冲区中的值复制到字符串并在串行监视器中打印。

void loop()
{
    uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];//max size of the buffer
    uint8_t buflen = sizeof(buf);
    if (driver.recv(buf, &buflen)) //Receive the value and store it in a buffer
    {
        str=(char*)buf;   //Copy the message from the buffer to a string
        Serial.println(str); 
    }
    delay(200);

数字引脚 5 和 6 用于控制左电机,引脚 7 和 8 用于控制右电机。

如果接收到的字符串是 Front,机器人应该向前跑。这是通过将电机的第一个引脚设置为高电平并将下一个引脚设置为低电平来实现的。

如果接收到的字符串是 Back,机器人应该向后跑。这是通过将电机的第一个引脚设置为低电平并将下一个引脚设置为高电平来实现的。

如果接收到的字符串是右,机器人应该右转。所以左电机应该向前转动,右电机应该向后转动。

如果接收到的字符串是 Left,机器人应该向左转。所以左电机应该向后转动,右电机应该向前转动。

要停止机器人,请将所有电机引脚设置为低电平。

if(str=="Front")
    {
        digitalWrite(5,HIGH); //5,6 Left motor
        digitalWrite(6,LOW);
        digitalWrite(7,HIGH); //7,8 Right motor
        digitalWrite(8,LOW);
    }
    else if(str=="Back")
    {
        digitalWrite(5,LOW);
        digitalWrite(6,HIGH);
        digitalWrite(7,LOW);
        digitalWrite(8,HIGH);
    }   
    else if(str=="Left")
    {
        digitalWrite(5,LOW);
        digitalWrite(6,HIGH);
        digitalWrite(7,HIGH);
        digitalWrite(8,LOW);
    }
    else if(str=="Right")
    {
        digitalWrite(5,HIGH);
        digitalWrite(6,LOW);
        digitalWrite(7,LOW);
        digitalWrite(8,HIGH);
    }
    else
    {
        digitalWrite(5,LOW);
        digitalWrite(6,LOW);
        digitalWrite(7,LOW);
        digitalWrite(8,LOW);
    }
}

第 6 步:故障排除

有时电机不会按所需方向运行。首先找出哪个电机以这种方式运行。然后该电机的电线必须互换并重新连接。这有望解决这个问题。

如果接收到的缓冲区包含一些不需要的值以及消息,则使用子字符串函数从中提取消息。

机器人的工作

在构建机器人并将代码上传到两个 Arduino 之后,机器人就可以正常工作了。此处附有机器人的工作视频。

由于封锁,我被迫使用可用的组件来完成这个项目。另外,由于同样的原因,我用我的手机相机拍摄了这个视频,因为质量很差。带来不便敬请谅解。如果您在构建此项目时遇到任何问题,请在评论中发布。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.jibsdb.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'手势控制机器人开源分享',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"https://www.elecfans.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);