资料介绍
描述
如果你有一只物联网宠物,它会吃什么?当然是 WiFi SSID!
Nerd 是一种无线电子宠物,通过收集 WiFi SSID 以及一些休息和阳光来生存。为了让它茁壮成长,你必须平衡离线和在线模式以及明暗,以确保它有一个适当的日常饮食 - 睡眠 - 书呆子例程。如果它长时间没有连接 WiFi,它会使用其内置的压电扬声器以摩尔斯电码发送 SOS。脱机时间越长,蜂鸣声越多。
简而言之
Nerd 每半小时醒来一次,扫描它周围的网络。如果它检测到新网络,它将存储它们并以低功耗模式返回睡眠状态(以节省电池寿命)。否则它会通过蜂鸣器发出噪音来抱怨,直到你喂它或把它放在黑暗中。它还会通过连接到您的 wifi 网络了解它何时在家。当在家时,书呆子将能够连接到互联网并获取当前时间和日期。如果超过两天不喂食,它会急剧死亡,发出很大的声音。
成分
学习目标
- 管理完整的 WiFi 功能
- 在闪存中存储数据
- 管理时间和实时时钟
- 管理低功耗模式
想知道更多?
本教程是让您熟悉 MKR1010 和物联网的一系列实验的一部分。所有实验都可以使用 MKRIoTBundle 中包含的组件来构建。
- 带 MKR WiFi 1010 的我爱你枕头
- 带 MKR WiFi 1010 的拼图盒
- 巴甫洛夫的猫与 MKR WiFi 1010
- 带 MKR WiFi 1010 的书呆子
- 带 MKR WiFi 1010 的工厂通讯器
设置董事会
为了实现所有功能,我们将使用以下库:
- WiFiNINA //连接到互联网并扫描网络
- FlashStorage // 保存值,这样它们就不会在每次重启时被删除
- RTCZero // 管理时间触发事件
- ArduinoLowPower // 节省电池电量
- WiFiUdp // 从互联网获取时间和日期
您可以按照本指南中的说明从库管理器下载它们。
扫描 WiFi 网络
书呆子渴望网络!扫描网络非常简单,只需上传此示例草图或转到> 示例 > WiFiNINA > ScanNetworksAdvanced以获得更扩展的版本。
#include#includevoidsetup(){//Initialize serial and wait for port to open:Serial.begin(9600);while(!Serial) {;// wait for serial port to connect. Needed for nativeUSBport only}// scan for existing networks:Serial.println();Serial.println("Scanning available networks...");listNetworks();}voidloop(){delay(10000);// scan for existing networks:Serial.println("Scanning available networks...");listNetworks();}voidlistNetworks(){// scan for nearby networks:Serial.println("** Scan Networks **");intnumSsid =WiFi.scanNetworks();if(numSsid ==-1){Serial.println("Couldn't get a WiFi connection");while(true);}// print the list of networks seen:Serial.print("number of available networks: ");Serial.println(numSsid);// print the network number and name for each network found:for(intthisNet =0; thisNet < numSsid; thisNet++) {Serial.print(thisNet +1);Serial.print(" SSID: ");Serial.println(WiFi.SSID(thisNet));Serial.flush();}Serial.println();}
在闪存中存储值
你肯定不希望 Nerd 每次没电时都死掉!为了避免这种行为,我们将在闪存中保存一些变量(如食物量),以便即使在电路板转动后也可以检索它们关闭并再次打开。您可以通过以下方式了解基本功能:
示例 > FlashStorage > FlashStoreAndRetrieve
我们将保存网络的名称,以便 Nerd 只吃一次,我们还将使用保存这些 SSID 的数组来计算它白天吃的食物量。保存在闪存中的值将保留下来重置电路板但不上传新草图。每次上传新草图时,闪存也会被清空。此草图将扫描网络并将 SSID 保存在闪存中。
#include#include#include#defineMAGIC_NUMBER 0x7423// arbitrary number to double check the saved SSID#defineMaxNet 30// max amount of network to be savedintPosToBeSaved =0;// Variable used to navigate the array of networksintdaily_amount_of_food =12;// The amount of food per day needed to survive// Struct of variable to be saved in flash memorytypedefstruct{intmagic;booleanvalid[MaxNet];charSSIDs[MaxNet][100];} Networks;FlashStorage(my_flash_store, Networks);Networks values;voidsetup(){Serial.begin(115200);while(!Serial);// wait until the Serial montior has be openeddelay(2000);values = my_flash_store.read();if(values.magic == MAGIC_NUMBER) {// If token is correct print saved networksSerial.println("saved data:");Serial.println("");for(inta =0; a < MaxNet; a++) {if(values.valid[a]) {Serial.println(values.SSIDs[a]);}else{PosToBeSaved = a;}}}}voidloop(){//Temporarly save the number of networksintnetworks_already_saved = PosToBeSaved;getNetwork();if(PosToBeSaved >= daily_amount_of_food) {Serial.println("Enough food for today");}delay(5000);}// Feed the Nerd with networks's SSIDvoidgetNetwork(){// scan for nearby networks:Serial.println("\n*Scan Networks*\n");intnumSsid =WiFi.scanNetworks();delay(1000);if(numSsid ==-1) {Serial.println("There are no WiFi networks here..");}else{Serial.print("number of available networks: ");Serial.println(numSsid);// print the network number and name for each network found:for(intthisNet =0; thisNet < numSsid; thisNet++) {Serial.print("SSID: ");Serial.println(WiFi.SSID(thisNet));delay(500);char* net =WiFi.SSID(thisNet);boolcanBeSaved =true;// check if the network has already been savedfor(inta =0; a < PosToBeSaved ; a++) {if(values.valid[a]) {if(strncmp(net, values.SSIDs[a],100) ==0|| strnlen(net,100) ==0) {Serial.println("Not saved");canBeSaved =false;}}}// Store ssid nameif(canBeSaved && PosToBeSaved < MaxNet) {if(strlen(net) +1<100&&strlen(net) >0) {memset(values.SSIDs[PosToBeSaved],0,sizeof(values.SSIDs[PosToBeSaved]));// set all charactersto zeromemcpy(values.SSIDs[PosToBeSaved], net,strlen(net) +1);// copy "net" to values.SSDs[thisNet]values.valid[PosToBeSaved] =true;values.magic = MAGIC_NUMBER;my_flash_store.write(values);Serial.println(String(values.SSIDs[PosToBeSaved]) +" saved in position "+String(PosToBeSaved));PosToBeSaved ++;}else{Serial.println(" network skipped");}}}}}
请注意我们如何定义可以保存的最大网络数量,以避免内存空间问题:
#define MaxNet30intPosToBeSaved =0;
已用于导航保存网络名称的数组并测量已经吃掉的食物量。
管理时间
我们可以将实时时钟 (RTC) 的功能与 WiFi 相结合,以获取当前时间和日期,然后设置电路板的内部时钟。通过这种方式,我们可以在很长一段时间内触发基于时间的事件,而无需使用millis()
将毫秒转换为天时可能会很棘手的功能。我们将从网络时间协议(NTP) 时间服务器获取时间,然后设置 RTC用它。请注意,收到的时间采用纪元格式,即自 1970 年 1 月 1 日以来的秒数。您可以从示例 > WiFiNINA> WiFiUdpNtpClient运行基本草图在下面的草图中,我们将所有内容放在一起:扫描网络功能和时间相关的。
bool atHome = false;
用于触发 WiFi 连接,因此请求服务器获取时间。check_home()
用于扫描所有可用网络,并查看其中一个是否是家庭 WiFi 网络。connect_WiFi()
然后调用,它会将开发板连接到 WiFi,触发对服务器的请求并打印当前时间。rtc.setEpoch(epoch + GMT);
用于以纪元格式的当前时间启动 RTC,修改 GMT 变量以将时间调整为您当前的时区。
#include#include#include#defineMAGIC_NUMBER 0x7423// arbitrary number to double check the saved SSID#defineMaxNet 30// max amount of network to be savedintPosToBeSaved =0;// Variable used to navigate the array of networksintdaily_amount_of_food =12;// The amount of food per day needed to survive// Struct of variable to be saved in flash memorytypedefstruct{intmagic;booleanvalid[MaxNet];charSSIDs[MaxNet][100];} Networks;FlashStorage(my_flash_store, Networks);Networks values;voidsetup(){Serial.begin(115200);while(!Serial);// wait until the Serial montior has be openeddelay(2000);values = my_flash_store.read();// Read values from flash memoryif(values.magic == MAGIC_NUMBER) {Serial.println("saved data:");Serial.println("");for(inta =0; a < MaxNet; a++) {if(values.valid[a]) {Serial.println(values.SSIDs[a]);}else{PosToBeSaved = a;}}}}voidloop(){// Temporarly save the number of networksintnetworks_already_saved = PosToBeSaved;getNetwork();if(PosToBeSaved >= daily_amount_of_food) {Serial.println("Enough food for today");}delay(5000);}// Feed the Nerd with networks's SSIDvoidgetNetwork(){// scan for nearby networks:Serial.println("\n*Scan Networks*\n");intnumSsid =WiFi.scanNetworks();delay(1000);if(numSsid ==-1) {Serial.println("There are no WiFi networks here..");}else{Serial.print("number of available networks: ");Serial.println(numSsid);// print the network number and name for each network found:for(intthisNet =0; thisNet < numSsid; thisNet++) {Serial.print("SSID: ");Serial.println(WiFi.SSID(thisNet));delay(500);char* net =WiFi.SSID(thisNet);boolcanBeSaved =true;// check if the network has already been savedfor(inta =0; a < PosToBeSaved ; a++) {if(values.valid[a]) {if(strncmp(net, values.SSIDs[a],100) ==0|| strnlen(net,100) ==0) {Serial.println("Not saved");canBeSaved =false;}}}// Store ssid nameif(canBeSaved && PosToBeSaved < MaxNet) {if(strlen(net) +1<100&&strlen(net) >0) {memset(values.SSIDs[PosToBeSaved],0,sizeof(values.SSIDs[PosToBeSaved]));memcpy(values.SSIDs[PosToBeSaved], net,strlen(net) +1);values.valid[PosToBeSaved] =true;values.magic = MAGIC_NUMBER;my_flash_store.write(values);Serial.println(String(values.SSIDs[PosToBeSaved]) +" saved in position "+String(PosToBeSaved));PosToBeSaved ++;}else{Serial.println(" network skipped");}}}}}
实现当前时间允许我们使用像这样的简单函数来管理 Nerd 的生死:
if(rtc.getEpoch() - values.last_time_fed >=86400*2){// complain and eventually die :(}
其中86400
是一天中的秒数, 是书呆子最后一次被喂食的纪元格式values.last_time_fed
时间的存储值,并以纪元格式返回当前时间。rtc.getEpoch()
低功耗模式
我们可以使用低功耗模式让我们的电路板进入睡眠状态。这意味着它将禁用大部分功能(包括 WiFi)以节省电池电量。由于我们希望书呆子定期醒来,我们可以轻松设置一个计时器:
#include"ArduinoLowPower.h"intsleeping_time =5000;// 5 secondsboolawake =true;voidsetup(){Serial.begin(9600);LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, WakeUp, CHANGE);pinMode(LED_BUILTIN,OUTPUT);}voidloop(){if(awake) {digitalWrite(LED_BUILTIN,HIGH);delay(500);digitalWrite(LED_BUILTIN,LOW);delay(500);}awake =false;Serial.println("going to sleep");LowPower.sleep(sleeping_time);}voidWakeUp(){Serial.println("awake");awake =true;}
请注意,该WakeUp()
函数附加到中断,这意味着它不能包含任何包含延迟的代码。但是我们可以设置 s 布尔变量 so 来触发循环中的事件。
- MKRWiFi1010+MKRRS 485 Shield连接到Ignition0次下载
- 使用ArduinoMKR1000通过WiFi进行HID攻击0次下载
- 带Arduino IoT捆绑包的书呆子0次下载
- 使用ArduinoMkrWifi1010和Thincloud构建连接灯的过程1次下载
- 带有ArduinoMKR1010和MKRRGB Shield的Otto Biped0次下载
- 将MQTT协议物联网与ArduinoMKR1010WiFi结合使用0次下载
- 我爱你枕头与MKRWiFi1010开源分享0次下载
- 带有MKRWiFi1010的植物通讯器0次下载
- 使用Grove Sensor的ArduinoMKR1010和阿里云IoT0次下载
- GBU1010-ASEMI规格书英文版下载0次下载
- KBU10005-THRU-KBU1010规格书0次下载
- KBJ10005-THRU-KBJ1010规格书3次下载
- 基于ITM-MKR680Temperature Sensing的参考设计11次下载
- 基于ITM-MKR680Temperature Sensing的参考设计2次下载
- 数据处理有9大编程语言详细资料介绍3次下载
- 如何制造世界上最小的三电子管收音机764次阅读
- 什么是wifi6,与wifi2.4g和wifi5g有什么区别5.1w次阅读
- 比WIFi快100倍的LIFI,什么时候会取代WIFI2450次阅读
- MKRVidor 4000一款拇指型的FPGA开发板1086次阅读
- 什么是2.4GWIFI什么是5GWiFi3.5w次阅读
- 简评FPGA——ArduinoMKRVidor 40006596次阅读
- 细说WiFi信号与路由器和WiFi模块的关系1.2w次阅读
- 了解机器学习算法的类别,把握对问题的认识层次619次阅读
- wifi探针技术的应用领域_公安局wifi探针用途2.3w次阅读
- wifi探针是什么_wifi探针的工作原理详解4.4w次阅读
- wifi模块异常是怎么回事_wifi模块异常怎样解决6.8w次阅读
- 手机wifi模块在哪里_手机wifi模块位置图解13.5w次阅读
- 双频wifi是什么意思_双频wifi的优点2.7w次阅读
- 高通双通路WiFi技术帮你解决家庭WiFi信号差的问题4144次阅读
- WiFi信号是怎样传播的?1.2w次阅读
下载排行
本周
- 1山景DSP芯片AP8248A2数据手册
- 1.06 MB |532次下载 |免费
- 2RK3399完整板原理图(支持平板,盒子VR)
- 3.28 MB |339次下载 |免费
- 3TC358743XBG评估板参考手册
- 1.36 MB |330次下载 |免费
- 4DFM软件使用教程
- 0.84 MB |295次下载 |免费
- 5元宇宙深度解析—未来的未来-风口还是泡沫
- 6.40 MB |227次下载 |免费
- 6迪文DGUS开发指南
- 31.67 MB |194次下载 |免费
- 7元宇宙底层硬件系列报告
- 13.42 MB |182次下载 |免费
- 8FP5207XR-G1中文应用手册
- 1.09 MB |178次下载 |免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB |234315次下载 |免费
- 2555集成电路应用800例(新编版)
- 0.00 MB |33566次下载 |免费
- 3接口电路图大全
- 未知 |30323次下载 |免费
- 4开关电源设计实例指南
- 未知 |21549次下载 |免费
- 5电气工程师手册免费下载(新编第二版pdf电子书)
- 0.00 MB |15349次下载 |免费
- 6数字电路基础pdf(下载)
- 未知 |13750次下载 |免费
- 7电子制作实例集锦 下载
- 未知 |8113次下载 |免费
- 8《LED驱动电路设计》 温德尔著
- 0.00 MB |6656次下载 |免费
总榜
- 1matlab软件下载入口
- 未知 |935054次下载 |免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB |537798次下载 |免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 |420027次下载 |免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB |234315次下载 |免费
- 5Altium DXP2002下载入口
- 未知 |233046次下载 |免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 |191187次下载 |免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M |183279次下载 |免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 |138040次下载 |免费
评论
查看更多