8.27
【写在前面】
这个帖子是roco小智和DF L298N驱动模块 双电机小车的故事- Makelog(造物记)的续集,小车部分上一帖子里完成了,可是还有不足,比如转向0.5秒,它就做不出来(需要修改库),所以这期就会想一个办法来曲线实现。更主要的是,要体验一下读取传感器的数据,DHT11,模拟光线传感器,模拟声音传感器的值,都集成到小车上,做成环境监测小车。

材料清单
- ROCO面包板小智 X1
- 双电机小车底盘 X1
- L298N DF 电机驱动模块 X1
- DHT11温湿度传感器 X1
- 模拟光线传感器 X1
- 模拟声音传感器 X1
步骤1 在ROCO小智双电机小车上增加传感器
正如上面所述,我增加了三个传感器:
DHT11温湿度传感器接到GPIO20。

模拟环境光线传感器接到GPIO7。

模拟声音传感器接到GPIO17。

roco小智双轮小车的接线图:

这个图线已经够多了,这3个传感器就不向上面画了哈。
最终的成品是这样子的:

步骤2 程序编写
要加载DHT温湿度传感器和本地物联控制库。

本地物联控制库的积木块:

写程序如下:
AI和硬件初始化及注册控制设备。

在语音交互中读取传感器数据、OLED显示和RGB指示灯


设备控制部分


电机运动控制自定义积木


代码中修改IO48为IO45。

代码
//代码部分
#include <Arduino.h>
#include "RoCoAI.h"
#include "oleddisplay.h"
#include <dhtESP32-rmt.h>
constexpr gpio_num_t kMicPinBclk = GPIO_NUM_42;
constexpr gpio_num_t kMicPinWs = GPIO_NUM_40;
constexpr gpio_num_t kMicPinDin = GPIO_NUM_41;
constexpr gpio_num_t kSpeakerPinBclk = GPIO_NUM_47;
constexpr gpio_num_t kSpeakerPinWs = GPIO_NUM_45;
constexpr gpio_num_t kSpeakerPinDout = GPIO_NUM_21;
constexpr gpio_num_t kTriggerPin = GPIO_NUM_0;
const char* kWifiSsid ="CMCC-QuYY";
const char* kWifiPassword ="qmsjyff2025";
AiVoxCore* g_ai_vox = nullptr;
constexpr gpio_num_t kI2cPinSda = GPIO_NUM_8;
constexpr gpio_num_t kI2cPinScl = GPIO_NUM_9;
constexpr uint32_t kDisplayWidth = 128;
constexpr uint32_t kDisplayHeight = 64;
constexpr bool kDisplayMirrorX = true;
constexpr bool kDisplayMirrorY = true;
constexpr uint8_t kI2cAddress = 0x3C;
DHT dht(20, DHT11);
std::shared_ptr<ai_vox::iot::Entity> g_car_forward_entity;
std::shared_ptr<ai_vox::iot::Entity> g_car_backward_entity;
std::shared_ptr<ai_vox::iot::Entity> g_car_left_entity;
std::shared_ptr<ai_vox::iot::Entity> g_car_right_entity;
std::shared_ptr<ai_vox::iot::Entity> g_dht_tem_entity;
std::shared_ptr<ai_vox::iot::Entity> g_dht_hum_entity;
std::shared_ptr<ai_vox::iot::Entity> g_illuminance_entity;
std::shared_ptr<ai_vox::iot::Entity> g_sound_entity;
std::shared_ptr<ai_vox::iot::Entity> g_forward_bit_entity;
std::shared_ptr<ai_vox::iot::Entity> g_backward_bit_entity;
std::shared_ptr<ai_vox::iot::Entity> g_left_bit_entity;
std::shared_ptr<ai_vox::iot::Entity> g_right_bit_entity;
using ChatState = AiVoxCore::ChatState;
void handleStateChange(ChatState old_state, ChatState new_state) {
g_dht_tem_entity->UpdateState("brightness", dht.readTemperature());
g_dht_hum_entity->UpdateState("brightness", dht.readHumidity());
g_illuminance_entity->UpdateState("brightness", analogRead(7));
g_sound_entity->UpdateState("brightness", analogRead(17));
if (new_state == ChatState::kConnecting) {
OLEDDisplay::ShowStatus("连接中");
ledcWrite(4, 50);
ledcWrite(5, 50);
ledcWrite(6, 0);
}
if (new_state == ChatState::kStandby) {
OLEDDisplay::ShowStatus("等待中");
ledcWrite(4, 0);
ledcWrite(5, 50);
ledcWrite(6, 0);
}
if (new_state == ChatState::kListening) {
OLEDDisplay::ShowStatus("聆听中");
ledcWrite(4, 50);
ledcWrite(5, 0);
ledcWrite(6, 50);
}
if (new_state == ChatState::kSpeaking) {
OLEDDisplay::ShowStatus("说话中");
ledcWrite(4, 0);
ledcWrite(5, 0);
ledcWrite(6, 50);
}
}
void handleChatMessage(const std::string& role, const std::string& content) {
OLEDDisplay::SetChatMessage(content.c_str());
}
void handleEmotion(const std::string& emotion) {
OLEDDisplay::SetEmotion(emotion.c_str());
}
void handleIotControl(const std::string& name,const std::string& function,const std::map<std::string, ai_vox::iot::Value>& params){
if (name == "car_forward" && function == "前进时间0-10秒") {
g_car_forward_entity->UpdateState("brightness", std::get<int64_t>(params.at("level")));
_E5_89_8D_E8_BF_9B_N_N(255, std::get<int64_t>(params.at("level")));
}
if (name == "car_backward" && function == "后退时间0-10秒") {
g_car_backward_entity->UpdateState("brightness", std::get<int64_t>(params.at("level")));
_E5_90_8E_E9_80_80_N_N(255, std::get<int64_t>(params.at("level")));
}
if (name == "car_left" && function == "左转时间0-10秒") {
g_car_left_entity->UpdateState("brightness", std::get<int64_t>(params.at("level")));
_E5_B7_A6_E8_BD_AC_N_N(180, std::get<int64_t>(params.at("level")));
}
if (name == "car_right" && function == "右转时间0-10秒") {
g_car_right_entity->UpdateState("brightness", std::get<int64_t>(params.at("level")));
_E5_8F_B3_E8_BD_AC_N_N(180, std::get<int64_t>(params.at("level")));
}
if (name == "forward_bit" && function == "前进一点点") {
g_forward_bit_entity->UpdateState("state", "前进");
_E5_89_8D_E8_BF_9B_N_N(180, 0.5);
}
if (name == "backward_bit" && function == "后退一点点") {
g_backward_bit_entity->UpdateState("state", "后退");
_E5_90_8E_E9_80_80_N_N(180, 0.5);
}
if (name == "left_bit" && function == "左转一点点") {
g_left_bit_entity->UpdateState("state", "左转");
_E5_B7_A6_E8_BD_AC_N_N(180, 0.5);
}
if (name == "right_bit" && function == "右转一点点") {
g_right_bit_entity->UpdateState("state", "右转");
_E5_8F_B3_E8_BD_AC_N_N(180, 0.5);
}
}
void _E5_89_8D_E8_BF_9B_N_N(float _E9_80_9F_E5_BA_A6, float _E6_97_B6_E9_97_B4) {
ledcWrite(1, _E9_80_9F_E5_BA_A6);
digitalWrite(2, LOW);
ledcWrite(11, _E9_80_9F_E5_BA_A6);
digitalWrite(12, LOW);
delay(_E6_97_B6_E9_97_B4 * 1000);
ledcWrite(1, 0);
ledcWrite(11, 0);
}
void _E5_90_8E_E9_80_80_N_N(float _E9_80_9F_E5_BA_A6, float _E6_97_B6_E9_97_B4) {
ledcWrite(1, _E9_80_9F_E5_BA_A6);
digitalWrite(2, HIGH);
ledcWrite(11, _E9_80_9F_E5_BA_A6);
digitalWrite(12, HIGH);
delay(_E6_97_B6_E9_97_B4 * 1000);
ledcWrite(1, 0);
ledcWrite(11, 0);
}
void _E5_B7_A6_E8_BD_AC_N_N(float _E9_80_9F_E5_BA_A6, float _E6_97_B6_E9_97_B4) {
ledcWrite(1, _E9_80_9F_E5_BA_A6);
digitalWrite(2, LOW);
ledcWrite(11, _E9_80_9F_E5_BA_A6);
digitalWrite(12, HIGH);
delay(_E6_97_B6_E9_97_B4 * 1000);
ledcWrite(1, 0);
ledcWrite(11, 0);
}
void _E5_8F_B3_E8_BD_AC_N_N(float _E9_80_9F_E5_BA_A6, float _E6_97_B6_E9_97_B4) {
ledcWrite(1, _E9_80_9F_E5_BA_A6);
digitalWrite(2, HIGH);
ledcWrite(11, _E9_80_9F_E5_BA_A6);
digitalWrite(12, LOW);
delay(_E6_97_B6_E9_97_B4 * 1000);
ledcWrite(1, 0);
ledcWrite(11, 0);
}
void setupIotDevices() {
std::vector<ai_vox::iot::Property> car_forward_props{
{"brightness", "小车前进运动时间", ai_vox::iot::ValueType::kNumber}
};
std::vector<ai_vox::iot::Function> car_forward_funcs{
{"前进时间0-10秒", "前进时间0-10秒", {
{"level", "前进时间0-10秒", ai_vox::iot::ValueType::kNumber}
}}
};
g_car_forward_entity = std::make_shared<ai_vox::iot::Entity>(
"car_forward",
"car_forward设备属性",
car_forward_props,
car_forward_funcs
);
g_car_forward_entity->UpdateState("brightness", 0);
g_ai_vox->registerIotDevice(g_car_forward_entity);
std::vector<ai_vox::iot::Property> car_backward_props{
{"brightness", "小车后退运动时间", ai_vox::iot::ValueType::kNumber}
};
std::vector<ai_vox::iot::Function> car_backward_funcs{
{"后退时间0-10秒", "后退时间0-10秒", {
{"level", "后退时间0-10秒", ai_vox::iot::ValueType::kNumber}
}}
};
g_car_backward_entity = std::make_shared<ai_vox::iot::Entity>(
"car_backward",
"car_backward设备属性",
car_backward_props,
car_backward_funcs
);
g_car_backward_entity->UpdateState("brightness", 0);
g_ai_vox->registerIotDevice(g_car_backward_entity);
std::vector<ai_vox::iot::Property> car_left_props{
{"brightness", "小车左转运动时间", ai_vox::iot::ValueType::kNumber}
};
std::vector<ai_vox::iot::Function> car_left_funcs{
{"左转时间0-10秒", "左转时间0-10秒", {
{"level", "左转时间0-10秒", ai_vox::iot::ValueType::kNumber}
}}
};
g_car_left_entity = std::make_shared<ai_vox::iot::Entity>(
"car_left",
"car_left设备属性",
car_left_props,
car_left_funcs
);
g_car_left_entity->UpdateState("brightness", 0);
g_ai_vox->registerIotDevice(g_car_left_entity);
std::vector<ai_vox::iot::Property> car_right_props{
{"brightness", "小车右转运动时间", ai_vox::iot::ValueType::kNumber}
};
std::vector<ai_vox::iot::Function> car_right_funcs{
{"右转时间0-10秒", "右转时间0-10秒", {
{"level", "右转时间0-10秒", ai_vox::iot::ValueType::kNumber}
}}
};
g_car_right_entity = std::make_shared<ai_vox::iot::Entity>(
"car_right",
"car_right设备属性",
car_right_props,
car_right_funcs
);
g_car_right_entity->UpdateState("brightness", 0);
g_ai_vox->registerIotDevice(g_car_right_entity);
std::vector<ai_vox::iot::Property> dht_tem_props{
{"brightness", "DTH传感器温度", ai_vox::iot::ValueType::kNumber}
};
std::vector<ai_vox::iot::Function> dht_tem_funcs{
{"读取传感器温度值(单位:摄氏度)", "读取传感器温度值(单位:摄氏度)", {
{"level", "读取传感器温度值(单位:摄氏度)", ai_vox::iot::ValueType::kNumber}
}}
};
g_dht_tem_entity = std::make_shared<ai_vox::iot::Entity>(
"dht_tem",
"dht_tem设备属性",
dht_tem_props,
dht_tem_funcs
);
g_dht_tem_entity->UpdateState("brightness", 0);
g_ai_vox->registerIotDevice(g_dht_tem_entity);
std::vector<ai_vox::iot::Property> dht_hum_props{
{"brightness", "DTH传感器湿度", ai_vox::iot::ValueType::kNumber}
};
std::vector<ai_vox::iot::Function> dht_hum_funcs{
{"读取湿度值", "读取湿度值", {
{"level", "读取湿度值", ai_vox::iot::ValueType::kNumber}
}},
{"读取传感器湿度值(单位:%)", "读取传感器湿度值(单位:%)", {
{"level", "读取传感器湿度值(单位:%)", ai_vox::iot::ValueType::kNumber}
}}
};
g_dht_hum_entity = std::make_shared<ai_vox::iot::Entity>(
"dht_hum",
"dht_hum设备属性",
dht_hum_props,
dht_hum_funcs
);
g_dht_hum_entity->UpdateState("brightness", 0);
g_ai_vox->registerIotDevice(g_dht_hum_entity);
std::vector<ai_vox::iot::Property> illuminance_props{
{"brightness", "环境光线传感器数据", ai_vox::iot::ValueType::kNumber}
};
std::vector<ai_vox::iot::Function> illuminance_funcs{
{"读取环境光线传感器(单位:勒克斯)", "读取环境光线传感器(单位:勒克斯)", {
{"level", "读取环境光线传感器(单位:勒克斯)", ai_vox::iot::ValueType::kNumber}
}}
};
g_illuminance_entity = std::make_shared<ai_vox::iot::Entity>(
"illuminance",
"illuminance设备属性",
illuminance_props,
illuminance_funcs
);
g_illuminance_entity->UpdateState("brightness", 0);
g_ai_vox->registerIotDevice(g_illuminance_entity);
std::vector<ai_vox::iot::Property> sound_props{
{"brightness", "环境音量传感器数据", ai_vox::iot::ValueType::kNumber}
};
std::vector<ai_vox::iot::Function> sound_funcs{
{"读取环境模拟音量(范围0-4095,没有单位))", "读取环境模拟音量(范围0-4095,没有单位))", {
{"level", "读取环境模拟音量(范围0-4095,没有单位))", ai_vox::iot::ValueType::kNumber}
}}
};
g_sound_entity = std::make_shared<ai_vox::iot::Entity>(
"sound",
"sound设备属性",
sound_props,
sound_funcs
);
g_sound_entity->UpdateState("brightness", 0);
g_ai_vox->registerIotDevice(g_sound_entity);
std::vector<ai_vox::iot::Property> forward_bit_props{
{"state", "小车前进一点点", ai_vox::iot::ValueType::kString}
};
std::vector<ai_vox::iot::Function> forward_bit_funcs{
{"前进一点点", "前进一点点", {}}
};
g_forward_bit_entity = std::make_shared<ai_vox::iot::Entity>(
"forward_bit",
"forward_bit设备属性",
forward_bit_props,
forward_bit_funcs
);
g_forward_bit_entity->UpdateState("state", "close");
g_ai_vox->registerIotDevice(g_forward_bit_entity);
std::vector<ai_vox::iot::Property> backward_bit_props{
{"state", "小车后退一点点", ai_vox::iot::ValueType::kString}
};
std::vector<ai_vox::iot::Function> backward_bit_funcs{
{"后退一点点", "后退一点点", {}}
};
g_backward_bit_entity = std::make_shared<ai_vox::iot::Entity>(
"backward_bit",
"backward_bit设备属性",
backward_bit_props,
backward_bit_funcs
);
g_backward_bit_entity->UpdateState("state", "close");
g_ai_vox->registerIotDevice(g_backward_bit_entity);
std::vector<ai_vox::iot::Property> left_bit_props{
{"state", "小车左转一点点", ai_vox::iot::ValueType::kString}
};
std::vector<ai_vox::iot::Function> left_bit_funcs{
{"左转一点点", "左转一点点", {}}
};
g_left_bit_entity = std::make_shared<ai_vox::iot::Entity>(
"left_bit",
"left_bit设备属性",
left_bit_props,
left_bit_funcs
);
g_left_bit_entity->UpdateState("state", "close");
g_ai_vox->registerIotDevice(g_left_bit_entity);
std::vector<ai_vox::iot::Property> right_bit_props{
{"state", "小车右转一点点", ai_vox::iot::ValueType::kString}
};
std::vector<ai_vox::iot::Function> right_bit_funcs{
{"右转一点点", "右转一点点", {}}
};
g_right_bit_entity = std::make_shared<ai_vox::iot::Entity>(
"right_bit",
"right_bit设备属性",
right_bit_props,
right_bit_funcs
);
g_right_bit_entity->UpdateState("state", "close");
g_ai_vox->registerIotDevice(g_right_bit_entity);
}
void setup() {
AiVoxCore::AudioConfig audio_config{kMicPinBclk, kMicPinWs, kMicPinDin,kSpeakerPinBclk, kSpeakerPinWs, kSpeakerPinDout};
g_ai_vox = new AiVoxCore(audio_config, kTriggerPin, kWifiSsid, kWifiPassword,true);
OLEDDisplay::Init(kI2cPinSda, kI2cPinScl, kDisplayWidth, kDisplayHeight, kDisplayMirrorX, kDisplayMirrorY, kI2cAddress);
ledcAttachChannel(4, 5000, 8, 0);
ledcAttachChannel(5, 5000, 8, 1);
ledcAttachChannel(6, 5000, 8, 2);
g_ai_vox->onStateChange(handleStateChange);
g_ai_vox->onChatMessage(handleChatMessage);
g_ai_vox->onEmotion(handleEmotion);
g_ai_vox->onIotControl(handleIotControl);
ledcAttachChannel(1, 5000, 8, 3);
pinMode(2, OUTPUT);
ledcAttachChannel(11, 5000, 8, 4);
pinMode(12, OUTPUT);
setupIotDevices();
g_ai_vox->begin();
}
void loop() {
repeat();
}
void repeat() {
g_ai_vox->update();
}
【小结】
读取传感器数据,数字和模拟传感器都可以的,需要库的传感器当前有DHT11/22。
在下一期,将会体验编程狮1.3.0的新增功能。
评论