×

使用RFID卡创建和读取唯一订单标识符的智能装箱站

消耗积分:0 | 格式:zip | 大小:0.26 MB | 2022-12-29

mintsy

分享资料个

描述

我们正在为Nile 项目构建一个开源原型

背景

Nile 是一个去中心化且免佣金的购物平台,旨在为当地经济赋能。尼罗河正在重新定义电子商务的现状,不是建立一个统治世界的巨型公司,而是赋予人们和社区权力,以作为强大且相互关联的生态系统与这些巨人竞争。为此,尼罗河将在普通人充当供应商的帮助下将当地商店和客户联系起来。因此,最重要的流程之一是订购流程,当客户在当地商店订购产品并希望供应商将其送货上门时,该流程就开始了。为了跟踪订单及其状态,我们希望提供一种工具来使用 RFID 卡创建和读取唯一的订单标识符。本文旨在指导您逐步创建此类工具。

概述

正如主图所示,本教程的目标是构建一个工具,用于向 RFID 卡写入和读取数据,并借助 LED 环的颜色指示器可视化该过程。MAM 根存储在 RFID 卡上,Web 应用程序读取 MAM 流并显示订单的代表性数据。我们有六个步骤来指导您完成:

1. 机箱准备- 准备机箱以将所有硬件放入其中。

2. 设置 Raspberry PiZero - 安装 Raspbian,配置 ssh 和 wifi 以及通过 SSH 连接到 Pi。

3. 添加 RFID 组件- 将 RFID 模块 (Mifare RC522) 连接到 Pi。

4. 添加 LED 组件- 将 NeoPixel Ring - 12 x 5050 RGB LED 模块连接到 Pi。

5. 将所有东西放在一起- 在这里,我们将修复机箱内的所有硬件。

6. 让代码运行——最后但并非最不重要的是,我们通过添加代码使整个事情正常进行。

1.案例准备

我们希望将工具所需的一切都放在一个冷藏箱中。为了准备案例,您需要做以下事情:

  • 一个盒子- 把所有东西都放在里面
  • 一个小玻璃杯——还有……
  • ...铅笔- 标记整体
  • 一把刀- 切出整体
  • 一张砂纸- 细化边缘
  • 一块方形磨砂玻璃- 用作窗户
  • 一把刷子——还有……
  • ...一些丙烯酸颜色- 以您喜欢的颜色绘制盒子
  • 一块方形磨砂玻璃- 用于窗户
  • 热胶枪- 固定盒子窗户后面的玻璃
 
 
 
 
poYBAGOrxq-AG8xaAAlrBaHgcjg112.jpg
 
1 / 10第 0 步:概览材料和工具
 

 

2. 树莓派零设置

准备好案例后,我们需要开始进行 Raspberry Pi 的基本设置。

第 1 步 - 安装 Raspbian

首先我们要安装Raspbian - 我们建议安装 Raspbian Stretch Lite(在此处下载)。为此,请将 Pi 的 SD 卡插入您的计算机并在其上闪存 Raspian Stretch Lite。提示:为此,您可以使用Etcher

第 2 步 - 配置无头 WiFi

闪烁过程完成后,SD 卡已从您的计算机中弹出。您需要做的就是将其拔出并插入,让操作系统再次识别它。一旦你的引导驱动器出现打开你的终端并执行:

$ cd /Volumes/boot 

现在我们要启用 SSH ,它在 Raspberry Pi 上默认是禁用的。ssh我们只需在驱动器中创建一个名为的文件。boot为此执行:

$ touch ssh 

即使文件为空,它也会在 Pi 启动后立即启用 ssh。

最后,我们还希望 Pi 在启动后立即连接到 wifi。为此,我们将连接详细信息存储在bootPi 的驱动器中。执行以下命令:

$ nano wpa_supplicant.conf

现在继续并将以下代码粘贴到文件中。还要输入您的 wifi 连接详细信息,然后按ctrl + x保存更改。

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
network={    
    ssid="YOUR_SSID"    
    psk="YOUR_WIFI_PASSWORD"    
    key_mgmt=WPA-PSK
}

提示:如果您打算在不同的地方使用该工具,您现在可以轻松设置多个 wifi 配置。通过这样做,当您更改位置时,您无需拔出 Pi 的 SD 卡。如果你想这样做,只需添加以下代码:

$ ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
$ update_config=1
$
$ network={
$     ssid="SCHOOL_NETWORK_NAME"
$     psk="SCHOOL_PASSWORD"
$     id_str="school"
$ }
$ 
$ network={
$     ssid="HOME_NETWORK_NAME"
$     psk="HOME_PASSWORD"
$     id_str="home"
$ }

您可以通过添加更多网络对象在此处添加任意数量的网络。

现在我们准备好通过 SSH 连接到 Pi。

第 3 步 - 通过 SSH 连接

要通过 SSH 连接到 Pi,您可以执行以下命令:

$ sshpass -p  ssh -o StrictHostKeyChecking=no pi@

提示:如果您打算在将来多次重复这个过程,为了使这个过程更容易,您可以创建一个别名来访问 pi,piz而不是上面的命令。为此执行:

$ nano ~/.zshrc

然后简单地创建一个别名将其粘贴到文件中:

alias

现在,打开一个新选项卡,您就可以通过执行以下命令连接到 pi:

$ piz
 
pYYBAGOrxrKATLiwAAB5Hdzrsfo843.png
成功的连接应该是这样的。
 

3.添加RFID组件

我们想通过 RFID 写入器和读取器扩展 Pi。我们决定使用 Mifare RC522。该模块可以使用 SPI 连接。

第 1 步:启用树莓派 SPI

要为 Pi 启用 SPI,请执行以下命令转到配置设置:

$ raspi-config

现在选择接口选项,然后选择 SPI。出现提示时确认yes并重新启动您的 Pi:

$ sudo reboot 

一旦您的 Pi 重新启动,通过执行以下命令打开 config.txt:

$ sudo nano /boot/config.txt 

现在寻找以下行:

$ dtparam=spi=on 

如果您找到它,则您的 SPI 接口工作正常,您可以继续下一步。

第 2 步:安装 RFID 软件

要安装 RFID 软件,我们首先需要安装 Python 2.7 dev。为此执行:

$ sudo apt-get install python2.7-dev

接下来我们需要下载并安装python的SPI工具。

$ git clone https://github.com/lthiery/SPI-Py.git
$ cd SPI-Py
$
$ sudo python setup.py install

最后下载以下python库来使用RC522模块:

$ git clone https://github.com/mxgxw/MFRC522-python.git
$
$ cd MFRC522-python

第三步:接线图

作为最后一步,请按照此接线图将 RC522 连接到 Raspberry Pi Zero。

 

 
poYBAGOrxraAYEYZAAEM8xgeAb4945.png
将 RC522 连接到 Raspberry Pi Zero 的示意图。
 

追溯

如果您遇到如下图所示的回溯,请按照这些说明进行操作。

 
pYYBAGOrxriARPqnAAC2CBRdp_M394.png
最终追溯
 

该问题是由 SPI python 库引起的,可以通过回滚到同一库的先前版本轻松解决。

$ git clone https://github.com/lthiery/SPI-Py.git
$ git checkout 8cce26b9ee6e69eb041e9d5665944b88688fca68
$
$ sudo python setup.py install

确保在回滚后再次运行安装程序。如果您仍然有问题请参阅相关的 StackOverflow 文章。

4.添加灯光组件

对我们来说,该工具具有一些奇特的即时用户反馈似乎很重要。最简单的方法是通过颜色的视觉反馈。所以我们决定添加一个磨砂玻璃窗和一个NeoPixel Ring - 12 x 5050 RGB LED以提供某种彩色进度条。

示意图要将此组件添加到 Raspberry Pi Zero,请遵循以下示意图:

 
poYBAGOrxryATAedAADlOHpoGWM411.png
将 NeoPixel Ring - 12 x 5050 RGB LED 添加到 Raspberry Pi Zero 的示意图。
 

5. 把所有东西放在一起

在我们构建了我们的案例并将所有硬件组件放在一起之后,我们准备好将所有东西放入案例中。您决定在框中放置元素的方式完全取决于您。我们所做的只是简单地使用一些聚苯乙烯泡沫塑料和胶带来固定盒子内的所有元件。

提示:从视觉的角度来看,真正重要的一件事是将灯的位置非常靠近窗户。

 
 
 
 
poYBAGOrxuKAHZJuAArgdZQMFUY235.jpg
 
1 / 9步骤1:将树莓派放在盒子的左下方,用两条胶带固定电缆。
 

6:运行代码

我们需要运行两个应用程序,一个用于商店,一个用于包装站按照代表性 Readme.md 文件中的说明安装依赖项并运行应用程序。

第一步:开店申请

创建您的商店首先,运行商店应用程序 -使用演示用户登录并导航到导航中的商店页面现在在这里输入您的商店名称和位置。创建商店后,应用程序会为您创建一个 MAM 根目录,其中存储了有关您商店的所有信息。

 
pYYBAGOrxuWAGqqNAAHY53mnhfk204.png
在受限的 MAM 频道中购买数据。
 

MAM 根以及用于向频道发布新消息的种子,两者都仅存储在浏览器的本地数据库中。所以没有第三方持有您的凭据

MAM 流中的新消息表示对商店数字双胞胎的更改 - 例如,如果您更改商店名称。通过这种方法,我们可以获得商店的整个变更历史记录。和处理产品order_request_addresscatalog_root订购流程,这不是本教程的一部分。

创建一些产品下一步是在Products 页面中创建一些产品之后,我们准备创建订单。为了简化本教程中的工作流程,我们直接在商店应用程序中创建订单,而不是在这里也使用客户应用程序。

 
poYBAGOrxumAP0muAAJnNa0QSm4921.png
具有存储在 Tangle 中的完整历史记录的产品编辑演示。
 

 

创建订单转到“订单”页面,选择一些产品并创建订单。

第二步:打包申请

写入 RFID 卡我们需要 Packing Station Prototype 将 MAM 根写入 RFID 卡。直接在Shop应用Order页面复制,然后去packing station app到Write页面。现在将 MAM 根粘贴到给定的输入中。完成后,按写入按钮读卡器上的灯现在应该从蓝色变为橙色,这表示将卡放在盒子上并等待几秒钟,直到灯变为绿色。这表明写入过程成功,我们现在可以读取卡了。

读取 RFID 卡现在导航至读取页面并等待指示灯变为蓝色。一旦它是蓝色的,您就可以将卡片放在盒子上,然后将从 MAM 根目录获取订单信息。RFID 阅读器从卡中读取 MAM 根,将其发送到前端并获取流中的当前数据。因此,无论何时执行此过程,您都将始终从 tangle 中获取最新数据。

 

 
poYBAGOrxvOAL4PlAAG7R6zcBeM147.png
通过 MAM 流从 Tangle 中获取的数据。
 

结论

本教程演示了一个真实世界的用例,使用 Tangle 作为分布式账本来存储有关本地商店、他们的产品和订单的数字双胞胎的重要数据。在本教程中,MAM 通道表示从供应商到客户的订单生命周期。智能包站只覆盖了我们需要构建的设备生态系统的一小部分,以便为整个过程提供服务,但这仍然是第一步。

我们打算进一步改进这个用例和教程。如果您有任何问题,请告诉我们!


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

评论(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.obk20.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:'使用RFID卡创建和读取唯一订单标识符的智能装箱站',//标题 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.obk20.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);