【ESP32 Arduino平衡小车制作】(三) 直流电机pwm控制

基于ESP32的直流电机PWM控制

直流电机驱动器

驱动器使用 H桥电路进行驱动,核心电路 H 桥加上一些必要的外围电路,共同组成直流有刷电机的驱动器。H 桥本身可作为集成电路使用,也可由分立元件构成。

集成电路形式的 H 桥一般用于中小功率需求的应用,或者是对电路面积有要求的场合。

分立元件形式的 H 桥通常用于大功率或者超大功率需求的应用,主要由 MOSFET 或 IGBT 晶体管组成。

这里我使用的是TB6612这款直流驱动芯片

可利用IN1和IN2这两个输入信号,选择正转,反转,短路制动器、和停机等四种模式的其中一种模式。

在这里插入图片描述

二、ESP32 - PWM(LEDC)输出

LED_PWM 主要用于控制 LED 的亮度和颜色,也可以产生 PWM 信号用于其他用途。

LED_PWM 有 16 路通道,即 8 路高速通道和 8 路低速通道。这 16 路通道能够产生独立的数字波形来驱动 RGB LED 设备。

高速或低速通道可以由四个高速定时器之一或四个低速定时器之一进行驱动。 PWM 控制器还能够自动逐渐增加或减少占空比,在无须处理器干预的情况下实现亮度和颜色渐变。 LED_PWM 还支持小数分频。

方法函数:

double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits)

(通道号,频率,计数位数)
channel为通道号,取值0 ~ 15;
freq,设置频率;
resolution_bits计数位数,取值0 ~ 20(该值决定后面ledcWrite方法中占空比的最大值,如该值写10,则占空比最大可写2^10-1=1023 ;
通道最终频率 = 时钟频率 / ( 分频系数 * ( 2^计数位数 ) );(分频系数最大为1024)
该方法返回值:最终频率;


void ledcWrite(uint8_t channel, uint32_t duty)

(通道,占空比)
指定通道输出一定占空比的波形;


double ledcWriteTone(uint8_t channel, double freq)

(通道,频率)
当外接无源蜂鸣器的时候可用该函数,发出某种音色(根据频率不同而不同);


double ledcWriteNote(uint8_t channel, note_t note, uint8_t octave)

(通道,调式,音阶)
该方法是上面方法的进一步封装,可以直接输出指定调式和音阶声音的信号,参数如下:
note:调式,取值为NOTE_C, NOTE_Cs, NOTE_D, NOTE_Eb, NOTE_E, NOTE_F, NOTE_Fs, NOTE_G, NOTE_Gs, NOTE_A, NOTE_Bb, NOTE_B
octave音阶,取值0~7;


uint32_t ledcRead(uint8_t channel)

(通道)
返回指定通道占空比的值;


double ledcReadFreq(uint8_t channel)

(通道)
返回指定通道当前频率(如果当前占空比为0 则该方法返回0);


void ledcAttachPin(uint8_t pin, uint8_t channel)

(引脚,通道)
绑定:将LEDC通道投射到指定IO口上;


void ledcDetachPin(uint8_t pin)

(引脚)
解除绑定:解除IO口的LEDC功能;


以上参考:
1、《esp32_技术参考手册.pdf》
2、使用Arduino开发ESP32(十三):PWM(LEDC)
3、玩转 ESP32 + Arduino (三) GPIO和串口

三、电机控制程序

#include <Arduino.h>
#include <Ticker.h>

//TB6612FNG驱动模块控制信号 共6个
#define IN1 14  //控制电机1的方向A,01为正转,10为反转 
#define IN2 12  //控制电机1的方向B,01为正转,10为反转 
#define IN3 27  //控制电机2的方向A,01为正转,10为反转 
#define IN4 26  //控制电机2的方向B,01为正转,10为反转 

#define PWMA 25	//控制电机1 PWM控制引脚
#define PWMB 33 //控制电机2 PWM控制引脚

#define freq 50000 		 //PWM波形频率5KHZ
#define pwm_Channel_1  0 //使用PWM的通道0
#define pwm_Channel_2  1 //使用PWM的通道1

#define resolution  10		//使用PWM占空比的分辨率,占空比最大可写2^10-1=1023
#define interrupt_time_control 15//定时器15ms中断控制时间

/**************************************************************************
函数功能:赋值给PWM寄存器 
入口参数:左轮PWM、右轮PWM
返回  值:无
**************************************************************************/
void Set_Pwm(int moto1, int moto2)
{
	int Amplitude = 900;  //===PWM满幅是1024 限制在950
	
	if (moto1 > 0)   digitalWrite(IN1, HIGH),      digitalWrite(IN2, LOW);  //TB6612的电平控制
	else             digitalWrite(IN1, LOW),       digitalWrite(IN2, HIGH); //TB6612的电平控制
	
	if (moto2 > 0)   digitalWrite(IN3, LOW),      digitalWrite(IN4, HIGH); //TB6612的电平控制
	else             digitalWrite(IN3, HIGH),     digitalWrite(IN4, LOW); //TB6612的电平控制
	
	//功能:限制PWM赋值 
	if (moto1 < -Amplitude)  moto1 = -Amplitude;
	if (moto1 >  Amplitude)  moto1 =  Amplitude;
	if (moto2 < -Amplitude)  moto2 = -Amplitude;
	if (moto2 >  Amplitude)  moto2 =  Amplitude;
	
	//赋值给PWM寄存器 
	ledcWrite(pwm_Channel_1,abs(moto1));
	ledcWrite(pwm_Channel_2,abs(moto2));
}

void control(void)
{
	Set_Pwm(50,50); //这里仅仅设置占空比为50%,电机转速50%
} 

/*********************************setup**********************************/
void setup()
{
    pinMode(IN1, OUTPUT);          //TB6612控制引脚,控制电机1的方向,01为正转,10为反转
    pinMode(IN2, OUTPUT);          //TB6612控制引脚,
    pinMode(IN3, OUTPUT);          //TB6612控制引脚,控制电机2的方向,01为正转,10为反转
    pinMode(IN4, OUTPUT);          //TB6612控制引脚,
    pinMode(PWMA, OUTPUT);         //TB6612控制引脚,电机PWM
    pinMode(PWMB, OUTPUT);         //TB6612控制引脚,电机PWM

    digitalWrite(IN1, 0);          //TB6612控制引脚拉低
    digitalWrite(IN2, 0);          //TB6612控制引脚拉低
    digitalWrite(IN3, 0);          //TB6612控制引脚拉低
    digitalWrite(IN4, 0);          //TB6612控制引脚拉低
  
    ledcSetup(pwm_Channel_1, freq, resolution);	//PWM通道一开启设置
    ledcAttachPin(PWMA, pwm_Channel_1);			//PWM通道一和引脚PWMA关联
    ledcWrite(pwm_Channel_1, 0);				//PWM通道一占空比设置为零
    
    ledcSetup(pwm_Channel_2, freq, resolution); //PWM通道二开启设置
    ledcAttachPin(PWMB, pwm_Channel_2);			//PWM通道二和引脚PWMB关联
    ledcWrite(pwm_Channel_2, 0);				//PWM通道二占空比设置为零
    
    timer_control.attach_ms(interrupt_time_control, control); //定时器中断开启
}

/************************************loop************************************/
void loop()
{

}
### 如何使用ArduinoESP32PWM功能来控制电机 #### PWM基本概念 PWM(脉宽调制)是一种通过改变信号高电平持续时间的比例即占空比,从而调整输出平均功率的技术[^1]。 #### 调整直流电机速度 对于直流电机而言,可以通过调节施加到电机上的电压有效值来改变转速。利用PWM技术,可以保持电源电压恒定而仅需更改占空比就能轻松达成这一目的。当占空比增大时,作用于电机两端的有效电压升高,进而使电机运转得更快;反之则减速[^2]。 #### 实现方法概述 为了在Arduino平台下的ESP32开发板上实施上述过程,需要先选定合适的GPIO引脚作为PWM输出端口并与目标电机相连。接着编写程序设定特定频率及初始占空比参数给这些指定管脚发送周期性的方波形电信号。随着软件逻辑内定义的变化规律动态更新该比例数值即可达到预期效果——平稳地加速/减速直至停止运动为止。 #### 示例代码展示 下面给出一段简单的C++语言源码片段用于演示如何操作: ```cpp // 定义连接至电机控制器输入端对应的数字I/O编号 const int motorPin = 18; void setup() { // 初始化串行通信以便调试打印信息 Serial.begin(9600); // 设置motorPin为输出模式 pinMode(motorPin, OUTPUT); // 配置PWM特性,默认情况下ESP32支持多种预设频率选项 ledcSetup(0, 5000, 8); // channel=0,freq=5kHz,resolution=8bits // 将配置好的channel绑定到实际硬件pin上去 ledcAttachPin(motorPin, 0); } void loop() { for (int dutyCycle = 0; dutyCycle <= 255; ++dutyCycle) { // 渐进式提高占空比让马达慢慢启动起来 ledcWrite(0, dutyCycle); delay(15); // 延迟一段时间观察变化趋势 Serial.println(dutyCycle); } } ``` 此段代码实现了从静止状态逐步提升至最大速率的过程,并且每一步骤之间都留有足够的间隔供使用者直观感受整个提速流程中的细微差别。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值