×

使用Arduino 33 BLE Sense的蜂巢监视器

消耗积分:0 | 格式:zip | 大小:0.04 MB | 2022-10-26

分享资料个

描述

我们五个人是巴黎索邦理工学院的嵌入式系统专业的学生。这项任务是几个月前交给我们的,目的是帮助养蜂人照顾他们的蜂箱。

蜂箱中可能会发生许多问题,养蜂人的工作是在需要时帮助它们并治愈它们。例如,养蜂人需要知道何时有一只大黄蜂在蜂箱入口处等待杀死每只从收获珍贵花粉回来的蜜蜂。因为大黄蜂可以保持静止并杀死尽可能多的蜜蜂,而且没有养蜂人愿意在他在家休息时释放成千上万的蜜蜂。而且大黄蜂在法国这个地区并不罕见,幸运的是我们蜜蜂在害怕时会发出特定的频率,这种嘶嘶声大约是 3000 赫兹,所以当一只疯狂的大黄蜂在他们家门口等着准备盛宴时,我们可以知道!使用同样的方法,我们可以知道蜜蜂是否蜂拥而至,以捕捉逃跑的老蜂王并将她放入新的蜂箱中,介于 340 赫兹和 450 赫兹之间

蜜蜂发出的频率并不是我们能从蜂巢中获得的唯一数据,因为蜜蜂能够在蜂巢内保持非常稳定的温度,大约35 摄氏度如果他们的体温变化太大,我们可以判断他们是否健康。重量也是一个重要的数据:我们可以知道蜂箱里蜜蜂和蜂蜜的数量!如果蜂箱每天都越来越重,我们可以根据蜂箱的大小给养蜂人采蜜设定一个阈值。有了所有这些数据,我们还可以更准确地检测到蜂群。

您可能想知道我们将如何获取所有这些信息,因为蜂箱通常位于远离城市的地区和偏远的乡村,那里可以选择 4G,而 Wi-Fi 则更糟。我们将使用 Sigfox 的 LPWAN(低功耗广域网)网络来增加我们的自主权和范围,因为我们不会传输大量数据,只是传输一些传感器的值,而不是实时视频馈送。我们将准时(每 10 分钟)发送一条短消息,其中所有数据都压缩到最小字节数。我们有多种物联网云平台可供选择,但我们选择了 Ubidots,因为它是最直观的,也是养蜂人最容易使用的。

对于这个有趣的项目,我们选择了最有趣的 Arduino 板之一,它具有令人难以置信的能力和多种不同用途的选择。凭借其惊人的 nrf52840 微芯片,您猜对了我们的 Arduino nano 33 BLE Sense!

pYYBAGNYjdaAeg6bAADxrNqk6Wo245.png
Arduino Nano 33 BLE 感知
 

从能量和编程方面来说,它都是一张简单而有效的卡片。事实上,我们能够为我们的代码从 Arduino 上已经存在的公共库中受益,尽管并不总是兼容,因为它与其他 Arduino 略有不同。此外,此卡包含传感器,例如温度、湿度、压力或蓝牙低功耗。谈到蓝牙低功耗,我们选择在我们的项目中实现它,因为它是一个非常酷且方便的功能!但尽管它很酷,但实现起来有点棘手和复杂,我们将在此处向您解释它在我们的项目中是如何工作的:

该协议必须包含如下所示的部分:客户端/中央和服务器/外围设备。

pYYBAGNYjdmAW_fSAADI7xqkc6Q092.png
Arduino官方文档截图
 

中央设备在任何情况下都将是养蜂人的电话,因此他可以从他的蜂巢中实时获取每个传感器值!

我们首先将服务和特征创建为全局变量,以便我们可以全局使用它们。服务是一组传感器和值,因此我们可以轻松找到它们,使用随机创建的 UUID 调用它们。在每个服务中,我们可以找到一些仅代表一个传感器/值的特性。

在我们的原型中,我们只有 2 个服务,即设备信息服务,用于指定有关用于蜂巢的硬件的信息,例如名称、信用和东西。第二个服务是传感器信息,其中包含我们需要的每个传感器值!您可以在下面看到我们如何实施我们的服务和特征!

BLEService optiService("181A");
BLEByteCharacteristic optiStatusCharacteristic(OPTI_CHARACTERISTIC_UUID, BLERead | BLEWrite);
BLEStringCharacteristic tmpCouvCharacteristic(TMP_COUVAIN_CHARACTERISTIC_UUID, BLERead, 20);
BLEStringCharacteristic tmp1Characteristic(TMP_1_CHARACTERISTIC_UUID, BLERead, 20);
BLEStringCharacteristic tmp2Characteristic(TMP_2_CHARACTERISTIC_UUID, BLERead, 20);
BLEStringCharacteristic batCharacteristic(BAT_CHARACTERISTIC_UUID, BLERead, 20);
BLEStringCharacteristic humCouvCharacteristic(HUM_COUVAIN_CHARACTERISTIC_UUID, BLERead, 20);
BLEStringCharacteristic humAmbCharacteristic(HUM_AMBIANT_CHARACTERISTIC_UUID, BLERead, 20);
BLEStringCharacteristic pressionCharacteristic(PRESSION_CHARACTERISTIC_UUID, BLERead, 20);
BLEStringCharacteristic poidsCharacteristic(POIDS_CHARACTERISTIC_UUID, BLERead, 20);
BLEStringCharacteristic freqCharacteristic(Freq_CHARACTERISTIC_UUID, BLERead, 20);

我们选择对它们中的大多数使用 BLEStringCharacteristic,因为我们希望在发送的数据中具有下面显示的传感器名称。我们使用 iOS 上的 LightBlue 应用程序从传感器读取值。它工作得非常好并且非常易于使用。

poYBAGNYjdyAec-MAADXHAy8ba8300.jpg
我们如何在手机上使用 BLE 从蜂巢中获取信息
 

如您所见,如果我们不想学习每个 UUID,那么选择发送字符串是一件非常明智的事情!

这个结果是通过这个初始化获得的:

  • 开始 BLE 并设置本地名称
  • 将每个特征添加到服务中
  • 将服务添加到 BLE
  • 设定值
  • 广告!

然后当我们做广告时,我们只需要定期更新我们的价值观!

此 BLE 功能可以方便地在不上网的情况下检查传感器值,但如果我们想更改 2 次测量之间的延迟(以节省能源),则最有必要。如果您需要有关 BLE 的更多信息,请随时查看官方 Arduino 文档

现在我们将看看我们的传感器,从重量传感器开始!

poYBAGNYjd-AcLXGAAAkVrU6SVY226.png
博世单称重传感器重量传感器
 

蜂箱将被支撑在上面,它的工作方式如下:

poYBAGNYjeGAaWhyAAAMaC3N3Rg154.png
我们的体重传感器的工作方式
 

为了通过我们的微控制器将这些信号转换为可读值,我们将使用 Seeed 制作的 Grove HX711 模块和几个贡献者在github上制作的库

这是我们用来与我们的规模交互的代码。

#include 

HX711 scale;

float Offset = 1936859.00; // Offset pour 66kg

void init_HX711(){
  scale.begin(D6, D5);      // LOADCELL_DOUT_PIN = D7, LOADCELL_SCK_PIN = D6;
  scale.set_scale(Offset);
}

void get_weight(data *data_weight){ //We take as a param a struct with our data
  scale.power_up();               
  delay(3000); // We wait a bit for the scale to initialize
  if(scale.wait_ready_retry(3, 500)){ 
    data_weight->Poids = scale.get_units(5);
    data_weight->Poids = data_weight->Poids * 10;
  } 
  if(data_weight->Poids < 0){
    data_weight->Poids = 0;
  }
  scale.power_down();    // We shutdown the scale to save energy         
}

我们现在可以看看我们的温度探头。我们选择 DS18B20 温度探头安装在蜂箱内,如下图所示:

poYBAGNYjeSAUvFMAAAfkcZcPSw441.png
DS18B20防水探头
 

这些传感器使用 OneWire 协议,这意味着它们只需要一根线来传输数据。如果我们只使用一个传感器,它总共只需要 2 根线:(VCC + Data)和 GND 而不是 VCC、Data 和 GND。尽管这个协议很方便,但不幸的是它并没有在我们的 Arduino 33 BLE Sense 上实现,因为正如之前所解释的,我们的微控制器不是常见的 Arduino Atmel 微控制器,它使用 Mbed,因此并非每个库都与它兼容。幸运的是,我们找到了为我们的董事会制作了一个新图书馆的人这是我们用来从 2 个串联探头中获取温度的代码:

#include <MaximWire.h>

MaximWire::Bus bus(PIN_BUS);
MaximWire::DS18B20 device;
  
void get_DS18B20(data *data_tempCote){
  unsigned short nbr_sensors;
  float temp;

  for(int i=0; i<2; i++){
    nbr_sensors = 1;
    MaximWire::Discovery discovery = bus.Discover();
    do{
      if (nbr_sensors > 2){
        break;
      }
      MaximWire::Address address;
      if (discovery.FindNextDevice(address)){
          if (address.GetModelCode() == MaximWire::DS18B20::MODEL_CODE){
            MaximWire::DS18B20 device(address);
            temp = device.GetTemperature<float>(bus);
            data_tempCote->Temp_cote[nbr_sensors - 1] = temp;
            device.Update(bus);
          }
      nbr_sensors++; //Increase the sensor counter
      } 
    } while (discovery.HaveMore());
  }
}

为了获得亮度级别,我们使用了 LDR04 光敏电阻。随后,我们制作了一个分压桥,以便为我们的光敏电阻提供稳定的值。此外,我们用照度计测试了不同的值,以便找到一个可以根据电压变化为我们提供正确亮度的函数。

poYBAGNYjeaAbvkiAAAKxnBB4Lw264.jpg
光敏电阻LDR04
 

获取亮度的代码:

for(int i=0; i<10; i++){    // average on 10 test
    Vin = analogRead(A7);   // between 0 to 1023
    Vin = Vin * (3.3/1023.0);
    R0 = (R1*3.3/Vin) - R1;
    temp = 500/(R0/1000);
    Lumen += temp;
}
// we get the value in Lumen

对于蜂巢内的湿度和温度,我们使用 DHT22 传感器。DHT22(或AM2302)通过串口与微控制器通信,所以有一个库,使用起来比较容易。

poYBAGNYjeiAJiXTAAAwU6nWwS8650.png
DHT22
 

使用 DHT22 的代码:

void get_DHT22(data *data_DHT){
    data_DHT->Temp_couvain = dht.readTemperature();
    data_DHT->Humi_couvain = dht.readHumidity();
}

现在我们已经看到了我们所有的传感器,让我们来看看我们的微控制器。

所有这些都需要电力,我们通过太阳能获得。我们使用太阳能电池板和电池。

poYBAGNYjeuAYGj9AAAXxHru2Rc230.png
2W太阳能电池板
 
poYBAGNYje2ALVyFAAAWS400GpM248.png
Accu 锂离子电池 1050mAh
 

我们使用 Seeed LiPo Rider Pro,它能够将从太阳能电池板获得的能量存储在我们之前展示的电池中。它在测试时也非常方便,因为我们可以使用 USB 为我们的威廉希尔官方网站 板供电,并通过 4 个 LED 显示剩余的电池电量。

pYYBAGNYje-ASBZiAAAZBZKapAk002.png
Seeed LiPo Rider Pro
 

我们选择的电池虽然便宜,但效率不高,所以我们必须尽可能多地节省电力。为此,我们不会使用它可以提供的 LiPo Rider 的 5V,因为我们有一个 3.3V 供电板,需要有一个稳压器(已经内置)将 5V 转换为 3.3V,这会消耗大量电力。

取而代之的是,我们将使用一个几乎不消耗电流并提供稳定的 3.3V 电压的常规电压,此外我们可以将其关闭。能够关闭 3v3 非常方便为传感器供电,这样我们将有2 个电压调节器,一个始终打开为威廉希尔官方网站 板供电,另一个可以禁用以关闭传感器,这样它们就不会在同时消耗电流我们不使用它们(因为我们每个传感器每 10 分钟只取一个值)。

最后是最重要的 Sigfox 模块,它允许我们使用无线电波发送值。

poYBAGNYjfKAITPEAAA8kzviEFM217.png
分线 Sigfox BRKWS01-RC1 + 天线 868Mhz
 

为了使每个组件一起工作,我们使用我们自己的 PCB 制造机打印了一个 PCB(在项目描述中)。

 

poYBAGNYjfWAK2EnAAI6AzhlADc034.png
印刷威廉希尔官方网站 板
 

 

一切都组装好后,我们制作了电缆和盒子防水。我们还为电池制造了一个护套来保护它。一切都是固定的,以抵抗养蜂人的处理、风和雨。我们添加了一个开关,以便更容易地关闭和打开设备。

poYBAGNYjfqAKeYQAArI1VG7lGU310.jpg
设备完成顶视图
 
poYBAGNYjgmAecKqAA3hkXPVJHY380.png
设备成品视角
 

为了最大限度地保护我们的设备,我们添加了一些“potit pieds”。它保存它在下雨天在泥泞中。

poYBAGNYjg2ADuMAAAFgrOK8TYs476.jpg
设备脚
 

为了从 Sigfox 到 Ubidot 获取值,我们使用了 Sigfox 的后端,明智地选择我们的回调,我们能够为我们拥有的每个传感器发送足够的数据。在 Ubidot 上,我们解密已压缩的值以作为 32 字节消息发送。我们通过简单的界面获得漂亮图形的所有价值。

pYYBAGNYjhCAa7ZPAADrsogKpD8677.png
 
poYBAGNYjhOANfeFAALl7hrTS5I447.png
Ubidot上的数据示例
 

 


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

评论(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:'使用Arduino 33 BLE Sense的蜂巢监视器',//标题 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);