让树莓派记下你的笑颜

我们很高兴展示借助 TensorFlow Lite 在 Raspberry Pi 上构建 Smart Photo Booth 应用的经验(我们尚未开放源代码)。该应用可以捕捉笑脸并自动进行记录。此外,您还可以使用语音命令进行交互。简而言之,借助 Tensorflow Lite 框架,我们构建出可实时轻松处理笑脸检测和识别语音命令的应用。

为什么选择 Raspberry Pi?

Raspberry Pi 不仅是使用广泛的嵌入式平台,且有体积小、价格便宜的优势。我们选择 TensorFlow Lite 是因为它专为移动端和 IoT 设备而设计,因此非常适合 Raspberry Pi。

构建 Photo Booth 应用需准备什么?

我们已在 Raspberry Pi 3B+ 上实现 Photo Booth 应用,其搭载 1GB RAM,并装有 32 位 ARMv7 操作系统。我们的应用具有图像输入和音频输入功能,因此我们还需要摄像头和麦克风。除此之外,我们还需要显示器来显示内容。总成本不到 100 美元。详情如下所列:

一台 Raspberry Pi(35 美元)

配置:

» 主频为 1.4GHz 的四核 64 位处理器

» 1GB LPDDR2 SRAM

一部用于捕获图像的摄像头(约 15 美元)

一个采集音频数据的麦克风(约 5 美元)

一台 7 英寸的显示器(约 20 美元)

Photo Booth 应用涉及到两个关键技术:

1、我们需要从相机的图像输入中检测是否有笑脸;

2、我们需要从麦克风的音频输入中识别出是否存在“是”或“否”的语音命令。

如何检测笑脸?

我们很难在使用单个模型检测人脸并预测笑脸得分结果的同时保证高精度和低延迟。因此,我们通过以下三个步骤来检测笑脸:

1、应用人脸检测模型来检测给定的图像中是否存在人脸。

2、如果存在,则将其从原始图像中裁剪出来。

3、对裁剪后的人脸图像应用人脸属性分类模型,以测量其是否为笑脸。

笑脸检测工作流

我们尝试了如下几种方法来降低笑脸检测的延迟时间:

1、为减少内存占用并加速执行进程,我们使用了 TensorFlow 模型优化工具包中的训练后量化 (Post Training Quantization) 技术。在本教程中,针对您自己的 TensorFlow Lite 模型,您会发现该技术将非常易于使用。

2、对从摄像头中捕获的原始图像进行大小调整,并固定其长宽比。压缩率根据原始图像大小采用 4 或 2。尽量让图像尺寸小于 160×160(原设计尺寸为 320×320)。输入尺寸较小的图像可以大大减少推理时间,如下表所示。在我们的应用中,从相机中捕获的原始图像尺寸为 640×480,所以我们将图像尺寸调整为 160×120。

3、我们并未使用原始图像进行面部属性分类,而是弃用背景并使用裁剪出的标准人脸。如此可在保留有用信息的同时减小输入图像的尺寸。

4、使用多线程开展推理

下表显示我们所用策略所带来的效果。我们使用 Tensorflow Lite 模型性能测试工具对人脸检测模型在 Raspberry Pi 上的表现进行性能评估。

人脸检测延迟时间对比

检测笑脸的整个流程(包括我们之前提到的三个步骤)平均耗时 48.1ms 并只使用一个线程,这意味着我们能够实现实时笑脸检测。

人脸检测

我们的人脸检测模型由定制的 8 位 MobileNet v1 模型和深度乘数为 0.25 的 SSD-Lite 模型所构成。其大小略大于 200KB。为什么这个模型这么小?第一,基于 Flatbuffer 的 TensorFlow Lite 模型大小比基于 Protobuf 的 TensorFlow 模型小。第二,我们采用 8 位量化模型。第三,我们的 MobileNet v1 经过改良,通道比原来更少。

与大多数人脸检测模型类似,模型会输出边界框和 6 个面部关键特征点(包括左眼、右眼、鼻尖、嘴部中心、左耳屏点和右耳屏点)的坐标。我们还应用了非极大值抑制 (Non-Maximum Suppression) 来过滤重复的人脸。人脸检测 TensorFlow Lite 模型的推理时间约为 30 毫秒。这意味着模型可以在 Raspberry Pi 上实现实时检测人脸。

边界框和 6 个面部关键特征点示例

人脸裁剪工具

检测到的人脸朝向和尺寸大小各不相同,为了统一并更好地进行分类,我们会旋转、裁剪和缩放原始图像。我们将从人脸检测模型中获得的 6 个面部关键特征点的坐标输入函数。通过这 6 个面部关键特征点,我们便可以计算出旋转角度和缩放比例。经过上述流程后,我们便可得到 128×128 的标准人脸图片。下图示例展示我们面部裁剪工具的功能。蓝色边界框是人脸检测模型的输出结果,而红色边界框是我们经计算得出的裁剪边界框。我们会复制图像外部的像素边界线。

人脸裁剪工具图示

人脸属性分类

我们的人脸属性分类模型也是 8 位量化 MobileNet 模型。将 128×128 的标准人脸输入该模型,其会输出介于 0 到 1 的浮点型变量用于预测微笑的概率。该模型也会输出 90 维向量来预测年龄,范围在 0 到 90 之间。其在 Raspberry Pi 上的推理时间可以达到 30 毫秒左右。

如何识别语音命令?

实时语音命令识别也可以分为三个步骤:

预处理:我们使用滑动窗口来储存最新的 1 秒音频数据,以及音频所对应的 512 帧图像。

推理:通过输入的 1 秒音频,我们可以应用语音命令模型来获得出现以下四种类别的概率(“是”/“否”/“无声”/“未知”)。

后期处理:我们通过当前的推理结果与先前的结果计算出平均值。当一个词语的平均出现概率高于某个阈值时,我们便判断已检测到语音命令。

我会在下文详细解释这三个步骤。

预处理

我们使用 PortAudio(一个开源代码库)获取来自麦克风的音频数据。下图展示我们如何储存音频数据。

音频流处理

由于我们的模型使用采样率为 16kHz 的 1 秒音频数据进行训练,因此数据缓冲区的大小为 16,000 字节。数据缓冲区亦作为循环缓冲区使用,我们每次会更新对应的 512 帧。此外,我们还会记录偏移量,用于指明上次更新的结束位置。当缓冲区尾部已满时,我们会从缓冲区的头部继续操作。在我们想要获取音频数据来展开推理时,我们会从偏移处开始读取,然后在偏移结束对应的帧结束。

语音命令识别

您可在许多公开的 TensorFlow 示例中找到我们使用的语音命令识别模型。该模型由 audio_spectrogram、MFCC、2 个卷积层和 1 个全连接层组成。这个模型的输入内容为采样率为 16kHz 的 1 秒音频数据。数据集支持公开访问,或者您也可自行训练。此数据集包含 30 种语音命令数据。由于我们只需要“是”和“否”类别,所以我们将其他标记归类为“未知”。

此外,我们也采用了其他方法来缩短延迟时间:

我们去除半数通道。压缩后的TensorFlow Lite 模型大小约为 1.9 MB。

与通常情况下使用最后一个全连接层的 12 个输出通道有所不同,由于我们只需要 4 种类别,所以我们使用了其中 4 个输出通道。

我们使用多线程来进行推理。

在训练中,我们将背景音量设置成 0.3,以提高模型的抗噪能力。我们还将“无声”和“未知”类别的比例各设置成 25%,以平衡训练集。

后期处理

音频流后期处理

由于我们获取的音频数据可能仅截取到一半命令,所以单个预测结果并不准确。我们储存先前结果(之前的记录时间不长于 1.5s),以取得平均预测结果。这可以大大提高关键字检测的实时性能。我们能够保存的先前结果的数量,在很大程度上取决于我们的推理时间。例如,我们模型在 Raspberry Pi 上的推理时间约为 160 毫秒,这意味着我们最多可以保存 9 个先前结果。

后续行动

我们希望在 TensorFlow Lite Github 代码库中尽快开放这个示例的源代码。如要了解关于如何上手使用 TensorFlow Lite 的更多详情,请参阅此处,并在此处查看其他参考示例。

参阅此处。

请告诉我们您的想法或与我们分享您的 TensorFlow Lite 用例。

致谢

感谢 Lucia Li、Renjie Liu、Tiezhen Wang、Shuangfeng Li、Lawrence Chan、Daniel Situnayake、Pete Warden。

原文:https://mp.weixin.qq.com/s/8zD3GqbQrQnZmuD59OoFuQ

https://tensorflow.google.cn/lite/guide

在 Windows 上编辑树莓派分区文件的方法

来自 RaspiSQH 的投稿,原文。

众所周知,树莓派运行的linux系统使用的分区是ext格式,而windows一般不能直接读写ext分区,这导致编辑一些系统文件导致不能启动时,就会陷入无尽的麻烦中。

不过,我最近发现了一个强大的软件:ext2fsd,可以解决这个烦恼。

介绍

介绍一下:ext2fsd是一个国人开发的适用于windows的ext2/3分区驱动(貌似在0.69版本支持了ext4?),这是其在 source forge 的主页。用这个软件,就可以轻松在windows里读写树莓派的磁盘了。

安装以及使用方法

下载方法

在 source forge 的主页下载最新版(撰写此文时最新为0.69,故本文用0.69演示)。下载 Ext2Fsd-x.xx.exe 即可。

安装

Ext2Fsd安装十分简单。下载完成后运行:

一路next即可,选项最好保持默认,直至安装完成。

使用方法

安装好后会在开始菜单出现一个快捷方式,打开软件。这时候可能需要等待一下。完成后会弹出界面:

这个软件是国人开发的,所以是中文。(这个必须点赞!)

这时候插入你的sd卡,就会在下方显示。

然后选中你的Ext分区(就是较大的分区,如上图中的 I: 分区),接着按下 F12,就会弹出如图窗口:

在下拉框中选择 0B FAT32,就可以把分区类型转换成FAT32。不过这里转换只是在这台电脑上查看用的,并不会真正影响分区哒~

这时候打开“此电脑”,就可以看到一个卷标为rootfs的分区,可以任意读写啦。

使用好后,就可以插回树莓派,愉快地开机了。

存在的不足

我实际使用时,发现即使安装时勾选了开机启动,重启时也不会在托盘显示,不过并不影响使用。

有时拔掉sd卡后还会显示rootfs分区(无法打开),不知道是什么原因。

三维激光扫描建模仪(基于树莓派)

MAKER:mfx2/译:趣无尽 Cherry(转载请注明出处)

只需要将物体放入到一个盒子里,就可以得到它的 3D 模型数据,是不是很方便呢?

今天我们就用树莓派制作一台三维激光扫描建模仪。能够将物体数字化为 .obj 网格文件,然后再使用 3D 打印来「复制」它。

项目通过线激光发射器和树莓派摄像头来实现计算机视觉数据采集。激光定位的角度与激光成 45 度倾斜,同时在物体的垂直切片上投射出一条红线。摄像头检测切片到中心的距离并给出网格切片。物体在托盘上慢慢的旋转,通过不断的重复这个过程,扫描完成整个物体,十分的方便。

创作灵感

开始制作前,我做了一些基础研究。发现许多 3D 扫描仪都使用旋转平台,然后使用各种不同的传感器来测量距中心的距离,建立旋转模型。很多采用了与 Kinect 扫描仪类似的双摄像头。

我的项目是基于Yscanner扫描仪开发的,采用单摄像头。它是一种低分辨率的激光扫描仪,项目简单、可行,而且这种激光技术是激光相对于摄像机的偏移量来进行照射的,测量到中心的距离,如图你可以清晰的看见那条线。

视频演示:

材料清单

树莓派 × 1

树莓派摄像头V2 × 1

LED × 1

电阻 × 1

电线 × 若干

3D 打印灯丝 × 若干

木板 × 1

M3 硬件 × 若干

步进电机 × 1

线激光发射器 × 1

LN298 步进电机驱动器 × 1

金属按钮 × 1

烙铁 × 1

激光切割机 × 1

3D 打印机 × 1

螺丝刀 × 1

钳子 × 1

设计原理

该项目核心组件就是能够垂直投射在物体上的线激光发射器。它通过树莓派摄像头获取投影,对其进行透视校正,然后在图像处理前进行过滤。在图像处理中,收集线的每个部分到物体中心的距离。在径向坐标中,此图片将同时产生 r 和 z 的分量,然后通过将物品的旋转得到新的切片来实现三维效果。

为了达到设计效果,我使用树莓派作为中央计算单元。

1、将树莓派与步进电机和电机驱动器连接。由外部 5V 电源供电并由树莓派的 GPIO 引脚控制。

2、将线激光发射器连接到树莓派的 3.3V 线上,将树莓派摄像头连接到摄像头的输入上。

3、安装一个简单的下拉按钮和一个用来显示状态的 LED 来向用户展示系统所处的状态。

需要注意的地方:

1、将电子设备安装到由 T 型槽和 M3 硬件搭建的激光切割盒中。

2、将电子设备隐藏在底部隔间中,盖子上放置旋转托盘,便于放置物品。这个盖子可以最大程度地减少遗漏到系统中的光源,而这些光在最终扫描中会产生噪声。

3D 打印外壳

使用 Autodesk Fusion 360 设计出 3D 外壳模型。外壳设计很简单,一个盒子和带活页的盖子(都是 3D 打印而成)。设备主要分为两层:电子设备层和主体层,两层之间有可穿电线的孔。

使用 Epilog Zing 40 W 激光切割机切割。如图所示,外壳主要由主体层、电子设备层、两个盖子部件、前面板块、后面板块以及两个侧面板块组成。

在主体层上,有三个切口:一个用于安装步进电机,一个用于放置激光器的电线,另一个用于放置树莓派摄像头的软排线。

底座有用于固定树莓派、面包板和电机驱动器的安装孔,以及用于放入步进电机的较大切口。

外壳的盖子可以简单地卡在一起,形成一个类似三角形状的盖子,合页宽度为侧板孔的直径长。

背面板块和其中一个侧面板块在侧面都有插槽,因此可以轻松访问树莓派的端口(HDMI、USB、以太网以及电源)。前面板块是一个简单的部分,手动钻孔用以安装按钮和 LED。

所有的零件由 M3 硬件、 T 型接头和插槽固定在一起。组拼时可以使用 M3 螺钉将零件固定在一起。

我使用激光切割机来处理大部分组件是因为它具有速度和便捷性的优势。虽然 3D 的几何形状在裁纸器上却很难创建。

第一个组件是线激光发射器支架。该组件将被安装在与摄像头视线成 45 度角的主体层上,有一个孔,可将激光器固定到位。

另外还需一个马达支架,因为马达的轴太长了。支架产生的摩擦力不妨碍激光切割的组件,并降低了电机连接的平面,从而使旋转平台与主体层齐平。

项目所需的文件请在项目文件库中下载:

https://make.quwj.com/project/204

电子部分

该项目的硬件接线部分非常简单,只需要将电机、按钮、LED、激光以及摄像头连接到树莓派。

1、将电阻与每个引脚串联,以保护引脚。GPIO 的一个引脚专用于控制 LED,当设备准备好后,LED 会亮起,当设备运行时,它会使用 PWM 进行脉冲控制。

2、将 GPIO 的另一个引脚连接到上拉按钮上,未按下按钮时为高电平,按下按钮时为低电平。

3、GPIO 的四个引脚用来驱动步进电机。

步进电机

由于项目中的电动机只需要一定程度上的步进而无需控制速度,因此选用了一款很简单的步进电动机驱动器(L298N)。该驱动器只需将控制线升压以馈入电动机的输入即可。

为了了解步进电机如何在非常低的水平上操作,我参考了 L298N 数据表和 Arduino 库。步进电动机的磁芯带有可交替极性的中心轴。使用四根线缠绕去控制两个电磁体,这两个电磁体分别为电动机中的每个相对的轴供电。通过切换轴的极性,就可以推动步进器。

了解完步进电机的工作原理,就能够更容易地控制步进电机。由于步进电机的最大电流约为 0.8A,超出了树莓派的供电能力,我最后选用 5V 电源而不是树莓派为其供电。

软件部分

该项目的软件部分由四个方面组成:图像处理,电机控制,网格创建和嵌入式功能。

1、如图所示,随着系统启动 .bashrc 自动登录到树莓派并开始运行 python 代码。系统点亮状态灯,告知用户它已正确启动,并等待按下按钮。

2、用户可以放置要扫描的物品并合上盖子。按下按钮后,LED 会闪烁,告知用户设备正在工作。设备将在图像处理和电机控制之间循环,直到旋转完成收集物品的所有数据为止。最后,创建网格并通过电子邮件将文件发送到预选的电子邮箱。

3、设备可以重新启动循环,只需按一下按钮就可以执行另一次扫描。

图像处理

第一步是处理获取的图像,以便将存储在图像中的信息提取为可用于创建空间点阵列的形式。

首先拍摄了平台上物体的照片,以及由激光照射到盒子背面并分散后产生的所有背景噪声。该图片的原始形式存在两个主要问题。一是拍摄物体的角度较高,二是背景噪音很大。视角的问题是第一个要考虑的,因为按原样使用照片将无法确定的物体一致高度。

如图所示,倒置的 “L” 形的高度是一致的。但是,由于一侧比另一侧长,它们在最靠近观察者的边缘处的高度似乎不同。

为了解决此问题,我必须将图像中的工作空间从以前的梯形形状转换为矩形。为此,我使用了链接中提供的代码。https://www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/

当给定一个图像和四个点时,该代码将在四个点之间裁剪图像并补偿转换裁剪后的图像。使用四个点来创建矩形,而不是之前的梯形形状。

下一个需要解决的问题是外部光形成的背景噪声和激光本身反射的光。我使用 OpenCV 的 inRange() 函数过滤光。我将阈值设置为仅在特定水平上拾取红光。为了获得正确的值,从较大的阈值开始,不断提高阈值水平,直到唯一被拾取的光是来自扫描物体上的激光。

获得此图像后,我发现每行中最亮的像素是每行的一个像素线,该线与激光线的最左侧相接。最后,将每个像素转换为 3D 空间中的顶点并存储在数组中,如网格创建部分所述。

电机控制

在成功处理单个图像以获取物体的切片之后,我还需要旋转物体获得不同角度的新照片。为此要控制好扫描物体平台下的步进电机。我通过创建一个变量来跟踪电机的状态和细分控制四个电机的输入,这些是实现步进机功能的基础。

网格创建

要从所有处理的图像创建网格,我必须首先将处理的图像中的每个白色像素转换为 3D 空间中的顶点。我要收集具有圆柱对称性的单个对象切片,所以要收集圆柱的坐标。图片的高度可以用 z 轴表示,到旋转台中心的距离可以用 R 轴表示,步进电机的旋转可以用 theta 轴表示。由于我将数据存储在圆柱坐标中,因此必须将每个顶点转换为笛卡尔坐标。

顶点创建好后,将它们存储在一个列表中。然后再将所述列表存储在另一个列表中,该列表包含为获取的每个图像创建的顶点列表。处理完所有图像并将其转换为顶点后,在最终网格中显示顶点。其中,最好包含顶部顶点和底部顶点,然后根据分辨率,我选择了均匀分布的顶点数以用于每个图像。因为并非所有顶点列表的长度都相同,所以我不得不通过找到顶点数量最少的列表并将所有其他列表中的顶点移除,直到它们均等为止。

创建顶点列表后就可以创建网格。我使用 .obj 文件标准设置网格格式,因为它很简单并且支持 3D 打印。

嵌入式功能

当设备正常运行后,我通过添加完整的嵌入式功能对其进行了完善。这意味着移除键盘,鼠标和显示器,处理完成后以无线方式将 .obj 文件发送过去。

1、将 .bashrc 代码更改为自动登录并在启动时启动 python 主程序。执行 sudo raspi-config 命令,设置 “Console Autologin”,并将 “sudo python /home/pi/finalProject/FINAL.py” 行添加到 /home/pi/.bashrc。

2、添加一个按钮和 LED 状态显示,用于用户输入和输出。按钮将会告知用户设备何时开始扫描,LED 将告诉用户机器的状态。

如果 LED 点亮,则表明设备已准备好开始扫描。如果 LED 闪烁,则表明设备当前正在扫描。如果 LED 报错,则表明软件错误,要求重启系统。

最后,我通过电子邮件向设备发送 .obj 文件。使用 smtplib 和 email 库来完成。这种无线的发送方式很方便,可以将生成的文件传递给用户也可以在不同的平台上访问。

将所有的组件合在一起

完成以上步骤后,现在可以将组件组合在一起。

1、组装外壳箱体。

2、将照相机和激光安装到盒子里。

3、安装其他电子设备。

4、树莓派的背面,可使用树莓派端口和 5V 电动机输入。

5、安装好设备正面以及带有 LED 状态指示灯的按钮。

完成

激光 3D 扫描仪能够精确地扫描物体。物体的特征是独特且可识别的,并且使用切片软件(例如Repetier)可以很容易地对零件进行 3D 打印。

通过测试最大的发现是设备的一致性。在对同一物品进行多次试验中,即使稍微改物品的位置,扫描程序也都能生成非常相似的 .obj 文件。

如图所示,三次扫描的结果都非常的相似,能够获取相同的细节。系统的一致性还是不错的。

可以调整的地方

可调整的变量之一是扫描的分辨率。因为步进器有 400 步,所以我可以选择每个 ΔΘ 来决定角度分辨率。在默认情况下,我将角度分辨率设置为 20 次迭代,这意味着电机每帧旋转 20 步(400/20=20)。选择此项主要是为了节省时间,以这种方式完成扫描大约需要 45 秒。但是如果想要更高质量的扫描,就需要将迭代次数增加到 400。这为 3D 构造模型提供了更多的点,从而可以进行更详细的扫描。

除了角分辨率外,还可以调整垂直分辨率,或选择沿激光切片扫描多少个不同的点。为了节省时间,我将默认值设置为 20,如果你想得到更好的效果可以增加数值。

如图所示,通过改变角分辨率和空间分辨率的参数,可以显示出不同的扫描结果。每个标签的格式设置为角度分辨率x空间分辨率。从默认的扫描设置中可以看出鸭子的功能是可识别的,但并不明显。

但是,随着分辨率的提高,精确的功能开始显现出来,包括眼睛、嘴巴、尾巴和鸭子的翅膀。最高分辨率的图像大约需要 5 分钟扫描。高分辨率的效果是非常成功的。每个标签的格式设置为角度分辨率x空间分辨率。从默认扫描设置中可以看出,鸭子的细节可识别出来,但并不明显。随着分辨率的提高,细节的准确性越来越高,包括眼睛、嘴巴、尾巴和鸭子的翅膀。

局限性

尽管该项目取得了成功,但在设计和实施方面仍然存在一些局限性。激光发射器的光散射问题,我扫描的物体都是半透明,很亮或者很暗的物体在表面的反射就存在缺陷。如果物体是半透明的,光线就会被吸收并散射,从而使切片的读数非常嘈杂。在发亮和黑暗的物体中,光线将会被反射或吸收,以至于难以拾取的程度。

此外,我使用摄像头获取物体的特征,就能感受到视线遮挡的限制,凹陷的物体和锐角通常会被物体的其他部分阻挡。小黄鸭的尾巴在扫描中就失去曲线率。摄像头只能检测物体表面结构,无法获取孔或者内部为几何形状的物体。这一常见问题也在其他扫描机中存在。

可改进的地方

虽然项目整体效果还不错,但还有可以优化的地方:

1、在当前状态下,只能通过更改代码中的硬编码分辨率变量来更改扫描分辨率。为了使项目更具嵌入式性,可以添加一个分辨率电位计,以便用户可以更改分辨率,而不用将监视器和键盘插入扫描仪。

2、扫描仪在创建时的图像效果不是很好。为了解决这个问题,可以使用网格平滑技术来平滑不规则和粗糙的位置。

3、像素坐标无法很好地缩放到现实世界中。我创建的网格比实际物品大六到七倍。

via

树莓派4B取消1G内存型号,2G版降至35美元

树莓派基金会刚刚宣布 Raspberry Pi 4(树莓派4代)取消 1G 内存型号,2G 版降至 35 美元。基金会创始人兼 CEO Eben Upton 将此次降价归功于 RAM 成本降低。他同时指出,树莓派 4B 和 8 年前树莓派一代发售时价格一致,实际上考虑这些年的通货膨胀,起初就等于优惠了 5 美元。

更别说,4B 的 CPU 比第一代快了 40 倍,运行内存是当年的8倍。

根据去年底的统计数据,树莓派累计销量已超 3000 万件。去年的树莓派 4B 算是一次较为重大的升级,顶配可选 4GB LPDDR4 内存,提供 USB 3.0、千兆网口、蓝牙 5.0、双 MicroHDMI 接口、耳机孔等。

使用树莓派®和MCC 134测量热电偶

使用热电偶来测量温度是一种较为普遍的方式,原因在于其成本较低、易于使用,且测量范围广。Measurement Computing Corp(MCC)在设计与构建用于测量热电偶的精确数据采集设备方面有着悠久的历史。在不可控的环境中,设计一种在树莓派上可精确测量热电偶的设备是十分困难的。本文阐述了在精确测量热电偶过程中遇到的难题,MCC 134 HAT如何完成工作以及MCC 134的用户应如何将测量误差最小化。

热电偶是如何工作的

热电偶是用于测量温度的一种传感器。它通过将温度梯度转化成电势差来工作,这种现象被称为塞贝克效应。热电偶由两种不同的金属线组成,它们的两端相互连接,各自形成一个节点。因为两种金属线在温度梯度上产生不同的电势,所以在电路感应中可测量出电压。通过测量回路中的电压就可得出该电势差值。

在不同类型的热电偶中,金属线的连接情况也不尽相同,因此可在不同的温度范围内测量。例如,J型热电偶由铁与康铜(铜-镍合金)组成,适合在-210℃与1200℃间测量;而T型热电偶由铜与康铜组成,适合在-270℃与400℃间测量。

上述温度梯度是指两个节点之间的温度差 — 测量点,即我们所关注的热端;参考点,为在测量设备处的冷端。

注:热端指测量端,与该端的温度无关;它的真实温度可能会高于或低于参考点,即冷端温度。

热电偶测量的基本原理

热电偶产生与温度梯度相对应的电压,即热端与冷端之间的电势差。确定热端绝对温度的唯一方式是获取冷端的绝对温度。

虽然较旧的系统依靠冰浴来实现冷端参考温度,但现代热电偶测量设备使用一个或多个传感器测量与其相连的终端(冷端)温度。

热电偶测量的误差来源

热电偶的测量有许多误差来源,包括噪声、线性误差与偏置误差,热电偶本身以及参考端或冷端的温度测量。现代的24位测量设备使用高精度的模数转换器(ADC),并采用设计实践以最小化噪声、线性误差与偏置误差。

热电偶测量误差无法避免,但可以将其最小化。这种误差是由于使用的合金缺陷导致,因为它们在不同批次之间略有不同。某些热电偶本身就有着较小的误差。标准K型与J型热电偶的误差可高达±2.2℃,而T型热电偶的误差最多为±1℃。更加昂贵的热电偶(SLE-特殊误差限制)由质量较好的导线构成,可使这些误差降低一半。

精确测量冷端,即热电偶与设备的连接处,是十分不易的。更加昂贵的仪器,如DT MEASURpoint系列产品,使用一种绝热金属板以保持冷端温度不变,并使得在高精度下的测量更加容易。对于较低成本的设备,绝热金属板过于昂贵。但若没有绝热金属板,是无法测量热电偶与铜制连接器接触点温度的。这导致冷端温度的测量极易受到其附近温度快速改变或功率情况的影响。

MCC 134的设计挑战

为了更好地理解MCC 134的设计挑战,我们需将其与MCC 受欢迎的E-TC系列产品作对比 — 一种高精度以太网热电偶测量设备。E-TC系列产品的冷端温度由模拟设备ADT7310 IC温度传感器测量。

由于测量环境的可控与稳定,IC传感器在 MCC E-TC 系列中工作良好。外部塑料盒用以控制气流、电路元件以及在恒定负载下工作的处理器。在E-TC的可控环境下,IC传感器可以出色地精确测量冷端温度。

然而,当第一次用IC 传感器对MCC 134进行设计以测量冷端温度时,精度不够的问题在设备校验过程中尤为突出。IC 传感器不能放置在连接器模块附近,因为树莓派所导致的较大且不可控的温度梯度与外部环境会造成欠佳的测量可重复性。

MCC通过改进的方案重新设计了 MCC 134,该方案在保持低成本的同时提供了更好的准确性和可重复性。不同于使用1个IC传感器与1个终端模块,MCC使用2个终端模块与3个热敏电阻对电路板进行了重新设计 — 每一个热敏电阻都分别放置于终端模块的一侧(如下图所示)。虽然这增加了设计的难度,但即使在处理器的负载与环境温度发生改变的情况下,热敏电阻仍可以更精确地捕获冷端温度的变化。

这种设计方式使测量结果几乎不受树莓派不可控环境的影响。但即使是新式的设计,某些因素也会影响测量精度。但用户可通过减少MCC 134上温度梯度的快速改变以改进测量结果。

MCC 134精确测量热电偶的最佳实践

当在标准的环境下工作时,MCC 134可实现热电偶的精度的最大化。剧烈的温度变化与气流变化会影响结果。多数情况下,MCC 134将完成其典型规格。为了实现最高精度的热电偶读数,MCC有以下实践建议:

降低树莓派处理器上的负载。当运行程序的负载占据了树莓派处理器的4个内核时,其温度会上升至70℃以上。运行仅加载1个内核的程序将在大约20℃的温度下运行。

将环境温度变化值最小化。使MCC 134远离循环往复的热源或冷却源。瞬间的温度变化可能导致误差增加。

提供持续的空气流动,如风扇。稳定的空气流动可以散热并降低误差。

将若干个MCC HATs配置于堆栈中时,将MCC 134放置于树莓派的最远端。由于树莓派是一个不可忽视的热源,因此将MCC 134放置于离其最远的地方将会增加精确度。

结论

热电偶提供了一种低成本且灵活的测量温度的方法,但精确测量热电偶是有难度的。通过创新设计和广泛测试,MCC克服了使用树莓派时,不受控制的环境下精确测量热电偶的挑战。MCC 134 DAQ HAT能够将标准热电偶与快速增长的低成本计算平台的需求配合使用。

产品及技术咨询:021-50509819

邮箱:sales.china@mccdaq.com

公司网址:china.mccdaq.com

数据采集专家MCC

https://mp.weixin.qq.com/s/3GbP5OhiAx_HkuptlgvlBA

特斯拉+树莓派实现车牌识别检测系统

转自机器之心 | 作者:Robert Lucian Chiriac | 参与:王子嘉、思、一鸣

怎样在不换车的前提下打造一个智能车系统呢?一段时间以来,本文作者 Robert Lucian Chiriac 一直在思考让车拥有探测和识别物体的能力。这个想法非常有意思,因为我们已经见识过特斯拉的能力,虽然没法马上买一辆特斯拉(不得不提一下,Model 3 现在看起来越来越有吸引力了),但他有了一个主意,可以努力实现这一梦想。

所以,作者用树莓派做到了,它放到车上可以实时检测车牌。

在接下来的内容里,我们将介绍项目中的每个步骤,并提供 GitHub 项目地址,其中项目地址只是客户端工具,还其它数据集与预训练模型都可以在原博客结尾处找到。

项目地址:

https://github.com/RobertLucian/cortex-license-plate-reader-client

下面,让我们看看作者 Robert Lucian Chiriac 是如何一步步打造一个好用的车载检测识别系统。

放一张成品图镇楼。

第一步:确定项目范围

开始之前,我脑海里出现的第一个问题是这样一个系统应该能够做到什么。如果说我活到现在学到了什么,那就是循序渐进——从小处着手永远是最好的策略。所以,除了基本的视觉任务,我需要的只是在开车时能清楚地识别车牌。这个识别过程包括两个步骤:

1、检测到车牌。

2、识别每个车牌边界框内的文本。

我觉得如果我能完成这些任务,再做其他类似的任务(如确定碰撞风险、距离等)就会容易得多。我甚至可能可以创建一个向量空间来表示周围的环境——想想都觉得酷。

在确定这些细节之前,我知道我得先做到:

1、一个机器学习模型,以未标记的图像作为输入,从而检测到车牌;

2、某种硬件。简单地说,我需要连接了一个或多个摄像头的计算机系统来调用我的模型。

那就先从第一件事开始吧——构建对象检测模型。

第二步:选择正确的模型

经过仔细研究,我决定用这些机器学习模型:

1、YOLOv3- 这是当下最快的模型之一,而且跟其他 SOTA 模型的 mAP 相当。我们用这个模型来检测物体;

2、CRAFT 文本检测器 – 我们用它来检测图像中的文本;

3、CRNN – 简单来说,它就是一个循环卷积神经网络模型。为了将检测到的字符按照正确的顺序排成单词,它必须是时序数据;

这三个模型是怎么通力合作的呢?下面说的就是操作流程了:

1、首先,YOLOv3 模型从摄像机处接收到一帧帧图像,然后在每个帧中找到车牌的边界框。这里不建议使用非常精确的预测边界框——边界框比实际检测对象大一些会更好。如果太挤,可能会影响到后续进程的性能;

2、文本检测器接收 YOLOv3 裁剪过的车牌。这时,如果边界框太小,那么很有可能车牌文本的一部分也被裁掉了,这样预测结果会惨不忍睹。但是当边界框变大时,我们可以让 CRAFT 模型检测字母的位置,这样每个字母的位置就可以非常精确;

3、最后,我们可以将每个单词的边界框从 CRAFT 传递到 CRNN 模型,以预测出实际单词。

有了我的基本模型架构草图,我可以开始转战硬件了。

第三步:设计硬件

当我发现我需要的是一种低功耗的硬件时,我想起了我的旧爱:树莓派。因为它有专属相机 Pi Camera,也有足够的计算能力在不错的帧率下预处理各个帧。Pi Camera 是树莓派(Raspberry Pi)的实体摄像机,而且有其成熟完整的库。

为了接入互联网,我可以通过 EC25-E 的 4G 接入,我以前的一个项目里也用过它的一个 GPS 模块,详情可见:

博客地址:https://www.robertlucian.com/2018/08/29/mobile-network-access-rpi/

然后我要开始设计外壳了——把它挂在汽车的后视镜上应该没问题,所以我最终设计了一个分为两部分的支撑结构:

1、在后视镜的方向上,树莓派+ GPS 模块+ 4G 模块将保留下来。关于我使用的 GPS 和 4G 天线,你可以去看一下我关于 EC25-E 模块的文章;

2、在另一侧,我用一个利用球关节活动的手臂来支撑 Pi Camera

我会用我可靠的 Prusa i3 MK3S 3D 打印机来打印这些零件,在原文文末也提供了 3D 打印参数。

图 1 :树莓派+4G/GPS 壳的外形

图 2:利用球关节活动臂支撑 Pi Camera

图 1 和图 2 就是它们渲染时候的样子。注意这里的 c 型支架是可插拔的,所以树莓派的附件和 Pi Camera 的支撑物没有和支架一起打印出来。他们共享一个插座,插座上插着支架。如果某位读者想要复现这个项目,这是非常有用的。他们只需要调整后视镜上的支架就可以了。目前,这个底座在我的车(路虎 Freelander)上工作得很好。

图 3:Pi Camera 支撑结构的侧视图

图 4:Pi Camera 支撑结构和 RPi 底座的正视图

图 5:预计的相机视野

图 6:内置 4G/GPS 模块、Pi Camera,树莓派的嵌入式系统近照

显然,这些东西需要一些时间来建模,我需要做几次才能得到坚固的结构。我使用的 PETG 材料每层高度为 200 微米。PETG 在 80-90 摄氏度下可以很好地工作,并且对紫外线辐射的抵抗力很强——虽然没有 ASA 好,但是也很强。

这是在 SolidWorks 中设计的,所以我所有的 SLDPRT/SLDASM 文件以及所有的 STLs 和 gcode 都可以在原文末找到。你也可以用这些东西来打印你自己的版本。

第四步:训练模型

既然硬件解决了,就该开始训练模型了。大家应该都知道,尽可能站在巨人的肩膀上工作。这就是迁移学习的核心内容了——先用非常大的数据集来学习,然后再利用这里面学到的知识。

YOLOv3

我在网上找了很多预先训练过的车牌模型,并没有我最初预期的那么多,但我找到了一个在 3600 张车牌图上训练过的。这个训练集并不大,但也比什么都没有强。除此之外,它也是在 Darknet 的预训练模型的基础上进行训练的,所以我可以直接用。

模型地址:https://github.com/ThorPham/License-plate-detection

因为我已经有了一个可以记录的硬件系统,所以我决定用我的系统在镇上转上几个小时,收集新的视频帧数据来对前面的模型进行微调。

我使用 VOTT 来对那些含有车牌的帧进行标注,最终创建了一个包含 534 张图像的小数据集,这些图像中的车牌都有标记好的边界框。

数据集地址:https://github.com/RobertLucian/license-plate-dataset

然后我又找到利用 Keras 实现 YOLOv3 网络的代码,并用它来训练我的数据集,然后将我的模型提交到这个 repo,这样别人也能用它。我最终在测试集上得到的 mAP 是 90%,考虑到我的数据集非常小,这个结果已经很好了。

1、Keras 实现:https://github.com/experiencor/keras-yolo3

2、提交合并请求:https://github.com/experiencor/keras-yolo3/pull/244

CRAFT & CRNN

为了找到一个合适的网络来识别文本,我经过了无数次的尝试。最后我偶然发现了 keras-ocr,它打包了 CRAFT 和 CRNN,非常灵活,而且有预训练过的模型,这太棒了。我决定不对模型进行微调,让它们保持原样。

keras-ocr 地址:https://github.com/faustomorales/keras-ocr

最重要的是,用 keras-ocr 预测文本非常简单。基本上就是几行代码。你可以去该项目主页看看这是如何做到的。

第五步:部署我的车牌检测模型

模型部署主要有两种方法:

1、在本地进行所有的推理;

2、在云中进行推理。

这两种方法都有其挑战。第一个意味着有一个中心「大脑」计算机系统,这很复杂,而且很贵。第二个面临的则是延迟和基础设施方面的挑战,特别是使用 gpu 进行推理。

在我的研究中,我偶然发现了一个名为 cortex 的开源项目。它是 AI 领域的新人,但作为 AI 开发工具的下一个发展方向,这无疑是有意义的。

cortex 项目地址:https://github.com/cortexlabs/cortex

基本上,cortex 是一个将机器学习模型部署为生产网络服务的平台。这意味着我可以专注于我的应用程序,而把其余的事情留给 cortex 去处理。它在 AWS 上完成所有准备工作,而我唯一需要做的就是使用模板模型来编写预测器。更棒的是,我只需为每个模型编写几十行代码。

如下是从 GitHub repo 获取的 cortex 运行时的终端。如果这都称不上优美简洁,那我就不知道该用什么词来形容它了:

因为这个计算机视觉系统不是为了实现自动驾驶而设计的,所以延迟对我来说不那么重要,我可以用 cortex 来解决这个问题。如果它是自动驾驶系统的一部分,那么使用云提供商提供的服务就不是一个好主意,至少现在不是。

部署带有 cortex 的 ML 模型只需:

1、定义 cortex.yaml 文件,它是我们的 api 的配置文件。每个 API 将处理一种类型的任务。我给 yolov3 的 API 分配的任务是检测给定帧上的车牌边界框,而 crnn API 则是在 CRAFT 文本检测器和 crnn 的帮助下预测车牌号码;

2、定义每个 API 的预测器。基本上你要做的就是在 cortex 中定义一个特定类的 predict 方法来接收一个有效负载(所有的 servy part 都已经被平台解决了),这个有效负载来可以来预测结果,然后返回预测结果。就这么简单!

这里有一个经典 iris 数据集的预测器示例,但因为文章篇幅原因,具体细节在此就不做赘述了。项目链接里可以找到 cortex 使用这两个 api 的方法——这个项目的所有其他资源都在本文的最后。

# predictor.pyimport boto3 import picklelabels = [“setosa”, “versicolor”, “virginica”] class PythonPredictor: def __init__(self, config): s3 = boto3.client(“s3”) s3.download_file(config[“bucket”], config[“key”], “model.pkl”) self.model = pickle.load(open(“model.pkl”, “rb”)) def predict(self, payload): measurements = [ payload[“sepal_length”], payload[“sepal_width”], payload[“petal_length”], payload[“petal_width”], ] label_id = self.model.predict([measurements])[0] return labels[label_id]

为了做预测,你只需要像下面这样使用 curl 就行了:

curl http://***.amazonaws.com/iris-classifier \ -X POST -H “Content-Type: application/json” \ -d ‘{“sepal_length”: 5.2, “sepal_width”: 3.6, “petal_length”: 1.4, “petal_width”: 0.3}’

然后你会收到类似setosa这样的反馈,非常简单!

第六步:开发客户端

有了 cortex 来帮我进行部署之后,我就可以开始设计客户端了——这算是比较棘手的部分。

我想到了以下架构:

1、从 Pi Camera 以可接受的分辨率(800×450 或 480×270)收集帧速率为 30 FPS 的帧,并将每个帧推入一个公共队列;

2、在一个单独的进程中,我将从队列中取出帧,并将它们分发给不同线程上的多个工作站;

3、每个工作线程(或者我称之为推断线程)都会向我的 cortex API 发出 API 请求。首先,一个请求到我的 yolov3API,然后,如果有任何车牌检测到,另一个请求会带着一批裁剪的车牌发到我的 crnn API。预测的车牌号码将以文本格式返回;

4、将每个检测到的牌照(带不带识别后的文本都可以)推到另一个队列,最终将其广播到浏览器页面。同时,还将车牌号码预测推到另一个队列,以便稍后将其以 csv 格式保存到磁盘;

5、广播队列将接收一组无序的帧。consumer 的任务是先把它们放在一个非常小的缓冲区(几个帧的大小),每次广播一个新的帧给 client 重新排序。这个 consumer 在另一个进程上单独运行,它还必须尝试保持队列的大小固定为指定值,以便以一致的帧速率显示帧。显然,如果队列大小下降,那么帧率的下降是成比例的,反之亦然;

6、与此同时,在主进程中还会运行另一个线程,从另一个队列获取预测和 GPS 数据。当客户端收到终止信号时,预测、GPS 数据和时间也会被转存到 csv 文件中。

下图是客户端与 AWS 上的云 api 之间的关系流程图。

图 7:基于 cortex 提供的云 api 与客户端流程图

在我们的例子中,客户端是树莓派,推理请求发送到的云 api 由 AWS 上的 cortex 提供。

客户端的源代码也可以在其 GitHub 中找到:https://github.com/robertlucian/cortex-licens-plate-reader-client

我必须克服的一个挑战是 4G 的带宽。最好减少此应用程序所需的带宽,以减少可能的 hangups 或对可用数据的过度使用。我决定让 Pi Camera 使用一个非常低的分辨率:480×270(我们这里可以用一个小分辨率,因为 Pi Camera 的视野非常窄,所以我们仍然可以很容易地识别车牌)。

不过,即使是在这个分辨率下,每一帧的 JPEG 大小也是大约 100KB(0.8MBits)。乘以每秒 30 帧就得到 3000KB,也就是 24mb /s,这还是在没有 HTTP 开销的情况下,这是很多的。

因此,我用了一些小技巧:

将宽度减少到 416 像素,也就是 YOLOv3 模型所需要的大小,而且尺度显然是完好无损的;

1、将图像转换为灰度图;

2、移除图片顶部 45% 的部分。这里的想法是车牌不会出现在车架的顶部,因为汽车不会飞,对吧?据我所知,删除 45% 的图像并不影响预测器的性能;

3、再次转换图像为 JPEG,但此时的质量变低了很多。

4、最终得到的帧的大小大约是 7-10KB,这是非常好的。这相当于 2.8Mb/s。但是考虑到响应等所有的开销,它大约是 3.5Mb/s。对于 crnn API,裁剪过的车牌根本不需要太多空间,即使没有进行压缩,它们的大小也就是 2-3KB 左右一个。

总而言之,要以 30FPS 的速度运行,推理 api 所需的带宽大约是 6Mb/s,这个数字我可以接受。

结果

成功了!

上面这个是通过 cortex 进行实时推理的例子。我需要大约 20 个装备了 gpu 的实例才能顺畅地运行它。根据这一组 gpu 的延迟,你可能需要更多的 gpu 或是更少的实例。从捕获帧到向浏览器窗口广播帧之间的平均延迟约为 0.9 秒,考虑到推断发生在很远的地方,这真是太神奇了——到现在我还是觉得惊讶。

文本识别部分可能不是最好的,但它至少证明了一点——它可以通过增加视频的分辨率或通过减少摄像机的视场或通过微调来更精确。

至于 GPU 需求数太高的问题,这可以通过优化来解决。例如,在模型中使用混合精度/全半精度 (FP16/BFP16)。一般来说,让模型使用混合精度对精度的影响很小,所以我们并没有做太多的权衡。

总而言之,如果所有的优化都到位,那么将 gpu 的数量从 20 个减少到一个实际上是可行的。如果进行了适当的优化,甚至一个 gpu 的资源都用不完。

原文地址:https://towardsdatascience.com/i-built-a-diy-license-plate-reader-with-a-raspberry-pi-and-machine-learning-7e428d3c7401

via https://mp.weixin.qq.com/s/onN61A13xuJzNk9zE0hM-w

KUNBUS 工业树莓派十问十答

作者介绍:黄华潘,虹科首席工程师,4年现场总线测试和诊断经验,1年海外水泥厂生产线开发、测试和维护项目经验。近两年来研究基于树莓派的物联网和大数据采集应用,完美地将自己多年现场设备OT经验与物联网应用IT经验结合,为实现智能制造、万物互联贡献了自己一份力量。

1、问:工业树莓派与网上买的消费类树莓派有什么区别?

答:以我们虹科携手德国KUNBUS厂商推出Revpi系列产品为例,他们之间的区别主要有以下几点:

1)工业树莓派最大特点是经过了工业封装的,宽温,使用温度在-40至+55℃,IP20的防护等级,以及经过了工业标准测试(EN61131-2和IEC 61000-6-2),如EMI,浪涌和突发事件等等的测试,还有ESD的极性保护,达到4KV/8KV。其本身也是工业使用的外壳保护。

2)模块化,可扩展性,符合工业要求。聚碳酸酯材料外壳,DIN导轨安装,可通过我们简单的连接件连接扩展IO和网关等一系列模块,在工业场合使用起来非常方便。

3)工业树莓派安装了基于LINUX的Rasbian系统并安装了实时补丁,它是一个实时的系统,内部也做了一些软件集成,有单独的配置软件Pictory。

4)工业树莓派使用工业常用的24V左右电源,电源更为稳定,加装负载保护等等。

2、问:您这边的工业树莓派的相应配置如何?

答:我们这边的树莓派跟我们消费类树莓派的核心配置是一致的,计算模块的核心是完全一致的,都是博通的CPU,树莓派1代是BCM2835的CPU芯片,单核,700Mhz,500M的内存以及1G的闪存,而树莓派3代是BCM2837的CPU芯片,4核,1.2Ghz,1G的内存以及4G的闪存。树莓派3+的版本是BCM2837的CPU芯片,与3代其他配置保持一致,只是在闪存上有8,16,32G多种版本可以选择。

3、工业树莓派在散热方面表现如何?

答:工业树莓派的使用温度为-40~55℃,相较于消费类树莓派做了宽温的设计,在65℃时,工业树莓派也可以运行,但是不能全速运行,会降频,可能会降频到0.4GHz。另外工业树莓派本身外壳设计考虑了散热这一块,塑料外壳顶部和底部的通风孔,水平安装可以确保空气可以向上流过RevPi模块并冷却电子设备(烟囱效应)。另外我们也可以采用在控制柜安装风扇或者水冷的措施等等。或者有更高的散热要求,供应商也可以提供OEM的定制化设计。

4、问:工业树莓派的主要用途?

答:工业树莓派以其开源的特性广泛应用在工业上的各个领域,目前工业树莓派应用较多的领域有数据采集上传,小型控制,结合软件用作软PLC,工业物联网的网关,亦可做一些边缘计算的应用等,在工业领域有无限可能,我们也正在丰富和拓展更多的应用。

5、问:您的工业树莓派做PLC是如何实现的?

答:工业树莓派是结合第三方软件来用作PLC的,比如Codesys,LogiCAD等软件,实质上是一种软PLC的功能,在我们的工业树莓派中安装第三方软件的Runtime,在软件上进行配置,使其能够运行软PLC的能力可以用作EtherCAT,Ethernet/IP,CANopen等协议的主站。

6、问:树莓派如何采集工业现场数据?

答:这主要从以下几个方面:一是工业树莓派本身可以扩展一些IO模块,直接直接采集一些数字量模拟量的数据;二是工业树莓派本身具有Modbus的功能,可以充当Modbus RTU和TCP的主从站功能,可以采集Modbus数据;三是工业树莓派可扩展其系列网关模块,包含了主流的一些现场总线和工业以太网,如Profibus,CANopen,Profinet,Ethernet/IP,EtherCAT等等,可以通过网关采集工业现场各种控制层网络的数据。

7、问:我们注意到CM4已经出来,工业树莓派4代什么时候可以出来?

答:消费类树莓派4确实已于2019年年中已经出来了,目前KUNBUS还没有工业级别的CM4出来,待进一步成熟之后,KUNBUS也会也研发4代的工业树莓派版本。4代的版本的内存最高可达4G,主频达到1.5Ghz,有千兆的以太网口。

8、问:工业树莓派怎么与扩展模块进行连接?

答:工业树莓派的核心模块通过PiBridge或ConBridge与我们的扩展模块进行连接,PiBridge和ConBridge走的是内部通讯。模块采用DIN导轨,PiBridge或ConBridge都为插件,连接非常方便。

9、问:工业树莓派在中国的应用如何?工业树莓派在工业互联网上的应用?

答:目前来自中国虹科公司与德国KUNBUS公司共同推进我们工业树莓派产品在中国的发展。已经有大量的工业树莓派产品应用在中国的工厂和企业,包括博世等大厂。工业树莓派目前结合OPC UA,MQTT等标准和协议应用到工业互联网领域,通过采集工业现场的数据,放到工业树莓派里面进行计算处理或者上传到MES,ERP或者云端进行云计算处理。

10、能否举一个简单的实例来描述一下工业树莓派的应用?

答:举一个在能源领域的应用吧,在欧洲有一家能源信息管理的公司,结合KUNBUS工业树莓派计算和IT解决方案合作开发,用于分散式发电厂产生的能源的自动对等(P2P)交易。私人和商业电力生产商(例如,通过在屋顶使用太阳能发电厂)可以在彼此之间进行分散交易和直接交易,而无需任何中间商。这种新型基础设施的目标之一是,消费者可以较低的电价购买电力,也可售卖电力给电网上,减少对大型电力公司的依赖。为了使系统正常工作,各个发电厂和用户当然必须能够不断地相互交换数据。客户选择了RevPi Core硬件,并将其用作将每个参与者集成到分散式网络中的智能网关,也就是每个用户都会配备一个工业树莓派硬件进行计算采集,实现对电网和各家庭的能源管理。

了解更多关于 Revpi Connect 产品的信息请访问:

https://www.hongconsys.com/revpi/

HomeAssistant 安装避坑指南

来自 RaspiSQH 的投稿,原文。

前情提要

最近突然看到这篇教程,就想玩homeassistant,又不想重装系统,于是就找ha中文网看文档。

发现只要执行一句 sudo pip3 install homeassistant 就可以装,炒鸡开心呐~马上开工!然鹅,我还是太天真了。

环境:raspbian 2018-11-13(debian9)

这是为不想重装系统的同学们写的,如果不想

折腾可以**直接使用这篇教程的镜像安装**

pip 源之坑

安装HA需要正确食用pip。

错误示范

文档里面建议换国内源,于是我照做了。

Linux:~/.pip/pip.conf(~/是用户的根目录,一般是“/home/你的Linux账号名”;如果是采用sudo pip install ……命令,配置文件一般会位于/root/.pip/pip.conf。比如下面例子中配置文件位于/home/sam/.pip/pip.conf)

然后我试了一下加上这个后:

THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMEN TS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.

意思是 sha256 不匹配!

网上让我重试几次,鬼知道我试了几个小时。。。。

经过上面一顿操作,下载速度还是 5kb/s,而且还超时、错误。。。我注意到 pip 下载的源还是 piwheel 源,当然说明这堆操作毫无用处。

换源正确姿势

最终,我在一篇blog看到:树莓派的pip源应该在`/etc/pip.conf`

我一看:果然里面赫然写着:

[global] extra-index-url=https://www.piwheels.org/simple

哦豁!

然后我把网址改成`https://mirrors.aliyun.com/pypi/simple`

然后pip执行,速度嗖嗖的,基本上在5m/s,很顺利地完成了下载。

非常的 amazing 啊。

编译安装之坑

按上述步骤完成下载后很可能会卡在buliding wheels。如果卡某个库时间过长,干脆按下ctrl-c开始下一个库的安装吧。待到最后全部安装完,再尝试执行一遍`sudo pip3 install homeassistant`

不过据我的经验,仅仅这样子还是不行滴。

由于默认源piwheels.org有用于树莓派的armv7的whl文件,因此无需编译。但是换源后就不同了,由于大多数库没有armv7的whl,所以必须自行安装。这里就有一个大坑:buliding wheel总是会报错:

#include ^ compilation terminated. error: command ‘arm-linux-gnueabihf-gcc’ failed with exi t status 1 —————————————- ERROR: Failed building wheel for cryptography Failed to build cryptography ERROR: Could not build wheels for cryptography which use P EP 517 and cannot be installed directly

网上解决方法一般是安装pep517或者想办法安装gcc-arm-linux-gnueabihf。然并卵。

假如安装pep517,还是同样报错;如果安装arm-linux-gnueabihf-gcc之类的东西,就会有各种各样的错误,比如这样:

E: Unable to correct problems, you have held broken packages.

最后发现,问题不在这里,只需要安装两个库:

sudo apt-get install libffi-dev libssl-dev

然后,终端终于输出了久违的 successfully。

最后一公里

最后当然是运行啦。hass

我没遇到什么坑,感动中国。

这个阶段,hass 会自动找到需要的东西并自动 pip,当然也有失败的时候。不过这时候只要等一段时间就可以了。如果你没耐心,可以按下 ctrl-c 并运行 hass –skip-pip 来跳过安装那些库。不过这样可能会使得一些功能不可用。

Enjoy!

国内有很多关于ha教程,树莓派实验室也有很多可以参考。在经过一定了解后,这里有一份可用的实体列表可以参考,内容还是很全面的。

用树莓派改造 NumWorks 计算器

MAKER:Zardam/译:趣无尽 Cherry(转载请注明出处)

本期我们将用树莓派 Zero 研究 STM32,内容主要包括 DMA 和中断方面,用于改造 NumWorks 计算器 。由于 NumWorks 计算器是由 STM32F412 驱动,那么何不试着把它们放在一起,看看是什么效果。

如果你希望马上体验 NumWorks 的功能,这里有一个线上的 NumWorks 模拟器:

https://www.numworks.com/simulator/

工作原理

1、在计算器上添加一个应用程序,该程序将显示树莓派的输出以及从键盘向其发送的按键数据。

2、在树莓派上通过 SPI 驱动 fbtft 进行显示,并且 NumWorks 的一些裸露的焊盘包含了 SPI 总线。

效果如下:

显示来自 SPI 的数据

计算器固件已经完成了所有艰苦的底层工作(初始化显示),并提供了用于控制显示的 API。实际上,它是由 FSMC(柔性静态内存控制器)驱动的,因此从 CPU 的角度来看,该显示可通过两个静态地址访问,一个用于命令,一个用于数据,宽度为 16 位。

对于此应用程序,唯一需要设置的命令,是像素显示区域的命令,它已经在固件中实现。其中,推入像素就像将每个像素依次写入数据地址一样简单,并且它们将会在标准监视器中从左到右,从上到下显示。

因此,只需要将像素从 SPI 控制器复制到显示地址。对于 DMA 引擎来说,复制像素是非常简单的。

窗口的设置是在每一帧之前完成的,使用 SPI 总线中未使用的 MISO 引脚作为软件芯片的选择。因此,当 MISO 变低时,触发将中断,设置 SPI 控制器上的软件芯片选择,用于接受传入的数据,并在显示控制器中配置窗口,覆盖整个屏幕。

设置窗口大约需要 3µs,因此 DMA 的第一个字将延迟到达。在树莓派端,芯片选择和第一个输入字节之间大约有 10 µs 的延迟。

设置 GPIO

SPI 引脚必须设置为第二功能模式,以便在内部连接到 SPI 控制器。MISO 引脚保留为普通 GPIO,因为它用于触发中断。

GPIOA.MODER()->setMode(5, GPIO::MODER::Mode::AlternateFunction); GPIOA.AFR()->setAlternateFunction(5, GPIO::AFR::AlternateFunction::AF5); GPIOA.MODER()->setMode(6, GPIO::MODER::Mode::Input); GPIOA.MODER()->setMode(7, GPIO::MODER::Mode::AlternateFunction); GPIOA.AFR()->setAlternateFunction(7, GPIO::AFR::AlternateFunction::AF5);

设置 SPI 控制器

SPI 控制器的配置非常简单。它设置为 16 位模式,即 RXONLY 和软件芯片选择。MISO 引脚被复用于芯片选择。

SPI1.CR1()->setRXONLY(true); SPI1.CR1()->setSSI(true); // Software chip select SPI1.CR1()->setSSM(true); // Software chip select mode SPI1.CR1()->setDFF(true); // 16 bits SPI1.CR1()->setSPE(true); // enable

设置 DMA 控制器

为了使 DMA 工作,需要选择正确的 DMA 控制器,流和通道。然后配置源地址(此处为 SPI1 数据寄存器),目标地址(显示控制器数据地址),源和目标数据宽度( 16 位),模式(循环)以及编号要传送的数据(此处为 1,因为我们处于循环模式)。无需增加源/目标地址,它始终是相同的。

DMAEngine.SPAR(DMAStream)->set((uint32_t)SPI1.DR()); // Source DMAEngine.SM0AR(DMAStream)->set((uint32_t)Ion::Display::Device::DataAddress); // Destination DMAEngine.SNDTR(DMAStream)->set(1); // Number of items DMAEngine.SCR(DMAStream)->setCHSEL(3); // SPI Channel DMAEngine.SCR(DMAStream)->setDIR(DMA::SCR::Direction::PeripheralToMemory); DMAEngine.SCR(DMAStream)->setMSIZE(DMA::SCR::DataSize::HalfWord); DMAEngine.SCR(DMAStream)->setPSIZE(DMA::SCR::DataSize::HalfWord); DMAEngine.SCR(DMAStream)->setCIRC(true); // Circular DMAEngine.SCR(DMAStream)->setEN(true); // Enable

设置 SPI 控制器以发出 DMA 请求

启用 SPI 控制寄存器中的 RXDMAEN bit 即可完成。

SPI1.CR2()->setRXDMAEN(true); // enable DMA requests

通过 MISO 引脚设置中断

这个部分设置比较复杂。引脚和实际的中断处理程序之间有多个抽象级别。

1、将 EXTI(外部中断/事件控制器)配置为触发 NVIC (嵌套矢量中断控制器)中的中断线。

2、启用 NVIC 线,并定义相应的中断处理程序。不要忘记在处理程序中确认中断。

SYSCFG.EXTICR2()->setEXTI(Ion::Rpi::Device::ChipSelectPin, Ion::Rpi::Device::ChipSelectGPIO); EXTI.RTSR()->set(Ion::Rpi::Device::ChipSelectPin, true); EXTI.FTSR()->set(Ion::Rpi::Device::ChipSelectPin, true); NVIC.NVIC_ISER0()->set(23, true);

中断处理程序

这里有两种情况:

当 CS 变低时,它将激活 SPI 控制器的软件芯片选择,然后触发显示控制器中窗口的配置。

当 CS 变高时,它会禁用 SPI 控制器的软件芯片选择。SPI 上收到的任何数据都将被丢弃。

void rpi_isr() { EXTI.PR()->set(Ion::Rpi::Device::ChipSelectPin, true); if(GPIOA.IDR()->get(6)) { SPI1.CR1()->setSSI(true); } else { Ion::Display::Device::setDrawingArea(KDRect(0,0,320,240), Ion::Display::Device::Orientation::Landscape); *Ion::Display::Device::CommandAddress = Ion::Display::Device::Command::MemoryWrite; SPI1.CR1()->setSSI(false); } }

注意:

如果出现问题,不进行错误处理的话,整个链就可能会被阻塞。这主要发生在 SPI 控制器上。如果DMA 读取数据的速度不够快,它将被卡住,等待错误的确认。

通过 SPI 总线发送树莓派显示

按计划使用原始的 fbtft,但研究代码之后发现不能直接使用,因为它直接访问显示控制器,用于优化像素的推送(通过限制到屏幕上已更改的区域)。但我不想在计算器上实现这种功能,因此我决定自己编写代码。

https://github.com/notro/fbtft

通过使用 fbtft 的概念和代码,fbtft 是 Sprite_tm 编写的另一个驱动程序,也是内核内的 vfb 驱动程序,我组装了一个 “quick and dirty” linux 模块,该模块能满足我的需要:将整个帧缓冲区推到 SPI 总线。

http://spritesmods.com/?art=spitft

https://github.com/torvalds/linux/blob/ffefb181728f7b97df49ceba18cacfb6c5ee19f2/drivers/video/fbdev/vfb.c

显示器为 320×240 像素,每个 16bpp,因此每帧为 1228800 位。STM32F412 的最大 SPI 频率为 50MHz,但树莓派无法精确产生。经过测试使用 62.5 MHz,运行良好,因此,理论上最大帧速率为(1228800/(62.5×106))−1 ≈ 50 fps。

https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md

设置键盘

这是计算器上应用程序的最“灵活”的部分(SPI 和 DMA 在后台运行)。计算器只是通过 UART 将固件的键盘扫描例程的结果(64 位位域)发送到树莓派。在树莓派这端,守护程序在 UART 上侦听,并使用 uinput 生成内核的密钥代码。

https://www.kernel.org/doc/html/v4.12/input/uinput.html

在 Linux 端使用自定义键映射。我没有采用这种方式,因为仍然可以使用外部蓝牙键盘(而且我不知道是否可以在多个键盘上使用不同的键盘映射)。你可以去试试。

计算器键盘只有 46 个键,因此为了映射足够的键,按钮 “ x,n,t” 和 “ var” 用于在标准键和数字之间切换。并非标准键盘的所有键都被映射。这一点值得加强。

鼠标仅依赖于 X.Org 的鼠标仿真。按下电源按钮即可触发。

https://wiki.archlinux.org/index.php/Xorg/Keyboard_configuration#Enabling_mouse_keys

Calc Keymap 1 Keymap 2 {“left”, {KEY_KP4, KEY_KP4}}, {“up”, {KEY_KP8, KEY_KP8}}, {“down”, {KEY_KP2, KEY_KP2}}, {“right”, {KEY_KP6, KEY_KP6}}, {“ok”, {BTN_LEFT, BTN_LEFT}}, {“back”, {BTN_RIGHT, BTN_RIGHT}}, {“home”}, // not handled here {“power”}, // toggle mouse mode {NULL}, {NULL}, {NULL}, {NULL}, {“shift”, {KEY_LEFTSHIFT, KEY_LEFTSHIFT}}, {“alpha”, {KEY_CAPSLOCK, KEY_CAPSLOCK}}, {“xnt”}, // Switch to first keymap {“var”}, // Switch to second keymap {“toolbox”, {KEY_RIGHTALT, KEY_RIGHTALT}}, {“backspace”, {KEY_BACKSPACE, KEY_ESC}}, {“A”, {KEY_Q, KEY_F1}}, {“B”, {KEY_B, KEY_F2}}, {“C”, {KEY_C, KEY_F3}}, {“D”, {KEY_D, KEY_F4}}, {“E ,”, {KEY_E, KEY_F5}}, {“F”, {KEY_F, KEY_F6}}, {“G”, {KEY_G, KEY_F7}}, {“H”, {KEY_H, KEY_F8}}, {“I”, {KEY_I, KEY_F9}}, {“J”, {KEY_J, KEY_F10}}, {“K”, {KEY_K, KEY_F11}}, {“L”, {KEY_L, KEY_F12}}, {“M 7”, {KEY_SEMICOLON, KEY_7}}, {“N 8”, {KEY_N, KEY_8}}, {“O 9”, {KEY_O, KEY_9}}, {“P (“, {KEY_P, KEY_5}}, {“Q )”, {KEY_A, KEY_MINUS}}, {NULL}, {“R 4”, {KEY_R, KEY_4}}, {“S 5”, {KEY_S, KEY_5}}, {“T 6”, {KEY_T, KEY_6}}, {“U *”, {KEY_U, KEY_KPASTERISK}}, {“V /”, {KEY_V, KEY_KPSLASH}}, {NULL}, {“W 1”, {KEY_Z, KEY_1}}, {“X 2”, {KEY_X, KEY_2}}, {“Y 3”, {KEY_Y, KEY_3}}, {“Z +”, {KEY_W, KEY_KPPLUS}}, {“space -“, {KEY_SPACE, KEY_KPMINUS}}, {NULL}, {“? 0”, {KEY_M, KEY_0}}, {“! .”, {KEY_COMMA, KEY_COMMA}}, {“x10^x”, {KEY_LEFTCTRL, KEY_LEFTCTRL}}, {“ans”, {KEY_LEFTALT, KEY_LEFTALT}}, {“exe”, {KEY_ENTER, KEY_EQUAL}},

给树莓派供电

我首先采用的板子是树莓派 zero,不带 WiFi 版。当以 2.8 V(计算器上的内部稳压电压)供电时,起初工作良好,而且板子上配备了 SD 读卡器和一个晶体管来控制其电源。我决定重新使用 SD 电源板来控制树莓派的电源。

但之后发现,没有 WiFi 还是不方便,最终还是采用了带 WiFi 的版本。注意,2.8V 的电源不能稳定运行,WiFi 版本需要 3V 电源。禁用 WiFi 芯片(config.txt 中的 “dtoverlay=pi3-disable-wifi”)可以使树莓派在 2.8 V 的情况下正常工作。

https://www.cypress.com/file/298756/download

最后,我选用电池直接为树莓派供电。由于无法再使用 SD 卡的占用空间,因此在 SD 推车插槽占用空间的未连接引脚上焊接了晶体管,并以“自由型”方式上拉了电阻。

我使用了一个 NTR1P02LT1 和一个 10kΩ 电阻,但是任何能够处理至少 100 mA电流的 P 通道 MOSFET 也应该不错。

电压水平没有问题,因为 STM32 上使用的所有引脚都可承受 5V 电压。

树莓派会在进入应用程序时启动,并在计算器关闭电源时关闭。因此,可以根据需要离开或进入树莓派应用程序。

安装计算器

计算器很容易放入树莓派。树莓派的连接器所在的位置没有组件。我在 HDMI 接口和计算器的显示接口上用双面胶将其固定到位。

但还是有点厚,所以原后盖无法使用(切掉了垂直凸片),但可以将它留在原处。

树莓派的软件配置

GitHub 库:

https://github.com/zardam/spifb

仅需要安装内核头文件,编译,安装和自动加载模块。

sudo apt-get install raspberrypi-kernel-headers build-essential git clone https://github.com/zardam/spifb.git cd spifb make -C /lib/modules/$(uname -r)/build M=$PWD sudo make -C /lib/modules/$(uname -r)/build M=$PWD modules_install sudo depmod -a

/etc/modules

spi-bcm2835 spifb uinput

/boot/config.txt

dtparam=spi=on # Disable HDMI output, saves some power hdmi_blanking=2 # Enable the mini uart (/dev/ttyS0 on a PI Zero W) enable_uart=1 # Disable LED, saves some power dtparam=act_led_trigger=none dtparam=act_led_activelow=on

这里会出现两种可能性:

直接使用帧缓冲区。这是最简单的方法,但是树莓派 GPU 的硬件加速将不可用。

使用 fbcp 将普通帧缓冲区(fb0)复制到 SPI 帧缓冲区(spi1)。该副本会带来一些 CPU 开销,但是可以使用硬件加速,并且可以缩放帧缓冲区,因为 320×240 的分辨率几乎无法使用。

直接使用帧缓冲区

配置与使用 fbtft 相同。

/boot/cmdline.txt

fbcon=map:10

X Server

sudo apt-get install xserver-xorg-video-fbdev

/usr/share/X11/xorg.conf.d/99-fbdev.conf

Section “Device” Identifier “myfb” Driver “fbdev” Option “fbdev” “/dev/fb1” EndSection

fbcp

我使用了分支,用 CMake 来构建。

https://github.com/Oper8or/rpi-fbcp

sudo apt-get install cmake git clone https://github.com/Oper8or/rpi-fbcp.git cd rpi-fbcp mkdir build cd build cmake .. make

/boot/config.txt

hdmi_force_hotplug=1 hdmi_cvt=640 480 60 1 0 0 0 hdmi_group=2 hdmi_mode=87

/etc/systemd/system/fbcp.service

[Unit] Description=NumWorks input device After=systemd-modules-load.service [Service] Type=simple WorkingDirectory=/home/pi/rpi-fbcp/build ExecStart=/home/pi/rpi-fbcp/build/fbcp User=root Group=root Restart=on-failure [Install] WantedBy=multi-user.target

启用并启动服务

sudo systemctl daemon-reload sudo systemctl enable fbcp sudo systemctl start fbcp

键盘

GitHub 库:

https://github.com/zardam/uinput-serial-keyboard

git clone https://github.com/zardam/uinput-serial-keyboard cd uinput-serial-keyboard gcc uinput.c -o uinput

需要在 lxde 会话配置中禁用 lxkeymap(只使用 GUI 工具)。

必须禁用 linux 串行控制台。在 /boot/cmdline.txt 中,删除:

console=serial0,115200

/etc/systemd/system/nwinput.service

[Unit] Description=NumWorks input device [Service] Type=simple WorkingDirectory=/home/pi/uinput-serial-keyboard/ ExecStart=/home/pi/uinput-serial-keyboard/uinput User=root Group=root Restart=on-failure [Install] WantedBy=multi-user.target

然后,启用并启动服务:

sudo systemctl daemon-reload sudo systemctl enable nwinput sudo systemctl start nwinput

计算器

GitHub 库:

https://github.com/zardam/epsilon/tree/rpi

在计算机上,安装 NumWorks SDK 之后:

git clone -b rpi https://github.com/zardam/epsilon.git cd epsilon make epsilon_flash

然后连接并重置计算器,以便刷新自定义固件。

完成

在计算器的浏览器中运行 NumWorks 模拟器。

现在,整个项目已经完成,希望你喜欢这个项目。

via

使用 Python 将树莓派的 IP 发到邮箱

本文来自 CDWEN 的投稿。由于树莓派的使用场景中大多数没有配备显示器,那么如何得知树莓派的 IP 地址以便通过 SSH 客户端访问呢?

之前有介绍过一种将树莓派 IP 地址发送到邮箱的实现方式,是通过 mutt 和 msmtp 来实现的。下面将介绍另一种方式,通过 Python 和邮件服务商的 SMTP 服务器来发送带有 IP 信息的邮件。

需要编写两个脚本,Python 邮件发送脚本 mail.py 和获取树莓派 IP 信息的脚本 ip.sh。

mail.py 内容如下:

#!/usr/bin/python #-*- coding:utf-8 -*- import smtplib from email.mime.text import MIMEText import sys mail_host = ‘smtp.exmail.qq.com’ #smtp地址如果不知可以百度如“163邮箱smtp地址” mail_user = ‘邮箱账号’ #此账号密码是用来给人发送邮件的 mail_pass = ‘邮箱密码’ #此账号密码是用来给人发送邮件的 mail_postfix = ‘exmail.qq.com’ #邮箱地址,smtp地址删去smtp字符如“163.com” def send_mail(to_list,subject,content): me = mail_user+”<"+mail_user+"@"+mail_postfix+">” msg = MIMEText(content) msg[‘Subject’] = subject msg[‘From’] = me msg[‘to’] = to_list try: s = smtplib.SMTP_SSL() s.connect(mail_host) s.login(mail_user,mail_pass) s.sendmail(me,to_list,msg.as_string()) s.close() return True except Exception,e: print str(e) return False if __name__ == “__main__”: send_mail(sys.argv[1], sys.argv[2], sys.argv[3])

ip.sh 内容如下:

#!/bin/bash sleep 10 wlan0=`ifconfig wlan0 | head -n2 | grep inet | awk ‘{print$2}’` eth0=`ifconfig eth0 | head -n2 | grep inet | awk ‘{print$2}’` if ping -c 2 -W 3 www.baidu.com &> /dev/null ;then /home/pi/mail.py 收件人邮箱地址(不可与mail.py脚本中账号一致) “树莓派已经开机,成功获取到ip地址” “无线网络地址:$wlan0||有线网络地址:$eth0” fi

假设脚本在 /home/pi/ 目录下,给脚本赋予执行权限。

sudo chmod +x /home/pi/ip.sh sudo chmod +x /home/pi/mail.py

将脚本加入开机执行。

sudo vim /etc/rc.local

在 exit 0 之前加入下面一行

sudo /home/pi/ip.sh

重启树莓派,开机后等待一点时间,打开你的邮箱会收到一份树莓派的 IP 地址信息的邮件,知道 IP 之后可以更方便 SSH 连接到树莓派操作或进行 VNC 操作。

树莓派通信模块在 igus 智能塑料拖链系统上的应用

——树莓派通信模块通过灵活的数据集成实现预测性维护,提高IT安全性

使用树莓派通信模块分析机器数据

实现预测和计划维护是igus推出智能塑料解决方案的初衷和目标。例如,通过智能传感器测量拖链、回转盘和直线导向装置的磨损程度。通过KUNBUS树莓派通信模块,用户可以决定以何种形式集成传感器采集来的数据。从适用于限制性环境的离线模式,到将阈值连接到igus服务器以用于自动订购备件的在线模式,用户可以自由地集成和读取其数据。

图1 树莓派物联网工控机

igus智能塑料拖链系统包括通过系统监视器显示出实际使用寿命,并及时报告必要的维护。由igus提供的具有精确使用寿命数据的安全帽导轨模块已经可以离线用于维护计划。连接到系统监视器后,它会指示使用寿命,并在出现偏差时触发警报并建议进行维护。为了使该系统完全数字化,该模块可以在线模式运行,从而创造最佳的预测性维护方式。

通过树莓派通信模块,用户可以自行决定如何集成传感器中的数据。比如,SD卡离线集成,采用限时在线学习的半离线集成,以及通过与igus的IoT服务器连接实现的完全在线集成。

德国igus公司推出了isense系列传感器,用于检测igus拖链、电缆和轴承等部件的使用状况。这一系列传感器可以在运行过程中检测部件的磨损情况,并发出预警以提醒用户对设备进行维修或更换。与树莓派模块联网后,传感器检测到的数据将被传输到智能系统。这款树莓派模块可以和所有的igus传感器连接。例如,它可以连接用于测量磨损的传感器,或者用于测量拖链销孔连接磨损的传感器,又或者是在电缆监测中用于检测断裂和推拉力的传感器。当传感器的测量值被传输到树莓派模块后,这些数据就会被“解读”,同时分析并生成指令。目前,只需连接到igus云即可实现这一功能。

图2 树莓派通信模块应用在igus拖链简图

树莓派导轨模块连接igus配备的各类传感器,在智能塑料拖链系统运行过程中,不断采集拖链及轴承等部件信息,连接上层SCADA系统,为值班人员及决策者提供了使用寿命及维护信息,如果没有永久性的Internet连接,数据将保留在公司系统中,同时可以使用igus服务器进行手动控制的更新,以比较使用寿命,显示生产环境中所有即将发生的故障,这非常适合对日常顺利工作感兴趣的生产经理和值班主管使用,并可以有效地部署其维护技术人员 ,快速轻松地安装精益软件解决方案,所有消息均可以显示在其他工业PC上。

灵活的模式选择

工业4.0早已不再是一个纯粹的流行语—许多公司都在应用这些流程和计划,甚至有些已经开始实施;有些事情进展很快,有些则需要更多时间。进行数字化转型的方式与存在的公司一样多。他们都知道,数字化不仅仅是通过互联网进行物联网,收集大数据,在云中工作或建立智能工厂。当然我们也更关注于安全。借助树莓派模块,其中可通过导轨模块可靠地显示系统的使用寿命和维护建议。为此,我们响应了公司运营商的各种需求及其数字化战略,因为该概念包含三种不同的数据使用方式:在线,半离线和离线。这些不是不同的系统和模块,而仅仅是模块处理传感器数据的方式不同。

图3 使用树莓派模块的智能塑料拖链系统

1.离线模式

除了维护建议,还可以捕获,收集和评估传感器数据,例如磨损信息。借助新模块,提供了一种技术解决方案,可将传感器数据传送到控制系统面板,例如,将所有配备传感器的e-chains,iglidur滑动轴承或chainflex电缆的运行条件或维护说明可视化。这具有很好的效果,尤其是在大型生产设备中,在没有互联网连接的情况下显示大量传感器数据结果。

2.半离线模式

即使模块离线运行,当系统参数更改时,用户也可以不时地将其实际测量数据与igus服务器的数据进行比较。为此,可以将模块切换到半离线模式。通过与igus服务器的安全数据进行的短期在线连接同时可以传输加密数据。重新计算使用寿命后,更新的使用寿命数据将被加密,并由igus服务器返回给模块。传输完成后,模块将返回离线模式。

3.在线模式

客户可以选择从一开始就在生产中以在线模式使用该模块。然后,通过igus服务器对使用寿命进行连续比较。数据使用AES 25加密并永久同步。对于客户而言,这意味着可以以最佳的方式利用系统的使用寿命并将故障风险降到最低。 无论在生产工厂中如何使用该模块的操作模式,它都是最大化运行时间并符合所有IT安全标准的。同时,数据丰富的模块和在线操作的结合为预测性维护奠定了基础。从长远来看,这可以降低服务成本。值班主管和维修人员放心了,仓储变得更加高效。如果您想更进一步,则可以连接到igus自己的ERP系统,并以报价和日期建议的形式自动接收建议,以进行必要的维护。踏上数字化之路的公司通过工业树莓派模块获得新的可能,这对他们提供了帮助。

通过连接到igus服务器来进行预测性维护

将用户的树莓派工控机和igus的数据库联网后,可以实现使用寿命计算与igus云的持续匹配,从而实现最大的系统运行时间,并将故障风险降至最低。云中的数据来源于igus在其占地3,800平方米的测试实验室中所进行的100亿次拖链和电缆测试循环。通过机器学习和人工智能,igus可以提供关于解决方案的耐久性情况的精确信息,并向用户发出必要的维护预警。

相关教程:

基于树莓派实现 Modbus TCP 通讯的工业方案

基于树莓派codesys主站实现CANopen通讯

了解更多关于 Revpi Connect 产品的信息请访问:

http://hkaco.com/zdh/KUNBUS/revolution/revolution.html

树莓派、HomeAssistant、微信小程序实现智能家居互联

本文来自 @店长大人 投稿。

树莓派4是开源硬件,Home assistant 是开源软件。当 Home assistant 遇上树莓派,强大的开源物联网互联平台让你体会科技带来的极度满足感。

本文介绍如何利用你手中的树莓派打造一个物联网平台,实现微信小程序远程控制管理,打开你的树莓派摄像头。

材料清单

树莓派—我用的是最新的树莓派4-2G版,性能强大,但是耗电恐怖,电源必须3A,不建议无散热裸跑。

树莓派CSI摄像头,USB也可以啦,只是后面的配置需要修改下。

Let’s go!

一、Home assistant 安装

根据HA官方和@cxlwill大神的推荐,树莓派安装HA有4种方式。由于本人极度喜欢简单系统,所以采用的是Hassbian无界面镜像安装。

镜像地址:https://github.com/home-assistant/pi-gen/releases/tag/v1.6.1

其他方式请移步以下网站参阅:

https://home-assistant.cc/installation/raspberrypi/

https://www.home-assistant.io/hassio/installation/

将系统烧录到SD卡后,如果不方便给树莓派接网线,还想启SSH服务的话,接入wifi,可以先将SD卡插在电脑上,在SD卡根目录下建立名为SSH的空文件夹,并且建立名为wpa_supplicant.conf的文件,在里面添加下面代码:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev network={ ssid=”你家里的WIFI名” psk=”WIFI密码” }

然后把SD卡插入树莓派,开机。耐心等15-20分钟左右,然后用你的浏览器访问http://“树莓派ip”:8123 即可访问到Home assistant,当当当!!!如下图:

在这里,你需要先设置下你的账号和密码。设置好了,登录即可。

二、配置你的树莓派摄像头,实现在HA中访问

此处以树莓派自带的CSI摄像头为例:

首先通过SSH连接树莓派或者直接在树莓派界面环境中运行命令行。

输入 sudo raspi-config 回车

选择:Interfacing Options>Camera>YES

打开树莓派摄像头服务。

回到Home assistant 主页,左侧选择开发者工具,在右侧发现Home assistant的配置文件路径,接下来我们开始配置HA的组件。

根据配置文件地址,在命令行终端中修改HA的配置文件。

sudo nano /home/homeassistant/.homeassistant/configuration.yaml

在文件最后添加如下代码:

camera: – platform: rpi_camera name: pi_camera

如图

然后ctrl+x >Y保存退出

修改好了配置文件,返回HA主页, 每次修改了配置以后,我们都要先检查下配置有没有问题,然后再重启HA服务器。步骤如下:

在HA主页左侧点击标签 “配置“,在右侧选择”服务器控制“,点击“检查配置”,等配置有效后,即可点击重启服务器,然后等半分钟左右,刷新即可。

接下来,进行摄像头添加,在HA中,每一个接入的设备或者服务叫做实体。配置好新的设备后,需要手动添加进入概览页面才可以。

点击左侧“概览”标签,页面右上角点击三个点的那个更多图标,选择配置UI进入页面编辑。

选择右下角加号图标,在出现的许多标签中选择“实体“,填写标题后,在下拉菜单中选择你的摄像头,名字为:camera.pi_camera,点击保存。回到HA首页,此时如果运气好的话,你就可以在概览页面看到你的摄像头了。

三、使用微信小程序绑定HA,实现远程访问

感谢国内大神Hawk开发的Molohub微信小程序,让HA不再需要各种复杂的内网穿透,映射,就可以远程访问。项目地址如下:

https://github.com/haoctopus/molohub

1、使用以下代码一键安装:

curl –silent –show-error –retry 5 https://raw.githubusercontent.com/haoctopus/molohub/master/auto_install.py | sudo python

安装完成后,重启HA服务。

2、点击访问https://www.molo.cn/,选择微信登录。添加小程序后,在HA主页的左下角通知中点击wechat,找到设备二维码,在小程序中扫描,即可按操作绑定你的HA。

然后你就可以在你的微信小程序中访问到你的HA了。建立绑定关系以后,无论你的树莓派ip地址如何变化,你都可以用手机控制你的智能家居了。Cool!

四、更多

HA目前支持接近2000种设备的接入。具体操作方法可以参考官方的组件配置说明。

其中包括了树莓派本身的GPIO控制功能,可以使用它来控制本地的LED灯开关。正巧我手中有个HA支持的小米的花花草草检测仪,是通过蓝牙接入的。经过配置,它已经完全在HA中显示了。请见下图

我在HA配置中新添加的代码:

sensor: – platform: miflora mac: ‘xx:xx:xx:xx:xx:xx’ //此处是花花草草检测仪的MAC地址 name: Flower 1 force_update: true median: 3 monitored_conditions: – moisture – light – temperature – conductivity – battery

树莓派 + DDNS 绑定域名实现外网访问

来自 yoyolife 的投稿。

目前的资料收集情况来说,只有中国电信可以开通外网IP。另外,不能使用80端口。如果你要80就不用往下看了。

我的开通过程是。微信找到中国电信公众号,找到客服,和他说你要开通IP回退(公网IP),他问你必须的验证资料后,然后等那个半天。电信小哥会到你的社区里面,把你的网口从一个盒子换到另外一个盒子,然后他会打电话给你。你重启一下。进入路由,看到的外网的ip,和你去baidu 打 ip 看到的ip是一样的了。如果不这么做,你得到的只是一个大局域网的ip。外面是不能访问的。

当你有了外网ip。然后你就要开始设置你的光猫和路由器。我用的是TPLink路由,你们用啥基本上是大同小异。

我们要做的事情是,关闭光猫的自动拨号功能,用路由器来拨号。现在默认光猫出厂,就能自己上网,因为光猫会自动帮你拨号了。我们要换成自己的路由器拨号,并开启DMZ公开你的树莓派到网外。

进入192.168.0.1 进入超级管理员

username=”telecomadmin”

web_passwd=”nE7jA%5m”

然后到 网络-宽带设置 把你拨号模式改成Bridge模式VLAN ID 设为41 如图

然后进入你的路由器192.168.1.1 进入WAN设置,使用PPPoE拨号

这个时候,你的IP和你外网的IP是一样了。

然后进去DMZ主机

把树莓派内网地址写上去。

这个时候,你用你的外网IP 就能进入SSH

重点来了。现在你要设置DDNS让你的域名当IP改变时可以自己绑定新的IP

登陆阿里云后

进入 https://ram.console.aliyun.com/users RAM 访问控制

新建立用户给权限

把这4个权限选上。然后开始跑我下面的python代码

先安装

pip3 install aliyunsdkcore pip3 install aliyun-python-sdk-alidns

# coding: utf-8 from aliyunsdkcore.client import AcsClient from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest import time import json import urllib.request ##这里要换成自己的哟 client = AcsClient(‘AccessKey ID’, ‘Access Key’, ‘cn-hangzhou’) def get_internet_ip(): with urllib.request.urlopen(‘http://www.3322.org/dyndns/getip’) as response: html = response.read() ip = str(html, encoding=’utf-8′).replace(”

“, “”) return ip def Describe_SubDomain_Records(client,record_type,subdomain): request = DescribeSubDomainRecordsRequest() request.set_accept_format(‘json’) request.set_Type(record_type) request.set_SubDomain(subdomain) response = client.do_action_with_exception(request) response = str(response, encoding=’utf-8′) relsult = json.loads(response) return relsult def add_record(client,priority,ttl,record_type,value,rr,domainname): request = AddDomainRecordRequest() request.set_accept_format(‘json’) request.set_Priority(priority) request.set_TTL(ttl) request.set_Value(value) request.set_Type(record_type) request.set_RR(rr) request.set_DomainName(domainname) response = client.do_action_with_exception(request) response = str(response, encoding=’utf-8′) relsult = json.loads(response) return relsult def update_record(client,priority,ttl,record_type,value,rr,record_id): request = UpdateDomainRecordRequest() request.set_accept_format(‘json’) request.set_Priority(priority) request.set_TTL(ttl) request.set_Value(value) request.set_Type(record_type) request.set_RR(rr) request.set_RecordId(record_id) response = client.do_action_with_exception(request) response = str(response, encoding=’utf-8′) return response def wirte_to_file(path,ip): f = open(path, ‘w’) # 若是’wb’就表示写二进制文件 f.write(ip) f.close() def domains(domain): try: des_relsult = Describe_SubDomain_Records(client, “A”, domain[‘full’]) # 判断子域名解析记录查询结果,TotalCount为0表示不存在这个子域名的解析记录,需要新增一个 if des_relsult[“TotalCount”] == 0: add_relsult = add_record(client, “5”, “600”, “A”, ip, domain[‘left’], domain[‘right’]) record_id = add_relsult[“RecordId”] print(“域名解析新增成功!”) # 判断子域名解析记录查询结果,TotalCount为1表示存在这个子域名的解析记录,需要更新解析记录,更新记录需要用到RecordId,这个在查询函数中有返回des_relsult[“DomainRecords”][“Record”][0][“RecordId”] elif des_relsult[“TotalCount”] == 1: record_id = des_relsult[“DomainRecords”][“Record”][0][“RecordId”] update_record(client, “5”, “600”, “A”, ip, domain[‘left’], record_id) print(“域名解析更新成功!”) else: record_id = 0 path = ‘./RecordId’ wirte_to_file(path, record_id) except Exception as e: print(e) while True: ip = get_internet_ip() with open(“./ip”, ‘r’) as f: old_ip = f.read() if ip == old_ip: print(“noupdate” + ”

new_ip:” + ip + ”

old_ip:” + old_ip) else: wirte_to_file(“./ip”, ip) ##多个域名 domains({‘full’:”*.tunnel.xxx.fun”,’left’:”*.tunnel”,”right”:”xxx.fun”}) domains({‘full’:”tunnel.xxx.fun”,’left’:”tunnel”,”right”:”xxx.fun”}) domains({‘full’:”*.frp.xxx.fun”,’left’:”*.frp”,”right”:”xxx.fun”}) time.sleep(10)

保存为 ddns.py 文件

在同级目录输入

touch ip touch RecordId

然后运行

python3 ddns.py

就会每10秒刷新一次ip 有改变就会去修改ddns

然后你可以把py放到supervisor里面守护

也可以放到 /etc/rc.local启动运行

也可以放到后台进程

nuhup python3 ddns.py &

守护这东西我就不详细说了。

这样你就有了 全速的网络,你可以做 NAS 或网盘 或什么你喜欢。

来自 yoyolife 的投稿,出处:http://www.yoyolife.fun:9000/blog/post/5e0d9acd9b86720030000154

树莓派和HMC5883(QMC5883)的使用方法(C语言)

本文来自 制造技术研究社 的投稿。

HMC5883是霍尼韦尔公司生产的一款地磁场检测芯片,其国产替代产品为QMC5883。这两种芯片基本相似,QMC 5883也是号称得到了霍尼韦尔公司的授权。

两款芯片在外观上没有明显的区别,本人在某宝上购买的QMC系列芯片上居然堂而皇之写着HMC5883,如果两者搞混了,就难得出正确结果。

网上有很多采用单片机虚拟i2c总线读取数据的例程,也有采用Python读取i2c总线数据的例子,但是如何利用linux系统中直接用C语言来读取数据的例子比较少,而且不是全面。很多专业的linux系统书籍中偏重于介绍如何编写i2c总线驱动程序,较少介绍如何直接利用系统中现有的命令读取数据。

本文主要介绍如何利用树莓派(Linux系统,3B+和4B+型号都通用)下读取5883系列传感器的数据,直接调用Linux系统中的指令来读取i2c总线上的数据。

一、硬件连接

首先HMC 5883模块具有4个引脚,Vcc、GND、SCL和SDA,分别连接到树莓派对应的引脚,Vcc接树莓派的5V电源即可,SCL和SDA接到i2c-1总线上(注意,请不要接到0号i2c总线上,需要进行另外设置才能打开该总线)。

二、开启总线,安装i2ctool工具

连接成功之后,首先要打开i2c总线,在树莓系统默认中是关闭i2c总线的,可以通过raspi-config配置界面中的interface开启(enable)i2c总线。

开启总线后,还需要安装i2ctool工具,才方便调试i2c总线,这是一个很小的工具。在控制台输入:

sudo apt-get install i2c-tools 命令即可安装i2c-tools。

安装完成后可以使用i2cdetect -l查看i2c总线开启情况:

使用i2cdetect -y 1命令即可扫描接在总线上的所有I2C设备,并打印出该设备的I2C总线地址。

这时,显示了该总线上挂载了一个设备,地址为0x0d,0x0d(二进制为0000 1101)是QMC 5883的7位地址,(注意:HMC 5883的7位地址是0x1e,这是两种芯片的第一处不同。)

数据手册上会说到8位地址,8位地址是这样计算的:将7位地址左移1位,读地址为末位加1,则对应的8位地址为0x1b(二进制为0001 1011 ),写地址为末位加0,则对应的8位地址为0x1A(二进制为0001 1010 )。但是利用linux系统自带的驱动程序不需要使用8位地址,7位地址就足够了。

另外微信公众号“制造技术研究社”觉得几个有用的指令是:

1、查看数据:i2cdump -f -y 1 0x0d 查看0d地址下所有地址上的数据

2、写寄存器:i2cset -f -y 1 0x0d 0x09 0x01 设置相应寄存器的数值,这里是向地址为0x0d设备下的0x09地址写入0x01这个数据。

三、QMC 5883和HMC 5883的芯片设置

QMC 5883需要设置0x09,0x0B、0x20、0x21这四个寄存器的内容,其中0x0B是置位复位的周期,默认值为0x01, 0x09是控制寄存器,bit0和bit1控制采样模式,分别为连续模式和等待模式,00是等待,01是连续模式,bit2和bit3是采集速率,bit4和bit5是测量范围,00为正负2高斯,01为正负8高斯,bit6,bit7是过采样率,这里是说多采集一些数据,得平均值的意思,这里可以不管。总之0x09的默认配置为0x0d或者0x1d。总结以上,QMC 5883需要配置的寄存器为:(值得吐槽的是,0x20和0x21寄存器是一定需要设置的,但是这个点在datasheet里面居然没有说明!)

芯片地址0x09数据为=0x0d/0x1d;

芯片地址0x0B数据为= 0x01;

芯片地址0x20数据为= 0x40;

芯片地址0x21数据为= 0x01;

根据测试的需求,很明显需要先配置这四个寄存器。

而对于HMC 5883需要配置3个寄存器,也就是i2c设备的头三个地址0x00、0x01、0x02,分别被称为配置寄存器A、配置寄存器B,模式寄存器,配置寄存器A设置过采样率和测试频率,配置寄存器B设置增益大小(放大系数、检测数据和磁场值的转换系数);模式寄存器是设置采样模式。

详细的配置说明可以参见数据手册,也可以联系微信公众号:“制造技术研究社”,留言获得。

总之,HMC 5883的配置参数可以按照以下内容:

#define HMC5883_CRA 0x14 采样频率30Hz #define HMC5883_CRB 0xe0 测量范围正负8.1高斯 #define HMC5883_MR 0x00 连续测量模式

四、QMC 5883和HMC 5883的测量数据

QMC 5883的数据存储在0x00-0x05连续6个地址,0x00是X方向的低8位数据,0x01是X方向的高8位数据;0x02是Y方向的低8位数据,0x03是Y方向的高8位数据;0x04是Z方向的低8位数据,0x05是Z方向的高8位数据;

HMC 5883的数据存储在0x03-0x08连续6个地址,顺序为XZY,(这又是不同点),0x03是X方向的高8位数据,0x04是X方向的高8位数据(高低次序也不同),其余类推。

所以只要将这些数据读取出来,就可以实现对磁场的测量。

五、调用linux驱动程度读取数据

以上全部为准备知识,只有清楚认识了5883系列芯片,才能正确读写芯片。虽然网上有些利用wringPi程序来读取i2c总线的方法,但是没有关于如何采用C语言编程读写芯片的例子,下面以QMC 5883的读取程序为例,详细讲解如何用C语言调用i2c总线驱动程序。

首先C语言头文件要包含基本输入输出函数stdio.h、

IO控制头文件

标准库函数

文件控制头文件

Linux下的i2c驱动头文件 Linux下的i2c设备头文件 其次,定义一些产生的地址常数,

其中#define QMC5883 “/dev/i2c-1″是linux系统的特色,将所有的设备看作挂载的路径,

#define Gain 12000 是配置数据和磁场值的转换系数,在文末解释了如何计算磁场和系数。

第三部分 i2c读写函数及流程

在检测之前,先要将配置数据写入设备中,以写入0x09寄存器和0x0B寄存器为例,

首先获得文件ID,

int fd=open(QMC5883,O_RDWR);

通过open函数,就获得了文件的ID,其中O_RDWR是系统自定义的宏,表示以读写模式打开文件,open( )函数的返回值是一个大于0的数,被称之为文件ID(file_ID),如果返回值为0,或者负数,说明读写文件出现了问题。

在后面的程序中,只要调用file_ID,就可以实现了对接口的调用。

注意,在读取结束,要close文件。

第二步是定义一个数组QMC5883_init_config_1[4],

QMC5883_init_config_1[4]={0x09,QMC5883_0x09,0x00,QMC5883_0x0B};

数组的第一个值是0x09,表示i2c设备的子地址(寄存器的地址),就是说在从第9个地址开始写入,顺序将后面的数据写入设备,该数组后面的数据就是需要配置的值,分别为0x0d、0x00、0x01,执行该指令后,LINUX系统驱动程序会在0x09地址之后,陆续写入这3个数,(其中地址0x0A的数据不需要写入,这里写进去只是为了方便。)

接着定义另一个数组,配置其他寄存器

QMC5883_init_config_2[3]={0x20,QMC5883_0x20,QMC5883_0x21};

完成了四个寄存器的配置,接下来将读写指针调回到数据地址的首地址,

定义一个无符号数suba,unsigned char suba=0 这个数的指针提出来,写入文件,读写指针就回到了0x00位置。

第三步是读取数据,

读取数据的函数为read(),其格式和write()很相似

unsigned char QMC5883_read_data[6]; read(fd,QMC5883_read_data,8);

XYZ三个方向的数据分别存在连续的6个地址内,将低8位(LSB)的数据左移8位,再和高8位“求或运算”就得到了测量的磁场数据。

最后将数据显示出来就可以了。

注:这里通过while循环,实现连续不断的测量,想要中止的话,按下Ctrl+C跳出循环,中止程序即可。

HMC 5883的读写方式也与此类似,可以对照写出程序,也可以联系微信公众号“制造技术研究社”,进一步交流相关内容。

总结:

读写5883系列传感器,关键是掌握linux系统下设备的读写,首先要掌握传感器的配置内容,其次一定要注意各个地址的区别,在正确的地址读写正确的内容。

附1:磁场的计算

传感器测出的数据为一个整型数据hpx,当测量范围为2Guass的时候,增益系数为12 000,那么磁场值为hpx/12000(Guass)

注意一,磁场强度的单位为A/m,在空气中,A/m和高斯的转换关系为1高斯=79.62A/m,可以继续转换为磁场强度作为单位。

注意二:整型数和实数之间还要注意数据类型的转换。

附2:源代码

/************************************************/ /* *Magnetic testing Program */ /* Edit by: Doctor Han in HFUT */ /* Date:2019.12.23 */ /************************************************/ #include #include #include #include #include #include #define QMC5883 “/dev/i2c-1” #define QMC5883_ADDR 0x0d //adress #define QMC5883_0x0B 0x01 //set/reset period #define QMC5883_0x20 0x40 //unkown configration #define QMC5883_0x21 0x01 //unkown configration #define QMC5883_0x09 0x0d //Configration #define Gain 12000 int main() { //printf(“Testing by QMC5883L (From i2c Bus)

“); int fd=open(QMC5883,O_RDWR); int i; int Num=1; unsigned char QMC5883_init_config_1[4]={0x09,QMC5883_0x09,0x00,QMC5883_0x0B}; unsigned char QMC5883_init_config_2[3]={0x20,QMC5883_0x20,QMC5883_0x21}; unsigned char suba=0; unsigned char QMC5883_read_data[6]; //unsigned char QMC5883_write_data_buff[4]={0,QMC5883_CRA,QMC5883_CRB,QMC5883_MR}; double Hx,Hy,Hz,Temp; short int hpx,hpy,hpz,temp; if(fd<0) { printf("Open QMC5883 failed "); } if(ioctl(fd,I2C_SLAVE_FORCE,QMC5883_ADDR)<0) { printf("Address fault "); close(fd); } //while(1) //{ write(fd,QMC5883_init_config_1,4); write(fd,QMC5883_init_config_2,3); write(fd,&suba,1); read(fd,QMC5883_read_data,8); hpx=*QMC5883_read_data; hpx=*(QMC5883_read_data+1)<<8|hpx; hpy=*(QMC5883_read_data+2); hpy=*(QMC5883_read_data+3)<<8|hpy; hpz=*(QMC5883_read_data+4); hpz=*(QMC5883_read_data+5)<<8|hpz; printf("No=%d ",Num); //printf("Hx=%d ;Hy=%d ;Hz=%d ",hpx,hpy,hpz); Hx=hpx*79.61/Gain; Hy=hpy*79.61/Gain; Hz=hpz*79.61/Gain; Temp=temp*1.00/100; Num=Num+1; printf("Hx=%f A/m; Hy=%f A/m; Hz=%f A/m; ",Hx,Hy,Hz); //} return 0; close(fd); }

Home Assistant 给你的鱼缸灯加点小确幸

MAKER: 店长大人

前几天家里的鱼缸灯突然就坏掉了,先是疯狂的无规律的间歇性频闪,我以为是受潮进水了,拆开检查了一下又重新安装了各个插头,然后它又坚持了一周,最终挂掉了。因为它的控制板用的是ASEMI家的PL61T020,可以通过触摸切换LED颜色。嗯,看起来不错,可它怎么就能坏掉了呢?主控板修起来很费劲,板子长这样(我把16V稳压电容拆了):

因为之前一直在学习Home assistant配置的物联网智能家居环境,我突然产生了很大胆的想法,为何不把整个板子换掉,用树莓派或者arduino驱动12V RGB灯组,然后接入Home assistant实现鱼缸灯的智能化呢?

好主意!那就开始动手搞!

材料准备

树莓派,搭载home assistant,具体配置,之前我写过一个乱七八糟的帖子,根据那个帖子完全可以在树莓派上配置好HA。

Arduino,我用的是UNO,便宜,80块不到。

Zigbee自组网模块,两个。如果你想把树莓派和arduino都扔到鱼缸中,可以不用它,用ttl串口完全就可以了,之所以用zigbee其实大部分只是为了提升逼格。

TIP41系列,3个。这是NPN达林顿三极管,驱动RGB灯用的,其实S8050就可以了,之所以用TIP41,是因为觉得看上去就很踏实。

1K电阻三个,16V电容1个,洞洞板。其他电路保护装置可以根据能力自己添加。

12V转5V的DC降压模块,或者其他给Arduino供电的模块。

先上成品图:

然后是驱动部分的电路图:

现在开始正式写流水账式的步骤了。

一、制作驱动电路部分

我家的这款鱼缸,原始电路部分四个模块,用图给解释下:

超级简单有没有,卖300+大洋啊。

接下来,我把12VDC到控制器的线取下来,拿掉传感器,拆掉灯组,把主控整个扔地上,使劲跺两脚,扔碎纸机里碎干净。额。。。当然记得把16V稳压电容取下来。

然后开始重组这个电路,RGB的工作原理很简单,共阴的RGB灯组,共有四根接线,分别是R G B 和+12V。如图:

从上至下依次是绿,红,蓝,+12V,那RGB工作时最简单的是三色叠加原理,如果想实现复杂颜色,可以调整每个颜色的色度,基色组合请看下图:

所以,只需要使用arduino三个IO管脚来驱动三极管,开闭对应颜色就好。因为我的是12VRGB,不可以直接用IO管脚来开闭大电压,只能用三极管来驱动大电压。电路图见上面。我的灯组是内带电阻的,所以不用额外加电阻来给LED限流,只需要把灯组上的接线接在NPN三极管的集电极就行。

如果你用PNP管子的话,那就是负逻辑了,此处不多说。三极管的发射极直接接地,基极是要接Arduino的IO口的,不过要加个1K欧的电阻用来限流。因为Arduino是要跟灯组一起最终封在原盖子里,所以此处我选择的是用12V灯组的电源分点过来给Arduino,到时候直接插上原来的插头就解决供电问题了。然后全部怼在洞洞板上,此处省略无数怨念!此处多说几个字,如果想把这个电路搞得好一些,还需要做一些电路保护,和防水保护。

三电学的好的同学,完全就可以自由发挥了,电容,电感,电阻一类的按需求怼吧,顺便的话最后的成品都可以商用了。

上图:焊工不好,切勿吐槽:

二、树莓派和Arduino通讯部分

之所以会选择用zigbee来通讯,纯粹是因为手头正好有这个模块,闲置也是闲置,为何不让逼格升起来呢?!当然不愿意买这个模块也可以选择USB/TTL直连,接线少,更稳定。

上图:

如果使用我这个方案,请将自组网zigbee波特率设置在57600,通讯模式是点对点模式(A or B)。Zigbee自组网,基本不用配置,连上就能直接用。

嗯嗯,树莓派端我选择用USB外挂的zigbee,是因为自带的软串口(TX/RX)又更多的任务,比如一键关机啥的,所以USB是比较好的方案。

三、软件配置部分

以上都准备好了,那就开始搞软件。

1.首先,根据HA的官方文档,给Arduino上载Firmata固件,见官方链接:

https://www.home-assistant.io/integrations/arduino/

https://github.com/firmata/

要求使用StandardFirmata分支,因为我手里的是UNO,所以经过多次尝试,我最终用烧录的是这个:

https://github.com/firmata/StandardFirmataYun 在编译之前,请把代码中的Serial1全部替换为Serial,好像是Arduino没有Serial1这个端口。编译,上传。。。。上传的时候一定要断开外部串口,我就是因为插着zigbee烧录,搞了好久都上不去!哎呀妈呀!全是坑!

2.树莓派端,根据之前的帖子配置好HA以后,先把Arduino平台写在配置文件中:

arduino:

port: /dev/ttyACM0

注意此处的ttyACM0是你的串口号,因为我用的是USB转zigbee,所以我的串口号实际是:ttyUSB0,所以请根据实际情况修改端口。至于如何看端口号,请参考下面的命令:

ls /dev 或 dmesg 或 journalctl -f 多个命令进行查看

接下来请赋予HA用户使用串口的权限:

sudo usermod -a -G dialout $USER

然后我们再安装下pyFirmata库,我也被它困惑了一会,多谢HA的错误日志的提醒。

sudo pip3 install pyFirmata

然后,在配置文件中添加三个switch实体,如下:

switch: platform: arduino pins: 8: name: Green LED 12: name: Red LED 13: name: Blue LED

也就是定义了Arduino的三个端口,每个端口驱动不同的三极管,也就对应不同的颜色。当然可以也可以自定义其他端口,不过对于Arduino而言,在HA中3, 5, 6, 9, 10, 11这几个口是无法使用的。因为官方就是这么说的。

配置文件修改好了以后,然后全部供电,保证zigbee在有限通讯范围内,检查下配置,重启HA服务,也可以重启树莓派,玄学。配置如图:

然后访问你的HA主页,添加三个switch实体到你的HA概览中,如果一切顺利,就会看到以下界面:

还记得那个逻辑么?全部打开就是白色,全部关闭就是关闭,只开红灯就是红。。。如果我数学不是体育老师教的,那算上关闭这个状态,3个按钮的组合应该是8种状态,对应8种颜色。当然,如果HA支持Arduino PWMI输出的话,那就是很多颜色了。可惜,可惜,暂时不行。HA支持微信小程序也支持亚马逊Alexa和Google 助手的远程控制。你把树莓派放在家里,你就可以远程给你的小鱼们开灯关灯了,再加个摄像头,改天再做个自动投食,。云养鱼啊这就是!当然灯不是给鱼用的,说到底还不是给缸内植物进行光合作用么。

四、写在最后,想说明几个问题,证明我不是个浪费硬件的傻子!

1、为何选择用Ardunio驱动而不是直接用树莓派驱动?

主要考虑到鱼缸灯的工作环境,潮湿,并且最后要将驱动封在灯盖子里,树莓派尺寸太大,并且它搭载了HA,如果封起来,调试啊,使用啊,都很不方便。反正手里的Arduino闲着也是闲着。

2、为何选择Arduino+zigbee,而不是树莓派tty直接通讯Arduino?

我的鱼缸灯盖子封起来以后,没有空间留给usb线,并且。。。无线连接是不是更牛逼一点?

3、为何不用ESP8266这类芯片?

答。因为以前不知道。。。现在知道了,觉得应该努力赚钱多囤几个。

4、为何选择TIP41驱动?

选管子是件很痛苦的事情,我看了下灯的官方驱动用的是S8050。嗯。呵呵。Arduino IO口的输出电流基本是20mA左右。。。。S8050肯定能用啊,但我觉得这玩意,还是保险点好。其实我都准备好了光耦,一想到还要焊板子,脑子就有点疼,暂时先不加了。

5、可以看看我的GitHub,因为没有一行代码,所以,我的github目前都是门可罗雀,求大爷们照顾下啊!我靠,这名字,又臭又长,真不要脸啊。

https://github.com/maowenniao/Raspberry-Homeassistant_Zigbee_Arduino_drive-12V-RGB