8.25
【写在前面】
这个帖子是体验ROCO小智物联控制GPIO外接硬件*LED/舵机/继电器- Makelog(造物记)的续集。我们可以看到,roco小智有了新本领,它不仅一个可以聊天,而且还可以控制引脚上LED、舵机、继电器等,这一帖子,记录roco小智控制双电机的转动,就是一个小车啦。
所用的软件是编程狮roco,所以我把这个手搓的小智也叫做roco小智。
roco小智的搭建物料和接线图记录在上一帖子中了,所以这里直接引线到电机驱动模块,控制两个电机。

材料清单
- roco小智 X1
- L298N直流电机驱动模块DF-MD X1 链接
- TT电机 X2
- 小车底盘 X1
步骤1 roco小智双电机小车的接线
先来熟悉一下DF的L298电机驱动模块:

详细资料:直流电机驱动、L298N、产品简介、产品参数、使用说明、应用样例

我的接线图:

E1------IO1
M1-----IO2
E2------IO11
M2-----IO12
GND---GND
VD-----5Vin
组装完成的小车,这个样子:

步骤2 编写程序
从roco小智基础程序上增加电机控制功能。
要加载本地物联库。

对引脚上设备的控制,就在这里面。

编写程序如下:



自定义模块:


代码中修改IO48为IO45。

代码
//代码部分
#include <Arduino.h>
#include "RoCoAI.h"
#include "oleddisplay.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;
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;
using ChatState = AiVoxCore::ChatState;
void handleStateChange(ChatState old_state, ChatState new_state) {
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(255, 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(255, std::get<int64_t>(params.at("level")));
}
}
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);
}
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();
}
【小结】
图形化小智,蛮有趣的,大大减少了编程难度。
评论