模拟量传感器的测量数据一般为连续性的度量值,如温度值、电位器阻值、陀螺仪的加速度值等,需要使用AnalogRead函数或特定的驱动库来读取。
下面用两个例子来讲解模拟量传感器的使用
从 https://gitee.com/billyzh/esp32-cpp-lesson 下载本教程的源码到本地硬盘文件夹,如d:\esp32-cpp-lesson
在VSCode中,选择【文件】->【打开文件夹...】选择上一步保存的文件夹打开
旋转电位计实际上就是可变电阻器,由于它在电路中的作用是获得与输入电压(外加电压)成一定 关系得输出电压,因此称之为电位计。
打开项目后,选择config.h文件,修改第10行为
#define APP_LESSON42_A 1
打开unit4-lesson42a/board_config文件,设置REG LED和电位器使用的引脚,
#define RGB_LED_R_PIN GPIO_NUM_32
#define RGB_LED_G_PIN GPIO_NUM_23
#define RGB_LED_B_PIN GPIO_NUM_33
#define POTENTIOMETER_PIN GPIO_NUM_36
并配置使用RGB LED
#define CONFIG_USE_LED_RGB 1
创建传感器实例,代码如下(unit4-lesson42a/my_board.cpp):
MyBoard::MyBoard() : Board() {
Log::Info(TAG, "===== Create Board ...... =====");
Log::Info(TAG, "initial led.");
led_ = new RgbLed(RGB_LED_R_PIN, RGB_LED_G_PIN, RGB_LED_B_PIN, false);
Log::Info(TAG, "initial sensor.");
std::shared_ptr<AnalogSensor> sensor_ptr = std::make_shared<AnalogSensor>(kPotentiometer, POTENTIOMETER_PIN);
AddSensor(sensor_ptr);
Log::Info( TAG, "===== Board config completed. =====");
}
程序解读
1. 本例使用的电位器为模拟量传感器,这里使用AnalogSensor类构造,并使用智能指针保存,第1个参数为名称,第2个参数为引脚;
2. 在Board类中有一个集合(map)用于保存传感器实例指针,通过AddSensor方法将指针放入集合中,可通过名称来获取对应实例指针;
调节LED亮度
闪烁代码如下(unit4-lesson42a/my_application.cpp):
void MyApplication::OnInit() {
Log::Info(TAG, "Initial.");
// 启动传感器收集数据
std::shared_ptr<Sensor> sensor_ptr = Board::GetInstance().GetSensor(kPotentiometer);
sensor_ptr->Start(100);
}
void MyApplication::OnLoop() {
Led *led = Board::GetInstance().GetLed();
if (value_ == 0) {
led->TurnOff();
} else {
led->SetColor(value_, 0, 0);
led->TurnOn();
}
delay(100);
}
bool MyApplication::OnSensorDataEvent(const std::string& sensor_name, const SensorValue& value) {
// 处理传感器数据
if (sensor_name == kPotentiometer) {
// 电位器的值范围为:0-4095,一般使用map函数进行转换
int new_value = map(value.intValue(), 0, 4095, 0, 255);
if (new_value != value_) {
Log::Info(TAG, "new value: %d", new_value);
value_ = new_value;
}
return true;
}
return Application::OnSensorDataEvent(sensor_name, value);
}
程序解读
1. 在OnInit方法中使用Board类的GetSensor方法取得传感器智能指针,然后调用Start方法启动传感器数据获取,参数是数据获取间隔时间(单位ms);
2. 在OnLoop方法中检测value_的值,若大于0,则点亮LED,否则熄灭。value_是MyApplication类的一个私有变量,用于保存电位器的值。使用了volatile定义,防止编译器优化变量访问,确保每次读写都直接操作内存;
3. 重载Application类的OnSensorDataEvent方法实现业务,这里根据传感器的值来设置value_变量,;
编译项目并上传开发板检验
map函数是Arduino自带的值区间映射函数,实际就是一个按比例缩小或放大区间值的函数。
上例中,从电位器获取的值是一个0~4095之间的值,而对于LED亮度,允许范围是0~255,
故使用map(val, 0, 4095, 0, 255)转换即可得到。
若要将电位器用于音量调节,希望一个0~100之间的值,可以使用map(0, 4095, 0, 100)来映射。
另外,反向映射也是可以的,如map(val, 0, 4095, 255, 0)将0~4095之间的值转换为255~0之间的值。
DHT11数字温度 - 湿度传感器是一种包含校准数字信号输出的复合传感器。
打开项目后,选择config.h文件,修改第10行为
#define APP_LESSON42_B 1
打开unit4-lesson42b/board_config文件,设置传感器使用的引脚,
#define DHT11_PIN GPIO_NUM_25
创建传感器实例,代码如下(unit4-lesson42b/my_board.cpp):
MyBoard::MyBoard() : Board() {
Log::Info(TAG, "===== Create Board ...... =====");
Log::Info(TAG, "initial led.");
led_ = new GpioLed(BUILTIN_LED_PIN, false);
Log::Info(TAG, "initial sensor.");
std::shared_ptr<Dht11Sensor> dht11_ptr = std::make_shared<Dht11Sensor>(kDht11, DHT11_PIN);
AddSensor(dht11_ptr);
Log::Info( TAG, "===== Board config completed. =====");
}
程序解读
本例使用的Dht11传感器使用了特定协议来传送数据,故需要自定义传感器类来实现数据获取。
Dht11传感器类,代码如下(unit4-lesson42b/dht11_sensor.h):
class Dht11Sensor : public Sensor {
public:
Dht11Sensor(const std::string& name, gpio_num_t pin) : Sensor(name) {
dht_ = new DHT(pin, DHT11);
dht_->begin();
}
bool ReadValue(SensorValue *value) override {
float shidu = dht_->readHumidity();
float wendu = dht_->readTemperature();
std::vector<float> list;
list.push_back(wendu);
list.push_back(shidu);
value->setFloatList(list);
return true;
}
private:
DHT* dht_;
};
程序解读
1.Dht11Sensor类继承Sensor类,内部采用第三方DHT库读取数据,使用前请自行安装DHT库: https://github.com/adafruit/DHT-sensor-library
2.在构造函数中创建DHT实例并指定芯片类型,然后开始测量温湿度,这个三方库支持DHT11,DHT22等温湿度传感器
3.在重载在ReadValue方法里,获取温度、湿度数据填充到SensorValue实例中,这里使用的是float向量列表来保存数据
在传感器的数据非单个数字量或模拟量时,一般可以参考Dht11Sensor类这样来自定义实现传感器类。
显示温度、湿度数据,代码如下(unit4-lesson42b/my_application.cpp):
void MyApplication::OnInit() {
// 启动传感器收集数据
std::shared_ptr<Sensor> dht11_ptr = Board::GetInstance().GetSensor(kDht11);
if (dht11_ptr!=nullptr) {
dht11_ptr->Start(180000);
}
}
bool MyApplication::OnSensorDataEvent(const std::string& sensor_name, const SensorValue& value) {
// 处理传感器数据
if (sensor_name == kDht11) {
float weidu = value.floatList().at(0);
float shidu = value.floatList().at(1);
Log::Info(TAG, "温度:%.1f, 湿度:%.1f", weidu, shidu);
// 其他显示操作
return true;
}
return Application::OnSensorDataEvent(sensor_name, value);
}
程序解读
1.在OnInit方法中启动传感器数据采集;
2.在OnSensorDataEvent中处理传感器数据,这里使用Log::Info输出到串口
万向节即万向接头,英文名称universal joint,是实现变角度动力传递的机件,用于需要改变传动轴线方向的位置
MimiClaw 是一款基于 ESP32-S3 芯片的超轻量级AI助手,适合嵌入式AI与物联网开发者快速部署本地化AI代理。本系列教程基于MimiClaw的Arduino移植版本进行讲解,小节主要讲解部署和测试。
就像我们用手机打开WiFi功能后可以浏览附近的可用WiFi。要将手机连接到热点,通常需要打开Wi-Fi设置应用程序,列出可用的网络,然后选择所需的热点。然后输入密码(或不输入密码),可以使用ESP32进行相同的操作。
本文本介绍配置飞书机器人为MimiClaw的一个输入/输出端,和添加一个控制WS2812与LED的控制技能。
一块 30 块钱的开发板 + 一个大模型 API,就能做出可以听懂人话的智能硬件。 本文记录完整安装过程和踩坑经验,确保你跟着做就能跑通。
本文将从手绘架构图入手,逐层拆解 MimiClaw 的分层设计、核心模块、数据流转与底层实现,带你解剖这只“智能虾”的技术骨架,看懂在 C 语言加持下,AI 智能体如何以可穿戴设备的形态,在你身边稳稳运行、离线服务、主动响应。
本文介绍如何在不脱离 ArduinoIDE 可视化开发的前提下,通过一个名为 platform.local.txt 的小文件,实现对 ESP32 编译流程的精准控制。
本文将系统分析程序体积增长的五大根源,并提供经过验证的优化方案,帮助减小固件大小。
本文所DIY的语音助手设备端使用的是MicroPython、服务端是Python,对于很多开发者来说MicroPython入门没难度。
本小节使用音频开发框架实现一个音频录制到文件的示例。
I2S协议通过BCLK、LRCLK和DATA三线精准传输音频数据,但时序边沿、帧格式、时钟源等细节常引发噪声或断连。本文详解ESP32的I2S实现,从协议原理到ESP-IDF v5.x代码配置,助你避开常见陷阱,确保音频稳定传输。