树莓派Zero做的电子墨水名片

“你好,我的名字是……”

人们参加沙龙或者酒会的时候,经常要对别人口述自己的名字和职业。

如果可以用电子墨水,以像素化的形式显示他们的名字和脸时,相信能节约很多时间。

创客Josh King做的这个PiE-Ink电子墨水名片,就很有意思。

在他的Instructables教程中,他解释了完整的方法。

乔什·金电子墨水名牌树莓派

对于徽章,Josh使用了Raspberry Pi Zero,PaPiRus 2“电子墨水HATAdafruit Powerboost 1000c和LiPo电池。他还用到了其它配件,例如磁铁和粘土。

Josh把树莓派Zero和Powerboost通过焊接连在一起,并允许LiPo电池为设备供电。

乔什·金电子墨水名牌树莓派

然后,他连接PaPiRus HAT并用粘土固定整个装置,以确保紧密贴合。他还加了一个迷你滑动开关。

乔什·金电子墨水名牌树莓派

在SD卡上预装Raspbian后,Josh遵循PaPiRus的设置,确保所有库文件都装好,并且让树莓派识别2英寸屏幕。

然后下载代码,运行……

注:你可以直接从Josh的GitHub帐户下载相关代码。记得将图像缩小到 200×96 才能使其适合电子墨水屏幕。

乔什·金电子墨水名牌树莓派

有了它,你就可以在各种活动和会议上让大家快速认识你了。

如果你想用树莓派Pico做电子墨水名片的话看这里:

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

用树莓派Pico和气体传感器保护厨房

当你在厨房烹饪食物,又跑去刷剧,玩游戏,取快递……

食物正在加热,没人看着,锅烧焦了怎么办?着火了怎么办?

无人看管的烹饪是迄今为止厨房火灾的主要原因。

你可能需要有个东西来帮你盯一下。

这个小东西主要是由树莓派Pico和传感器构成的。

先说开发板,虽然该项目是基于Raspberry Pi Pico构建的,但你可以使用任何与RP2040兼容的电路板创建它。

该项目中使用的Grove-HCHO传感器可检测空气VOCs(挥发性有机化合物)的气体浓度。比如:甲醛和苯。

相关链接:

https://wiki.seeedstudio.com/Grove-HCHO_Sensor/

它是如何工作的?

通过在Raspberry Pi Pico上运行Edge Impulse的Sensor Fusion软件,它可以从气体,温度和湿度传感器读取数据。然后数据通过神经网络模型计算,会判断当前的厨房是否处于安全状态。

是的,要更准确的判断厨房安全状态,你需要更多传感器配合。

Edge Impulse相关链接:

https://studio.edgeimpulse.com/

这里有相关视频来引导你完成软件下载、设置和部署。如果你有兴趣构建自己的厨房监视器,可以照着完成。

经过AI训练,它可以检测厨房的三种状态:空闲,正常烹饪和非正常燃烧。

隐藏在炉子上方风扇罩中的传感器

除了烹饪,从新房子到新家具,也都会存在危害健康的挥发性有机化合物(比如甲醛)。如果你在家里检测到高浓度的挥发性有机化合物,那么你要尽快通风来保证安全。

相关链接:

用Phew在Pico W上构建登录系统

Home Assistant 加 Pico W 改进车库门

树莓派Pico如何用好定时器

在树莓派Pico上跑BASIC程序

Pico SDK — 树莓派Pico起步

树莓派Pico W控制玩具车

树莓派Pico怎么接DHT11温湿度传感器

树莓派Pico W迷你火星车

用Arduino IDE给Pico W开发应用

树莓派Pico上跑TinyML音频分类

用Rust语言来开发树莓派Pico

树莓派Pico的CircuitPython入门

用Pico W做个手机遥控的车库门

太阳能驱动的Pico W在线气象站

Pico W搭网站并显示访问者IP

通过MicroPython控制Pico W上的板载LED

基于树莓派Pico的机器学习

在树莓派Pico上运行“毁灭战士”

用树莓派Pico制作的无人机PiWings

如何让树莓派Pico支持LoRaWAN

长者为你开启树莓派Pico的I/O世界

在树莓派Pico上播放《Bad Apple》

在树莓派Pico上用BBC Micro模拟器玩游戏

树莓派能跑Stable Diffusion了

Stable Diffusion是一种文本到图像生成的大型深度学习模型,它可以根据文本的描述生成详细的图像,也可以用于其他任务,如图像修复、图像扩展、图像翻译等。

它是基于潜在扩散模型(Latent Diffusion Model)的一种变体,通过对图像添加和去除噪声来训练和生成图像。

该模型由Stability AI和LAION联合开发,目前是一个开源的AI平台,有很多用户和开发者贡献了不同的预训练模型和插件。

一般情况下,跑Stable Diffusion需要的配置:最好是有英伟达(Nvidia)的独立显卡,显存不少于4GB,推荐8GB以上;内存8GB以上,推荐16GB或以上;硬盘40GB以上的可用空间,最好是固态硬盘;操作系统支持Windows 10/11,macOS(仅限Apple Silicon或更新版本),Linux等。

但最近有人在树莓派Zero 2上运行Stable Diffusion了,而树莓派 Zero 2 只是内存512MB 的单板计算机。

它的配置和规格如下:

  • 处理器:Broadcom BCM2710A1,四核64位SoC(Arm Cortex-A53 @ 1GHz)
  • 内存:512MB LPDDR2
  • 连接性:2.4GHz IEEE 802.11b/g/n无线局域网,蓝牙4.2,BLE,带天线的屏蔽罩
  • 接口:1 × USB 2.0 OTG接口
  • HAT兼容的40针I/O头插座(未焊接)
  • microSD卡插槽
  • Mini HDMI端口
  • CSI-2摄像头连接器
  • 视频:HDMI接口
  • 复合的视频和复位引脚焊点
  • 多媒体:H.264, MPEG-4解码(1080p30)
  • H.264编码(1080p30)
  • OpenGL ES 1.1, 2.0图形
  • 输入电源:5V DC 2.5A
  • 工作温度:-20°C to +70°C

Raspberry Pi Zero 2 W的尺寸是65mm × 30mm,与原来的Raspberry Pi Zero一样。它的性能比原来的单核Raspberry Pi Zero提高了五倍。一般用于智能家居、物联网等项目。

为了让更多低配置的计算机也能用Stable Diffusion出图。

一个名为vitoplantamura的开发者决定写一个超小的推理库,让260MB内存的单板机也能将Stable Diffusion跑起来。终于,他成功了。

他用C++开发的OnnxStream,是一个能够在低内存设备上运行 Stable Diffusion 的推理库,它通过分离推理引擎和权重提供器,以及量化等技术,完成了在树莓派 Zero 2 上生成图像的挑战。

与微软的OnnxStream 相比,vitoplantamura的OnnxStream 只需要消耗 1/55 的内存就可以达到同样的效果,但(在 CPU 上的)速度只比前者慢 0.5-2 倍。

虽然运行速度较慢,但它却是大模型在更小、更有限的设备上部署的崭新尝试。

相关源码:

https://github.com/vitoplantamura/OnnxStream

用Arduino做一个自动割草机

这个项目中,我们将用Arduino制作一个自动割草机。该机器可以自动修剪院子里长高的草。如果有障碍物,它会自动改变方向,有助于减少人力。

本文提供了项目的基本概述,以及制作Arduino割草机器人所需的组件。提供了电路原理图和Arduino源代码,以便简化组装和编程过程。

注意:这个项目不是玩具,它包含锋利的刀片。如果不小心使用,可能会造成严重的伤害。不要让它无人看管,刀片应正确固定。操作前检查一下。

材料清单

我们需要以下组件:

1、 Arduino UNO
2、 L293D电机驱动盾
3、 超声波传感器HC-SR04
4、 超声波传感器外壳/支架
6、 直流减速电机 x4
7、 BLDC电机100KV
8、 舵机SG-90
9、 ESC模块
10、舵机测试仪
11、3针滑动开关
12、X型十字支架
13、机器人底盘
14、11.1V锂电池

什么是割草机器人(割草机)?

割草机器人是一种用于自动修剪和维护草坪的机器人设备。这些机器人使用传感器和算法来导航和修剪草坪,并且可以根据草坪的生长速度或特定的时间表来编程修剪草坪。一些割草机器人还配备了诸如障碍物检测、防盗保护和通过智能手机应用程序远程控制等功能。它们近年来越来越受欢迎,因为可以节省割草的时间和精力。

电路和连接

源代码/程序

AFMotor Library:
https://github.com/adafruit/Adafruit-Motor-Shield-library

NewPing Library:
https://github.com/microflo/NewPing

需要编译到Arduino UNO开发板中的代码:

#include <AFMotor.h>  
#include <NewPing.h>
#include <Servo.h> 
 
#define TRIG_PIN A0 
#define ECHO_PIN A1 
#define MAX_DISTANCE 200 
#define MAX_SPEED 190 
#define MAX_SPEED_OFFSET 20
 
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); 
 
AF_DCMotor motor1(1, MOTOR12_1KHZ); 
AF_DCMotor motor2(2, MOTOR12_1KHZ);
AF_DCMotor motor3(3, MOTOR34_1KHZ);
AF_DCMotor motor4(4, MOTOR34_1KHZ);
Servo myservo;   
 
boolean goesForward=false;
int distance = 100;
int speedSet = 0;
 
void setup() {
 
  myservo.attach(10);  
  myservo.write(115); 
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}
 
void loop() {
 int distanceR = 0;
 int distanceL =  0;
 delay(40);
 
 if(distance<=15)
 {
  moveStop();
  delay(100);
  moveBackward();
  delay(300);
  moveStop();
  delay(200);
  distanceR = lookRight();
  delay(200);
  distanceL = lookLeft();
  delay(200);
 
  if(distanceR>=distanceL)
  {
    turnRight();
    moveStop();
  }else
  {
    turnLeft();
    moveStop();
  }
 }else
 {
  moveForward();
 }
 distance = readPing();
}
 
int lookRight()
{
    myservo.write(50); 
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115); 
    return distance;
}
 
int lookLeft()
{
    myservo.write(170); 
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115); 
    return distance;
    delay(100);
}
 
int readPing() { 
  delay(70);
  int cm = sonar.ping_cm();
  if(cm==0)
  {
    cm = 250;
  }
  return cm;
}
 
void moveStop() {
  motor1.run(RELEASE); 
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
  } 
  
void moveForward() {
 
 if(!goesForward)
  {
    goesForward=true;
    motor1.run(FORWARD);      
    motor2.run(FORWARD);
    motor3.run(FORWARD); 
    motor4.run(FORWARD);     
   for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) 
   {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet);
    delay(5);
   }
  }
}
 
void moveBackward() {
    goesForward=false;
    motor1.run(BACKWARD);      
    motor2.run(BACKWARD);
    motor3.run(BACKWARD);
    motor4.run(BACKWARD);  
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) 
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet);
    delay(5);
  }
}  
 
void turnRight() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);     
  delay(500);
  motor1.run(FORWARD);      
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);      
} 
 
void turnLeft() {
  motor1.run(BACKWARD);     
  motor2.run(BACKWARD);  
  motor3.run(FORWARD);
  motor4.run(FORWARD);   
  delay(500);
  motor1.run(FORWARD);     
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}  

测试

上传代码后,你可以把机器人带到野外,也许在高草地区。高草地区可以是一个很好的测试选择。

打开机器人上的开关,确保电源为Arduino板提供正确的电压,并且所有组件都正确连接。通过手动控制机器人的运动来测试机器人的电机,确保机器人运动平稳准确。

测试机器人的传感器,在其路径上放置障碍物,并确保能避开它们。此外,检查传感器的范围和灵敏度,以确保机器人可以检测到草的存在。

flutter包在内地安装不了怎么办?

一般我们在flutter pub get安装包的时候,经常会遇到如下错误。

Got socket error trying to find package coverage at http://pub.dartlang.org.

或者

Got socket error trying to find package flame at https://pub.dev.

你打开浏览器访问pub.dev的时候,又可以正常访问。

这个咋解决呢?

如果你是Windows用户,你可以在Powershell的界面下运行:

setx PUB_HOSTED_URL “https://mirrors.cloud.tencent.com/dart-pub”
setx FLUTTER_STORAGE_BASE_URL “https://mirrors.cloud.tencent.com/flutter”

这两条命令。

如果你是Mac用户,你可以在命令行下运行:

$ export PUB_HOSTED_URL=https://mirrors.cloud.tencent.com/dart-pub
$ export FLUTTER_STORAGE_BASE_URL=https://mirrors.cloud.tencent.com/flutter

之前有教程说改成这样:

setx PUB_HOSTED_URL “https://pub.flutter-io.cn”
setx FLUTTER_STORAGE_BASE_URL “https://storage.flutter-io.cn”

但实际操作是无效的,现在还不知道怎么回事。

用Pi-Timolo和树莓派做一个夜视摄像头

安德鲁·格雷戈里 (Andrew Gregory) 发现,后花园的狗经常深夜叫唤。

于是他用树莓派做了一个夜间摄像头,来拍下那个不断引发狗叫的神秘访客。

要放在室外,少不了一个防雨且有一定强度的容器,这里他用到了几块厚木板。

市场上有一系列适用于 Raspberry Pi 的摄像头,比如:Pi Camera Module 3、Raspberry Pi Global Shutter Camera、Raspberry Pi High Quality Camera 和各种热敏模块。

但当访客在夜间到来,最好用的是 Pimoroni 等厂商提供的夜视摄像头。

关于树莓派的选择,作者用到了Raspberry Pi Zero W,比较轻便,兼容性也很好。

这个摄像头设在后花园,距离足够近,可以通过家庭 Wi-Fi 网络即可获取视频流。

但作者不想拉电源线,所以需要电池供电。

事后看来,最好是选择 USB 电池组——这种电池组可以即插即用到任何设备,并具有一定程度的保护作用。

作者选择了 1200mAh,3.7 V LiPo 电池,它裸露且易碎,无法直接连接到 Raspberry Pi Zero W。所以需要给 Raspberry Pi Zero 添加一个 LiPo SHIM(这需要一些焊接)。

本文提到的树莓派电池连接板,相关地址:

把供电模块、摄像头、树莓派都接好后的状态,差不多是这样。

装好系统,通电联网,登录系统执行如下命令进行测试:

raspistill -v -o test.jpg

如果一切顺利,你会看到一个图像在屏幕上闪了一两秒钟,然后颜色会变暗。那是因为夜视摄像头模块使用红外线(大多数摄像头模块会过滤掉这层光谱)。

作者在这里使用的软件包为 Pi-Timolo(Raspberry Pi Time、Motion 和 Low light),由 Claude Pageau 开发。 

可以执行如下命令安装(最好是update系统以后):

curl -L https://raw.github.com/pageauc/pi-timolo/master/source/pi-timolo-install.sh | bash

然后到一个设置界面,自行操作即可。

不过与 Raspberry Pi Camera Module 3 的 12MP 相比,夜视摄像头上的 5MP 传感器还是有些很小,因此作者很想找到一些红外 LED 并制作自己的摄像头模块。

来自:HackSpace 第 66 期

谷歌Sheets和ESP8266构建的考勤系统

用户刷卡后,系统会与包含用户列表的谷歌表单进行核对。

如果用户获得授权,LCD上会显示用户的姓名、接入类型和自定义留言,并发出“嘟”的一声。系统还将考勤数据记录在谷歌Sheet中,供以后查看和分析。

开始之前,你得有一个Google账户,且所在网络可以顺利登录Google。

https://mp.weixin.qq.com/cgi-bin/readtemplate?t=tmpl/video_tmpl&vid=wxv_2903425061842321412

主要材料:

RFID RC522

https://www.aliexpress.us/item/2251832760608169.html

esp8266

https://www.aliexpress.us/item/2251832470086446.html

lcd1602

https://www.aliexpress.us/item/2251832499297742.html

breadboard

https://www.aliexpress.us/item/2251832028089611.html

相关源码:

https://github.com/unreeeal/ESP/tree/master/ESP-RFID-GOOGLE

注:这里ESP32和ESP8266的使用场景是差不多的,两者都可以实现类似功能。

谁进我屋了之“无线门户报警器”

前面我们讲到了简易门户报警器的实现。

相关链接:

这次来做一个升级,实现网络报警。

项目需求:

当有人打开门或没关上门时,Micro:bit马上通过无线网络向你报警。

实现原理:

Micro:bit上面有个磁力计,这里可以设定每2秒测量一次磁场强度。当磁场低于某个特定水平(阈值)时,它会发送一个无线信号“door open”。如果磁性读数超过阈值,则会发送“door closed”。

当警报器Micro:bit收到“door closed”信息时,其 LED显示屏上会显示一个勾号。 当收到“door open”无线电讯息时,它会显示一个大叉并发出警报声。

所需材料:

Micro:bit 2个
电池包 2个
磁铁 1个
万能胶或类似工具,用以将磁铁固定在门上,并将Micro:bit固定在门框上。
可选的蜂鸣器或扬声器
鳄鱼夹引线

门户端代码:

from microbit import *
import radio
radio.config(group=17)
compass.calibrate()
radio.on()

while True:
    if button_a.was_pressed():
        display.scroll(compass.get_field_strength())
    if compass.get_field_strength() < 100000:
        display.show(Image.DIAMOND_SMALL)
        radio.send('door open')
    else:
        display.clear()
        radio.send('door closed')
    sleep(2000)

报警端代码:

from microbit import *
import music
import radio
radio.config(group=17)
radio.on()

while True:
    message = radio.receive()
    if message:
        if message == 'door open':
            display.show(Image.NO)
            music.play(["C4:4"])
        if message == 'door closed':
            display.show(Image.YES)

离线编辑器:

在线编辑器:

https://makecode.microbit.org/#editor

https://python.microbit.org/v/3?l=zh-CN

进阶:

1、按下Micro:bit上的按键A,以帮助校准磁力的最佳阈值。在MakeCode中将其设置为100 microteslas,与在Python中的10000 nanoteslas相同。
2、使用多个Micro:bit来发送不同的无线电消息(例如“back door open”)以追踪多门的状态。
3、使用变量来计算门保持打开状态的时间。

谁进我屋了之“简易门户警报器”

这是写给物联网新手的教程,熟手如果好奇也可以看一下。

有人来过你的房间吗?使用Micro:bit,电池组和磁铁,你可以让门发出警报,以提醒有人闯入。

关于Micro:bit:

Micro:bit是一个卡片大小的计算机,它有一个LED显示屏、按键、传感器和一些输入/输出引脚,可以在Scratch和Python程序的控制下,与你的世界交互。

原理:

Micro:bit上面内建了一个compass sensor,称为磁力计。 你可以使用它来测量地球的磁场,以作为指南针-或感应到附近的磁场强度!

代码:

当磁力强度感应低于200,就显示愤怒的表情。

当按钮A按下时,显示当前磁力强度。

如果用Python的话,这样写:

# Python uses nanoteslas to measure magnetism.
# Experiment with different numbers depending on the
# strength of your magnet, which you can read by 
# pressing button A.

from microbit import *

while True:
    if button_a.was_pressed():
        display.scroll(compass.get_field_strength())
    if compass.get_field_strength() < 200000:
        display.show(Image.ANGRY)

做法:

将磁铁固定在门上,然后将写入开门警报器程序的Micro:bit靠近它,固定在墙上。

接好电源。这样一个简单的报警装置就做好啦。

进阶:

1、添加声音警报。

2、使用一个变量来计算门被打开的次数,这里需要添加一个程序来感应门是否被打开或关闭。

3、创建一个定时器计算门被打开多长时间

好了,拿去玩吧。

本文主要内容来自:

microbit.org

相关视频:

谁进我屋了之“简易门户警报器” (qq.com)