eagler8 发表于 2020-12-11 12:40:45

MX1508双路马达驱动模块电原理图

eagler8 发表于 2020-12-11 12:59:11

MX1508双路马达驱动模块接脚图

eagler8 发表于 2020-12-11 13:05:23

MX1508 电机驱动逻辑真值表

eagler8 发表于 2020-12-11 13:08:25

MX1508双路电机驱动模块接线示意图

eagler8 发表于 2020-12-11 16:13:43

本帖最后由 eagler8 于 2020-12-11 20:07 编辑

下载安装MX1508库

链接 https://codeload.github.com/Saeterncj/MX1508/zip/master

eagler8 发表于 2020-12-11 17:25:01

本帖最后由 eagler8 于 2020-12-11 20:11 编辑

/*
【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验一百七十二:MX1508 四通道双路有刷直流马达驱动模块
2路直流电机驱动模块 双H桥步进电机 正反转PWM调速

1、安装库:下载链接https://codeload.github.com/Saeterncj/MX1508/zip/master
2、实验接线方法
MX1508模块   Ardunio Uno
GND---------GND接地线
VCC---------5V 接电源
IN1---------D9(PWM)
IN2 ------- D10(PWM)
3、实验之一:简易控制电机(MOTOR-A)连续正转,
PWM设置为180,运转电流大约70MA
*/

#include <MX1508.h>

#define PINA 9
#define PINB 10
#define NUMPWM 2
#define PWM 180

MX1508 motorA(PINA, PINB, FAST_DECAY, NUMPWM);

void setup() {}

void loop() {
motorA.motorGo(PWM);
}

eagler8 发表于 2020-12-11 18:02:40

实验一场景示意图

eagler8 发表于 2020-12-11 19:44:50

本帖最后由 eagler8 于 2020-12-11 20:08 编辑

/*
【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验一百七十二:MX1508 四通道双路有刷直流马达驱动模块
2路直流电机驱动模块 双H桥步进电机 正反转PWM调速

1、安装库:下载链接 https://codeload.github.com/Saeterncj/MX1508/zip/master
2、实验接线方法
MX1508模块   Ardunio Uno
GND---------GND接地线
VCC---------5V 接电源
IN1---------D9(PWM)
IN2 ------- D10(PWM)
3、实验之二:控制电机(MOTOR-A)正转与反转,
PWM为0-180,180-0,,逐步加速然后减速,循环
*/

#include <MX1508.h>

#define PINA 9
#define PINB 10
#define NUMPWM 2

MX1508 motorA(PINA, PINB, FAST_DECAY, NUMPWM);

void setup() {
Serial.begin(115200);
}


/*
通过每50毫秒将pwm增加1来将斜坡增加到pwm = 180。
   然后通过每50毫秒降低pwm降低到pwm = -180。
   正值pwm表示正向。
   负值pwm的方向相反。
*/

void loop() {
static unsigned long lastMilli = 0;
static bool cwDirection = true; // 假设初始方向(正pwm)为顺时针
static int pwm = 1;

if (millis() - lastMilli > 50) { // 每50毫秒
    if (cwDirection && pwm++ > 180 ) {
      cwDirection = false;
    } else if (!cwDirection && pwm-- < -180) {
      cwDirection =true;
    }
    motorA.motorGo(pwm);
    lastMilli = millis();
    Serial.println(motorA.getPWM()); // 我们可以只打印pwm,但是仅显示成员函数getPWM()起作用。
}

}

eagler8 发表于 2020-12-11 20:03:34

MX1508库的几个函数
1、motorGo(pwmVal)
这将设置PWM val(速度)其值为0-200(数值太小,电机只是抖动而无法转动,合适的数值需要通过实验来确定)

2、stopMotor()
只需停止电动机

3、setResolution(pwmResolution)
可以更改pwm的分辨率。要使用此功能,必须使用arduino nano / uno的9和10的pwm可以实现16位PWM。理论上,该值可以在0-65535之间的任何值)

说明:
MX1508电机驱动器的主要缺点之一是需要PWM引脚,每1台电机需要2 pwm引脚。通过实验发现,仅使用一个PWM和任何数字引脚,而不是使用2个不同的PWM引脚是可能的。这是一个巨大的折衷。电机转动一个方向所获得的响应不同于电机转动另一个方向所获得的响应。在一种方式中,将获得FAST_DECAY响应(线性响应,看起来像一个“ V”),然后在另一种情况下,将获得SlOW_DECAY响应(积极反应,看起来像个“ U”)。仅当绝对没有更多的PWM引脚时才应使用此功能。

eagler8 发表于 2020-12-11 20:16:37

MX1508.h文件

#ifndef MX1508_h
#define MX1508_h

#include "Arduino.h"

typedef enum
{
FAST_DECAY= 0,// set non-PWM pin low
SLOW_DECAY = 1    // set non-PWM pin high
} DecayMode;

typedef enum
{
PWM_1PIN= 1,
PWM_2PIN= 2
} NumOfPwmPins;

class MX1508 {
public:
    MX1508(uint8_t pinIN1, uint8_t pinIN2); // default fast decay, 2 pwm pins
    MX1508(uint8_t pinIN1, uint8_t pinIN2, DecayMode decayMode, NumOfPwmPins numPWM);
    void motorGo(long pwmVal); //
    void setResolution(unsigned int resolution);
    int getPWM();
    void stopMotor();
        void analogWrite16(uint8_t pin, uint16_t val);
    void setPWM16(uint8_t prescaler, unsigned int resolution);
private:

    uint8_t _pinIN1;
    uint8_t _pinIN2;
        bool _useAnalogWrite16 = false;
    int _pwmVal;
    int _pwmResolution = 255;   //max resolution of pwm, default is 255.
    DecayMode _whichMode;
    NumOfPwmPins _numPwmPins;
};

#endif

eagler8 发表于 2020-12-11 20:18:42

MX1508.cpp文件

#include "MX1508.h"

MX1508::MX1508( uint8_t pinIN1, uint8_t pinIN2) {
_pinIN1 = pinIN1; // always a PWM pin
_pinIN2 = pinIN2; // can be a non-Pwm pin.
_whichMode = FAST_DECAY;
_numPwmPins = PWM_2PIN;
pinMode(_pinIN1, OUTPUT);
pinMode(_pinIN2, OUTPUT);
}

MX1508::MX1508( uint8_t pinIN1, uint8_t pinIN2, DecayMode decayMode, NumOfPwmPins numPins) {
_pinIN1 = pinIN1; // always a PWM pin
_pinIN2 = pinIN2; // can be a non-Pwm pin.
_whichMode = decayMode;
_numPwmPins = numPins;
pinMode(_pinIN1, OUTPUT);
pinMode(_pinIN2, OUTPUT);
}

int MX1508::getPWM() {
return _pwmVal;
}

void MX1508::stopMotor() {
digitalWrite(_pinIN1, LOW);
digitalWrite(_pinIN2, LOW);
}

void MX1508::setResolution(unsigned int pwmResolution) {
_pwmResolution = pwmResolution;
if(_useAnalogWrite16) ICR1 = pwmResolution;
}

void MX1508::setPWM16(uint8_t prescaler, unsigned int resolution){
        if(prescaler > 5 || prescaler == 0) prescaler = 3; // default to 64 if not in range.
        DDRB|= _BV(PB1) | _BV(PB2);       /* set pin 9and 10 as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);    // non-inverting PWM, mode 14 fastPWM, TOP =ICR1
        TCCR1B = _BV(WGM13) | _BV(WGM12) | prescaler ;        // rescaler must be 1->5, 1,8,64,256,1028 respectively
        ICR1 = resolution;
        _pwmResolution = resolution;
        _useAnalogWrite16 = true;
}

void MX1508::analogWrite16(uint8_t pin, uint16_t val)
{
if(_useAnalogWrite16){
        if(val < 5) val =5;
        switch (pin) {
                case9: OCR1A = val; break;
                case 10: OCR1B = val; break;
                default: analogWrite(pin,val);
        }
}else{
          analogWrite(pin, val);
}
}

void MX1508::motorGo(long pwmSpeed) {
_pwmVal = pwmSpeed;

// if set decay mode is set as fast decay mode
if (this->_whichMode == FAST_DECAY) {
    if (pwmSpeed >= 0) {                        //forward fast decay
      if(_numPwmPins == PWM_1PIN)digitalWrite(_pinIN2, LOW);
          else analogWrite16(_pinIN2, 1);
      analogWrite16(_pinIN1, pwmSpeed);
    } else if (this->_numPwmPins == PWM_2PIN) { // reverse fast decay
      pwmSpeed *= -1;
          analogWrite16(_pinIN1, 1);
      analogWrite16(_pinIN2, pwmSpeed);
    } else if (this->_numPwmPins == PWM_1PIN) { // reverse slow decay
      pwmSpeed *= -1;
      pwmSpeed = map(pwmSpeed, 0, _pwmResolution, _pwmResolution, 0);
      digitalWrite(_pinIN2, HIGH);
      analogWrite16(_pinIN1, pwmSpeed);
    }
}
   // if decay mode is set as slow decay mode
else {
    if (pwmSpeed >= 0) {                        // forward slow decay
      pwmSpeed = map(pwmSpeed, 0, _pwmResolution, _pwmResolution, 0);
      if(_numPwmPins == PWM_1PIN)digitalWrite(_pinIN1, HIGH);
          else analogWrite16(_pinIN1, _pwmResolution);
      analogWrite16(_pinIN2, pwmSpeed);
    } else if (this->_numPwmPins == PWM_2PIN) { // reverse slow decay
      pwmSpeed *= -1;
      pwmSpeed = map(pwmSpeed, 0, _pwmResolution, _pwmResolution, 0);
          analogWrite16(_pinIN2, _pwmResolution);
      analogWrite16(_pinIN1, pwmSpeed);
    } else if (this->_numPwmPins == PWM_1PIN) { // reverse fast decay
      pwmSpeed *= -1;
      digitalWrite(_pinIN1, LOW);
      analogWrite16(_pinIN2, pwmSpeed);
    }
}
}

eagler8 发表于 2020-12-12 16:56:44

实验之三:通过D9和D10的pwm引脚来实现16位PWM
    使用功能setPWM16(uint8_t预分频器,unsigned int分辨率)的Arduino Nano / Uno引脚9和10的分辨率。

    快速pwm频率的公式= MPU(16Mhz)/预分频器/分辨率的频率, F_PWM = 16000000 /预分频器/分辨率

    预分频器参数值必须在1-5之间,分别代表1、8、64、256、1024。分辨率必须为0-65535之间的值。

    MX1508(uint8_t pinIN1,uint8_t pinIN2,DecayMode衰减模式,NumOfPwmPins numPWM);

    DecayMode必须为FAST_DECAY或SLOW_DECAY,NumOfPwmPins,对于setPWM16()函数,其值必须为2,PINA和PINB必须!!! 是setPWM16()函数的引脚9和10 。

    示例MX1508 myMotor(10,9,FAST_DECAY,2)。

eagler8 发表于 2020-12-12 16:58:40

/*
【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验一百七十二:MX1508 四通道双路有刷直流马达驱动模块
2路直流电机驱动模块 双H桥步进电机 正反转PWM调速

1、安装库:下载链接 https://codeload.github.com/Saeterncj/MX1508/zip/master
2、实验接线方法
MX1508模块   Ardunio Uno
GND---------GND接地线
VCC---------5V 接电源
IN1---------D9(PWM)
IN2 ------- D10(PWM)
3、实验之三:通过D9和D10的pwm引脚来实现16位PWM
*/

#include <MX1508.h>

#define PINA 9
#define PINB 10
#define NUMPWM 2

MX1508 motorA(PINA, PINB, FAST_DECAY, 2);

int resolution = 1000;
void setup() {
Serial.begin(115200);

motorA.setPWM16(2, resolution); // 预分频器为8,分辨率1000,PWM频率= 16Mhz / 8/1000 = 2000Hz
// prescalar 1=1, 2=8, 3=64, 4=256, 5 =1028
/*------------ setPWM16 Class function is defined as below-----------------
    void MX1508::setPWM16(uint8_t prescaler, unsigned int resolution){
    if(prescaler > 5 || prescaler == 0) prescaler = 3; // default to 64 if not in range.
    DDRB|= _BV(PB1) | _BV(PB2);       // set pin 9and 10 as outputs
      TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);    // non-inverting PWM, mode 14 fastPWM, TOP =ICR1
    TCCR1B = _BV(WGM13) | _BV(WGM12) | prescaler ;
    ICR1 = resolution;
    _pwmResolution = resolution;
    _useAnalogWrite16 = true;
    }
*/
}
/*
通过每50毫秒将pwm增加1,将斜率提高到pwm =分辨率/ 2。
    然后通过每50毫秒降低pwm降低到pwm = -resolution / 2。
    正值pwm表示正向。
    负值pwm的方向相反。   
*/
void loop() {
static unsigned long lastMilli = 0;
static bool cwDirection = true; // 假设初始方向(正pwm)为顺时针
static int pwm = 1;

if (millis() - lastMilli > 50) { // 每50毫秒
    if (cwDirection && pwm++ > resolution / 2 ) {
      cwDirection = false;
    } else if (!cwDirection && pwm-- < -(resolution / 2)) {
      cwDirection =true;
    }
    motorA.motorGo(pwm);
    lastMilli = millis();
    Serial.println(motorA.getPWM()); // we can just print pwm but just showing that member function getPWM() works.
}
}

eagler8 发表于 2020-12-14 17:39:37

实验开源图形编程(Mind+、编玩边学)
通过数字口12和13,简单控制电机A正转与反转

eagler8 发表于 2020-12-14 19:51:00

实验开源仿真编程(linkboy3.7)
使用按键控制电机1,按下正转,松开停止

页: 1 [2] 3
查看完整版本: 【Arduino】168种传感器系列实验(172)---MX1508双路马达驱动