1 Dulciurilla:Fitbit智能糖果分配器-德赢Vwin官网 网
×

Dulciurilla:Fitbit智能糖果分配器

消耗积分:0 | 格式:zip | 大小:0.01 MB | 2023-02-07

李巍

分享资料个

描述

什么想法?

我的女儿喜欢甜食。她非常爱他们,以至于她愿意做任何事情来得到他们:不吃饭,从秘密藏身处偷他们,只要她得到她的糖剂量,她甚至愿意在这样做时被抓到受到惩罚。

糖会激活大脑的奖赏系统。该系统的激活会导致强烈的奖赏感,从而导致渴望和上瘾。所以药物和糖都会激活大脑中相同的奖励系统,导致多巴胺的释放。

我们全家都使用 Fitbit 健身追踪器,但她的步伐不是那么好。但是,如果我们将她对甜食的渴望与她的实际日常活动同步起来呢?如果我可以让她增加体力活动以获得这些奖励怎么办?我想那没关系,因为一般来说我对甜食没有问题,但我在沙发上发胖的同时吃甜食有问题。:)

因此,检查了他们的 API,发现他们公开了日常活动指标,例如步数、攀爬的楼层数、距离、卡路里等。唯一要做的就是糖果分配器能够根据她的活动水平给她糖果。为了让事情变得更有趣,我决定让整个家庭都参加这次比赛,并让这个分配器具有多用户功能。这打开了一些有趣的家庭挑战的大门,其中涉及含糖奖励。

 
 
 
20191106_084657_5S6at2j4PU.jpg?auto=compress%2Cformat&w=740&h=555&fit=max
 
1 / 7
 

项目一览

该项目相当简单。如果您熟悉基本概念,那么棘手的部分不是电子设备,而是机械部分。

  • 糖果垂直排列在塔状盒子内
  • 微控制器 ESP8266 NodeMCU 设置一个 HTTP 服务器监听 LAN 上的连接。
  • 可以托管在互联网上的配套网络应用程序,发送和接收 HTTP 消息以分发糖果或获取状态信息。
  • 配套应用程序可以有任何逻辑,但我的版本会根据您使用 Fitbit 进行的健身活动为您提供糖果。您可以轻松编写不同的逻辑,因为分配器本身可以使用 Restful API 进行控制。当你在 Facebook 上收到点赞时,比如给你糖果 :) 疯了!
  • 如果通过 API 请求糖果,微控制器会指示伺服电机移动,进而使托盘滑动,最终将糖果推出
  • 该设备非常基本。附加功能包括灯光和最后播放带有蜂鸣器的愚蠢旋律。

点胶机构

20191106_084338_AMjEjv10z4.jpg?auto=compress%2Cformat&w=740&h=555&fit=max
 
  • 因为机器是点胶机,所以只有一个主命令点胶
  • 当微控制器接收到点胶指令时,它会利用360度连续伺服来完成这项工作。
  • 伺服正在向前推动托盘并可以通过推拉杆将其拉回,
  • 托盘在轨道上滑动。您可以轻松地用两根坚硬的金属棒制作轨道。润滑杆以改善滑动并最大程度地减少令人不快的噪音。托盘可以由木头、塑料甚至金属制成。我建议你把托盘做得尽可能薄,但能把糖果移出来,把托盘安装得尽可能靠近地面,最好不要接触地面。由于糖果下落的角度较小,这将有助于防止卡纸。
  • 托盘最初位于塔内最底部,所有糖果都在顶部。
  • 首先,伺服电机拉回托盘,为下一颗糖果腾出空间,下一颗糖果落在外壳底部,同时托盘缩回,然后托盘向前推动,进而将糖果推​​到外面。
  • 有两个金属传感器,一个在前面,一个在后面,可以判断托盘何时到达最终或初始位置。它们的作用类似于按钮,并使用中断进行处理,以提高安全性和响应能力。
  • 如果托盘没有在预期的时间范围内到达目的地(设置为 1 秒),则实施软件卡纸保护以防止损坏
  • 对于维护,有前后移动托盘的命令,但如果托盘卡住,您可以用手移动托盘 :)。

笔记:

使用不同类型的电机也可以。我有一个连续伺服,但我想位置伺服甚至步进电机或普通直流电机都可以工作。如果您依靠它们的固定定位精度,您甚至可以放弃初始/最终位置传感器。移除这些的一个问题可能是位置校准和轴位置的手动更改。

你需要把伺服喇叭做得更长;为此,您可以像我一样用螺丝连接 7-8 厘米的胶合板延伸件。控制杆通常在与喇叭连接的一端有一个 Z 形弯头(弯成字母 Z 的形状),另一端有一个 90 度弯头,带有弹簧固定器。我的 Z 弯不太好,因为我使用了非常坚硬的电线并且没有合适的工具,所以我实际上使用了 U 弯,效果很好。这个想法是杆不应该从喇叭中脱出。这是一个很好的补充,可以确保杆移动的孔不会磨损(特别是如果喇叭材料像木头或塑料一样柔软),所以我插入了一个橡胶垫圈。要制作弹簧固定器,您可以使用一些弹性线和一根热缩管。

20191006_152915_blTmJdzlwn.jpg?auto=compress%2Cformat&w=740&h=555&fit=max
带 Z 形弯曲和弹簧固定器的控制杆
 

不要忘记用提供的螺丝将喇叭固定到伺服器上。您可能需要在木质延伸件上钻一个孔,以便将螺丝实际连接到塑料喇叭上。

20191027_104653_JWVf6ghmG6.jpg?auto=compress%2Cformat&w=740&h=555&fit=max
固定喇叭
 

通电

所有基于 ESP8266 的开发板都有一个内置稳压器,因此您只需连接一根 USB 数据线,它将提供 5V 电压,内置稳压器将为芯片提供 3.3V 电压。请注意,舵机连接到 5V 输入,因为它需要更多功率。所以基本上输入电压为 5 伏,设备在点胶时需要高达 1.5A 的电流。不分配时,WiFi 芯片通常消耗 50 - 300 毫安,每个 LED 消耗 30 毫安。我没有实现省电模式,但在待机状态下,它不应超过 120 毫安。

灯光

任何凉爽的分配器都有一个透明面板,供您检查里面的食物,并配有照明。

我没有在照明方面走得太远,即使你对彩色 LED 发疯了。我只是在前面板使用了两个白色 LED,由一个 NPN 晶体管激活。前面板灯也可用作状态和错误指示器。

当设备连接到 WiFi 时,灯会慢慢淡入和熄灭,直到建立连接,然后灯会亮到更高的强度。我只是使用 PWM 引脚来控制光的强度。

 
 
 
led-connection-board_bb_E0Q5C6vtKi.png?auto=compress%2Cformat&w=740&h=555&fit=max
 
1 / 6
 

该电路是一个标准的低侧 NPN 开关。

如果您是初学者,请继续阅读

它被称为低侧开关,因为晶体管正在切换接地路径。负载的 VCC 输入直接连接到电源正输出,而负载的地通过连接到集电极引脚的晶体管连接。如果足够的电压和电流施加到晶体管的基极,晶体管就会饱和并从集电极传导到发射极。负载由我们的两个白色 LED 组成,正极(阳极)通过串联电阻连接,以限制电流.为了激活“开关”,我们通过串联电阻向晶体管的基极发送逻辑 1。基极没有电阻的三极管就像没有限流电阻的LED. 电阻器的值及其两端的电压将设置电流。电阻器需要足够大以有效地限制电流,但又要足够小以便为基极提供足够的电流。您可以根据您的晶体管和负载计算该值。例如,我的 NPN3904 的 hFE=100 与 5k 电阻器配合使用可以很好地切换 60mA,因此我使用了一个 4.7K 的电阻器,它应该在 3.3V 和 3.3V 的正向 LED 电压下处理 70mA。我使用了一个非常小的 1.8 欧姆电阻来限制 LED 电流,因为 LED 的正向电压应该相同,并且电压是稳定的。您可以使用此计算器计算基极电阻。这个用于 LED 电阻器。

安全和糖果防盗保护

为了防止未经授权访问糖果(基本上是为了防止我的女儿偷糖果 :))我使用了一把普通的旧锁。如果你想避免作弊,我认为这个问题不能被忽视 :)

音效

分配过程完成后,我正在使用无源蜂鸣器播放旋律。由于播放旋律通常有延迟,我创建了一个safeDelay函数以较小的增量(100 毫秒)延迟,让内部 ESP8266 进程更频繁地运行,延迟被认为是一种不好的做法,但旋律是在最后播放的分配过程,所以它不应该影响响应有用命令的能力。

外壳

外壳是用胶合板建造的。前门有一个透明的塑料面板,可以看到里面的食物。

 
 
 
enclosure-front_MDhsTUoavQ.jpg?auto=compress%2Cformat&w=740&h=555&fit=max
 
1 / 5正视图
 

最重要的方面是确定糖果塔的尺寸。我建造了一个巨型 Tic-Tac 盒尺寸的塔。这个方便的塑料盒有一个小活动铰链盖,可以装 M&Ms、Smarties 或类似的小糖果,完全取下盖子后,您可以放入巧克力块,如 Kinder 巧克力棒或任何适合的东西。糖果塔应该与 Tic-Tac 盒子紧密贴合,各个方向的间距只有几毫米。如果空间太多或太少,Tic-tacs 就会卡住,

在外壳上加一个盖子或门是非常有用的,这样你就可以进行维护。维护可以包括润滑导轨。在我的版本中,无法通过打开盖子取出糖果,因此没有必要固定它。

一个很好的补充也是一个电源开关。您可以剪断 USB 电缆并将一个小开关连接到正极。

网络应用

配套网络应用程序是用 PHP/Javascript 编写的。实际上,我将此功能集成到一个更复杂的应用程序中,我正在使用该应用程序将食物记录到 Fitbit 中,并连接到我的 DIY Healtzuilla 体重秤。

作为高级概述,该应用程序使用通过 HTTP 分配的 LAN IP 与分配器通信。如果完成定义的挑战,它使用statusdispense端点提供糖果。为了检查挑战是否完成以及如何完成,它使用 OAuth2 身份验证连接到 Fitbit Web API 并检索每日统计数据。它会跟踪已经分配(吃掉)的糖果,如果您赢得了新糖果,它会为您提供新糖果。它为不同的用户保留单独的统计信息。

从这个更大的代码库中提取与 Dulciurilla 相关的 PHP 源代码会有点困难,但如果有足够的请求,我可以做一些努力。

使用 jquery 的分配器的 ES6 Javascript 类示例:

class DispenserApi {
    constructor(baseUrl) {
        this.baseUrl = baseUrl;
    }

    executeCall(endpoint, method = 'GET', body = null) {
        return $.ajax({
            type: method,
            url: this.baseUrl + endpoint,
            dataType: 'json',
            data: body
        }).fail(function (jqXHR, textStatus, errorThrown) {
            console.log('Request failed: ' + jqXHR.status);
        });
    }

    getStatus() {
        return this.executeCall('dispenser/status');
    }

    dispense() {
        return this.executeCall('dispenser/dispense', 'POST');
    }
}

它可以像这样实例化和使用:

// replace with your dispenser IP
var dispenser = new DispenserApi('http://192.168.0.152/api/');

dispenser.dispense().done(function (dispenseData) {
    console.log("Success");
}).fail(function (jqXHR, textStatus, errorThrown) {
    console.log("Failed");
});

宁静 API 参考

RESTful HTTP API 可在 获得http:///api/所有响应都是 json 格式。

成功的 POST/PATCH 操作返回 HTTP 状态代码 200 和如下所示的 JSON:

{"success": true}

失败的请求返回一个非 200 的 HTTP 状态代码和一个带有两个键的 JSON 对象:

  • 错误:bool (始终为真)
  • 消息:字符串(可选)

例子:

{"error": "true", "message": "Something went wrong"}

以下所有路径均与秤 IP 地址相关。

分配器API

要求分发糖果

POST /api/dispenser/dispense

获取设备状态

GET /api/dispenser/status

设备可能处于以下状态之一:

  • 正在初始化(代码 0)-尚未准备好命令
  • 空闲(代码 1)-准备好执行命令
  • 点胶(代码 2)-在点胶过程中,此时无法处理新命令
  • 错误(代码 3)- 如果托盘卡住,WiFi 未连接。无法处理任何命令。

示例响应:

{"statusCode":  2, "statusText": "Dispensing"}

维护API

向前移动托盘

POST /api/dispenser/maintenance/tray/move-forward

向后移动托盘

POST /api/dispenser/maintenance/tray/move-backwards

获取托盘状态

GET /api/dispenser/maintenance/tray/status

托盘可以处于以下状态之一:

  • 已停止(代码 0)
  • 向后移动(代码 1)
  • 前进(代码 2)

示例响应:

{"status": 1, "statusText": "向后移动", "operationTime": 360}


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

评论(0)
发评论

下载排行榜

全部0条评论

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

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"//www.hzfubeitong.com/m/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="https://m.elecfans.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:'Dulciurilla:Fitbit智能糖果分配器',//标题 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:"//www.hzfubeitong.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);