- 2024-10-28
-
发表了主题帖:
【2024 DigiKey 创意大赛】家庭环境检测器-完成贴
本帖最后由 白菜虫虫 于 2024-10-29 12:32 编辑
家庭环境检测器
作者:白菜虫虫
一、作品简介
作品照片:
作品功能介绍:
本作品旨在实现家庭智能环境检测,实现的主要功能有如下几点:
1.使用大尺寸LCD屏开发板结合LVGL制作精美界面,实时显示家庭环境质量。
2.使用BME680等传感器获取家庭环境数据,并通过网络传输到LCD屏幕开发板上实时显示。
3.通过网络获取天气预报信息并在LCD屏幕开发板上实时显示。
4.根据事先设定的条件,控制其他家庭智能设备,调节室内温度,湿度等等环境条件。
物料清单:
本次使用的的板卡是乐鑫官方的ESP32-S3-LCD-EV-BOARD开发板,配备了ESP32-S3-WROOM-1作为主控,搭配了3.95
寸480x480LCD 触摸屏,屏幕驱动IC为GC9503CV触摸IC为FT5x06
BME680传感器,BME680是一款多功能高精度传感器,可以检测温度,湿度,气压,和有机气体。我购买的是单独芯片,然后自己制作了配套的底板。
ESP32C3开发板,用来进行数据的采集和开发板发送数据。
二、系统框图
本系统设计主要分为3个部分:
1.LVGL大屏显示部分。2.家庭环境信息采集部分。3.家庭环境调节部分。
各部分之间通过MQTT相互传递数据。
三、各部分功能说明
1.LVGL大屏显示部分:
这部分的程序主要完成三个部分的功能:一是LVGL界面的初始化和显示;二是连接到心知天气服务器并获取天气预报数据;三是连接MQTT服务器并订阅获取传感器信息数据。
2.家庭环境信息采集部分:
本部分功能为通过BME680传感器采集家庭环境信息,并格式化为JSON数据,通过MQTT对应主题发送到MQTT服务器。
3.家庭环境调节部分:
本部分主要演示根据MQTT接收到的传感器数据和设定值,自动开始和关闭家庭环境调节设备(本部分中以LED代替通风扇热系统进行演示)。
四、作品源码
本次程序均使用arduino完成,压缩包内包含三个部分:
1、Porting20241024:为LVGL显示部分,对应ESP32-S3-LCD-EV-BOARD开发板。
2、mqtt_esp32c3_bme680:为BME680传感器信息采集及上传部分,对应ESP32-C3开发板。
3、mqtt_esp32c3_hot:为接收传感器信息并进行环境调节部分,对应ESP32-C3开发板。
五、作品功能演示视频
[localvideo]f180c40ea94c9227a64c713fc98b89b9[/localvideo]
六、项目总结
第一次参加大赛,很荣幸也很激动,能和这么多大佬一起参赛,亚历山大。
经过两个月的努力,受限于个人技术水平,项目堪堪完成了个大概,距离开始的预想还有一些距离,跟各位大佬的作品相比更显稚嫩。但两个月我也收获了很多,对LVGL的使用有了新的认识,学会了MQTT通讯,HTTP通讯的实现,掌握了BME680高精度传感器,还自己打了传感器底板,也可谓收获满满。
最后感谢得捷和电子工程世界给了这么一次锻炼提高的机会,祝大赛越办越好。
开箱帖链接:https://bbs.eeworld.com.cn/thread-1291882-1-1.html
传感器打板帖链接:https://bbs.eeworld.com.cn/thread-1292331-1-1.html
花絮分享贴链接:https://bbs.eeworld.com.cn/thread-1295998-1-1.html
WORD版文档:
- 2024-10-14
-
发表了主题帖:
【2024 DigiKey 创意大赛】90年代风格的UI界面
、
画了个UI界面,越看越想笑,被兄弟们评价为90年代风格,发上来大家一起笑一下。
- 2024-09-26
-
回复了主题帖:
【Follow me第二季第2期】arduinoUNOR4+homeassistant任务提交
慕容雪花 发表于 2024-9-26 11:15
感谢大佬无私分享!
大佬不敢当,小小学徒一枚
-
回复了主题帖:
【Follow me第二季第2期】arduinoUNOR4+homeassistant任务提交
修改补充了DAC增加负反馈分压电阻的部分,请各位大佬指正
- 2024-09-25
-
上传了资料:
【Follow me第二季第2期】arduinoUNOR4+homeassistant代码汇总
-
回复了主题帖:
【Follow me第二季第2期】arduinoUNOR4+homeassistant任务提交
Maker_kun 发表于 2024-9-25 08:46
运放要加反馈电阻不加波形失真严重,起不到运放的作用
是滴,手上没有直插的电阻,所以偷懒这么搞了
- 2024-09-24
-
发表了主题帖:
【Follow me第二季第2期】arduinoUNOR4+homeassistant任务提交
本帖最后由 白菜虫虫 于 2024-11-2 22:59 编辑
很开心又一次参加得捷和eeworld联合举办的follow me活动。
这次活动使用的板卡是Arduino UNO R4 WiFi。其实对于arduino还是有一些小情结的,因为当时虽然第一款学的MCU是51,但真正入门并领略了微电子的乐趣,还是arduino UNO R3,所以这次能参加follow me的活动还是很nice的。
[localvideo]c51648a519370934a0b4a947eabf6b92[/localvideo]
任务实现简介:
这次完成的任务主要有以下这些,具体实现方式相见后面。
入门任务(必做):搭建环境并开启第一步Blink / 串口打印Hello EEWorld!
基础任务(必做):驱动12x8点阵LED;
用DAC生成正弦波;
用OPAMP放大DAC信号;
用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
进阶任务(必做):通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)
扩展任务(必做,自选任务):
1.通过外部AHT20温湿度传感器,上传温湿度到HA,通过HA面板显示数据
2.连接XiaoC3到HA,并用板载LED模拟灯泡。用HA面板控制LED亮灭模拟控制家庭照明灯的亮灭。
物料清单:
本次使用的物料主要由:
1、arduino UNO R4 wifi 开发板
2、AHT20温湿度传感器
3、Seeed XIAO C3开发板
任务实现详情:
入门任务(必做):搭建环境并开启第一步Blink / 串口打印Hello EEWorld!
搭配器件: Arduino UNO R4 WiFi
设计思路:初始化数字引脚,重复点亮LED和熄灭LED并添加适当延时;初始化串口,输出文字“Hello EEWorld!”。
软件流程图:
每次做入门任务,其实最重要的还是环境的搭建。既然板卡是Arduino UNO R4 WiFi,那么使用的编程软件自然首选arduinoIDE。
1.下载安装软件
首先,打开arduino官网的软件下载页面
https://www.arduino.cc/en/software
根据自己的操作系统,选择合适的软件版本下载。
然后按照默认设置一路next安装完毕。
在右侧的侧边栏点第二个图标,出现开发板管理器栏,输入Arduino UNO R4并
回车搜索,选择arduino官方的arduino UNO R4 Boards板卡进行安装。
3.点亮板卡
3.1依次点击文件→示例→内置示例 01.basics→blink。
3.2依次点击→工具→开发板→arduino UNO R4 boards→arduino UNO R4 wifi
3.3然后点击(→)编译上传。
等待软件编译上传完成,开发板上的小灯开始闪烁,blink程序烧录完成。
4.串口打印Hello EEWorld!
将刚才的程序进行修改
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.print("Hello EEWorld!");
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
点击工具→串口监视器。
再次点击(→)编译上传,串口监视器输出Hello EEWorld!
基础任务(必做):1、驱动12x8点阵LED;2、用DAC生成正弦波;3、用OPAMP放大DAC信号;4、用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
搭配器件: Arduino UNO R4 WiFi
设计思路:1、点阵LED的驱动很简单,找到相应的库简单修改就行,以二维数组,一维数组,字符串数组三选一的方式将需要显示的内容表示出来,然后通过驱动库进行显示。因为步骤太简单了,就不画流程图了。
2-4生成波形及采集的部分,主要就是通过DAC生成一个波形,将波形通过分压电阻输入给运算放大器的正负反馈输入端,然后进行放大并输出给ADC进行采样,并将采集到的数据通过串口输出,通过ARDUINO IDE自带的串口绘图仪进行观察。
软件流程图:
1.驱动12x8点阵LED;
Arduino UNO R4 WiFi开发板自带了一个12X8的led矩阵,还是挺好玩的。
这个LED矩阵的驱动也是比较简单的,使用Arduino_LED_Matrix库就可以轻松驱动。(具体可以参考示例当中LED_Martrix相关例程。)
而操作起来一般也就三种方式,
①8x12数组,具体参见 Matrix Frame Buffer例程
②三组8位16进制数,具体参见Displays single frames例程
③字符串显示,具体参见ArduinoGraphics例程
我这次选择体验的是第三种方式,只需要修改例程中的text[]数组,编译上传即可。
2.用DAC生成正弦波;
开始研究了半天没找到资料,后来还是在arduinoIED的示例立马找到了。
//FollowMe第二季第2期-白菜虫虫-任务2.1(驱动12x8点阵LED)
#include "analogWave.h"
analogWave wave(DAC);
int freq = 10;
void setup() {
wave.sine(freq);
}
void loop() {
}
A0引脚是波形输出,把示波器接好A0和GND。
3.用OPAMP放大DAC信号;
OPAMP运算放大器的例程同样可以在arduino里面找到。
//FollowMe第二季第2期-白菜虫虫-任务2.3(用DAC生成正弦波)
#include "analogWave.h"
#include <OPAMP.h>
analogWave wave(DAC);
int freq = 10;
void setup () {
Serial.begin(9600);
delay(2000);
wave.sine(freq);
if (!OPAMP.begin(OPAMP_SPEED_HIGHSPEED)) {
Serial.println("Failed to start OPAMP!");
}
bool const isRunning = OPAMP.isRunning(0);
if (isRunning) {
Serial.println("OPAMP running on channel 0!");
} else {
Serial.println("OPAMP channel 0 is not running!");
}
}
void loop() {
delay(2000);
}
编译上传,把A0的输入接到A1,然后用示波器接OPAMP运算放大器的输出A3。
这个波形有点失真,想了想应该是偷懒没接负反馈的问题。
把A3的输出接到A2的负反馈输入。
波形恢复正常。
这里由于是又偷懒没给负反馈做分压,所以A3的输出波形虽然正常了,但是放大倍数有点忒小了,需要增大放大倍数的同学可以给负反馈做一个分压,用分压后A3输出波形给A2做输入。
负反馈增加分压电阻:
后续找到了几颗直插电阻,现在添加上使用分压电阻的做法。
首先是直接给A3的输出增加分压电阻,取大约1/2的电压输入到A2。通过示波器和ADC查看均存在削峰的情况,波谷倒是显示正常。、
猜测是超过了ARUDINO的上限,于是考虑给输入也增加分压。
A0的输出通过2/3的分压输入给A1,依旧削峰。再次改变电路,把A0的1/3分压给A1作为输入,波形全部正常显示。
电路图如下:
分压后的输入波形:
接负反馈后的输出波形:
4.用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
这一步就比较简单了。
在上一个任务的基础上简单修改就可以了。
//FollowMe第二季第2期-白菜虫虫-任务2.4(用DAC生成正弦波)
#include "analogWave.h"
#include <OPAMP.h>
analogWave wave(DAC);
int freq = 10;
int sensorPin = A5;
void setup () {
Serial.begin(9600);
delay(2000);
wave.sine(freq);
if (!OPAMP.begin(OPAMP_SPEED_HIGHSPEED)) {
Serial.println("Failed to start OPAMP!");
}
bool const isRunning = OPAMP.isRunning(0);
if (isRunning) {
Serial.println("OPAMP running on channel 0!");
} else {
Serial.println("OPAMP channel 0 is not running!");
}
}
void loop() {
Serial.println(analogRead(sensorPin));
}
编译上传,然后点击arduinoIED菜单栏 工具→串口绘图仪就能看到波形。
再给大家看看不加负反馈时候的波形。
因为放大之后的波形超过了ADC采样的范围,所以波峰波谷都被削平了。想用ADC看波形的兄弟们也可以给ADC输入加上分压电路。
这里也补充增加了输入和负反馈分压后的ADC采样波形:
输入波形
负反馈分压输出波形
进阶任务(必做):通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)
搭配器件: Arduino UNO R4 WiFi
设计思路:这一步主要是HA平台的搭建,平台搭建好了之后使用UNO R4通过MQTT发送一个注册传感器的消息,HA平台接收到后就会显示一个温湿度传感器的标签。
软件流程图:
1.搭建HomeAssistant。
homeassistant的安装坑很多,建议按照官网的说明进行。我个人是选择的VMware虚拟机的方式进行安装的。
打开homeassistant官网https://www.home-assistant.io/installation/
参照官网说明,按照自己设备或操作系统选择合适的方式进行安装。
安装完毕在浏览器输入IP地址:8123打开homeassistant,比如我的就是http://192.168.11.135:8123/
第一次启动经过漫长的等待,进行科学上网可以有效缩短等待时间。
更新完毕会进入注册和设置页面,需要设置登录使用的账号密码和一些其他东西,按照提示进行设置就可以。
2.安装mqtt 服务器
点击设置,点右下角加载项商店,搜索emqx并安装。
打开emqx,添加自己的一个自己的mqtt账号。
3.配置
在设置→设备与服务→集成中搜索添加并配置mqtt项目。
配置mqtt集成的时候,建议单独注册一个HA用户分配给mqtt使用,不要使用默认管理账户。
4.Arduino UNO R4 WiFi连接HA
homeassistant端配置完毕之后,来看UNO R4端,UNO R4主要是配置并连接到mqtt服务器。
先搜索安装ArduinoMqttClient库,然后根据示例修改为我们的程序:
//FollowMe第二季第2期-白菜虫虫-进阶任务
#include <ArduinoJson.h>
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
char ssid[] = "BAICAICHONGCHONG";
char pass[] = "PASSWORD";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "192.168.66.121";
int port = 1883;
const char register_topic[] = "homeassistant/sensor/sensorBedroomT/config";
const char refresh_topic[] = "homeassistant/followme/state";
const long interval = 1000;
unsigned long previousMillis = 0;
int count = 0;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
String register_doc1="{\"device_class\":\"temperature\",\"name\":\"Temperature\",\"state_topic\":\"homeassistant/followme/state\",\"unit_of_measurement\":\"C\",\"value_template\":\"{{value_json.temp}}\",\"unique_id\":\"temp01ae\",""\"device\":{\"identifiers\":[\"bedroom01ae\"],\"name\":\"FollowMe\"}}";
String register_doc2="{\"device_class\":\"temperature\",\"name\":\"Temperature\",\"state_topic\":\"homeassistant/followme/state\",\"unit_of_measurement\":\"C\",\"value_template\":\"{{value_json.temp}}\",\"unique_id\":\"temp01ae\",""\"device\":{\"identifiers\":[\"bedroom01ae\"],\"name\":\"FollowMe\"}}"; // attempt to connect to WiFi network:
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println("You're connected to the network");
Serial.println();
// You can provide a unique client ID, if not set the library uses Arduino-millis()
// Each client must have a unique client ID
mqttClient.setId("clientId");
// You can provide a username and password for authentication
mqttClient.setUsernamePassword("unor4", "test123");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
mqttClient.poll();
Serial.print("register sensor");
Serial.println();
mqttClient.beginMessage(register_topic);
mqttClient.print(register_doc1);
mqttClient.print(register_doc2);
mqttClient.endMessage();
}
void loop() {
String refresh_doc= "{\"temp\": 23.20, \"hum\": 43.70}";
mqttClient.poll();
Serial.print("refresh data");
mqttClient.beginMessage(refresh_topic);
mqttClient.print(refresh_doc);
mqttClient.endMessage();
Serial.println();
delay(1000);
}
编译并上传后,刷新HA界面,可以看到新的传感器。
扩展任务(必做,自选任务)
1.通过外部AHT20温湿度传感器,上传温湿度到HA,通过HA面板显示数据
搭配器件: Arduino UNO R4 WiFi、AHT20温湿度传感器
设计思路:UNO R4通过IIC采集AHT20等传感器的温湿度数据,并以MQTT的方式上传到HA。
软件流程图:
首先要将AHT20温湿度传感器接在UNO R4上,如果传感器有Qwiic接口,可以使用PRT-14426(Qwiic缆线-50mm)把传感器连接到UNO R4上,或者也可以使用杜邦线进行连接,注意按照VCC→3.3V,GND→GND,SCL→A5,SDA→A4的顺序进行连接。
然后搜索并安装驱动库,我使用的是DFRobot_AHT20库
接下来将我们进阶任务的程序进行修改:
//FollowMe第二季第2期-白菜虫虫-扩展任务1
#include <ArduinoJson.h>
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include "DFRobot_AHT20.h"
DFRobot_AHT20 aht20;
char ssid[] = "sishuiyouyu"; // your network SSID (name)
char pass[] = "Jj19860123"; // your network password (use for WPA, or use as key for WEP)
// char ssid[] = "FAST_7664"; // your network SSID (name)
// char pass[] = "12345678";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "192.168.66.121";
// const char broker[] = "192.168.11.140";
int port = 1883;
const char register_topicT[] = "homeassistant/sensor/sensorBedroomT/config";
const char register_topicH[] = "homeassistant/sensor/sensorBedroomH/config";
const char refresh_topic[] = "homeassistant/followme/state";
const long interval = 1000;
unsigned long previousMillis = 0;
int count = 0;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
String register_docT="{\"device_class\":\"temperature\",\"name\":\"Temperature\",\"state_topic\":\"homeassistant/followme/state\",\"unit_of_measurement\":\"C\",\"value_template\":\"{{value_json.temp}}\",\"unique_id\":\"temp01ae\",\"device\":{\"identifiers\":[\"bedroom01ae\"],\"name\":\"FollowMe\"}}";
String register_docH="{\"device_class\":\"humidity\",\"name\":\"Humidity\",\"state_topic\":\"homeassistant/followme/state\",\"unit_of_measurement\":\"%\",\"value_template\":\"{{value_json.hum}}\",\"unique_id\":\"hum01ae\",\"device\":{\"identifiers\":[\"bedroom01ae\"],\"name\":\"FollowMe\"}}";
uint8_t status;
while((status = aht20.begin()) != 0){
Serial.print("AHT20 sensor initialization failed. error status : ");
Serial.println(status);
delay(1000);
}
// attempt to connect to WiFi network:
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println("You're connected to the network");
Serial.println();
// You can provide a unique client ID, if not set the library uses Arduino-millis()
// Each client must have a unique client ID
mqttClient.setId("clientId");
// You can provide a username and password for authentication
mqttClient.setUsernamePassword("unor4", "test123");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
mqttClient.poll();
Serial.print("register sensor");
Serial.println();
mqttClient.beginMessage(register_topicT);
mqttClient.print(register_docT);
mqttClient.endMessage();
mqttClient.poll();
mqttClient.beginMessage(register_topicH);
mqttClient.print(register_docH);
mqttClient.endMessage();
}
void loop() {
if(aht20.startMeasurementReady(/* crcEn = */true)){
Serial.print("temperature(-40~85 C): ");
Serial.print(aht20.getTemperature_C());
Serial.print(" C, ");
Serial.print("humidity(0~100): ");
Serial.print(aht20.getHumidity_RH());
// String refresh_doc= +gcvt()++gcvt()+;
mqttClient.poll();
Serial.print("refresh data");
mqttClient.beginMessage(refresh_topic);
mqttClient.print("{\"temp\": ");
mqttClient.print(aht20.getTemperature_C());
mqttClient.print(", \"hum\": ");
mqttClient.print(aht20.getHumidity_RH());
mqttClient.print("}");
mqttClient.endMessage();
Serial.println();
delay(1000);
}
else{
mqttClient.poll();
Serial.print("wait aht20");
delay(1000);
}
}
编译并上传到开发板。
刷新HA页面就能看到不断变化的温度湿度值了。
2.连接XiaoC3到HA,并用板载LED模拟灯泡。用HA面板控制LED亮灭模拟控制家庭照明灯的亮灭。
搭配器件:Seeed XIAO C3开发板
设计思路:使用ESPHome配合HA来控制XIAO C3为代表的智能终端设备
软件流程图:
下面我来演示一种更简单的把设备加入HA的方式,这种方式适用于ESP32和ESP8266的驱动板,这里我选择的是XiaoC3。
在HA设置→加载项中搜索并安装ESPHome然后启动它。
添加一个新的设备,选择ESP32-C3,添加完毕后点edit编辑yaml文件,修改SSID和密码,在文件最后添加代码
light:
- platform: binary
name: "FollowMeLED"
output: bin_led
output:
- id: bin_led
platform: gpio
pin: GPIO2
inverted: true
要注意缩进,yaml和python类似,是以缩进代表归属的语言。
烧录代码到XiaoC3,刷新HA就可以看到我们的LED。
点击LED标签上的按钮,就可以控制LED的亮灭。
活动心得体会:这是活动总体来说收获巨大,以这次活动为契机督促自己详细的研究了homeassistant智能家居的实现方式。期间遇坑无数,爬坑也不少,尤其是HA的搭建,说多了都是泪啊。
重要完成了,也大体学会了,HA还是很好玩的,尤其在生活中也能用得上,监测一下屋里的温湿度和空气质量情况呀,控制一下灯光亮灭啦,控制一些职能家电等等,还能自定义定时或者定条件的自动事项,灰常的方便。
最后,再次感谢主办方得捷和电子工程世界。
- 2024-09-07
-
回复了主题帖:
【2024 DigiKey 创意大赛】家庭环境检测器-BME680焊接成功
秦天qintian0303 发表于 2024-9-4 09:29
数字通信好使很方便的,总感觉自己上锡膏不爱沾呢
我给锡膏加了点料,稀释了一下,也更好焊接,缺点就是板子会更脏一些
- 2024-09-04
-
回复了主题帖:
【2024 DigiKey 创意大赛】家庭环境检测器-BME680焊接成功
wangerxian 发表于 2024-9-2 17:45
这种传感器外围电路还是挺简单的。
是呀,出乎意料的简单
- 2024-09-02
-
发表了主题帖:
【2024 DigiKey 创意大赛】家庭环境检测器-BME680焊接成功
本帖最后由 白菜虫虫 于 2024-9-2 16:41 编辑
书接上回,上回书说到了收到BEM680传感器之后,看着这小小的封装,一个头两个大。
不过事已至此,只能闷着头上了。
首先打开立创开源广场,搜索BME680
点开第一位大佬的项目分享,看了一下原理图,BME680需要的驱动电路还是很简单的,4个上下拉电阻,两个电源滤波电容,LED和它的限流电阻可有可没有。
但是他的PCB设计元器件靠的比较近,本人眼花手笨的,怕焊补了,而且大佬的电容电阻封装都是0805的,我下单的物料是0603的。
于是乎,新建个工程自己画吧。
站在大佬的肩上完成的还是挺快的。
预览一下:
下单打板,感谢嘉立创每月两次的免费打板。
收到PCB,正反面再拍一下:
涂好锡膏
热风枪开310度,小风慢慢的吹
用万用表对照PCB设计挨个检测,发现一个虚焊,补焊一下。
这时候发现传感器上的孔和PCB上的位置不一样,吓出了一脑门子的汗。
NND刚才放传感器的时候明明下面的点是一样的位置啊,怎么旁边的点不一样啊,赶紧回去看PCB封装图。
果然好坑,传感器盖住的位置有个点,引脚旁边有个点,俩点位置就是不一样,这可咋办,万一上电测试别烧了。
赶紧去得捷网站上翻数据手册。
原来传感器上的圆孔叫通气孔,不是引脚标记,吓死宝宝了,又学到了新的知识。
虚惊一场,焊接好排针,翻出个树莓派PICO,打开ARDUINO IDE,搜索一下BME680的驱动库,选了adafruit的驱动库。
安装好驱动之后点开示例里面的bme680test,配置好管脚,接好线,编译上传。
卧槽,报错了,啥情况,不是芯片真焊反了吧。
稳住,先别慌,想想有啥地方还能出错,要不把SDO,SDI换过来试试。
哎呀,这次出数据了。
一波三折,虚惊一场,好事多磨。
唠唠叨叨说了一大堆,感谢各位看到了这里,谢谢!
-
回复了主题帖:
【2024 DigiKey 创意大赛】家庭环境检测器-开箱帖
有点太小了,耍了一点小心机,有惊无险的焊接成功了。
- 2024-08-29
-
发表了主题帖:
【2024 DigiKey 创意大赛】家庭环境检测器-开箱帖
本帖最后由 白菜虫虫 于 2024-8-29 10:52 编辑
很荣幸能参加这次的大赛,很开心,很荣幸,压力也山大。
下单的物料来到了,激动的心,颤抖的手,开箱看一下物料:
得捷的包装真是没话说,每个元件都有自己的包装,上面也有详细的贴纸,另外箱子里也附了好几页各种说明文档。最外层的大纸箱的风口还有塑料线加强。
这次选的开发板做工也很好,屏幕很清晰,触摸灵敏,板子的边也都打磨过,摸起来很舒服,就是第一次玩RGB屏幕,心里还没有一点底。
BMP680模块已经打好版了,看到实物才知道这么小,不知道自己能不能焊的了。
-
回复了主题帖:
【Follow me第二季第1期】学习总结
关于水果钢琴的最新进展,如果出现了水果钢琴无论如何都不响,或者就只能偶尔响一下的情况,可以多接一根鳄鱼夹到GND,然后另外一头夹个水果攥在手里,然后用这只手去触摸其他水果,就可以正常使用。
- 2024-08-28
-
上传了资料:
followme第二季第1期2024-白菜虫虫-代码汇总
-
发表了主题帖:
【Follow me第二季第1期】学习总结
本帖最后由 白菜虫虫 于 2024-10-10 18:06 编辑
【Follow me第二季第1期】
很开心可以参加这一期的Follow me活动,感谢EEworld和得捷联合举办的这次活动给了我一次很好的学习提高的机会,通过这次的学习,我基本掌握了CircuitPython和SAMD21的使用,受益颇丰。下面是我这次学习情况汇报:
这次活动的开发板是Adafruit Circuit Playground Express(名字太长了,后面就叫小圆板吧)。
开发方式我选择的是官方的CircuitPython(后面简称CPY),选择CPY的愿意有以下几个:一是这是官方固件,稳定性有保障;二是CPY的库很全面,不需要再到网上去找库;三是以前没有接触过,以这次活动为契机学习提高下自己。
[localvideo]9717ff3df4b03c52b1e7b222aeffa2ec[/localvideo]
物料展示:
首先展示一下本次使用的所有器件:
从左到右依次是USB数据线,Adafruit Circuit Playground Express小圆板本体,小圆板外壳,还有小圆板专用电池盒。
入门任务(必做):开发环境搭建,板载LED点亮
操作过程:
1.下载最新的CircuitPython固件。
1.1下载固件:打开CircuitPython官网,点击DOWNLOAD,选择Adafruit Circuit Playground Express,就可以下载小圆板的专用固件,固件有英文、拼音等等各个语言的版本,我先尝试了一下拼音的版本,感觉挺别扭的,得一个一个字读出音来再连起来品意思,所以还是换回英文吧,英文有美国英语和英国英语,也不知道啥区别就随便下个吧。
CircuitPython固件下载地址:
https://CircuitPython.org/board/circuitplayground_express/
1.2烧录CircuitPython固件:
Adafruit Circuit Playground Express小圆板烧录固件还是很简单的,简单到都不需要额外的软件。使用USB数据线连接小圆板,等待驱动安装完毕。这时候自带的出厂固件就会开始跑马灯,按D4键会发出音乐,按D5件会改变亮度(貌似),拨动D7则会改变跑马灯的方向。
按住D4再按reset键,会弹出U盘,把下载好的固件拖进U盘里面,等待重启(到这里跟树莓派PICO差不多),会弹出一个名为CIRCUITPY的U盘,则说明固件烧录成功(这里则跟树莓派PICO不一样)。
固件烧录前:
固件烧录后:
2.编辑软件准备。
2.1安装Thonny:
本来听说Mu和CircuitPython更配,但折腾了一下,发现还是Thonny更好用。
下载安装Thonny就不细说了,常玩MPY的大佬们朋友们都有,没有的兄弟们浏览器搜索一下很好找。
2.1配置Thonny:
在使用Thonny开始我们的编程前,我们还需要做一些配置。
①打开Thonny,点击右下角开发板串口标志,点击配置编辑器。
或者点击菜单栏运行,在点击配置编辑器。
②在Thonny应该使用那种解释器来运行您的代码选项中点击下拉菜单,选择CircuitPython(通用),然后点击好的。
③用USB数据线连接板子到电脑,再次点击右下角开发板串口标志,选择自己的开发板串口号就可以了。
连接成功的话Thonny就会出现类似下图的显示,开发板同时会亮起白光。如果连接失败可以尝试按下开发板RESET,点击Thonny的STOP按钮,或者组合使用。
3.点亮一个LED。
CircuitPython其实和MicroPython很多地方是类似的,都要先引用开发板定义和相关库。为了点亮板载的WS2812,我们需要引用board和neopixel,前者是开发板定义,后者是WS2812的驱动库。
然后我们输入如下程序:
import neopixel
from board import *
pixels = neopixel.NeoPixel(NEOPIXEL, 10)
pixels[0] = 0x100010
点击运行当前脚本(绿圈白三角的按钮),开发板上的第一个LED就成功的被点亮了。
基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
首先,在活动页面下载使用指南。
打开指南16页,可以看到WS2812彩灯的介绍。
下面细说一下程序:
①首先还是引用需要的库文件
import neopixel
from board import *
import time
②定义颜色代码:
COLOR = [
[255, 0, 0], # 红色
[255, 60, 0], # 橙色
[255, 255, 0], # 黄色
[0, 255, 0], # 绿色
[0, 255, 255], # 青色
[0, 0, 255], # 蓝色
[180, 0, 255], # 紫色
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
③初始化NeoPixel
pixels = neopixel.NeoPixel(NEOPIXEL, 10, brightness=0.1,auto_write=False)
④编写NeoPixel流水灯代码:
def one_cycle(color):
pixels.fill(0)
pixels.show()
time.sleep(DELAY)
for i in range(10):
pixels.fill(0)
pixels[i] = color
pixels.show()
time.sleep(DELAY)
下面是完整的任务一代码:
#【Follow me第二季第1期】白菜虫虫
# 基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
import neopixel
from board import *
import time
DELAY = 0.1
COLOR = [
[255, 0, 0], # 红色
[255, 60, 0], # 橙色
[255, 255, 0], # 黄色
[0, 255, 0], # 绿色
[0, 255, 255], # 青色
[0, 0, 255], # 蓝色
[180, 0, 255], # 紫色
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
pixels = neopixel.NeoPixel(NEOPIXEL, 10, brightness=0.1,auto_write=False)
def one_cycle(color):
pixels.fill(0)
pixels.show()
time.sleep(DELAY)
for i in range(10):
pixels.fill(0)
pixels[i] = color
pixels.show()
time.sleep(DELAY)
def rainbow_cycle(n):
pixels.fill(0)
for i in range(n+10,n,-1):
pixels[(i)%10] = COLOR[10+n-i]
pixels.show()
time.sleep(DELAY)
def main():
for i in range(7):
one_cycle(COLOR)
for i in range(70):
rainbow_cycle(i)
main()
运行效果如图:
基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度
小圆板搭载了A8:光线传感器和A9:温度传感器。
其中A8:光线传感器采用的是ALS-PT19光敏三极管,虽然是三极管但没引出基极,第一眼看到还以为是个光敏二极管。
A9:温度传感器采用的是NCP15XH103F03RC热敏电阻。
二者均采用了直接读取模拟量的方式获取数值。
手册18页两个传感器的介绍:
小圆板搭载了A8:光线传感器和A9:温度传感器。
其中A8:光线传感器采用的是ALS-PT19光敏三极管,虽然是三极管但没引出基极,第一眼看到还以为是个光敏二极管。
手册214页可以看到A8光线传感器的例程
import time
import board
import neopixel
import analogio
import simpleio
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=.05, auto_write=False)
pixels.fill((0, 0, 0))
pixels.show()
light = analogio.AnalogIn(board.LIGHT)
while True:
# light value remapped to pixel position
peak = simpleio.map_range(light.value, 2000, 62000, 0, 9)
print(light.value)
print(int(peak))
for i in range(0, 9, 1):
if i <= peak:
pixels[i] = (0, 255, 0)
else:
pixels[i] = (0, 0, 0)
pixels.show()
time.sleep(0.01)
手册216页顶部则有A9温度传感器的例程
import time
import adafruit_thermistor
import board
thermistor = adafruit_thermistor.Thermistor(
board.TEMPERATURE, 10000, 10000, 25, 3950)
while True:
temp_c = thermistor.temperature
temp_f = thermistor.temperature * 9 / 5 + 32
print("Temperature is: %f C and %f F" % (temp_c, temp_f))
time.sleep(0.25)
结合二者制作出我们任务二的程序:
①由于光线传感器是使用 analogio库进行的读取,数值范围是0-65535,所以把读取到的数值除以0x1000并取整进行转换,方便后续使用。
light=int(light_pin.value/0x1000)
print(f"Light:{light}")
if light>=9:
pixels[4]=COLOR[8]
else:
pixels[4]=COLOR[light]
采用转换后的light值的高低并以相应颜色来进行表示,因为比较懒就制作了一个9色数组,所以9以上数值都显示红色,经测试也基本符合对光线强弱的直观感受。
②温度传感器由于采用的是adafruit_thermistor库,读取温度是摄氏温度数值,所以选取了13℃-40℃的范围,每3℃一档的方式进行不同温度表示,高于40℃显示红色,低于13℃显示冰蓝色。
celsius = thermistor.temperature
print(f"Temperature:{celsius}")
temp=int((celsius-13)/3)
print
if temp>=9:
pixels[5]=COLOR[8]
else:
if temp<=0:
pixels[5]=COLOR[0]
else:
pixels[5]=COLOR[temp]
完整程序如下:
import analogio
from board import *
import time
import neopixel
import adafruit_thermistor
COLOR = [
[0, 0, 255], #0 蓝色
[0, 255, 255], #1 青色
[0, 127, 127], #2 浅绿
[0, 255, 0], #3 绿色
[127, 127, 0], #4 浅黄色
[255, 127, 0], #5黄色
[255, 255, 0], #6黄色
[255, 60, 0], #7 橙色
[255, 0, 0], #8红色
]
pixels = neopixel.NeoPixel(NEOPIXEL,10, brightness=0.1)
pixels.fill(0)
light_pin = analogio.AnalogIn(A8)
resistor = 10000
resistance = 10000
nominal_temp = 25
b_coefficient = 3950
thermistor = adafruit_thermistor.Thermistor(
TEMPERATURE, resistor, resistance, nominal_temp, b_coefficient
)
while True:
light=int(light_pin.value/0x1000)
print(f"Light:{light}")
if light>=9:
pixels[4]=COLOR[8]
else:
pixels[4]=COLOR[light]
celsius = thermistor.temperature
print(f"Temperature:{celsius}")
temp=int((celsius-13)/3)
print
if temp>=9:
pixels[5]=COLOR[8]
else:
if temp<=0:
pixels[5]=COLOR[0]
else:
pixels[5]=COLOR[temp]
time.sleep(1)
温度检测演示:
[localvideo]a1204e7f836429ffe9347d2bc24b400c[/localvideo]
亮度检测演示:
[localvideo]7e111b2b393e7d2f4fe7b0784ab3198a[/localvideo]
基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
接近检测这个任务,一开始我是懵逼的,因为在板子上没有找到接近传感器,难道我要外接一个超声波测距模块?那多不优雅。
不是有光线传感器吗,那拿你试试行不行吧。
结果是,行,但不完全行,因为得靠的很近才能出现明显的数值变化,离远了变化都没传感器跳动的误差大。继续想办法吧。
继续翻指南,在22页有了收获:
这段话翻译过一下:
这不就有了吗。
基本思路是使用红外LED照一下,然后关闭红外LED,再读取A10的数值。一定不要一直开着红外LED,一会就烫手,吓得我还以为烧了呢。
A10的数值会在一个范围内波动,将这个范围平均分成10份(稍微多一点也成),然后对应10颗灯珠,测试一下选个合适的距离触发报警,我这里选择的是大于等于6时报警。
下面是完整程序:
#【Follow me第二季第1期】白菜虫虫
#基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
from board import *
import time
import neopixel
pixels = neopixel.NeoPixel(NEOPIXEL,10, brightness=0.1)
pixels.fill(0)
from digitalio import *
from analogio import *
ir_tx = DigitalInOut(IR_TX)
ir_tx.direction = Direction.OUTPUT
proximity = AnalogIn(IR_PROXIMITY)
button5 = DigitalInOut(D5)
button4 = DigitalInOut(D4)
import array
import math
try:
from audiocore import RawSample
except ImportError:
from audioio import RawSample
try:
from audioio import AudioOut
except ImportError:
try:
from audiopwmio import PWMAudioOut as AudioOut
except ImportError:
pass # not always supported by every board!
FREQUENCY = 440 # 440 Hz middle 'A'
SAMPLERATE = 8000 # 8000 samples/second, recommended!
# Generate one period of sine wav.
length = SAMPLERATE // FREQUENCY
sine_wave = array.array("H", [0] * length)
for i in range(length):
sine_wave[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15) + 2 ** 15)
# Enable the speaker
speaker_enable = DigitalInOut(SPEAKER_ENABLE)
speaker_enable.direction = Direction.OUTPUT
speaker_enable.value = True
audio = AudioOut(SPEAKER)
sine_wave_sample = RawSample(sine_wave)
max_value = 42000
min_value = 37000
interval_value = 500
while True:
time.sleep(0.4)
pixels.fill(0)
print("max_value: %d" % max_value)
print("min_value: %d" % min_value)
print("interval_value: %d" % interval_value)
if button4.value == True:
max_value = 22300
min_value = 41200
interval_value = 100
if button5.value == True:
ir_tx.value = True
time.sleep(0.001)
ir_tx.value = False
proximity_value = proximity.value
print("proximity Level: %d" % proximity_value)
if max_value < proximity_value:
max_value = proximity_value
print("max_value: %d" % max_value)
if min_value > proximity_value:
min_value = proximity_value
print("min_value: %d" % min_value)
interval_value = (max_value - min_value) / 10
print("interval_value: %d" % interval_value)
elif interval_value > 1:
ir_tx.value = True
time.sleep(0.001)
ir_tx.value = False
proximity_value = proximity.value
print("proximity Level: %d" % proximity_value)
proximity_index = int((proximity_value - min_value) / interval_value)
print(proximity_index)
for p in range(10):
if p <= proximity_index:
pixels[p] = 0x000f0f
else:
pixels[p] = 0
if proximity_index >= 6:
audio.play(sine_wave_sample, loop=True)
time.sleep(0.4)
audio.stop()
本来是想用两个按键实现自适应范围的功能来着,但是发现会有一些数据毛刺形象范围的自动调整,时间太紧也没再优化,有机会再搞。
[localvideo]07d026cc6c27fab0d04b1c0e80c48892[/localvideo]
进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
制作不倒翁,就需要使用三轴传感器LIS3DH,查看手册19页有三轴传感器介绍
从网上搜索资料,发现一个好网站:http://www.circuitpython.cn/projects/circuitplayground/en/latest/api.html
和一个好的库CP,前者有详细的CPY和小圆板的资料,后者则是为小圆板量身定制的几乎包含小圆板所有的库。
通过一下简单的测试程序,我们就可以查看X,Y,Z三个方向的偏转情况:
from adafruit_circuitplayground import cp
while True:
x, y, z = cp.acceleration
print(x, y, z)
摇动小圆板,可以观察X,Y,Z轴向数据的变化规律,其数值都是在-10到10之间变化,静止不动时接近于0,但有少量跳动的误差。
我们需要知道小圆板向哪个方向倾斜,其实倾斜方向与X,Y轴正好构成了一个直角三角形,运用我们中学学过的三角函数知识,X/Y就是角度的正切值,而atan(X/Y)便是角度值
t=(math.atan2(y,x)*180/math.pi+180)
t便是小圆板倾斜的角度值,修改程序并打印t值发现,其与与WS2812彩灯的编号方向存在90度的偏转;同时 10颗彩灯和USB口和电源接口正好接近于12等分排列,每个占据12分之一也就是30度,于是角度值计算可以更新为:
t=int((math.atan2(y,x)*180/math.pi+ 270+15)%360/30)
将10颗WS2812彩灯和USB接口、电池接口按照位置重新编组,编写三轴传感器控制WS2812在对应角度下点亮的部分,得到完整不倒翁程序如下:
#【Follow me第二季第1期】白菜虫虫
# 进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
from adafruit_circuitplayground import cp
print(1)
# WS2812=('',cp.pixels[0],cp.pixels[1],cp.pixels[2],cp.pixels[3],cp.pixels[4],'',cp.pixels[5],cp.pixels[6],cp.pixels[7],cp.pixels[8],cp.pixels[9])
print(2)
import time
import math
while True:
x, y, z = cp.acceleration
if (int(y)==0)and(int(x)==0):
t=0 #消除开发板平放静止时传感器误差产生的错误角度值
else:
t=int((math.atan2(y,x)*180/math.pi+ 270+15)%360/30)
print(t)
if t==None or t==0 or t==6:
cp.pixels.fill(0)
else:
t=t-1
if t>5:
t=t-1
cp.pixels.fill(0)
cp.pixels[t]=0x0f000f
time.sleep(0.1)
PS:使用CP库和atan2()函数编写的程序真是简洁,比我开始不用CP库加上使用atan()函数然后根据XY正负情况再进行修正的那版程序行数少了一多半。
[localvideo]040914d774c2616f86687d0adc92b473[/localvideo]
创意任务(创意任务我选择的是创意任务三)
■ 创意任务三:水果钢琴——通过触摸水果弹奏音乐,并配合灯光效果
搭配器件: Adafruit Circuit Playground Express、水果自备
创意任务三--1 触摸钢琴
查看指南第20页,有触摸IO功能介绍
打开指南160页,有touchio的例程,可以复制例程运行测试。
import time
import board
import touchio
touch_A1 = touchio.TouchIn(board.A1)
touch_A2 = touchio.TouchIn(board.A2)
touch_A3 = touchio.TouchIn(board.A3)
touch_A4 = touchio.TouchIn(board.A4)
touch_A5 = touchio.TouchIn(board.A5)
touch_A6 = touchio.TouchIn(board.A6)
touch_TX = touchio.TouchIn(board.TX)
while True:
if touch_A1.value:
print("A1 touched!")
if touch_A2.value:
print("A2 touched!")
if touch_A3.value:
print("A3 touched!")
if touch_A4.value:
print("A4 touched!")
if touch_A5.value:
print("A5 touched!")
if touch_A6.value:
print("A6 touched!")
if touch_TX.value:
print("TX touched!")
time.sleep(0.01)
通过观察例程,我们可以了解touchio库的使用方式。
使用CP库可以更好更精炼的使用touchio,同时CP库也包含了PIXELS和TONE,真是一库在手,小圆板不发愁。
①首先还是引用所需的库:
import time
from adafruit_circuitplayground import cp
使用了CP库之后真心简洁,就CP和TIME两个齐活。
②然后是从网上扒来的音调频率对照数组
tones=(0,392,440,494,523,587,659,698,784)
不要问我tones[0]为啥是0,问就是因为开始的时候不仔细看手册,以为A0也可以触摸,结果写完程序验证发现不行,然后就也懒得该回去了,直接赋0算了。
③下面以A1触摸来进行介绍每个触摸按键的程序。
1、判断A1是否被触摸
if cp.touch_A1:
2、当A1被触摸时蜂鸣器播放dao的音,同时与A1临近的两个WS2812亮起,因为触摸IO和WS2812的位置对应不好,所以亮起的都是临近的彩灯。
cp.start_tone(tones[1])
cp.pixels[6]=0x0f000f
cp.pixels[7]=0x0f000f
print("A1 touched!")
3、同理处理其他触摸IO被触摸时的逻辑。
elif cp.touch_A2:
cp.start_tone(tones[2])
cp.pixels[7]=0x0f000f
cp.pixels[8]=0x0f000f
print("A2 touched!")
elif cp.touch_A3:
cp.start_tone(tones[3])
cp.pixels[8]=0x0f000f
cp.pixels[9]=0x0f000f
print("A3 touched!")
elif cp.touch_A4:
cp.start_tone(tones[4])
cp.pixels[0]=0x0f000f
cp.pixels[1]=0x0f000f
print("A4 touched!")
elif cp.touch_A5:
cp.start_tone(tones[5])
cp.pixels[1]=0x0f000f
cp.pixels[2]=0x0f000f
print("A5 touched!")
elif cp.touch_A6:
cp.start_tone(tones[6])
cp.pixels[2]=0x0f000f
cp.pixels[3]=0x0f000f
print("A6 touched!")
elif cp.touch_TX:
cp.start_tone(tones[7])
cp.pixels[3]=0x0f000f
cp.pixels[4]=0x0f000f
print("A7 touched!")
4、当所有IO都没有被触摸时,关闭蜂鸣器,所有彩灯熄灭,延时0.1秒开始下一次检测。
else:
cp.stop_tone()
cp.pixels.fill(0)
time.sleep(0.1)
完整程序如下:
#【Follow me第二季第1期】白菜虫虫
# 创意任务三:水果钢琴——通过触摸水果弹奏音乐,并配合灯光效果
import time
from adafruit_circuitplayground import cp
tones=(0,392,440,494,523,587,659,698,784)
cp.pixels.fill(0)
while True:
if cp.touch_A1:
cp.start_tone(tones[1])
cp.pixels[6]=0x0f000f
cp.pixels[7]=0x0f000f
print("A1 touched!")
elif cp.touch_A2:
cp.start_tone(tones[2])
cp.pixels[7]=0x0f000f
cp.pixels[8]=0x0f000f
print("A2 touched!")
elif cp.touch_A3:
cp.start_tone(tones[3])
cp.pixels[8]=0x0f000f
cp.pixels[9]=0x0f000f
print("A3 touched!")
elif cp.touch_A4:
cp.start_tone(tones[4])
cp.pixels[0]=0x0f000f
cp.pixels[1]=0x0f000f
print("A4 touched!")
elif cp.touch_A5:
cp.start_tone(tones[5])
cp.pixels[1]=0x0f000f
cp.pixels[2]=0x0f000f
print("A5 touched!")
elif cp.touch_A6:
cp.start_tone(tones[6])
cp.pixels[2]=0x0f000f
cp.pixels[3]=0x0f000f
print("A6 touched!")
elif cp.touch_TX:
cp.start_tone(tones[7])
cp.pixels[3]=0x0f000f
cp.pixels[4]=0x0f000f
print("A7 touched!")
else:
cp.stop_tone()
cp.pixels.fill(0)
time.sleep(0.1)
[localvideo]d32142352f6e07518dc38fa92050e162[/localvideo]
创意任务三--2 陈皮水果钢琴
其实吧本来做完触摸钢琴就想着结束来着,但是家里有小朋友吧,就想着真让他们试试水果钢琴。
在我的小仓库里面翻出来鳄鱼夹接上,运行程序傻眼了,直接不用触摸就开始响了,取下鳄鱼夹就不响,试了试用镊子搭上触摸IO也是一样响。
尝试了CP库的touch和手册例程的touchio库都是这样(猜测这俩是一样的),没办法就只能从最基础的地方下手了。触摸这东西猜一下原理应该是通过模拟值来实现的,先用analogio 库读取A1的值并循环显示。
触摸时数值如下:
而不触摸时数值如下:
观察可知,不触摸的时候,数值是类似随机数的波动(物理随机数,真随机)。而触摸时,数值会在0和65535两个数之间来回波动,于是我们就可以自己写一个触摸逻辑:
A_1 = analogio.AnalogIn(A1)
while True:
if A_1.value==0 or A_1.value==65535:
cp.start_tone(tones[1])
cp.pixels[6]=0x0f000f
cp.pixels[7]=0x0f000f
print("A1 touched!")
同样的逻辑完成整个程序的修改,完成程序如下:
import analogio
from board import *
import time
from adafruit_circuitplayground import cp
tones=(0,392,440,494,523,587,659,698,784)
A_1 = analogio.AnalogIn(A1)
A_2 = analogio.AnalogIn(A2)
A_3 = analogio.AnalogIn(A3)
A_4 = analogio.AnalogIn(A4)
A_5 = analogio.AnalogIn(A5)
A_6 = analogio.AnalogIn(A6)
A_7 = analogio.AnalogIn(TX)
while True:
if A_1.value==0 or A_1.value==65535:
cp.start_tone(tones[1])
cp.pixels[6]=0x0f000f
cp.pixels[7]=0x0f000f
print("A1 touched!")
elif A_2.value==0 or A_2.value==65535:
cp.start_tone(tones[2])
cp.pixels[7]=0x0f000f
cp.pixels[8]=0x0f000f
print("A2 touched!")
elif A_3.value==0 or A_3.value==65535:
cp.start_tone(tones[3])
cp.pixels[8]=0x0f000f
cp.pixels[9]=0x0f000f
print("A3 touched!")
elif A_4.value==0 or A_4.value==65535:
cp.start_tone(tones[4])
cp.pixels[0]=0x0f000f
cp.pixels[1]=0x0f000f
print("A4 touched!")
elif A_5.value==0 or A_5.value==65535:
cp.start_tone(tones[5])
cp.pixels[1]=0x0f000f
cp.pixels[2]=0x0f000f
print("A5 touched!")
elif A_6.value==0 or A_6.value==65535:
cp.start_tone(tones[6])
cp.pixels[2]=0x0f000f
cp.pixels[3]=0x0f000f
print("A6 touched!")
elif A_7.value==0 or A_7.value==65535:
cp.start_tone(tones[7])
cp.pixels[3]=0x0f000f
cp.pixels[4]=0x0f000f
print("A7 touched!")
else:
cp.stop_tone()
cp.pixels.fill(0)
print("null")
time.sleep(0.2)
接好鳄鱼夹测试,可以正常演奏。
但是手头上没有水果,只好从水杯里扒拉出几片陈皮擦干顶一下,没想到竟然也能演奏。
于是乎,陈皮钢琴闪亮诞生。
[localvideo]8b983a2972e36658d5df54dba6bae6f6[/localvideo]
心得体会
总体来说这是一次很快乐的活动,难度不是很高,以我这种老菜鸟的水平也没有遇到什么困难。小圆板硬件设计的很出色,集成了很多功能还保持了合适的体积。circuitPython使用起来也非常的方便,用一个大佬兄弟的话来说就是已经把饭喂到了你的嘴里。这次的软硬件非常适合新手入门和小朋友学编程使用。
通过这次活动我进一步的熟悉了WS2812彩色LED、音乐播放的操作,学习了光线传感器、三轴运动传感器、触摸按键等功能的使用。通过这次的活动,我加深了对各种硬件的了解,增长了自己的编程技巧,同时也积累的调试的经验,可以说是收获满满。
以上就是我惨这这次follow me活动的学习总结,如有错漏欢迎各位大佬斧正,最后再次感谢主办方EEworld和得捷提供的这次学习提高的机会,谢谢各位的能看到这里。
- 2023-12-11
-
加入了学习《【得捷电子Follow me第3期】可以使用ESPNOW同步获取数据的家庭气象站》,观看 【得捷电子Follow me第3期】可以使用ESPNOW同步获取数据的家庭气象站