目录
前言
端口配置
代码
前言
本文基于esp32使用platformio平台,通过udp来控制电机运行。
关键词:platformio,freertos,upd,esp32,motor,
端口配置
采用drv8833驱动板,其中esp32的d25接in2,d26接in1,d13接in4,d12接in3,esp32的3v3接drv8833的vcc,esp32的GND接drv8833的GND,2个电机的正负极接drv8833的OUT1至4。
代码
电机motor.h和motor.cpp代码如下
#ifndef MOTOR_H_
#define MOTOR_H_
#include <stdint.h>
class Motor
{
public:
Motor(int inv);
~Motor();
void initialize(int pin_A, int pwm_channel_A, int pin_B, int pwm_channel_B);
void setPwmDuty(float duty);
private:
double frequency = 1000;
uint8_t resolution_bits = 10;
int pin_A;
int pin_B;
int pwm_channel_A;
int pwm_channel_B;
int inverse;
};
#endif
#include "Motor.h"
#include <Arduino.h>
#include <esp32-hal-ledc.h>
void Motor::initialize(int pin_A, int pwm_channel_A, int pin_B, int pwm_channel_B)
{
this->pin_A = pin_A;
this->pin_B = pin_B;
this->pwm_channel_A = pwm_channel_A;
this->pwm_channel_B = pwm_channel_B;
ledcSetup(pwm_channel_A, frequency, resolution_bits);
ledcAttachPin(pin_A, pwm_channel_A);
ledcSetup(pwm_channel_B, frequency, resolution_bits);
ledcAttachPin(pin_B, pwm_channel_B);
}
void Motor::setPwmDuty(float duty)
{
duty = constrain(inverse * duty, -1, 1);
if (duty > 0)
{
ledcWrite(this->pwm_channel_A, (int)(1000* duty));
ledcWrite(this->pwm_channel_B, 0);
}
else
{
ledcWrite(this->pwm_channel_B, (int)(1000 * -duty));
ledcWrite(this->pwm_channel_A, 0);
}
}
Motor::Motor(int inv): inverse(inv)
{
}
Motor::~Motor()
{
}
main函数如下
#include<Arduino.h>
#include "motor.h"
#include<WiFi.h>
Motor * motorFL = new Motor(1);
Motor *motorFR = new Motor(1);
const char *ssid = "PDCN";
const char *password = "1234567890";
WiFiUDP udp;
int recv_length;
char recvbuff[255]; // 存储接收到的数据
uint16_t udp_port = 1234; // 端口号,ESP32默认IP:192.168.4.1
void motorTask(void *param){
int recv_length;
while (1)
{
recv_length = udp.parsePacket(); // 获取接收的数据的长度
//Serial.println("recvlength:" + recv_length);
if (recv_length) // 如果有数据那么recv_length不为0
{
int len = udp.read(recvbuff, 255); // 读取数据到recvbuff中
if (len > 0)
{
int a = atoi(recvbuff);
Serial.println(recvbuff); // 串口打印网口收到的数据
switch (a)
{
case 1 /* constant-expression */:
/* code */
motorFL->setPwmDuty(1);
break;
case 2:
motorFL->setPwmDuty(-1);
break;
case 0:
motorFL->setPwmDuty(0);
default:
break;
}
vTaskDelay(100);
motorFL->setPwmDuty(0);
}
// 将接收到的数据发送回去
udp.beginPacket(udp.remoteIP(), udp.remotePort()); // 准备发送数据到目标IP和目标端口
udp.print("Receive:");
udp.println(recvbuff); // 数据放入发送的缓冲区
udp.endPacket(); // 发送
for (int i = 0; i < 255; i++) // 清空接收数组
{
recvbuff[i] = 0;
}
}
vTaskDelay(100);
}
}
void setup(){
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("正在连接到WiFi...");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("已连接到 ");
Serial.println(ssid);
Serial.print("IP地址:");
Serial.println(WiFi.localIP());
Serial.println(udp_port);
udp.begin(udp_port); // 启动UDP监听端口,等待电脑发送数据
Serial.println("Ready!");
motorFL->initialize(25, 8, 26, 9);//PWM通道8和9,对应esp32的d25和d26
motorFR->initialize(12, 10, 13, 11);//PWM通道的10和11,对应esp32的d12和d13
//motorFL->setPwmDuty(0.5);
xTaskCreatePinnedToCore(motorTask,"motorTask",8192,NULL,1,NULL,1);
}
void loop()
{
// Do nothing. Everything is done in another task by the web server
//motorFL->setPwmDuty(1);
//motorFR->setPwmDuty(1);
}
实验通过电脑端串口调试器,如下所示,通过发送数字1或2使得电机运转0.1秒。