极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: eagler8

【Arduino】168种传感器系列实验(172)---MX1508双路马达驱动

[复制链接]
 楼主| 发表于 2020-12-11 12:40:45 | 显示全部楼层
MX1508双路马达驱动模块电原理图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 12:59:11 | 显示全部楼层
MX1508双路马达驱动模块接脚图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 13:05:23 | 显示全部楼层
MX1508 电机驱动逻辑真值表

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 13:08:25 | 显示全部楼层
MX1508双路电机驱动模块接线示意图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 16:13:43 | 显示全部楼层
本帖最后由 eagler8 于 2020-12-11 20:07 编辑

下载安装MX1508库

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 17:25:01 | 显示全部楼层
本帖最后由 eagler8 于 2020-12-11 20:11 编辑
  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  3.   实验一百七十二:MX1508 四通道双路有刷直流马达驱动模块
  4.   2路直流电机驱动模块 双H桥步进电机 正反转PWM调速

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

  15. #include <MX1508.h>

  16. #define PINA 9
  17. #define PINB 10
  18. #define NUMPWM 2
  19. #define PWM 180

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

  21. void setup() {}

  22. void loop() {
  23.   motorA.motorGo(PWM);
  24. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 18:02:40 | 显示全部楼层
实验一场景示意图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 19:44:50 | 显示全部楼层
本帖最后由 eagler8 于 2020-12-11 20:08 编辑
  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  3.   实验一百七十二:MX1508 四通道双路有刷直流马达驱动模块
  4.   2路直流电机驱动模块 双H桥步进电机 正反转PWM调速

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

  15. #include <MX1508.h>

  16. #define PINA 9
  17. #define PINB 10
  18. #define NUMPWM 2

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

  20. void setup() {
  21.   Serial.begin(115200);
  22. }


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

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

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

  43. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 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引脚时才应使用此功能。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 20:16:37 | 显示全部楼层
MX1508.h文件

  1. #ifndef MX1508_h
  2. #define MX1508_h

  3. #include "Arduino.h"

  4. typedef enum
  5. {
  6.   FAST_DECAY  = 0,  // set non-PWM pin low
  7.   SLOW_DECAY = 1    // set non-PWM pin high
  8. } DecayMode;

  9. typedef enum
  10. {
  11.   PWM_1PIN  = 1,
  12.   PWM_2PIN  = 2
  13. } NumOfPwmPins;

  14. class MX1508 {
  15.   public:
  16.     MX1508(uint8_t pinIN1, uint8_t pinIN2); // default fast decay, 2 pwm pins
  17.     MX1508(uint8_t pinIN1, uint8_t pinIN2, DecayMode decayMode, NumOfPwmPins numPWM);
  18.     void motorGo(long pwmVal); //
  19.     void setResolution(unsigned int resolution);
  20.     int getPWM();
  21.     void stopMotor();
  22.         void analogWrite16(uint8_t pin, uint16_t val);
  23.     void setPWM16(uint8_t prescaler, unsigned int resolution);
  24.   private:
  25.   
  26.     uint8_t _pinIN1;
  27.     uint8_t _pinIN2;
  28.         bool _useAnalogWrite16 = false;
  29.     int _pwmVal;
  30.     int _pwmResolution = 255;   //max resolution of pwm, default is 255.  
  31.     DecayMode _whichMode;
  32.     NumOfPwmPins _numPwmPins;
  33. };

  34. #endif
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 20:18:42 | 显示全部楼层
MX1508.cpp文件

  1. #include "MX1508.h"

  2. MX1508::MX1508( uint8_t pinIN1, uint8_t pinIN2) {
  3.   _pinIN1 = pinIN1; // always a PWM pin
  4.   _pinIN2 = pinIN2; // can be a non-Pwm pin.
  5.   _whichMode = FAST_DECAY;
  6.   _numPwmPins = PWM_2PIN;
  7.   pinMode(_pinIN1, OUTPUT);
  8.   pinMode(_pinIN2, OUTPUT);
  9. }

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

  18. int MX1508::getPWM() {
  19.   return _pwmVal;
  20. }

  21. void MX1508::stopMotor() {
  22.   digitalWrite(_pinIN1, LOW);
  23.   digitalWrite(_pinIN2, LOW);
  24. }

  25. void MX1508::setResolution(unsigned int pwmResolution) {
  26.   _pwmResolution = pwmResolution;
  27.   if(_useAnalogWrite16) ICR1 = pwmResolution;
  28. }

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

  38. void MX1508::analogWrite16(uint8_t pin, uint16_t val)
  39. {
  40.   if(_useAnalogWrite16){
  41.         if(val < 5) val =5;
  42.         switch (pin) {
  43.                 case  9: OCR1A = val; break;
  44.                 case 10: OCR1B = val; break;
  45.                 default: analogWrite(pin,val);
  46.         }
  47.   }else{
  48.           analogWrite(pin, val);
  49.   }
  50. }

  51. void MX1508::motorGo(long pwmSpeed) {
  52.   _pwmVal = pwmSpeed;
  53.   
  54.   // if set decay mode is set as fast decay mode
  55.   if (this->_whichMode == FAST_DECAY) {
  56.     if (pwmSpeed >= 0) {                        //forward fast decay
  57.       if(_numPwmPins == PWM_1PIN)digitalWrite(_pinIN2, LOW);
  58.           else analogWrite16(_pinIN2, 1);
  59.       analogWrite16(_pinIN1, pwmSpeed);
  60.     } else if (this->_numPwmPins == PWM_2PIN) { // reverse fast decay
  61.       pwmSpeed *= -1;
  62.           analogWrite16(_pinIN1, 1);
  63.       analogWrite16(_pinIN2, pwmSpeed);
  64.     } else if (this->_numPwmPins == PWM_1PIN) { // reverse slow decay
  65.       pwmSpeed *= -1;
  66.       pwmSpeed = map(pwmSpeed, 0, _pwmResolution, _pwmResolution, 0);
  67.       digitalWrite(_pinIN2, HIGH);
  68.       analogWrite16(_pinIN1, pwmSpeed);
  69.     }
  70.   }
  71.    // if decay mode is set as slow decay mode
  72.   else {
  73.     if (pwmSpeed >= 0) {                        // forward slow decay
  74.       pwmSpeed = map(pwmSpeed, 0, _pwmResolution, _pwmResolution, 0);
  75.       if(_numPwmPins == PWM_1PIN)digitalWrite(_pinIN1, HIGH);
  76.           else analogWrite16(_pinIN1, _pwmResolution);
  77.       analogWrite16(_pinIN2, pwmSpeed);
  78.     } else if (this->_numPwmPins == PWM_2PIN) { // reverse slow decay
  79.       pwmSpeed *= -1;
  80.       pwmSpeed = map(pwmSpeed, 0, _pwmResolution, _pwmResolution, 0);
  81.           analogWrite16(_pinIN2, _pwmResolution);
  82.       analogWrite16(_pinIN1, pwmSpeed);
  83.     } else if (this->_numPwmPins == PWM_1PIN) { // reverse fast decay
  84.       pwmSpeed *= -1;
  85.       digitalWrite(_pinIN1, LOW);
  86.       analogWrite16(_pinIN2, pwmSpeed);
  87.     }
  88.   }
  89. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 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)。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-12 16:58:40 | 显示全部楼层
  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  3.   实验一百七十二:MX1508 四通道双路有刷直流马达驱动模块
  4.   2路直流电机驱动模块 双H桥步进电机 正反转PWM调速

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

  14. #include <MX1508.h>

  15. #define PINA 9
  16. #define PINB 10
  17. #define NUMPWM 2

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

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

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

  46.   if (millis() - lastMilli > 50) { // 每50毫秒
  47.     if (cwDirection && pwm++ > resolution / 2 ) {
  48.       cwDirection = false;
  49.     } else if (!cwDirection && pwm-- < -(resolution / 2)) {
  50.       cwDirection =  true;
  51.     }
  52.     motorA.motorGo(pwm);
  53.     lastMilli = millis();
  54.     Serial.println(motorA.getPWM()); // we can just print pwm but just showing that member function getPWM() works.
  55.   }
  56. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-14 17:39:37 | 显示全部楼层
实验开源图形编程(Mind+、编玩边学)
通过数字口12和13,简单控制电机A正转与反转

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-14 19:51:00 | 显示全部楼层
实验开源仿真编程(linkboy3.7)
使用按键控制电机1,按下正转,松开停止

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-24 22:10 , Processed in 0.046826 second(s), 15 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表