久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索

【Arduino】168種傳感器系列實驗(170)---L293D四路電機驅動板

查看數: 10164 | 評論數: 63 | 收藏 2
關燈 | 提示:支持鍵盤翻頁<-左 右->
    組圖打開中,請稍候......
發布時間: 2020-10-26 18:53

正文摘要:

37款傳感器與模塊的提法,在網絡上廣泛流傳,其實Arduino能夠兼容的傳感器模塊肯定是不止37種的。鑒于本人手頭積累了一些傳感器和執行器模塊,依照實踐出真知(一定要動手做)的理念,以學習和交流為目的,這里準備 ...

回復

ID:513258 發表于 2020-12-30 18:16
使用
AFMotor電機擴展板的麥克納姆輪小車(視頻)



https://v.youku.com/v_show/id_XNTAzNDYyMzE1Mg==.html?spm=a2hzp.8253869.0.0





ID:513258 發表于 2020-11-13 17:38
  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:百度搜索“AFMotor庫”— 下載 — 拷貝到Arduino-libraries 文件夾中
  6.   2、實驗之九:測試M1M2M3M4電機前進與后退
  7. */

  8. #include <AFMotor.h>

  9. // 創建對象
  10. AF_DCMotor motor1(1);
  11. AF_DCMotor motor2(2);
  12. AF_DCMotor motor3(3);
  13. AF_DCMotor motor4(4);


  14. // 主程序開始
  15. void setup() {

  16. }
  17. void loop() {
  18.   motor1.setSpeed(200);
  19.   motor1.run(FORWARD);
  20.   motor2.setSpeed(200);
  21.   motor2.run(FORWARD);
  22.   motor3.setSpeed(200);
  23.   motor3.run(FORWARD);
  24.   motor4.setSpeed(200);
  25.   motor4.run(FORWARD);
  26.   delay(2000);
  27.   
  28.   motor1.setSpeed(0);
  29.   motor1.run(RELEASE);
  30.   motor2.setSpeed(0);
  31.   motor2.run(RELEASE);
  32.   motor3.setSpeed(0);
  33.   motor3.run(RELEASE);
  34.   motor4.setSpeed(0);
  35.   motor4.run(RELEASE);
  36.   delay(1000);
  37.   
  38.   motor1.setSpeed(200);
  39.   motor1.run(BACKWARD);
  40.   motor2.setSpeed(200);
  41.   motor2.run(BACKWARD);
  42.   motor3.setSpeed(200);
  43.   motor3.run(BACKWARD);
  44.   motor4.setSpeed(200);
  45.   motor4.run(BACKWARD);
  46.   delay(2000);
  47.   
  48.   motor1.setSpeed(0);
  49.   motor1.run(RELEASE);
  50.   motor2.setSpeed(0);
  51.   motor2.run(RELEASE);
  52.   motor3.setSpeed(0);
  53.   motor3.run(RELEASE);
  54.   motor4.setSpeed(0);
  55.   motor4.run(RELEASE);
  56.   delay(1000);
  57. }
復制代碼


ID:513258 發表于 2020-11-13 11:05
Arduino AFMotor電機擴展板(上)
https://www.bilibili.com/video/BV1vb411q7xz?p=1

Arduino AFMotor電機擴展板(下)
https://www.bilibili.com/video/BV1vb411q7xz?p=2
ID:513258 發表于 2020-11-13 09:51
補充實驗

  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:IDE—工具—管理庫—搜索“Servo”—安裝
  6.   2、實驗之八:測試M1M2電機
  7. */

  8. #include <AFMotor.h>

  9. AF_DCMotor motor1(1);
  10. AF_DCMotor motor2(2);

  11. void setup() {
  12.   Serial.begin(9600);
  13.   Serial.println("測試M1M2電機!");

  14.   // turn on motor
  15.   motor1.setSpeed(200);
  16.   motor2.setSpeed(200);

  17.   motor1.run(RELEASE);
  18.   motor2.run(RELEASE);
  19. }

  20. void loop() {
  21.   uint8_t i;

  22.   Serial.println("正轉");

  23.   motor1.run(FORWARD);
  24.   motor2.run(FORWARD);
  25.   for (i = 0; i < 255; i++) {
  26.     motor1.setSpeed(i);
  27.     motor2.setSpeed(i);
  28.     delay(10);
  29.   }

  30.   for (i = 255; i != 0; i--) {
  31.     motor1.setSpeed(i);
  32.     motor2.setSpeed(i);
  33.     delay(10);
  34.   }

  35.   Serial.println("反轉");

  36.   motor1.run(BACKWARD);
  37.   motor2.run(BACKWARD);

  38.   for (i = 0; i < 255; i++) {
  39.     motor1.setSpeed(i);
  40.     motor2.setSpeed(i);
  41.     delay(10);
  42.   }

  43.   for (i = 255; i != 0; i--) {
  44.     motor1.setSpeed(i);
  45.     motor2.setSpeed(i);
  46.     delay(10);
  47.   }

  48.   Serial.println("斷電一秒");
  49.   motor1.run(RELEASE);
  50.   motor2.run(RELEASE);
  51.   delay(1000);
  52. }
復制代碼



ID:513258 發表于 2020-11-13 09:04

附錄:AFMotor.cpp庫文件
目錄—adafruit/Adafruit-Motor-Shield-library
鏈接—https://github.com/adafruit/Adaf ... /master/AFMotor.cpp


  1. // Adafruit Motor shield library
  2. // copyright Adafruit Industries LLC, 2009
  3. // this code is public domain, enjoy!


  4. #if (ARDUINO >= 100)
  5.   #include "Arduino.h"
  6. #else
  7.   #if defined(__AVR__)
  8.     #include <avr/io.h>
  9.   #endif
  10.   #include "WProgram.h"
  11. #endif

  12. #include "AFMotor.h"



  13. static uint8_t latch_state;

  14. #if (MICROSTEPS == 8)
  15. uint8_t microstepcurve[] = {0, 50, 98, 142, 180, 212, 236, 250, 255};
  16. #elif (MICROSTEPS == 16)
  17. uint8_t microstepcurve[] = {0, 25, 50, 74, 98, 120, 141, 162, 180, 197, 212, 225, 236, 244, 250, 253, 255};
  18. #endif

  19. AFMotorController::AFMotorController(void) {
  20.     TimerInitalized = false;
  21. }

  22. void AFMotorController::enable(void) {
  23.   // setup the latch
  24.   /*
  25.   LATCH_DDR |= _BV(LATCH);
  26.   ENABLE_DDR |= _BV(ENABLE);
  27.   CLK_DDR |= _BV(CLK);
  28.   SER_DDR |= _BV(SER);
  29.   */
  30.   pinMode(MOTORLATCH, OUTPUT);
  31.   pinMode(MOTORENABLE, OUTPUT);
  32.   pinMode(MOTORDATA, OUTPUT);
  33.   pinMode(MOTORCLK, OUTPUT);

  34.   latch_state = 0;

  35.   latch_tx();  // "reset"

  36.   //ENABLE_PORT &= ~_BV(ENABLE); // enable the chip outputs!
  37.   digitalWrite(MOTORENABLE, LOW);
  38. }


  39. void AFMotorController::latch_tx(void) {
  40.   uint8_t i;

  41.   //LATCH_PORT &= ~_BV(LATCH);
  42.   digitalWrite(MOTORLATCH, LOW);

  43.   //SER_PORT &= ~_BV(SER);
  44.   digitalWrite(MOTORDATA, LOW);

  45.   for (i=0; i<8; i++) {
  46.     //CLK_PORT &= ~_BV(CLK);
  47.     digitalWrite(MOTORCLK, LOW);

  48.     if (latch_state & _BV(7-i)) {
  49.       //SER_PORT |= _BV(SER);
  50.       digitalWrite(MOTORDATA, HIGH);
  51.     } else {
  52.       //SER_PORT &= ~_BV(SER);
  53.       digitalWrite(MOTORDATA, LOW);
  54.     }
  55.     //CLK_PORT |= _BV(CLK);
  56.     digitalWrite(MOTORCLK, HIGH);
  57.   }
  58.   //LATCH_PORT |= _BV(LATCH);
  59.   digitalWrite(MOTORLATCH, HIGH);
  60. }

  61. static AFMotorController MC;

  62. /******************************************
  63.                MOTORS
  64. ******************************************/
  65. inline void initPWM1(uint8_t freq) {
  66. #if defined(__AVR_ATmega8__) || \
  67.     defined(__AVR_ATmega48__) || \
  68.     defined(__AVR_ATmega88__) || \
  69.     defined(__AVR_ATmega168__) || \
  70.     defined(__AVR_ATmega328P__)
  71.     // use PWM from timer2A on PB3 (Arduino pin #11)
  72.     TCCR2A |= _BV(COM2A1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2a
  73.     TCCR2B = freq & 0x7;
  74.     OCR2A = 0;
  75. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  76.     // on arduino mega, pin 11 is now PB5 (OC1A)
  77.     TCCR1A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc1a
  78.     TCCR1B = (freq & 0x7) | _BV(WGM12);
  79.     OCR1A = 0;
  80. #elif defined(__PIC32MX__)
  81.     #if defined(PIC32_USE_PIN9_FOR_M1_PWM)
  82.         // Make sure that pin 11 is an input, since we have tied together 9 and 11
  83.         pinMode(9, OUTPUT);
  84.         pinMode(11, INPUT);
  85.         if (!MC.TimerInitalized)
  86.         {   // Set up Timer2 for 80MHz counting fro 0 to 256
  87.             T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  88.             TMR2 = 0x0000;
  89.             PR2 = 0x0100;
  90.             MC.TimerInitalized = true;
  91.         }
  92.          // Setup OC4 (pin 9) in PWM mode, with Timer2 as timebase
  93.         OC4CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  94.         OC4RS = 0x0000;
  95.         OC4R = 0x0000;
  96.     #elif defined(PIC32_USE_PIN10_FOR_M1_PWM)
  97.         // Make sure that pin 11 is an input, since we have tied together 9 and 11
  98.         pinMode(10, OUTPUT);
  99.         pinMode(11, INPUT);
  100.         if (!MC.TimerInitalized)
  101.         {   // Set up Timer2 for 80MHz counting fro 0 to 256
  102.             T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  103.             TMR2 = 0x0000;
  104.             PR2 = 0x0100;
  105.             MC.TimerInitalized = true;
  106.         }
  107.          // Setup OC5 (pin 10) in PWM mode, with Timer2 as timebase
  108.         OC5CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  109.         OC5RS = 0x0000;
  110.         OC5R = 0x0000;
  111.     #else
  112.         // If we are not using PWM for pin 11, then just do digital
  113.         digitalWrite(11, LOW);
  114.     #endif
  115. #else
  116.    #error "This chip is not supported!"
  117. #endif
  118.     #if !defined(PIC32_USE_PIN9_FOR_M1_PWM) && !defined(PIC32_USE_PIN10_FOR_M1_PWM)
  119.         pinMode(11, OUTPUT);
  120.     #endif
  121. }

  122. inline void setPWM1(uint8_t s) {
  123. #if defined(__AVR_ATmega8__) || \
  124.     defined(__AVR_ATmega48__) || \
  125.     defined(__AVR_ATmega88__) || \
  126.     defined(__AVR_ATmega168__) || \
  127.     defined(__AVR_ATmega328P__)
  128.     // use PWM from timer2A on PB3 (Arduino pin #11)
  129.     OCR2A = s;
  130. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  131.     // on arduino mega, pin 11 is now PB5 (OC1A)
  132.     OCR1A = s;
  133. #elif defined(__PIC32MX__)
  134.     #if defined(PIC32_USE_PIN9_FOR_M1_PWM)
  135.         // Set the OC4 (pin 9) PMW duty cycle from 0 to 255
  136.         OC4RS = s;
  137.     #elif defined(PIC32_USE_PIN10_FOR_M1_PWM)
  138.         // Set the OC5 (pin 10) PMW duty cycle from 0 to 255
  139.         OC5RS = s;
  140.     #else
  141.         // If we are not doing PWM output for M1, then just use on/off
  142.         if (s > 127)
  143.         {
  144.             digitalWrite(11, HIGH);
  145.         }
  146.         else
  147.         {
  148.             digitalWrite(11, LOW);
  149.         }
  150.     #endif
  151. #else
  152.    #error "This chip is not supported!"
  153. #endif
  154. }

  155. inline void initPWM2(uint8_t freq) {
  156. #if defined(__AVR_ATmega8__) || \
  157.     defined(__AVR_ATmega48__) || \
  158.     defined(__AVR_ATmega88__) || \
  159.     defined(__AVR_ATmega168__) || \
  160.     defined(__AVR_ATmega328P__)
  161.     // use PWM from timer2B (pin 3)
  162.     TCCR2A |= _BV(COM2B1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2b
  163.     TCCR2B = freq & 0x7;
  164.     OCR2B = 0;
  165. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  166.     // on arduino mega, pin 3 is now PE5 (OC3C)
  167.     TCCR3A |= _BV(COM1C1) | _BV(WGM10); // fast PWM, turn on oc3c
  168.     TCCR3B = (freq & 0x7) | _BV(WGM12);
  169.     OCR3C = 0;
  170. #elif defined(__PIC32MX__)
  171.     if (!MC.TimerInitalized)
  172.     {   // Set up Timer2 for 80MHz counting fro 0 to 256
  173.         T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  174.         TMR2 = 0x0000;
  175.         PR2 = 0x0100;
  176.         MC.TimerInitalized = true;
  177.     }
  178.     // Setup OC1 (pin3) in PWM mode, with Timer2 as timebase
  179.     OC1CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  180.     OC1RS = 0x0000;
  181.     OC1R = 0x0000;
  182. #else
  183.    #error "This chip is not supported!"
  184. #endif

  185.     pinMode(3, OUTPUT);
  186. }

  187. inline void setPWM2(uint8_t s) {
  188. #if defined(__AVR_ATmega8__) || \
  189.     defined(__AVR_ATmega48__) || \
  190.     defined(__AVR_ATmega88__) || \
  191.     defined(__AVR_ATmega168__) || \
  192.     defined(__AVR_ATmega328P__)
  193.     // use PWM from timer2A on PB3 (Arduino pin #11)
  194.     OCR2B = s;
  195. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  196.     // on arduino mega, pin 11 is now PB5 (OC1A)
  197.     OCR3C = s;
  198. #elif defined(__PIC32MX__)
  199.     // Set the OC1 (pin3) PMW duty cycle from 0 to 255
  200.     OC1RS = s;
  201. #else
  202.    #error "This chip is not supported!"
  203. #endif
  204. }

  205. inline void initPWM3(uint8_t freq) {
  206. #if defined(__AVR_ATmega8__) || \
  207.     defined(__AVR_ATmega48__) || \
  208.     defined(__AVR_ATmega88__) || \
  209.     defined(__AVR_ATmega168__) || \
  210.     defined(__AVR_ATmega328P__)
  211.     // use PWM from timer0A / PD6 (pin 6)
  212.     TCCR0A |= _BV(COM0A1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on OC0A
  213.     //TCCR0B = freq & 0x7;
  214.     OCR0A = 0;
  215. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  216.     // on arduino mega, pin 6 is now PH3 (OC4A)
  217.     TCCR4A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc4a
  218.     TCCR4B = (freq & 0x7) | _BV(WGM12);
  219.     //TCCR4B = 1 | _BV(WGM12);
  220.     OCR4A = 0;
  221. #elif defined(__PIC32MX__)
  222.     if (!MC.TimerInitalized)
  223.     {   // Set up Timer2 for 80MHz counting fro 0 to 256
  224.         T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  225.         TMR2 = 0x0000;
  226.         PR2 = 0x0100;
  227.         MC.TimerInitalized = true;
  228.     }
  229.     // Setup OC3 (pin 6) in PWM mode, with Timer2 as timebase
  230.     OC3CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  231.     OC3RS = 0x0000;
  232.     OC3R = 0x0000;
  233. #else
  234.    #error "This chip is not supported!"
  235. #endif
  236.     pinMode(6, OUTPUT);
  237. }

  238. inline void setPWM3(uint8_t s) {
  239. #if defined(__AVR_ATmega8__) || \
  240.     defined(__AVR_ATmega48__) || \
  241.     defined(__AVR_ATmega88__) || \
  242.     defined(__AVR_ATmega168__) || \
  243.     defined(__AVR_ATmega328P__)
  244.     // use PWM from timer0A on PB3 (Arduino pin #6)
  245.     OCR0A = s;
  246. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  247.     // on arduino mega, pin 6 is now PH3 (OC4A)
  248.     OCR4A = s;
  249. #elif defined(__PIC32MX__)
  250.     // Set the OC3 (pin 6) PMW duty cycle from 0 to 255
  251.     OC3RS = s;
  252. #else
  253.    #error "This chip is not supported!"
  254. #endif
  255. }



  256. inline void initPWM4(uint8_t freq) {
  257. #if defined(__AVR_ATmega8__) || \
  258.     defined(__AVR_ATmega48__) || \
  259.     defined(__AVR_ATmega88__) || \
  260.     defined(__AVR_ATmega168__) || \
  261.     defined(__AVR_ATmega328P__)
  262.     // use PWM from timer0B / PD5 (pin 5)
  263.     TCCR0A |= _BV(COM0B1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on oc0a
  264.     //TCCR0B = freq & 0x7;
  265.     OCR0B = 0;
  266. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  267.     // on arduino mega, pin 5 is now PE3 (OC3A)
  268.     TCCR3A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc3a
  269.     TCCR3B = (freq & 0x7) | _BV(WGM12);
  270.     //TCCR4B = 1 | _BV(WGM12);
  271.     OCR3A = 0;
  272. #elif defined(__PIC32MX__)
  273.     if (!MC.TimerInitalized)
  274.     {   // Set up Timer2 for 80MHz counting fro 0 to 256
  275.         T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  276.         TMR2 = 0x0000;
  277.         PR2 = 0x0100;
  278.         MC.TimerInitalized = true;
  279.     }
  280.     // Setup OC2 (pin 5) in PWM mode, with Timer2 as timebase
  281.     OC2CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  282.     OC2RS = 0x0000;
  283.     OC2R = 0x0000;
  284. #else
  285.    #error "This chip is not supported!"
  286. #endif
  287.     pinMode(5, OUTPUT);
  288. }

  289. inline void setPWM4(uint8_t s) {
  290. #if defined(__AVR_ATmega8__) || \
  291.     defined(__AVR_ATmega48__) || \
  292.     defined(__AVR_ATmega88__) || \
  293.     defined(__AVR_ATmega168__) || \
  294.     defined(__AVR_ATmega328P__)
  295.     // use PWM from timer0A on PB3 (Arduino pin #6)
  296.     OCR0B = s;
  297. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  298.     // on arduino mega, pin 6 is now PH3 (OC4A)
  299.     OCR3A = s;
  300. #elif defined(__PIC32MX__)
  301.     // Set the OC2 (pin 5) PMW duty cycle from 0 to 255
  302.     OC2RS = s;
  303. #else
  304.    #error "This chip is not supported!"
  305. #endif
  306. }

  307. AF_DCMotor::AF_DCMotor(uint8_t num, uint8_t freq) {
  308.   motornum = num;
  309.   pwmfreq = freq;

  310.   MC.enable();

  311.   switch (num) {
  312.   case 1:
  313.     latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B); // set both motor pins to 0
  314.     MC.latch_tx();
  315.     initPWM1(freq);
  316.     break;
  317.   case 2:
  318.     latch_state &= ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // set both motor pins to 0
  319.     MC.latch_tx();
  320.     initPWM2(freq);
  321.     break;
  322.   case 3:
  323.     latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B); // set both motor pins to 0
  324.     MC.latch_tx();
  325.     initPWM3(freq);
  326.     break;
  327.   case 4:
  328.     latch_state &= ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // set both motor pins to 0
  329.     MC.latch_tx();
  330.     initPWM4(freq);
  331.     break;
  332.   }
  333. }

  334. void AF_DCMotor::run(uint8_t cmd) {
  335.   uint8_t a, b;
  336.   switch (motornum) {
  337.   case 1:
  338.     a = MOTOR1_A; b = MOTOR1_B; break;
  339.   case 2:
  340.     a = MOTOR2_A; b = MOTOR2_B; break;
  341.   case 3:
  342.     a = MOTOR3_A; b = MOTOR3_B; break;
  343.   case 4:
  344.     a = MOTOR4_A; b = MOTOR4_B; break;
  345.   default:
  346.     return;
  347.   }
  348.   
  349.   switch (cmd) {
  350.   case FORWARD:
  351.     latch_state |= _BV(a);
  352.     latch_state &= ~_BV(b);
  353.     MC.latch_tx();
  354.     break;
  355.   case BACKWARD:
  356.     latch_state &= ~_BV(a);
  357.     latch_state |= _BV(b);
  358.     MC.latch_tx();
  359.     break;
  360.   case RELEASE:
  361.     latch_state &= ~_BV(a);     // A and B both low
  362.     latch_state &= ~_BV(b);
  363.     MC.latch_tx();
  364.     break;
  365.   }
  366. }

  367. void AF_DCMotor::setSpeed(uint8_t speed) {
  368.   switch (motornum) {
  369.   case 1:
  370.     setPWM1(speed); break;
  371.   case 2:
  372.     setPWM2(speed); break;
  373.   case 3:
  374.     setPWM3(speed); break;
  375.   case 4:
  376.     setPWM4(speed); break;
  377.   }
  378. }

  379. /******************************************
  380.                STEPPERS
  381. ******************************************/

  382. AF_Stepper::AF_Stepper(uint16_t steps, uint8_t num) {
  383.   MC.enable();

  384.   revsteps = steps;
  385.   steppernum = num;
  386.   currentstep = 0;

  387.   if (steppernum == 1) {
  388.     latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
  389.       ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
  390.     MC.latch_tx();
  391.    
  392.     // enable both H bridges
  393.     pinMode(11, OUTPUT);
  394.     pinMode(3, OUTPUT);
  395.     digitalWrite(11, HIGH);
  396.     digitalWrite(3, HIGH);

  397.     // use PWM for microstepping support
  398.     initPWM1(STEPPER1_PWM_RATE);
  399.     initPWM2(STEPPER1_PWM_RATE);
  400.     setPWM1(255);
  401.     setPWM2(255);

  402.   } else if (steppernum == 2) {
  403.     latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
  404.       ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
  405.     MC.latch_tx();

  406.     // enable both H bridges
  407.     pinMode(5, OUTPUT);
  408.     pinMode(6, OUTPUT);
  409.     digitalWrite(5, HIGH);
  410.     digitalWrite(6, HIGH);

  411.     // use PWM for microstepping support
  412.     // use PWM for microstepping support
  413.     initPWM3(STEPPER2_PWM_RATE);
  414.     initPWM4(STEPPER2_PWM_RATE);
  415.     setPWM3(255);
  416.     setPWM4(255);
  417.   }
  418. }

  419. void AF_Stepper::setSpeed(uint16_t rpm) {
  420.   usperstep = 60000000 / ((uint32_t)revsteps * (uint32_t)rpm);
  421.   steppingcounter = 0;
  422. }

  423. void AF_Stepper::release(void) {
  424.   if (steppernum == 1) {
  425.     latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
  426.       ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
  427.     MC.latch_tx();
  428.   } else if (steppernum == 2) {
  429.     latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
  430.       ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
  431.     MC.latch_tx();
  432.   }
  433. }

  434. void AF_Stepper::step(uint16_t steps, uint8_t dir,  uint8_t style) {
  435.   uint32_t uspers = usperstep;
  436.   uint8_t ret = 0;

  437.   if (style == INTERLEAVE) {
  438.     uspers /= 2;
  439.   }
  440. else if (style == MICROSTEP) {
  441.     uspers /= MICROSTEPS;
  442.     steps *= MICROSTEPS;
  443. #ifdef MOTORDEBUG
  444.     Serial.print("steps = "); Serial.println(steps, DEC);
  445. #endif
  446.   }

  447.   while (steps--) {
  448.     ret = onestep(dir, style);
  449.     delay(uspers/1000); // in ms
  450.     steppingcounter += (uspers % 1000);
  451.     if (steppingcounter >= 1000) {
  452.       delay(1);
  453.       steppingcounter -= 1000;
  454.     }
  455.   }
  456.   if (style == MICROSTEP) {
  457.     while ((ret != 0) && (ret != MICROSTEPS)) {
  458.       ret = onestep(dir, style);
  459.       delay(uspers/1000); // in ms
  460.       steppingcounter += (uspers % 1000);
  461.       if (steppingcounter >= 1000) {
  462.         delay(1);
  463.         steppingcounter -= 1000;
  464.       }
  465.     }
  466.   }
  467. }

  468. uint8_t AF_Stepper::onestep(uint8_t dir, uint8_t style) {
  469.   uint8_t a, b, c, d;
  470.   uint8_t ocrb, ocra;

  471.   ocra = ocrb = 255;

  472.   if (steppernum == 1) {
  473.     a = _BV(MOTOR1_A);
  474.     b = _BV(MOTOR2_A);
  475.     c = _BV(MOTOR1_B);
  476.     d = _BV(MOTOR2_B);
  477.   } else if (steppernum == 2) {
  478.     a = _BV(MOTOR3_A);
  479.     b = _BV(MOTOR4_A);
  480.     c = _BV(MOTOR3_B);
  481.     d = _BV(MOTOR4_B);
  482.   } else {
  483.     return 0;
  484.   }

  485.   // next determine what sort of stepping procedure we're up to
  486.   if (style == SINGLE) {
  487.     if ((currentstep/(MICROSTEPS/2)) % 2) { // we're at an odd step, weird
  488.       if (dir == FORWARD) {
  489.         currentstep += MICROSTEPS/2;
  490.       }
  491.       else {
  492.         currentstep -= MICROSTEPS/2;
  493.       }
  494.     } else {           // go to the next even step
  495.       if (dir == FORWARD) {
  496.         currentstep += MICROSTEPS;
  497.       }
  498.       else {
  499.         currentstep -= MICROSTEPS;
  500.       }
  501.     }
  502.   } else if (style == DOUBLE) {
  503.     if (! (currentstep/(MICROSTEPS/2) % 2)) { // we're at an even step, weird
  504.       if (dir == FORWARD) {
  505.         currentstep += MICROSTEPS/2;
  506.       } else {
  507.         currentstep -= MICROSTEPS/2;
  508.       }
  509.     } else {           // go to the next odd step
  510.       if (dir == FORWARD) {
  511.         currentstep += MICROSTEPS;
  512.       } else {
  513.         currentstep -= MICROSTEPS;
  514.       }
  515.     }
  516.   } else if (style == INTERLEAVE) {
  517.     if (dir == FORWARD) {
  518.        currentstep += MICROSTEPS/2;
  519.     } else {
  520.        currentstep -= MICROSTEPS/2;
  521.     }
  522.   }

  523.   if (style == MICROSTEP) {
  524.     if (dir == FORWARD) {
  525.       currentstep++;
  526.     } else {
  527.       // BACKWARDS
  528.       currentstep--;
  529.     }

  530.     currentstep += MICROSTEPS*4;
  531.     currentstep %= MICROSTEPS*4;

  532.     ocra = ocrb = 0;
  533.     if ( (currentstep >= 0) && (currentstep < MICROSTEPS)) {
  534.       ocra = microstepcurve[MICROSTEPS - currentstep];
  535.       ocrb = microstepcurve[currentstep];
  536.     } else if  ( (currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2)) {
  537.       ocra = microstepcurve[currentstep - MICROSTEPS];
  538.       ocrb = microstepcurve[MICROSTEPS*2 - currentstep];
  539.     } else if  ( (currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3)) {
  540.       ocra = microstepcurve[MICROSTEPS*3 - currentstep];
  541.       ocrb = microstepcurve[currentstep - MICROSTEPS*2];
  542.     } else if  ( (currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4)) {
  543.       ocra = microstepcurve[currentstep - MICROSTEPS*3];
  544.       ocrb = microstepcurve[MICROSTEPS*4 - currentstep];
  545.     }
  546.   }

  547.   currentstep += MICROSTEPS*4;
  548.   currentstep %= MICROSTEPS*4;

  549. #ifdef MOTORDEBUG
  550.   Serial.print("current step: "); Serial.println(currentstep, DEC);
  551.   Serial.print(" pwmA = "); Serial.print(ocra, DEC);
  552.   Serial.print(" pwmB = "); Serial.println(ocrb, DEC);
  553. #endif

  554.   if (steppernum == 1) {
  555.     setPWM1(ocra);
  556.     setPWM2(ocrb);
  557.   } else if (steppernum == 2) {
  558.     setPWM3(ocra);
  559.     setPWM4(ocrb);
  560.   }


  561.   // release all
  562.   latch_state &= ~a & ~b & ~c & ~d; // all motor pins to 0

  563.   //Serial.println(step, DEC);
  564.   if (style == MICROSTEP) {
  565.     if ((currentstep >= 0) && (currentstep < MICROSTEPS))
  566.       latch_state |= a | b;
  567.     if ((currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2))
  568.       latch_state |= b | c;
  569.     if ((currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3))
  570.       latch_state |= c | d;
  571.     if ((currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4))
  572.       latch_state |= d | a;
  573.   } else {
  574.     switch (currentstep/(MICROSTEPS/2)) {
  575.     case 0:
  576.       latch_state |= a; // energize coil 1 only
  577.       break;
  578.     case 1:
  579.       latch_state |= a | b; // energize coil 1+2
  580.       break;
  581.     case 2:
  582.       latch_state |= b; // energize coil 2 only
  583.       break;
  584.     case 3:
  585.       latch_state |= b | c; // energize coil 2+3
  586.       break;
  587.     case 4:
  588.       latch_state |= c; // energize coil 3 only
  589.       break;
  590.     case 5:
  591.       latch_state |= c | d; // energize coil 3+4
  592.       break;
  593.     case 6:
  594.       latch_state |= d; // energize coil 4 only
  595.       break;
  596.     case 7:
  597.       latch_state |= d | a; // energize coil 1+4
  598.       break;
  599.     }
  600.   }


  601.   MC.latch_tx();
  602.   return currentstep;
  603. }
復制代碼



ID:513258 發表于 2020-11-13 08:59
附錄:AFMotor.h庫文件
目錄—adafruit/Adafruit-Motor-Shield-library
鏈接—https://github.com/adafruit/Adaf ... ob/master/AFMotor.h

  1. // Adafruit Motor shield library
  2. // copyright Adafruit Industries LLC, 2009
  3. // this code is public domain, enjoy!

  4. /*
  5. * Usage Notes:
  6. * For PIC32, all features work properly with the following two exceptions:
  7. *
  8. * 1) Because the PIC32 only has 5 PWM outputs, and the AFMotor shield needs 6
  9. *    to completely operate (four for motor outputs and two for RC servos), the
  10. *    M1 motor output will not have PWM ability when used with a PIC32 board.
  11. *    However, there is a very simple workaround. If you need to drive a stepper
  12. *    or DC motor with PWM on motor output M1, you can use the PWM output on pin
  13. *    9 or pin 10 (normally use for RC servo outputs on Arduino, not needed for
  14. *    RC servo outputs on PIC32) to drive the PWM input for M1 by simply putting
  15. *    a jumber from pin 9 to pin 11 or pin 10 to pin 11. Then uncomment one of the
  16. *    two #defines below to activate the PWM on either pin 9 or pin 10. You will
  17. *    then have a fully functional microstepping for 2 stepper motors, or four
  18. *    DC motor outputs with PWM.
  19. *
  20. * 2) There is a conflict between RC Servo outputs on pins 9 and pins 10 and
  21. *    the operation of DC motors and stepper motors as of 9/2012. This issue
  22. *    will get fixed in future MPIDE releases, but at the present time it means
  23. *    that the Motor Party example will NOT work properly. Any time you attach
  24. *    an RC servo to pins 9 or pins 10, ALL PWM outputs on the whole board will
  25. *    stop working. Thus no steppers or DC motors.
  26. *
  27. */
  28. // <BPS> 09/15/2012 Modified for use with chipKIT boards


  29. #ifndef _AFMotor_h_
  30. #define _AFMotor_h_

  31. #include <inttypes.h>
  32. #if defined(__AVR__)
  33.     #include <avr/io.h>

  34.     //#define MOTORDEBUG 1

  35.     #define MICROSTEPS 16                       // 8 or 16

  36.     #define MOTOR12_64KHZ _BV(CS20)             // no prescale
  37.     #define MOTOR12_8KHZ _BV(CS21)              // divide by 8
  38.     #define MOTOR12_2KHZ _BV(CS21) | _BV(CS20)  // divide by 32
  39.     #define MOTOR12_1KHZ _BV(CS22)              // divide by 64

  40.     #define MOTOR34_64KHZ _BV(CS00)             // no prescale
  41.     #define MOTOR34_8KHZ _BV(CS01)              // divide by 8
  42.     #define MOTOR34_1KHZ _BV(CS01) | _BV(CS00)  // divide by 64
  43.    
  44.     #define DC_MOTOR_PWM_RATE   MOTOR34_8KHZ    // PWM rate for DC motors
  45.     #define STEPPER1_PWM_RATE   MOTOR12_64KHZ   // PWM rate for stepper 1
  46.     #define STEPPER2_PWM_RATE   MOTOR34_64KHZ   // PWM rate for stepper 2
  47.    
  48. #elif defined(__PIC32MX__)
  49.     //#define MOTORDEBUG 1
  50.    
  51.     // Uncomment the one of following lines if you have put a jumper from
  52.     // either pin 9 to pin 11 or pin 10 to pin 11 on your Motor Shield.
  53.     // Either will enable PWM for M1
  54.     //#define PIC32_USE_PIN9_FOR_M1_PWM
  55.     //#define PIC32_USE_PIN10_FOR_M1_PWM

  56.     #define MICROSTEPS 16       // 8 or 16

  57.     // For PIC32 Timers, define prescale settings by PWM frequency
  58.     #define MOTOR12_312KHZ  0   // 1:1, actual frequency 312KHz
  59.     #define MOTOR12_156KHZ  1   // 1:2, actual frequency 156KHz
  60.     #define MOTOR12_64KHZ   2   // 1:4, actual frequency 78KHz
  61.     #define MOTOR12_39KHZ   3   // 1:8, acutal frequency 39KHz
  62.     #define MOTOR12_19KHZ   4   // 1:16, actual frequency 19KHz
  63.     #define MOTOR12_8KHZ    5   // 1:32, actual frequency 9.7KHz
  64.     #define MOTOR12_4_8KHZ  6   // 1:64, actual frequency 4.8KHz
  65.     #define MOTOR12_2KHZ    7   // 1:256, actual frequency 1.2KHz
  66.     #define MOTOR12_1KHZ    7   // 1:256, actual frequency 1.2KHz

  67.     #define MOTOR34_312KHZ  0   // 1:1, actual frequency 312KHz
  68.     #define MOTOR34_156KHZ  1   // 1:2, actual frequency 156KHz
  69.     #define MOTOR34_64KHZ   2   // 1:4, actual frequency 78KHz
  70.     #define MOTOR34_39KHZ   3   // 1:8, acutal frequency 39KHz
  71.     #define MOTOR34_19KHZ   4   // 1:16, actual frequency 19KHz
  72.     #define MOTOR34_8KHZ    5   // 1:32, actual frequency 9.7KHz
  73.     #define MOTOR34_4_8KHZ  6   // 1:64, actual frequency 4.8KHz
  74.     #define MOTOR34_2KHZ    7   // 1:256, actual frequency 1.2KHz
  75.     #define MOTOR34_1KHZ    7   // 1:256, actual frequency 1.2KHz
  76.    
  77.     // PWM rate for DC motors.
  78.     #define DC_MOTOR_PWM_RATE   MOTOR34_39KHZ
  79.     // Note: for PIC32, both of these must be set to the same value
  80.     // since there's only one timebase for all 4 PWM outputs
  81.     #define STEPPER1_PWM_RATE   MOTOR12_39KHZ
  82.     #define STEPPER2_PWM_RATE   MOTOR34_39KHZ
  83.    
  84. #endif

  85. // Bit positions in the 74HCT595 shift register output
  86. #define MOTOR1_A 2
  87. #define MOTOR1_B 3
  88. #define MOTOR2_A 1
  89. #define MOTOR2_B 4
  90. #define MOTOR4_A 0
  91. #define MOTOR4_B 6
  92. #define MOTOR3_A 5
  93. #define MOTOR3_B 7

  94. // Constants that the user passes in to the motor calls
  95. #define FORWARD 1
  96. #define BACKWARD 2
  97. #define BRAKE 3
  98. #define RELEASE 4

  99. // Constants that the user passes in to the stepper calls
  100. #define SINGLE 1
  101. #define DOUBLE 2
  102. #define INTERLEAVE 3
  103. #define MICROSTEP 4

  104. /*
  105. #define LATCH 4
  106. #define LATCH_DDR DDRB
  107. #define LATCH_PORT PORTB
  108. #define CLK_PORT PORTD
  109. #define CLK_DDR DDRD
  110. #define CLK 4
  111. #define ENABLE_PORT PORTD
  112. #define ENABLE_DDR DDRD
  113. #define ENABLE 7
  114. #define SER 0
  115. #define SER_DDR DDRB
  116. #define SER_PORT PORTB
  117. */

  118. // Arduino pin names for interface to 74HCT595 latch
  119. #define MOTORLATCH 12
  120. #define MOTORCLK 4
  121. #define MOTORENABLE 7
  122. #define MOTORDATA 8

  123. class AFMotorController
  124. {
  125.   public:
  126.     AFMotorController(void);
  127.     void enable(void);
  128.     friend class AF_DCMotor;
  129.     void latch_tx(void);
  130.     uint8_t TimerInitalized;
  131. };

  132. class AF_DCMotor
  133. {
  134. public:
  135.   AF_DCMotor(uint8_t motornum, uint8_t freq = DC_MOTOR_PWM_RATE);
  136.   void run(uint8_t);
  137.   void setSpeed(uint8_t);

  138. private:
  139.   uint8_t motornum, pwmfreq;
  140. };

  141. class AF_Stepper {
  142. public:
  143.   AF_Stepper(uint16_t, uint8_t);
  144.   void step(uint16_t steps, uint8_t dir,  uint8_t style = SINGLE);
  145.   void setSpeed(uint16_t);
  146.   uint8_t onestep(uint8_t dir, uint8_t style);
  147.   void release(void);
  148.   uint16_t revsteps; // # steps per revolution
  149.   uint8_t steppernum;
  150.   uint32_t usperstep, steppingcounter;
  151. private:
  152.   uint8_t currentstep;

  153. };

  154. uint8_t getlatchstate(void);

  155. #endif
復制代碼




ID:513258 發表于 2020-11-12 20:26
使用Arduino AFMotor驅動四只直流電機

  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:百度搜索“AFMotor庫”— 下載 — 拷貝到Arduino-libraries 文件夾中
  6.   2、實驗之七:使用Arduino AFMotor驅動四只直流電機
  7. */

  8. #include <AFMotor.h> // 本程序中使用AFMotor庫

  9. AF_DCMotor motor1(1); // 這4條語句的作用是建立4個直流電機對象,它們的名稱分別是:motor1/2/3/4.
  10. AF_DCMotor motor2(2); // 這四條語句括號中的數字代表各個電機對象所連接在AFMotor擴展板的電機端口號碼。
  11. AF_DCMotor motor3(3); // AF_DCMotor motor1(1); 代表motor1對象連接在AFMotor擴展板的M1端口上。
  12. AF_DCMotor motor4(4); // AFMotor電機擴展板最多可以驅動4個直流電機,最少可以驅動1個直流電機。

  13. void setup() {
  14.   motor1.setSpeed(200); // 這4條語句的作用是通過setSpped庫函數設置電機運行速度。
  15.   motor2.setSpeed(200); // setSpped庫函數中的參數是運行速度參數。
  16.   motor3.setSpeed(200); // 運行速度參數允許范圍是0~255。
  17.   motor4.setSpeed(200); // 速度參數越大,運轉速度越快。參數為0時電機停止轉動。

  18.   motor1.run(RELEASE); // 這4條語句的作用是讓4個電機在啟動時停止轉動
  19.   motor2.run(RELEASE); // run庫函數允許使用的關鍵字參數有RELEASE、FORWARD、BACKWARD
  20.   motor3.run(RELEASE); // 使用關鍵字RELEASE作為參數使用時,run庫函數將會讓擴展板停止提供電機運轉動力
  21.   motor4.run(RELEASE); // 電機旋轉一旦失去動力就會自然的停止轉動。
  22. }

  23. void loop() {
  24.   motor1.run(FORWARD); // 這4條語句的作用是利用run庫函數控制4個電機"正向"旋轉。
  25.   motor2.run(FORWARD); // 這里所謂的“正向”旋轉只是一種說法,假如您發現電機旋轉方向和您所要的“正向”不一致。
  26.   motor3.run(FORWARD); // 您可以將電機的兩個引線從擴展板上斷開,然后交換順序再接到擴展板接口上
  27.   motor4.run(FORWARD); // 這時您會看到同樣使用FORWARD關鍵字作為run庫函數的參數,電機的旋轉方向卻反過來了。

  28.   for (int i = 0; i <= 255; i++) { // 這里使用for循環語句控制4個電機速度由停止逐步加速,最終電機運轉達到最大速度。
  29.     motor1.setSpeed(i);          // 在for循環語句的作用下,setSpeed庫函數的速度參數i由0逐漸增大,最終達到255。
  30.     motor2.setSpeed(i);          // 因此電機運行速度也是由停止逐漸加速,最終達到最大速度。
  31.     motor3.setSpeed(i);          // 對于一些模型電機來說,當速度參數小于一定數值以后就不能轉動了。也就是說,也許您的電機
  32.     motor4.setSpeed(i);          // 在速度參數在小于某一個速度參數數值的時候就無法轉動了。這屬于正常現象。
  33.     delay(10);                   // 具體這個最小值是多少,對于不同的電機來說是不同的。有的可能是50也有的可能是100。
  34.   }                               // 換句話說,很可能您的某一個直流電機在速度參數小于50的情況下就無法轉動了。
  35.   // 也可能您的另一個直流電機在參數100以下的情況下就無法轉動了。

  36.   for (int i = 255; i >= 0; i--) { // 這里使用for循環語句控制4個電機由最大旋轉速度逐步減速最終停止旋轉。
  37.     motor1.setSpeed(i);          // 這一系列語句的操作與上一段for循環語句類似。唯一區別是上一段for循環控制速度參數i由0漲到255
  38.     motor2.setSpeed(i);          // 而這一段語句控制速度參數i由255減小到0。同樣您可能會發現當速度參數沒有減小到零的時候,電機就已經
  39.     motor3.setSpeed(i);          // 停止旋轉了。這其中的原因在上一段for循環語句中已經介紹了。不在這里贅述了。
  40.     motor4.setSpeed(i);
  41.     delay(10);
  42.   }

  43.   motor1.run(BACKWARD); // 這4條語句的作用是利用run庫函數控制4個電機"反向"旋轉。
  44.   motor2.run(BACKWARD); // 同樣的,這里所謂的“反向”旋轉也只是一種說法。這部分程序內容
  45.   motor3.run(BACKWARD); // 與本程序33-36行中的內容十分類似。唯一區別就是使用了“BACKWARD”
  46.   motor4.run(BACKWARD); // 關鍵字參數來通過庫函數run控制電機“反向”旋轉。

  47.   for (int i = 0; i <= 255; i++) { // 利用for循環語句控制速度參數i由小到大
  48.     motor1.setSpeed(i);          // 電機也會以“反向”旋轉的方式由停止逐步達到最大速度
  49.     motor2.setSpeed(i);
  50.     motor3.setSpeed(i);
  51.     motor4.setSpeed(i);
  52.     delay(10);
  53.   }

  54.   for (int i = 255; i >= 0; i--) { // 利用for循環語句控制速度參數i由大到小
  55.     motor1.setSpeed(i);          // 電機也會以“反向”旋轉的方式由最大速度逐步減小到停止
  56.     motor2.setSpeed(i);
  57.     motor3.setSpeed(i);
  58.     motor4.setSpeed(i);
  59.     delay(10);
  60.   }

  61.   motor1.run(RELEASE);   // 這四條語句作用是使用關鍵字RELEASE作為run函數的參數。
  62.   motor2.run(RELEASE);   // 在這種情況下,AFMotor擴展板將會停止為電機旋轉提供動力。
  63.   motor3.run(RELEASE);   // 電機也就會自然的停止轉動。
  64.   motor4.run(RELEASE);   // 本段程序后面的delay(1000)的作用就是讓4個電機保持無旋轉動力狀態1秒鐘

  65.   delay(1000);
  66. }
復制代碼



ID:513258 發表于 2020-11-12 19:38
  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:百度搜索“AFMotor庫”— 下載 — 拷貝到Arduino-libraries 文件夾中
  6.   2、實驗之六:連接每轉48步(7.5度)的步進電機,電機端口2#(M3和M4)
  7. */

  8. #include <AFMotor.h>

  9. // Connect a stepper motor with 48 steps per revolution (7.5 degree)
  10. // to motor port #2 (M3 and M4)
  11. AF_Stepper motor(48, 2);

  12. void setup() {
  13.   Serial.begin(9600);           // set up Serial library at 9600 bps
  14.   Serial.println("Stepper test! 測試步進電機!");

  15.   motor.setSpeed(10);  // 10 rpm
  16. }

  17. void loop() {
  18.   Serial.println("Single coil steps 單線圈步");
  19.   motor.step(100, FORWARD, SINGLE);
  20.   motor.step(100, BACKWARD, SINGLE);

  21.   Serial.println("Double coil steps 雙線圈步");
  22.   motor.step(100, FORWARD, DOUBLE);
  23.   motor.step(100, BACKWARD, DOUBLE);

  24.   Serial.println("Interleave coil steps 交錯線圈臺階");
  25.   motor.step(100, FORWARD, INTERLEAVE);
  26.   motor.step(100, BACKWARD, INTERLEAVE);

  27.   Serial.println("Micrsostep steps 微步前進");
  28.   motor.step(100, FORWARD, MICROSTEP);
  29.   motor.step(100, BACKWARD, MICROSTEP);
  30. }
復制代碼


ID:513258 發表于 2020-11-11 19:37
與步進電機有關的函數
確保導入AFMotor庫文件并#include < AFMotor.h>后,有這么幾個函數需要用到

1、AF_Stepper steppername(steps,portnumber)
(1)steppername
給電機起個名字,然后這個名字就是此電機在程序中的代號了
(2)steps
設置電機每轉的步數,比如設置36,則每步走1/36轉
(3)portnumber
選擇電機的通道,范圍為1(通道1,2)和2(通道3和4)

2、Step(steps,direction,style)
(1)step
轉動的步數
(2)direction
轉動的方向FORWARD 或者 BACKWARD
(3)style
步進的模式,可以選擇的參數:
a\SINGLE - 一次只給一相線圈供電
b\DOUBLE - 一次給兩項項圈都供電,得到更大的扭矩
c\INTERLEAVE - 電機會運轉得更柔滑,因為步數增加了一倍,同時速度也減小一半
d\MICROSTEP - 電機會運轉的更柔滑,精度更高,但扭矩也會減小

如果想更精細地控制步進電機,可以使用AccelStepper library,這個庫帶有電機加減速度功能。

ID:513258 發表于 2020-11-11 19:30
  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:百度搜索“AFMotor庫”— 下載 — 拷貝到Arduino-libraries 文件夾中
  6.   2、實驗之五:驅動28BYJ-48步進電機
  7. */

  8. #include <AFMotor.h> // 本程序中使用AFMotor庫

  9. AF_Stepper motor1(2048, 1);  // 這2條語句的作用是建立2個步進電機對象,它們的名稱分別是:motor1/2。
  10. AF_Stepper motor2(2048, 2);  // 對象名稱后面括號中的兩個參數分別代表了步進電機旋轉一周的步數以及
  11.                               // 步進電機連接在擴展板上的端口號。如AF_Stepper motor1(2048, 1)語句中
  12.                               // 參數2048代表motor1旋轉一周需要走2048步。假如您的電機旋轉一周需要32步,
  13.                               // 那么請在第一個參數位置輸入32這一數字參數。
  14.                               // 括號中第二個參數1代表motor1連接在M1和M2端口。
  15.                               // 對于motor2對象,它括號中的參數2代表該電機連接在M3和M4端口。

  16. void setup() {
  17.   Serial.begin(9600);         //啟動串口通訊
  18.   
  19.   motor1.setSpeed(10);        // 這2條語句的作用是通過setSpped庫函數設置電機運行速度。
  20.   motor2.setSpeed(10);        // setSpped庫函數中的參數是運行速度參數。
  21.                               // 速度參數越大,運轉速度越快。參數為0時電機停止轉動。
  22. }

  23. /*
  24. 以下的loop函數中有4段程序語句。它們的內容十分類似,主要語句都是是通過step庫函數來控制
  25. 步進電機的運行模式。step庫函數一共有3個參數。如loop函數的第二行語句:motor1.step(2048, FORWARD, SINGLE)。
  26. 括號中的第一個參數是控制電機走的步數,這里的參數2048就是讓電機走2048步。
  27. 接下來的關鍵字參數"FORWARD"作用是控制電機旋轉方向。"FORWARD"是控制電機"正轉",
  28. 這里也可以使用關鍵字"BACKWARD"讓電機"反轉"。
  29. 最后一個關鍵字參數是用于控制步進電機運轉模式的。這里可選的關鍵字參數有:
  30. SINGLE - 全步進模式(單線圈)。電機每走一步,擴展板只給一相線圈供電。
  31. DOUBLE - 全步進模式(雙線圈)。電機每走一步,擴展板會同時給兩相線圈供電。
  32.          此模式運行的電機比SINGLE模式下的扭矩要更大,但是電機耗電也會更多。
  33. INTERLEAVE - 半步進模式。這種模式是SINGLE和DOUBLE的混合。電機每走一步,擴展板對線圈供電方式
  34.              在一相和兩相之間交替切換。舉例來說,電機走第一步時,只有一相線圈通電。
  35.              走第二步時,會有兩相線圈供電,然后又是一相,再兩相......這樣交替通電。
  36.              這種控制模式的優點是電機運行更流暢,但是缺點是運行速度大打折扣。
  37. MICROSTEP - 微步進模式。此模式下的電機運行更光滑,但缺點是扭矩會打折扣。   
  38. */

  39. void loop() {
  40.   Serial.println("Single Mode");        //串口監視器輸出當前運行模式為“Single”
  41.   motor1.step(2048, FORWARD, SINGLE);    //步進電機以SINGLE模式"正轉"2048步
  42.   motor1.step(2048, BACKWARD, SINGLE);   //步進電機以SINGLE模式"反轉"2048步

  43.   Serial.println("Double Mode");        //串口監視器輸出當前運行模式為“Double”
  44.   motor2.step(2048, FORWARD, DOUBLE);    //步進電機以DOUBLE模式"正轉"2048步
  45.   motor2.step(2048, BACKWARD, DOUBLE);   //步進電機以DOUBLE模式"反轉"2048步

  46.   Serial.println("Interleave Mode");        //串口監視器輸出當前運行模式為“Interleave”
  47.   motor1.step(2048, FORWARD, INTERLEAVE);    //步進電機以INTERLEAVE模式"正轉"2048步
  48.   motor1.step(2048, BACKWARD, INTERLEAVE);   //步進電機以INTERLEAVE模式"反轉"2048步

  49.   Serial.println("Micrsostep Mode");         //串口監視器輸出當前運行模式為“Micrsostep”
  50.   motor2.step(2048, FORWARD, MICROSTEP);      //步進電機以MICROSTEP模式"正轉"2048步
  51.   motor2.step(2048, BACKWARD, MICROSTEP);     //步進電機以MICROSTEP模式"反轉"2048步
  52. }
復制代碼


ID:513258 發表于 2020-11-11 18:40
3、Servo-writeMicroseconds()函數(精確控制)
以微秒(uS)為單位寫入一個值,從而相應地控制軸。在標準伺服系統上,這將設置軸的角度。在標準伺服器上,參數值1000完全是逆時針方向,2000完全是順時針方向,中間是1500。

請注意,某些制造商并未非常嚴格地遵循此標準,因此,伺服器通常會對700到2300之間的值做出響應。可以隨意增加這些端點,直到伺服器不再繼續增加其范圍為止。但是請注意,嘗試將伺服驅動器驅動通過其端點(通常由嘶嘶聲表示)是高電流狀態,應避免使用。連續旋轉伺服器將以類似于寫入功能的方式響應writeMicrosecond功能。

句法
servo.writeMicroseconds(uS)

參量
伺服:伺服類型的變量
us:參數值(以微秒為單位)(int)


#include <Servo.h>

Servo myservo;

void setup()
{
  myservo.attach(9);
  myservo.writeMicroseconds(1500);  // set servo to mid-point
}

void loop() {}


4、Servo-read()函數(讀取)
讀取伺服器的當前角度(該值傳遞給對write()的最后一次調用)。

句法
servo.read()

參量
伺服:類型變量Servo
反饋
伺服角度為0到180度。


5、Servo-Attached()函數(附加)
檢查是否將Servo變量附加到引腳上。

句法
servo.attached()

參量
伺服:類型變量Servo
反饋
true如果伺服系統連接到引腳上;false除此以外。

6、Servo-detach()函數(分離)
從其引腳上拆下伺服變量。如果所有伺服變量均已分離,則可以使用AnalogWrite()將引腳9和10用于PWM輸出。

句法
servo.detach()

參量
伺服:類型變量Servo

ID:513258 發表于 2020-11-11 18:39
使用Servo庫
1、Servo-attach()函數(連接)
將伺服變量附加到引腳上。請注意,在Arduino 0016及更早版本中,Servo庫僅在兩個引腳上僅支持舵機:9和10。

句法
servo.attach(pin)
servo.attach(pin, min, max)

參量
伺服:類型變量Servo
pin:伺服器連接的引腳號
min(可選):脈沖寬度(以微秒為單位),對應于伺服器上的最小(0度)角度(默認為544)
最大(可選):脈沖寬度(以微秒為單位),對應于伺服器上的最大(180度)角度(默認為2400)


#include <Servo.h>
Servo myservo;
void setup()
{
  myservo.attach(9);
}
void loop() {}

2、Servo-write(x)函數(寫入)
將值寫入伺服器,從而相應地控制軸。在標準伺服器上,這將設置軸的角度(以度為單位),將軸移動到該方向。在連續旋轉伺服系統(360度舵機)上,這將設置伺服系統的速度(0表示一個方向的全速,180表示另一方向的全速,而90左右的值表示無運動)。

句法
servo.write(angle)

參量
伺服:伺服類型的變量
angle:寫入伺服的值,從0到180


#include <Servo.h>
Servo myservo;
void setup()
{
  myservo.attach(9);
  myservo.write(90);  // set servo to mid-point
}
void loop() {}

ID:513258 發表于 2020-11-11 16:55
實驗之四:驅動二只伺服電機(1號與2號舵機)

  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:IDE—工具—管理庫—搜索“Servo”—安裝
  6.   2、實驗之四:驅動二只伺服電機(1號與2號舵機)
  7. */

  8. #include <Servo.h>

  9. Servo servo1;   //建立舵機對象servo1
  10. Servo servo2;   //建立舵機對象servo2

  11. int pos = 0;   
  12. void setup() {
  13.   servo1.attach(10);    //servo1對象接在擴展板servo1端口。
  14.                         //servo1端口是由Arduino的10號引腳來控制的。
  15.   servo2.attach(9);     //servo2對象接在擴展板servo2端口。
  16.                         //servo2端口是由Arduino的9號引腳來控制的。
  17. }

  18. void loop() {
  19.   //以下程序將控制servo1輸出軸左右旋轉180度
  20.   for (pos = 0; pos <= 180; pos += 1) {
  21.     servo1.write(pos);              
  22.     delay(15);                       
  23.   }
  24.   for (pos = 180; pos >= 0; pos -= 1) {
  25.     servo1.write(pos);   
  26.     delay(15);      
  27.   }
  28.   
  29.   //以下程序將控制servo2輸出軸左右旋轉180度
  30.   for (pos = 0; pos <= 180; pos += 1) {
  31.     servo2.write(pos);              
  32.     delay(15);                       
  33.   }
  34.   for (pos = 180; pos >= 0; pos -= 1) {
  35.     servo2.write(pos);   
  36.     delay(15);      
  37.   }  
  38. }
復制代碼



ID:513258 發表于 2020-11-11 16:37
本帖最后由 eagler8 于 2020-11-11 16:51 編輯

實驗之三:驅動單只伺服電機(2號舵機)

  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:IDE—工具—管理庫—搜索“Servo”—安裝
  6.   2、實驗之三:驅動單只伺服電機(2號舵機)
  7. */

  8. #include <Servo.h>

  9. Servo myservo;  // create servo object to control a servo
  10. // twelve servo objects can be created on most boards

  11. int pos = 0;    // variable to store the servo position

  12. void setup() {
  13.   myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  14. }

  15. void loop() {
  16.   for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
  17.     // in steps of 1 degree
  18.     myservo.write(pos);              // tell servo to go to position in variable 'pos'
  19.     delay(15);                       // waits 15ms for the servo to reach the position
  20.   }
  21.   for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
  22.     myservo.write(pos);              // tell servo to go to position in variable 'pos'
  23.     delay(15);                       // waits 15ms for the servo to reach the position
  24.   }
  25. }
復制代碼



ID:513258 發表于 2020-11-6 11:16
AF_DCMotor 類函數
AFMotor類配合Adafruit Motor Shied可以最多同時控制4個直流電機的速度和方向。要使用這些功能,首先要在開頭添加庫文件:
#include <AFMotor.h>

AF_DCMotor motorname(portnum,freq)
這是一個建立一個直流電機的函數。在程序中需要聲明每個電機各一次。像下面的例子中一樣,每個電機必須使用不同的名字。
參數:
port num - 選擇你的電機連接到電機驅動板上的接口(1-4)
freq - 選擇PWM頻率。如果你沒有選擇這個選項,默認設置為1KHZ。
適用于通道1和2的頻率:
MOTOR12_64KHZ
MOTOR12_8KHZ
MOTOR12_2KHZ
MOTOR12_1KHZ
適用于通道3和4的頻率:
MOTOR34_64KHZ
MOTOR34_8KHZ
MOTOR34_1KHZ
例如:
AF_DCMotor motor4(4);//通道4,默認1KHZ頻率
AF_DCMotor left_motor(1,MOTOR12_64KHZ);//通道1,64KHZ頻率
注意:更高的頻率會減小電機在運動過程中的噪音,但同時也會降低扭矩。

setSpeed(speed)
設置電機的速度
參數:
speed-范圍為0到255,0代表停止,255代表全速。
注意:直流電機的回饋并不是典型線性的,所以真正的轉速并不會與程序中設定的速度成正比。

run(cmd)
設置電機的運轉模式
參數:
cmd - 選擇你想要的電機運轉模式
可選擇的模式:
FORWARD - 正轉(真正的轉動方向取決于你電機的連線)
BACKWARD - 反轉 (轉動方向與正轉相反)
RELEASE - 停止。使電機斷電,與setSpeed(0)函數功能相同。調用了這個函數后,電機需要一定時間才能徹底停止。

ID:513258 發表于 2020-11-4 14:52
本帖最后由 eagler8 于 2020-11-5 19:32 編輯
  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:百度搜索“AFMotor庫”— 下載 — 拷貝到Arduino-libraries 文件夾中
  6.   2、實驗之二:引擎測試—用串口查看2號直流電機運轉情況
  7. */

  8. #include "AFMotor.h"

  9. AF_DCMotor motor(2);

  10. void setup() {
  11.   Serial.begin(9600);           // set up Serial library at 9600 bps
  12.   Serial.println("引擎測試 Motor test!");

  13.   // turn on motor
  14.   motor.setSpeed(200);

  15.   motor.run(RELEASE);
  16. }

  17. void loop() {
  18.   uint8_t i;

  19.   Serial.println("向前 FORWARD!");

  20.   motor.run(FORWARD);
  21.   for (i = 0; i < 255; i++) {
  22.     motor.setSpeed(i);
  23.     delay(10);
  24.   }

  25.   for (i = 255; i != 0; i--) {
  26.     motor.setSpeed(i);
  27.     delay(10);
  28.   }

  29.   Serial.println("向后 BACKWARD!");

  30.   motor.run(BACKWARD);
  31.   for (i = 0; i < 255; i++) {
  32.     motor.setSpeed(i);
  33.     delay(10);
  34.   }

  35.   for (i = 255; i != 0; i--) {
  36.     motor.setSpeed(i);
  37.     delay(10);
  38.   }


  39.   Serial.println("停止 RELEASE!");
  40.   motor.run(RELEASE);
  41.   delay(1000);
  42. }
復制代碼

ID:513258 發表于 2020-11-4 14:52
本帖最后由 eagler8 于 2020-11-4 16:17 編輯
  1. /*
  2.   【Arduino】168種傳感器模塊系列實驗(資料+代碼+圖形+仿真)
  3.   實驗一百七十:L293D四路電機驅動板 motor control shield 馬達板
  4.   Adafruit Motor Shield模塊 Arduino AFMotor 電機擴展板

  5.   1、安裝庫:百度搜索“AFMotor庫”— 下載 — 拷貝到Arduino-libraries 文件夾中
  6.   2、實驗之一:測試驅動M2直流電機
  7. */

  8. #include <AFMotor.h>

  9. AF_DCMotor motor(2, MOTOR12_64KHZ);

  10. void setup() {
  11.   motor.setSpeed(200);
  12. }

  13. void loop() {
  14.   motor.run(FORWARD);
  15.   delay(1000);
  16.   motor.run(BACKWARD);
  17.   delay(1000);
  18.   motor.run(RELEASE);
  19.   delay(1000);
  20. }
復制代碼

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区三区在线免费观看 | av电影手机在线看 | 久久久亚洲精品视频 | 国产一区二区精华 | 日本精品一区二区三区视频 | 欧美在线一区二区三区 | yeyeav| 精品国产乱码久久久久久影片 | 欧美在线观看一区 | 99精品国产一区二区三区 | 天天躁日日躁狠狠躁白人 | 亚洲视频在线观看 | 日韩精品无码一区二区三区 | 夜夜摸天天操 | 日本精品一区二区三区在线观看视频 | 91美女视频| 国产精品精品视频一区二区三区 | 天天躁日日躁狠狠很躁 | 免费观看成人av | 国产免费一区二区三区 | 日韩手机在线视频 | 国产高清在线精品一区二区三区 | 欧美成人一级视频 | 丁香婷婷久久久综合精品国产 | 不卡在线视频 | 精精精精xxxx免费视频 | 久久精品国产亚洲a | 91精品国模一区二区三区 | 日韩一区中文字幕 | 日韩精品中文字幕在线 | 本道综合精品 | 亚洲色图插插插 | 三级国产三级在线 | 日韩中文字幕在线视频 | 久久爱黑人激情av摘花 | 天天看天天爽 | 国产高清免费视频 | 久久麻豆精品 | 欧美不卡 | 一区视频在线播放 | 国产精品视频一二三区 |