树莓派可以网络安装了—— Beta版正在公测

大部分时候,我们都是用另一台计算机(比如运行 Raspberry Pi Imager写入镜像)来给树莓派装系统的。

但是,如果你一开始没有PC,如何将操作系统安装到 SD 卡上呢?

这是经典的先有鸡还是先有蛋的问题,我们刚刚解决了它。

新的网络安装程序正在运行

现在有一个实现网络安装的 Raspberry Pi 引导加载程序beta 版本,我们希望你能帮助我们对其进行测试。

新的网络安装功能可直接在 Raspberry Pi 4 或 Raspberry Pi 400 上启动Raspberry Pi Imager应用程序,方法是:先用以太网电缆从 Internet 下载它。

Raspberry Pi Imager 应用程序将在你的 Raspberry Pi 内存中运行,然后把操作系统写入空白 SD 卡或 USB 磁盘,就像平常一样。

如何使用网络安装程序

如果你想试用这个网络安装程序,首先必须安装bootloader的测试版。

对于当前已经上市的电路板,需要更新bootloader。

不过一旦测试期结束,我们最终将在树莓派出厂时直接安装新的网络引导加载程序,不再需要此步骤。

安装新的 beta 引导加载程序

在 Raspberry Pi 4 或 400 上更新bootloader最简单方法是在 Raspberry Pi 或另一台计算机上运行Raspberry Pi Imager,将所需的软件复制到 SD 卡上。

你需要一张备用的空白 SD 卡,如果你使用的是 Raspberry Pi 或另一台没有 SD 卡插槽的计算机,则需要一个 USB to SD转接头。

你应该知道,用于更新 Raspberry Pi 引导加载程序的 SD 卡将被擦除所有现有数据,因此不要将有重要数据的 SD 卡装在当前Raspberry Pi上 。

在 Imager 应用程序中,单击“选择操作系统”按钮并在弹出窗口中向下滚动“操作系统”列表。选择“Misc utility images”,然后选择“Beta Test Bootloader”。

选择新的 Beta 测试引导加载程序

接下来,你需要选择引导顺序。

所有选项相同,但启动顺序不同。有其他理由,否则应该选择“SD Card Boot”。

选择引导顺序

然后按照正常说明将更新的引导加载程序写入 SD 卡。

当 SD 卡完成写入后,你应该关闭 Raspberry Pi 并移除现有的 SD 卡并将其放在安全的地方。

将刚用 Imager 应用程序写过的卡插入 Raspberry Pi 并重新打开电源。板子 LED 会定期闪烁,屏幕会变绿,表示新的 beta 版本引导加载程序成功启动。

如果你想将引导加载程序恢复到“Release”版本,可以再次执行这些步骤,选择顶部的“引导加载程序”选项而不是“Beta 测试引导加载程序”选项。

现在移除你的引导加载程序更新 SD 卡并重启树莓派。

尝试网络启动

现在你已经更新了引导加载程序,一切应该和以前一样工作。

当 Raspberry Pi 启动时,引导加载程序会搜索要加载的软件。它首先查找 SD 卡,然后查找 USB 记忆棒,依此类推。

它会一直循环下去,直到找到要使用的软件。几秒钟后,你会在屏幕上看到一个诊断信息,告知它正在做什么。

如果你想插入原来的 SD 卡(你在这一切开始之前使用的那个),你的 Raspberry Pi 应该会像往常一样无缝地引导回操作系统。

如果你在插槽中没有 SD 卡或使用空白 SD 卡的情况下启动 Raspberry Pi,并且连接了键盘,那么你现在会看到一些不同的东西。

如果你连接了键盘(Raspberry Pi 400 总是如此),但 Raspberry Pi 无法找到操作系统,它将显示新的网络安装界面。

新的网络安装界面


在后台,你的 Raspberry Pi 仍在寻找可运行的操作系统。但是此时,你可以通过按住该Shift键三秒钟来启动网络安装过程。在出现提示时按确认你要继续按Space,它应该会要求你插入以太网电缆。

你将需要通过以太网电缆将 Raspberry Pi 物理连接到路由器,而不是将其连接到无线网络。你需要一根两端都有公头 RJ45 连接器的以太网电缆。大多数家用路由器的背面都有网口,可让你插入以太网电缆,因此将电缆的一端插入路由器,另一端插入树莓派。

记得插网线

当它检测到已插入电缆时,它会自动下载 Raspberry Pi Imager。如果下载失败,你可以重复该过程。

安装 Raspberry Pi Imager

最终,Raspberry Pi Imager 应用程序在树莓派上启动,允许你将完整的操作系统安装到新的空白 SD 卡或 USB 记忆棒上。

如果你还没有这样做,此时应该将另一张空白 SD 卡插入 Raspberry Pi 卡槽。Raspberry Pi Imager 允许你直接从 Internet 烧录系统。

系统装好后不会在启动时看到网络安装界面。如果还想运行它,只需要删除所有可启动磁盘,等 Raspberry Pi Imager 运行再重新插入它们。但注意不要覆盖任何有重要工作内容的磁盘!

Jupyter怎么装到Rocky Linux 8上

Jupyter是Python数据分析的一个重要工具,除非你对图表没什么要求,或者习惯了命令行。否则大多会用到这个工具。

Rocky Linux是红帽家族的一个开源免费发行版。两者加到一起,就是一个字:稳。

首先,你可以用Root用户登录。然后执行如下命令:

jupyter notebook --generate-config

生成配置文件,程序会提醒你配置文件保存在哪里的。

比如我这里是:

/root/.jupyter/jupyter_notebook_config.py

然后,编辑这个配置文件。

第一步,让Jupyter可以远程访问,因为默认都是localhost Only。

c.NotebookApp.ip = ‘*’

第二步,让Jupyter换个端口,这个看自己,不是必选项。

c.NotebookApp.port = 8888

改完配置文件后,还得设置Jupyter需要密码登录,不然你的小秘密都被人看光光了。

执行:

jupyter notebook password

敲两遍密码,成功。密码文件会保存在这里。

/root/.jupyter/jupyter_notebook_config.json

最后执行:

jupyter notebook –allow-root

就可以启动Jupyter了。

我是王文文,欢迎关注IoT前哨站和我交流。

树莓派挖矿教程之Chia篇

随着数字货币的兴起,不少人又开始了挖矿生涯。

除了经典的显卡和CPU挖矿以外,其实业内还有一种硬盘挖矿的方法。这就是号称“绿色比特币”的Chia。

目前的价格大概是4500-5500RMB一枚。

它倒是不怎么耗电,但很耗硬盘。所以你接个树莓派也可以挖。

基本配置:

树莓派4B(至少4GB内存版本)

64位系统(不一定要RaspberryPi OS)

大容量硬盘一块

步骤:

先到chia.net下载工具。

找到树莓派的版本,目前官方测过的主要就是树莓派4B。

直接安装或者下载后安装都可以。

安装完启动该程序。

别忘了24个助记词。

把P好的文件导入。当然,如果你不嫌慢,在树莓派上生成Plots也可以。

如果硬盘挂载顺利,可以看到现成的Plot文件。

导入以后你可以在标签栏里看到它们。

在网络同步完成之后,你就可以开始挖了。

Chia挖矿的入门,就是这么简单。

如何让树莓派Pico支持LoRaWAN

LoRaWAN是由LoRa联盟推出的一个低功耗广域网规范,这一技术可以为电池供电的无线设备提供区域、国家甚至全球的网络。

它瞄准了物联网中的一些核心需求,比如安全的双向通讯、移动化和本地服务。该技术无需复杂配置,即可以让智能设备实现无缝的互操作,给物联网领域的用户、开发者和企业自由操作权限。

使用合理的LoRa天线,你可以通过网关将电池供电的传感器连到互联网,信号覆盖半径大约15公里。缺点是可用带宽将以字节为单位,而不是以兆字节甚至千字节为单位。

一个Adafruit RFM95W LoRa无线电装置连接到树莓派Pico

Arduino LoRa库的作者Sandeep Mistry为树莓派Pico搞定了LoRa和以太网支持。

目前他的库能让Semtech SX1276无线电模块更好的工作在Pico和其它RP2040芯片的开发板上。

当然,这意味着像Adafruit的RFM95W、LoRa FeatherWing这样的模块,也可以获得很好的支持。

LoRaWAN覆盖情况

要使用LoRaWAN启用的Pico,你(的设备)需要在LoRa网关覆盖的范围内。幸运的是,有一个名叫“The Things Network”的LoRaWAN网络,它几乎覆盖全球。

关于The Things Network的视频:

https://mp.weixin.qq.com/s/GIPuEb6qQMOmHcPDRXmF9A

这取决于你当前所处的地理位置,很可能你已经在覆盖范围内了。比如英国境内的LoRa网络情况(如图)。

一个LoRaWAN基站的成本在几千美元的日子已经一去不复返了。现在你可以花75英镑买个LoRa网关。

注:The Things Network 是 LoRaWAN 行业里著名的 Network Server 提供方,许多国外的厂家,都是默认连接 TTN 的平台。

作为 LoRa 联盟董事会成员,TTN 现在已经在全球90多个国家和地区部署了3000多个基站,这个数字还在飞速增长中。TTN一直秉承的 “Let’s build this thing together”的开放文化也吸引了超过3万名开发者加入 TTN 社区。

获取源码

如果你已经设置并可以使用树莓派Pico工具链,请确保你的 pico-sdk 是最新的。如果没有,你应该首先设置C/C++ SDK,然后再从GitHub中获取项目。

$ git clone --recurse-submodules https://github.com/sandeepmistry/pico-lorawan.git

$ cd pico_lorawan

PICO_SDK_PATH 在继续操作之前,请确保做好设置。举例来说,如果你要在一个树莓派上构建相关应用,你要先运行 pico_setup.sh 脚本,或者按照我们的指示入门指南。

先设置好环境变量。

$ export PICO_SDK_PATH = /home/pi/pico/pico-sdk

之后,你可以准备构建库和示例应用程序。但是在执行此操作之前,我们需要做另外两件事:在要存储数据的云基础架构上进行配置,并将LoRa无线电模块连接到Raspberry Pi Pico。

设置一个应用程序

The Things Network 目前正在从V2迁移到V3堆栈。由于我的家庭网关是几年前设置的,因此我仍在使用V2软件,尚未迁移。

因此,我将构建一个V2风格的应用程序。但如果你用公共网关或自己构建网关,则可构建V3样式的应用程序。

同理,你可以根据下面的内容逐步完成操作。请注意,对于新的V3堆栈,有一个单独的网络控制台,外观可能有所不同。

地址:https://account.thethingsnetwork.org/users/authorize?client_id=ttn-console&redirect_uri=https:%2F%2Fconsole.thethingsnetwork.org%2Foauth%2Fcallback&response_type=code&state=_wyzCpGx9A

当新网关覆盖范围内的任何LoRa设备将其数据包接收和发送到上游的“The Things Network”时,除非数据包有其它地方可去,否则数据包将被丢弃。换句话说,“The Things Network”需要知道网关接收的数据包路由到哪里。

为了提供此信息,我们首先需要在The Things Network Console中创建一个应用程序 。

然后你需要做的就是输入唯一的Application ID字符串(可以是任何内容)。控制台将生成一个Application EUI和一个默认的Access Key,我们将通过它们,将设备注册到我们的应用程序中。

一旦我们注册了应用程序,我们要做的就是将单个设备(以后可能有多个设备)注册到该应用程序,以便后端知道从该设备路由数据包的位置。

注册设备

可以从控制台的应用程序页面注册我们的设备。

设备ID是易于识别的字符串,用于标识我们的远程设备。

由于Adafruit的RFM9W功能板在包装袋中有像无线入网号那种唯一标识符的贴纸,因此我们可以使用它在字符串后附加以唯一地标识我们的树莓派Pico,因此最终得到类似pico-xy-xy-xy-xy-xy-xy的设备ID名称。

我们还需要生成一个Device EUI2,这是一个64位的唯一标识符。这里我们同样可以使用标签上的唯一标识符,只不过这次我们可以用两个前导零 0000xyxyxyxyxyxyxy填充它,以便生成我们的Device EUI。你也可以使用pico_get_unique_board_id()来生成Device EUI。

相关链接:https://github.com/sandeepmistry/pico-lorawan/blob/main/examples/default_dev_eui/main.c

如果你要在注册后查看“设备”页面,则需要设置Application EUI 2Application Key 2来让开发板与LoRa网络通信。准确地说,是让网络正确地将数据包从你的开发板路由到你的应用程序。

在面包板上接线

现在我们已经设置了云后端,接下来需要做的是将Pico连接到LoRa扩展板。不幸的是,RFM95W breakout 与面包板的连接并不友好 —— 比如这个项目,需要访问电路板两侧的无线电引脚。在这种情况下,板子的分接头宽度有点太大了(对于标准面包板而言)。

幸运的是,这并不是什么大问题,但是你需要准备一束公对母跳线以及面包板。继续接通RFM95W模块和Raspberry Pi Pico。接线板上的引脚和你的Pico之间的映射应该如下所示:

PicoRP20401SX1276 ModuleRFM95W Breakout
3V3 (OUT)VCCVIN
GNDGNDGNDGND
Pin 10GP7DIO0G0
Pin 11GP8NSSCS
Pin 12GP9RESETRST
Pin 14GP10DIO1G1
Pin 21GP16 (SPI0 RX)MISOMISO
Pin 24GP18 (SPI0 SCK)SCKSCK
Pin 25GP19 (SPI0 TX)MOSIMOSI
物理引脚,RP2040引脚,SX1276模块和RFM95W扩展板之间的映射
注:这些引脚是库的默认引脚,可以在软件中更改。

构建和部署软件

现在,我们已经在云上建立了后端,并且我们已经物理上“构建”了无线电,我们可以构建和部署LoRaWAN应用程序。该库提供的示例应用程序之一将从RP2040微控制器上的传感器读取温度,并通过LoRaWAN无线电将其定期发送到你的Things Network应用程序。

void internal_temperature_init() {
    adc_init();
    adc_select_input(4);
    adc_set_temp_sensor_enabled(true);
}

float internal_temperature_get() {
    float adc_voltage = adc_read() * 3.3f / 4096;
    float adc_temperature = 27 - (adc_voltage - 0.706f) / 0.001721f;

    return adc_temperature;
}

继续,进入签出的otaa_temperature_led示例应用程序目录。这个例子用到了OTAA,所以我们需要Device EUI,Application EUI和Application Key。

$ cd examples/otaa_temperature_led/

打开config.h文件,在你喜欢的编辑和更改REGION,DEVICE_EUI,APP_EUI,并APP_KEY在网络控制台中显示的值。该代码期望使用(默认)字符串格式,十六进制数字之间没有空格,而不是字节数组表示形式。

在你喜欢的编辑器中打开config.h文件,并将REGION、DEVICE_EUI、APP_EUI和APP_KEY更改为网络控制台中显示的值。该字符串默认是中间没有空格的十六进制数字,而不是字节数组。

#define LORAWAN_REGION          LORAMAC_REGION_EU868
#define LORAWAN_DEVICE_EUI      "Insert your Device EUI"
#define LORAWAN_APP_EUI         "Insert your Application EUI"
#define LORAWAN_APP_KEY         "Insert your App Key"
#define LORAWAN_CHANNEL_MASK    NULL

我当前位于英国,LoRa广播频率为868MHz。

因此我要将区域设置为LORAMAC_REGION_EU868。

如果你在美国,则使用915MHz,因此需要将区域设置为LORAMAC_REGION_US915。

编辑config.h文件之后,就可以继续构建示例应用程序了。

$ cd ../..
$ mkdir build
$ cd build
$ cmake ..
$ make

如果一切顺利的话,你应该有一个UF2文件在build/examples/otaa_temperature_led/的目录,名字是pico_lorawan_otaa_temperature_led.uf2

现在,你可以按照常规方式将此UF2文件加载到树莓派Pico上。

先接好你的Raspberry Pi Pico开发板和Micro USB电缆,然后再将电缆的另一头插入有集成开发环境的电脑,按住Pico上的BOOTSEL按钮。插入后,松开按钮。

桌面上将会弹出一个名为RPI-RP2的磁盘。

双击将其打开,然后将UF2文件拖放到里面。如果遇到问题,请参阅《入门指南》第4章以 获取 更多信息。

Pico现在将运行LoRaWAN应用程序,如果需要,可以通过打开与Pico的USB串行连接来查看一些调试信息。打开终端窗口并启动 minicom

$ minicom -D /dev/ttyACM0

传送资料

但是,你需要转向Network控制台来查看真实的信息。你应该能看到一个初始连接消息,后面跟着一些帧。每一帧代表一个温度测量值通过LoRaWAN网关,从你的Pico发送到The Things Network网络应用。

有效负载值是Raspberry Pi Pico内部温度传感器以十六进制形式测得的温度。

这有点超出本文的讨论范围,但是你现在可以添加一个解码器和集成功能,使你可以将数据从十六进制解码为人类可读的数据,然后将其保存到数据库中。

为了说明你可以在此处执行的操作的强大功能,请转到应用程序的“有效载荷格式”标签,然后在“解码器”框中输入以下Javascript,然后向下滚动并点击绿色的“保存有效载荷功能”按钮。

function Decoder(bytes, port) {
 
  var decoded = {};
  decoded.temp = bytes[0];
  
  return decoded;
}

返回“数据”选项卡,你应该看到现在以十六进制表示的有效负载已经以摄氏温度为后缀。我们的简单解码器已将有效负载提取并将其转换回Javascript对象。

发送命令

除了发送温度数据之外,该示例应用程序还让你可以直接从The Things Network控制台切换Raspberry Pi Pico上的LED。

进入网络控制台的设备页面,在Downlink Payload框中输入“01”,并点击“发送”按钮。然后切换到Data选项卡。你应该会看到一个“Download scheduled”行,如果继续观察,你应该会看到下行的字节。

当这种情况发生时,你树莓派Pico上的LED应该会亮起!返回网络控制台并在有效载荷箱中输入“00”将(最终)关闭Pico的LED。

请记住,LoRaWAN是远程的,但带宽很低。你不要期望下行命令能即时响应。

接下来还有什么

OTAA示例应用程序是一个非常好的框架,你可以在此基础上构建它,它允许你获取数据并通过LoRa将其发送到云端,还可以从云端向支持LoRa的Pico发送命令。

地址:https://github.com/sandeepmistry/pico-lorawan/tree/main/examples/otaa_temperature_led

小结

可以在树莓派论坛上找到对Pico开发的支持。还有一个(非官方的)Discord频道,很多活跃在社区的人似乎都在那里玩。

地址:https://discord.com/invite/avzEvd6Euv

关于文档的反馈应该作为一个问题发布到GitHub上的pico-feedback仓库,或者直接发布到它关注的相关仓库。

所有的文档,以及其他帮助和链接,都可以在入门页面上找到。

如果你不知道未来它在哪里,你总是可以从你的Pico找到它。如果你要访问相关页面,只需按住你Pico上的BOOTSEL按钮,把它插到你的笔记本电脑或树莓派上,然后释放按钮。最后打开RPI-RP2盘符,单击INDEX.HTM文件。

它将把你带到入门页。

可将照片自动同步到苹果电脑的PiPhoto

用传统数码相机拍完照总是要导照片,但要把SD卡上的照片导到苹果电脑上并不容易。一般都得要USB转接头什么的。

如果拍完照,能直接通过网络,自动同步SD卡里的照片到电脑上,那该多好啊。

别担心,PiPhoto可以帮你实现这个需求。

自动化解决方案

一名名叫Lou Kratz的国外网友几乎每个周末都花很多时间在镜头前记录自己的冒险经历。但是他受不了每次都手动导入,所以他发明了PiPhoto,使流程自动化。

视频地址:

从视频中你可以看到,Lou Kratz用了一个非常简单的方案。只需将SD卡插入Raspberry Pi中,照片就会自动上传到计算机上。

树莓派上的LED用于显示状态:

在处理过程中,绿色指示灯将开始闪烁。绿色常亮表示作业成功,红色闪烁表示作业失败。

相关代码:

https://github.com/IoToutpost/pi-photo-sync

安装步骤:

下载代码,在树莓派上运行:
sudo ./install.sh

创建一个新的配置文件,并对其进行编辑。:
sudo cp config/piphoto.conf.example /etc/piphoto.conf

需要设置的变量是:
mount_point – SD卡的安装位置(应与以下udev规则中的位置相匹配。)
run_as_user – 用于运行同步程序的用户。
sync_command – 运行什么命令来同步照片。(请参见上面的目标)。

作者最新的改进可以让Raspberry Pi按日期整理所上传的照片,具体用法可参考代码。

让鸿蒙智能家居开发板与AWS IoT云完美连通

本期直播简介:

使用鸿蒙智能家居开发板连通AWS IoT云平台


直播课程大纲:

1、AWS IoT平台介绍

2、AWS IoT SDK介绍

3、移植AWS IoT SDK到HarmonyOS

4、实现HarmonyOS接入AWS IoT

三大隐藏福利:

1、讲师在线答疑互动

2、一个小时两轮抽奖

3、进群掌握一手资讯

讲师介绍:

连志安——广州旗点智能科技有限公司创始人

从事物联网行业开发,擅长物联网、嵌入式、Linux、HarmonyOS、RTOS等技术。

书籍《物联网——嵌入式开发实战》

直播抽奖:

免费报名+到会看直播,赢取HarmonyOS官方联名T恤、HarmonyOS官方开发板(HiSpark Wi-Fi IoT 智能家居套件)

(中奖用户所填写收件人姓名、电话、地址需为真实信息,信息仅用于工作人员联系用户发放奖品。)

适合人群:

想要学习以下知识的人群:

1、HarmonyOS网络通信

2、利用HarmonyOS连接云平台

3、AWS IoT平台接入

扫码进群:

扫描下方二维码,加入AWS技术交流群

(如无法进群,请添加小助手微信:xiao51cto,备注“AWS加群”)

触碰即盛放的“宝莲灯”——Arduino创意作品

编者注:这是一个名叫JiříPraus的外国小哥实现的Arduino创意作品,实际上是“郁金香”,但看着太像中国神话故事里的“宝莲灯”了。

轻轻抚摸就会绽放,它的六个花瓣将缓慢打开并照耀出彩虹般的光。当花瓣闭合时,它们会产生令人难以置信的带有叶子图案的光。

所需材料:

Arduino Nano R3
SG90微型伺服电机
TTP223触摸传感器
1mm黄铜丝
2mm黄铜管
0.3mm绝缘铜线
WS2812 5050 NeoPixel LED灯 x 7
白色SMD 1206 LED x 30

附注:如何焊接黄铜

https://davidneat.wordpress.com/2015/05/03/a-quick-guide-to-soldering-brass/amp/

推杆如何与花瓣一起运动

当推杆向上移动时,它将连杆和花瓣向下拉。当它向下移动时,它拖着连杆,将花瓣闭合。

单片花瓣的构成:

花瓣由黄铜细条组成,花瓣内有5个白色LED和同一根导线构成的“静脉”结构。

相同的花瓣,一共要做6个。否则它们在关闭时不会构成漂亮的郁金香形状,甚至会卡住。

相关代码:


#include <Adafruit_TiCoServo.h>
#include "SoftPWM.h"

#define NEOPIXEL_PIN A0
#define TOUCH_SENSOR_PIN 2

#define SERVO_PIN 9
//#define SERVO_OPEN 1750
#define SERVO_OPEN 1650
#define SERVO_SAFE_MIDDLE 1000
#define SERVO_CLOSED 775

#define RED 0
#define GREEN 1
#define BLUE 2

float currentRGB[] = {0, 0, 0};
float changeRGB[] = {0, 0, 0};
byte newRGB[] = {0, 0, 0};

#define MODE_SLEEPING 0
#define MODE_BLOOM 3
#define MODE_BLOOMING 4
#define MODE_BLOOMED 5
#define MODE_FADE 6
#define MODE_FADING 7
#define MODE_FADED 8
#define MODE_FALLINGASLEEP 9

#define MODE_RAINBOW 90

byte mode = MODE_FADED;

byte petalPins[] = {3, 4, 5, 6, 10, 11};

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(7, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ400);
Adafruit_TiCoServo servo;

int servoChange = 1; // open
int servoPosition = SERVO_SAFE_MIDDLE;

void setup() {
  Serial.begin(115200);
  pixels.begin();
  servo.attach(SERVO_PIN, SERVO_CLOSED, SERVO_OPEN);

  pinMode(TOUCH_SENSOR_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(TOUCH_SENSOR_PIN), _touchISR, RISING);

  randomSeed(analogRead(A7));
  SoftPWMBegin();

  pixelsUnifiedColor(pixels.Color(0, 0, 0));
  //pixelsUnifiedColor(pixels.Color(255, 70, 0));

  prepareCrossFade(140, 70, 0, 140);
  servo.write(servoPosition);
}

int counter = 0;
byte speed = 15;

void loop() {
  boolean done = true;
  switch (mode) {
    case MODE_BLOOM:
      prepareCrossFadeBloom(500);
      changeMode(MODE_BLOOMING);
      break;

    case MODE_BLOOMING:
      done = crossFade() && done;
      done = openPetals() && done;
      done = petalsBloom(counter) && done;
      if (done) {
        changeMode(MODE_BLOOMED);
      }
      break;

    case MODE_FADE:
      //prepareCrossFade(0, 0, 0, 800);
      changeMode(MODE_FADING);
      break;

    case MODE_FADING:
      done = crossFade() && done;
      done = closePetals() && done;
      done = petalsFade(counter) && done;
      if (done) {
        changeMode(MODE_FADED);
      }
      break;

    case MODE_FADED:
      //prepareCrossFade(140, 70, 0, 140);
      changeMode(MODE_FALLINGASLEEP);
      break;

    case MODE_FALLINGASLEEP:
      done = crossFade() && done;
      done = closePetals() && done;
      if (done) {
        changeMode(MODE_SLEEPING);
      }
      break;

    case MODE_RAINBOW:
      rainbow(counter);
      break;
  }

  counter++;
  delay(speed);
}

void changeMode(byte newMode) {
  if (mode != newMode) {
    mode = newMode;
    counter = 0;
  }
}

void _touchISR() {
  if (mode == MODE_SLEEPING) {
    changeMode(MODE_BLOOM);
  }
  else if (mode == MODE_BLOOMED) {
    changeMode(MODE_FADE);
  }
}

// petals animations

boolean petalsBloom(int j) {
  if (j < 250) {
    return false; // delay
  }
  if (j > 750) {
    return true;
  }
  int val = (j - 250) / 2;
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(petalPins[i], val);
  }
  return false;
}

boolean petalsFade(int j) {
  if (j > 510) {
    return true;
  }
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(petalPins[i], (510 - j) / 2);
  }
  return false;
}

// animations

void prepareCrossFadeBloom(unsigned int duration) {
  byte color = random(0, 5);
  switch (color) {
    case 0: // white
      prepareCrossFade(140, 140, 140, duration);
      break;
    case 1: // red
      prepareCrossFade(140, 5, 0, duration);
      break;
    case 2: // blue
      prepareCrossFade(30, 70, 170, duration);
      break;
    case 3: // pink
      prepareCrossFade(140, 0, 70, duration);
      break;
    case 4: // orange
      prepareCrossFade(255, 70, 0, duration);
      break;
  }
}

void rainbow(int j) {
  uint16_t i;
  byte num = pixels.numPixels() - 1;
  pixels.setPixelColor(pixels.numPixels() - 1, 100, 100, 100);

  for (i = 0; i < num; i++) {
    pixels.setPixelColor(i, colorWheel(((i * 256 / num) + j) & 255));
  }
  pixels.show();
}

// servo function

boolean openPetals() {
  if (servoPosition >= SERVO_OPEN) {
    return true;
  }
  servoPosition ++;
  servo.write(servoPosition);
  return false;
}

boolean closePetals() {
  if (servoPosition <= SERVO_CLOSED) {
    return true;
  }
  servoPosition --;
  servo.write(servoPosition);
  return false;
}

// utility function

void pixelsUnifiedColor(uint32_t color) {
  for (unsigned int i = 0; i < pixels.numPixels(); i++) {
    pixels.setPixelColor(i, color);
  }
  pixels.show();
}

void prepareCrossFade(byte red, byte green, byte blue, unsigned int duration) {
  float rchange = red - currentRGB[RED];
  float gchange = green - currentRGB[GREEN];
  float bchange = blue - currentRGB[BLUE];

  changeRGB[RED] = rchange / (float) duration;
  changeRGB[GREEN] = gchange / (float) duration;
  changeRGB[BLUE] = bchange / (float) duration;

  newRGB[RED] = red;
  newRGB[GREEN] = green;
  newRGB[BLUE] = blue;

  Serial.print(newRGB[RED]);
  Serial.print(" ");
  Serial.print(newRGB[GREEN]);
  Serial.print(" ");
  Serial.print(newRGB[BLUE]);
  Serial.print(" (");
  Serial.print(changeRGB[RED]);
  Serial.print(" ");
  Serial.print(changeRGB[GREEN]);
  Serial.print(" ");
  Serial.print(changeRGB[BLUE]);
  Serial.println(")");
}

boolean crossFade() {
  if (currentRGB[RED] == newRGB[RED] && currentRGB[GREEN] == newRGB[GREEN] && currentRGB[BLUE] == newRGB[BLUE]) {
    return true;
  }
  for (byte i = 0; i < 3; i++) {
    if (changeRGB[i] > 0 && currentRGB[i] < newRGB[i]) {
      currentRGB[i] = currentRGB[i] + changeRGB[i];
    }
    else if (changeRGB[i] < 0 && currentRGB[i] > newRGB[i]) {
      currentRGB[i] = currentRGB[i] + changeRGB[i];
    }
    else {
      currentRGB[i] = newRGB[i];
    }
  }
  pixelsUnifiedColor(pixels.Color(currentRGB[RED], currentRGB[GREEN], currentRGB[BLUE]));
  /*
    Serial.print(currentRGB[RED]);
    Serial.print(" ");
    Serial.print(currentRGB[GREEN]);
    Serial.print(" ");
    Serial.print(currentRGB[BLUE]);
    Serial.println();
  */
  return false;
}

uint32_t colorWheel(byte wheelPos) {
  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  wheelPos = 255 - wheelPos;
  if (wheelPos < 85) {
    return pixels.Color(255 - wheelPos * 3, 0, wheelPos * 3);
  }
  if (wheelPos < 170) {
    wheelPos -= 85;
    return pixels.Color(0, wheelPos * 3, 255 - wheelPos * 3);
  }
  wheelPos -= 170;
  return pixels.Color(wheelPos * 3, 255 - wheelPos * 3, 0);
}
Credits

将树莓派打造成RFID和NFC的识别装置

用华为和苹果的朋友,应该知道自己的手机上基本都带NFC支付功能。

实际上NFC相关的场景不只是支付,还涵盖我们生活中的方方面面。比如IoT前哨站之前发过的一篇:DIY带数据的NFC“袖扣”

NFC(近场通信)基于RFID(射频识别)标准,两者都允许设备从被动令牌或电子标签接收数据(这意味着它不需要外部电源即可工作)。

市场上有现成的RFID和NFC识别设备出售,但可定制化程度不高。不过熟悉树莓派的朋友,可以凭借WaveShare的RFID/NFC扩展板,DIY一个更极客的识别装置。

和树莓派适配后的成品

开始之前,你需要一个能跑Raspberry Pi OS Lite(Buster)的树莓派,还有一个WaveShare NFC扩展板(大约人民币几十块)。

登录系统后,先更新系统。

sudo apt -y update && sudo apt -y upgrade

启用串行接口

该扩展版能够通过三个不同的接口进行通信:I2C,SPI和UART。

我们这里使用UART,因为它演示起来最简单。首先运行sudo raspi-config,进入“接口选项”,然后选择“串行接口”。

当系统询问你是否要登录控制台时,请选择“否”。当询问你是否要启用串行接口时,请选择“是”。

你需要立即重启,这将允许WaveShare HAT通过串行接口与我们的Raspberry Pi对话。

Waveshare HAT包含许多设置。请务必阅读说明!

配置并安装扩展板

如上所述,我们可以通过更改扩展板本身的某些物理开关来选择不同的接口。默认情况下,我们可以将其配置为UART / Serial,但具体接法最好到以下网址核对:

https://www.waveshare.com/wiki/PN532_NFC_HAT#Raspberry_Pi_examples

一般I1和I0处的跳线均应短接“ L”,D16和D20应短接,在DIP开关上,除RX和TX外,所有其他器件均应关闭。

仔细检查,然后将板子插到树莓派GPIO口上,启动。

然后执行如下命令:

sudo apt install rpi.gpio p7zip-full python3-pip
pip3 install spidev pyserial

wget https://www.waveshare.com/w/upload/6/67/Pn532-nfc-hat-code.7z
7z x Pn532-nfc-hat-code.7z

在尝试任何操作之前,需要编辑示例文件,以便我们使用UART。请根据自身要求将其注释或启用。

cd ~/raspberrypi/python
nano example_get_uid.py

pn532 = PN532_UART(debug=False, reset=20)

拿RFID令牌来测试一下

试试看!

如下所示启动示例代码:
python3 example_get_uid.py

如果一切顺利,屏幕将会显示与扩展板连接的信息。

现在,你可以将RFID令牌放在标有“ NFC”的HAT区域上。十六进制数字会开始在屏幕上滚动。这意味着,你的令牌已被检测到!

每个RFID令牌都有唯一的编号,因此可以用来标识不同人员的身份。

但是,该扩展板的功能远不止于此,因为它还支持NFC,并且可以与MIFARE Classic等通用标准进行通信,该标准允许卡上存储1kB的存储空间。

对应的example_dump_mifare.py文件在同一目录中(请确保你已正确设置串行连接)。

更进一步

现在,你可以读取RFID和NFC令牌上的唯一标识符了。

如前所述,如果你用的是MIFARE或NTAG2标准,还可以将数据写到卡上。

examples文件夹包含一些C程序,你可以试一下。

在卡上读取和写入少量数据,可以产生一些有趣的项目。在2018年的电磁场节上,整个游戏都是基于查找物理位置并使用MIFARE卡注册玩家的存在来进行的。

智能手机还可以使用NFC交换任何形式的数据,以及更多可能。

来自:Raspberrypi.org

编译:王文文

【鸿蒙直播】从零开发鸿蒙小游戏App

2020年11月4日(周三,晚20:00),我将为大家做一场鸿蒙App开发的直播,主题是《从零开发鸿蒙小游戏App》。我会从零开始手把手地带领大家开发一款运行在鸿蒙设备上的、曾经风靡全球的小游戏。我会对编写的每一行代码进行讲解。我们采用边做边学的方式,在做中学,在学中做,在直播过程中完成一个小游戏App的所有功能。

>>>点击免费报名<<<

讲师介绍:

就目前而言,鸿蒙App开发可用的平台有三个:智慧屏、智能手表、运动手表。

如果我们开发的是智慧屏或智能手表上的App,那么目前华为还没有开放基于X86的本机模拟器,因此,需要将编写的代码发送到远程的ARM处理器以运行代码,在本机上只能预览运行结果,而无法在本机上运行和调试代码。

如果我们开发的是运动手表上的App,那么既可以使用本机的预览器Previewer来预览代码的运行效果,也可以使用本机的模拟器simulator来运行和调试代码。在运动手表这个平台上,相关的设备和开发工具是最成熟、最完善的,给开发者的体验已经很棒了!

本次直播主要是在运动手表上使用JavaScript编程语言完成项目的编写,直播后会尽快将Java版的项目代码共享给大家。

学习有礼:

参加HarmonyOS公开课,抽官方定制周边! 

官方定制T恤等你来拿!还有机会赢取HarmonyOS官方开发板(HiSpark Wi-Fi IoT 智能家居套件)

直播前导课程:https://edu.51cto.com/course/25054.html

鸿蒙运动手表呼吸训练项目源代码下载:https://harmonyos.51cto.com/posts/1076

用树莓派驱动的青蛙泡泡机

吹泡泡机可能大家小时候都玩过,加满肥皂液,接上电源以后,它就会自动吹出泡泡。

现在有了树莓派,可以把它改成互联网控制的自动泡泡机了。

改造之前,泡泡机由手动开关控制,该开关可打开或关闭青蛙体内的电机。如果你想看到电机驱动青蛙吹出泡泡,则需要自己轻触此开关。

几个国外的创客制作了这款自动泡泡机,该机器由树莓派供电和控制,并且可以通过互联网启动。

他们选择了青蛙形的泡泡机,但你可以根据自己的喜好重新调整。改造使用两节AA电池运行的模型会更容易。

在解剖了“塑料两栖朋友”之后,他们通过继电器模块将其电机连接到Raspberry Pi。他们分享了相关的技术细节,可将继电器模块连接到Raspberry Pi的GPIO引脚。

相关技术介绍:

https://tutorials-raspberrypi.com/raspberry-pi-control-relay-switch-via-gpio

现在,我们可以用代码打开和关闭青蛙体内的马达。

通过在:

https://remo.tv/join/rffrwxr

这个地址登录,命令Raspberry Pi打开泡泡机的开关。

为了让互联网泡泡迷们看到一键劳动的成果,我们设置了Raspberry Pi摄像头模块,并将其构建的装置连接到机器人流媒体平台remo.tv。

别忘了加肥皂水。

用料清单:

泡泡机(最好是用两节AA电池运行的那种)
树莓派
5V继电器模块
Raspberry Pi摄像头模块
Remo.tv帐户
跳线

剩下的问题是:最好的泡沫肥皂配方是什么?

来自:​Raspberrypi.org

编译:王文文