模拟量传感器的测量数据一般为连续性的度量值,如温度值、电位器阻值、陀螺仪的加速度值等,需要使用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输出到串口
I2S(Inter—IC Sound)总线, 又称集成电路内置音频总线,是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准。
本小节讲解Sensor类及派生类、数字量传感器使用和传感器的推荐交互流程。
本小节讲解ESP32内置触摸引脚的用法,
本小节主要介绍按键信号转换、Button类及派生类、和Button交互推荐流程。
本小节主要介绍Ws2812灯珠的使用、对父类进行扩展实现自定义功能,和指针向下强制转换的使用。
本小节主要介绍RGB三色LED的使用,以及多态的具体实现。
ESP32 Arduino Framework是专门针对ESP32开发板的Arduino应用开发框架,为用户开发IOT应用、HMI应用提供一致的开发体验。
ESPConnect是一个基于现代浏览器的管理器,在你需要快速验证、调试、管理文件、检查状态的时候,它能帮你省下大量打开和切换重型工具的时间。
本文介绍两种使用TEA5767收音机模块实现FM收音机的方案,感兴趣的朋友可在此基础上实现更丰富的功能。
GPIOViewer 是一个强大的 Arduino 库,专门为 ESP32 芯片设计,可以实时监控 ESP32 芯片上的所有 GPIO 引脚状态。它可以帮助你快速直观地了解每个引脚的当前状态,例如高电平、低电平、输入、输出、中断等等。
在音频处理领域,I2S是一种广泛使用的通信协议,它专门用于芯片之间的音频数据传输。ESP32 作为一款高性能的微控制器,不仅支持 I2S 通信,还提供了强大的硬件接口和灵活的软件库,使其成为音频项目开发的理想选择。