• Interfacing Servo Motor with PIC Microcontroller using MPLAB and XC8 - Giao diện động cơ Servo với Vi điều khiển PIC sử dụng MPLAB và XC8

QC

Interfacing Servo Motor with PIC Microcontroller using MPLAB and XC8 - Giao diện động cơ Servo với Vi điều khiển PIC sử dụng MPLAB và XC8

 


Đây là hướng dẫn thứ 11 của chúng tôi về Học vi điều khiển PIC sử dụng MPLAB và XC8. Trong hướng dẫn này, chúng ta sẽ học Cách điều khiển Động cơ Servo bằng Vi điều khiển PIC. Nếu bạn đã làm việc với động cơ Servo, bạn có thể bỏ qua nửa đầu của hướng dẫn này nhưng nếu bạn chưa quen với chính động cơ servo thì hãy tiếp tục đọc.


Cho đến nay, chúng tôi đã đề cập đến nhiều hướng dẫn cơ bản như nhấp nháy LED với PIC, Bộ hẹn giờ trong PIC, giao diện LCD, giao tiếp 7 đoạn, ADC sử dụng PIC, v.v. Nếu bạn là người mới bắt đầu, vui lòng truy cập danh sách đầy đủ các hướng dẫn PIC tại đây và bắt đầu học.


Trong phần hướng dẫn trước, chúng ta đã học cách tạo tín hiệu PWM bằng Vi điều khiển PIC, các tín hiệu được tạo dựa trên giá trị đọc được từ chiết áp. Sau đó, nếu bạn đã hiểu tất cả các chương trình, Xin chúc mừng bạn cũng đã mã hóa cho một động cơ Servo. CÓ, động cơ Servo phản hồi lại các tín hiệu PWM (mà chúng tôi tạo bằng cách sử dụng bộ hẹn giờ ở đây), chúng ta sẽ tìm hiểu lý do và cách làm trong hướng dẫn này. Chúng tôi sẽ mô phỏng và xây dựng thiết lập phần cứng cho dự án này và bạn có thể tìm thấy Video chi tiết ở cuối Hướng dẫn này.

What is a Servo Motor?

Động cơ Servo là một loại cơ cấu truyền động (chủ yếu là hình tròn) cho phép điều khiển góc. Có nhiều loại động cơ Servo nhưng trong hướng dẫn này, chúng ta hãy tập trung vào các động cơ servo sở thích được hiển thị bên dưới.



Servos sở thích là một phương pháp phổ biến vì chúng là phương pháp điều khiển chuyển động rẻ tiền. Họ cung cấp một giải pháp có sẵn cho hầu hết các R / C và nhu cầu của những người yêu thích robot. Họ cũng loại bỏ nhu cầu thiết kế tùy chỉnh hệ thống điều khiển cho từng ứng dụng.


Hầu hết các động cơ servo sở thích có thiên thần quay từ 0- 180 ° nhưng bạn cũng có thể nhận được động cơ servo 360 ° nếu bạn quan tâm. Hướng dẫn này sử dụng động cơ servo 0- 180 °. Có hai loại động cơ Servo dựa trên bánh răng, một loại là Động cơ Servo bánh răng bằng nhựa và loại còn lại là Động cơ Servo bánh răng kim loại. Bánh răng kim loại được sử dụng ở những nơi động cơ bị mài mòn nhiều hơn, nhưng nó chỉ có giá cao.


Động cơ servo được đánh giá theo kg / cm (kilogam trên cm) hầu hết các động cơ servo sở thích được đánh giá ở 3kg / cm hoặc 6kg / cm hoặc 12kg / cm. Kg / cm này cho bạn biết trọng lượng động cơ servo của bạn có thể nâng ở một khoảng cách cụ thể là bao nhiêu. Ví dụ: Một động cơ Servo 6kg / cm sẽ có thể nâng 6kg nếu tải được treo cách trục động cơ 1cm, khoảng cách càng lớn thì khả năng mang trọng lượng càng giảm. Tìm hiểu tại đây Kiến thức cơ bản về động cơ Servo.

Interfacing Servo Motors with Microcontrollers:

Việc kết nối động cơ Servo theo sở thích với MCU rất dễ dàng. Servos có ba dây ra khỏi chúng. Trong số đó, hai sẽ được sử dụng cho Nguồn cung cấp (tích cực và tiêu cực) và một sẽ được sử dụng cho tín hiệu được gửi từ MCU. Trong hướng dẫn này, chúng tôi sẽ sử dụng Động cơ Servo bánh răng kim loại MG995 được sử dụng phổ biến nhất cho các bot hình người trên ô tô RC, v.v. Hình ảnh của MG995 được hiển thị bên dưới:

Mã màu của động cơ servo của bạn có thể khác nhau, do đó hãy kiểm tra biểu dữ liệu tương ứng của bạn.


Tất cả các động cơ servo đều hoạt động trực tiếp với đường cung cấp + 5V của bạn nhưng chúng tôi phải cẩn thận về lượng dòng điện mà động cơ sẽ tiêu thụ, nếu bạn dự định sử dụng nhiều hơn hai động cơ servo, cần thiết kế một tấm chắn servo thích hợp. Trong hướng dẫn này, chúng tôi sẽ chỉ sử dụng một động cơ servo để trình bày cách lập trình MCU PIC của chúng tôi để điều khiển động cơ. Kiểm tra các liên kết dưới đây để giao tiếp Động cơ Servo với Bộ vi điều khiển khác:


Programming Servo Motor with PICF877A PIC Microcontroller:


Trước khi có thể bắt đầu lập trình cho động cơ Servo, chúng ta nên biết loại tín hiệu nào sẽ được gửi để điều khiển động cơ Servo. Chúng ta nên lập trình MCU để gửi tín hiệu PWM đến dây tín hiệu của động cơ Servo. Có một mạch điều khiển bên trong động cơ servo đọc chu kỳ làm việc của tín hiệu PWM và đặt trục động cơ servo ở vị trí tương ứng như thể hiện trong hình bên dưới




Mỗi động cơ servo hoạt động trên các tần số PWM khác nhau (tần số phổ biến nhất là 50HZ được sử dụng trong hướng dẫn này) vì vậy hãy lấy biểu dữ liệu của động cơ của bạn để kiểm tra khoảng thời gian PWM mà động cơ Servo của bạn hoạt động.

  Chi tiết về tín hiệu PWM cho Tower pro MG995 của chúng tôi được hiển thị bên dưới.




Từ đó, chúng tôi có thể kết luận rằng động cơ của chúng tôi hoạt động với Chu kỳ PWM là 20ms (50Hz). Vì vậy, tần số của tín hiệu PWM của chúng tôi nên được đặt thành 50Hz. Tần số của PWM mà chúng tôi đã đặt trong hướng dẫn trước của chúng tôi là 5 KHz, việc sử dụng cùng một tần số sẽ không giúp ích cho chúng tôi ở đây.

Nhưng, chúng tôi có một vấn đề ở đây. PIC16F877A không thể tạo tín hiệu PWM tần số thấp bằng mô-đun CCP. Theo biểu dữ liệu, giá trị thấp nhất có thể có thể được đặt cho tần số PWM là 1,2 KHz. Vì vậy, chúng tôi phải từ bỏ ý định sử dụng mô-đun CCP và tìm cách tạo tín hiệu PWM của riêng mình.

Do đó, trong hướng dẫn này, chúng tôi sẽ sử dụng mô-đun hẹn giờ để tạo ra tín hiệu PWM với tần số 50Hz và thay đổi chu kỳ làm việc của chúng để điều khiển thiên thần của động cơ servo. Nếu bạn chưa quen với bộ đếm thời gian hoặc ADC với PIC, vui lòng quay lại hướng dẫn này, vì tôi sẽ bỏ qua hầu hết nội dung vì chúng tôi đã đề cập đến chúng ở đó.

Chúng tôi khởi tạo mô-đun Bộ hẹn giờ của mình với bộ đếm trước là 32 và làm cho nó bị tràn sau mỗi 1us. Theo bảng dữ liệu của chúng tôi, PWM chỉ nên có khoảng thời gian là 20ms. Vì vậy, thời gian đúng giờ của chúng tôi và thời gian nghỉ cùng nhau phải chính xác bằng 20ms.

OPTION_REG = 0b00000100;  // Timer0 with external freq and 32 as prescaler
    TMR0=251;       // Load the time value for 1us delayValue can be between 0-256 only
    TMR0IE=1;       //Enable timer interrupt bit in PIE1 register
    GIE=1;          //Enable Global Interrupt
    PEIE=1;         //Enable the Peripheral Interrupt


Vì vậy, bên trong chức năng định kỳ ngắt của chúng tôi, chúng tôi bật chân RB0 trong thời gian được chỉ định và tắt nó trong thời gian doa (20ms - on_time). Giá trị của thời gian đúng giờ có thể được chỉ định bằng cách sử dụng Potentiometer và mô-đun ADC. Ngắt được hiển thị bên dưới.

oid interrupt timer_isr()
{  
    if(TMR0IF==1) // Timer has overflown
    {
        TMR0 = 252;     /*Load the timer Value, (Note: Timervalue is 101 instaed of 100 as the
                         TImer0 needs two instruction Cycles to start incrementing TMR0 */
        TMR0IF=0;       // Clear timer interrupt flag
        count++;
    } 
    
    if (count >= on_time)
    {
        RB0=1;  // complement the value for blinking the LEDs
    }
    
    if (count >= (on_time+(200-on_time)))
    {
        RB0=0;
        count=0;
    }
}

Bên trong vòng lặp while của chúng tôi, chúng tôi chỉ cần đọc giá trị của chiết áp bằng cách sử dụng mô-đun ADC và cập nhật đúng thời gian của PWM bằng cách sử dụng giá trị đọc.


  while(1)
    { 
        pot_value = (ADC_Read(4))*0.039;
        on_time = (170-pot_value);
    }
Bằng cách này, chúng tôi đã tạo ra một tín hiệu PWM có Chu kỳ là 20ms và có chu kỳ nhiệm vụ thay đổi có thể được đặt bằng cách sử dụng Chiết áp. Mã hoàn chỉnh đã được đưa ra bên dưới trong phần mã.

Bây giờ, hãy xác minh đầu ra bằng cách sử dụng mô phỏng proteus và tiếp tục với phần cứng của chúng tôi.

Circuit Diagram:


Nếu bạn đã xem qua hướng dẫn PWM thì các sơ đồ của hướng dẫn này sẽ giống nhau, ngoại trừ việc chúng tôi sẽ thêm một động cơ servo thay cho đèn LED.




Simulation and Hardware Setup:

Với sự trợ giúp của mô phỏng Proteus, chúng ta có thể xác minh tín hiệu PWM bằng máy hiện sóng và cũng có thể kiểm tra thiên thần quay của động cơ Servo. Dưới đây là một vài ảnh chụp nhanh của mô phỏng, nơi thiên thần quay của động cơ servo và chu kỳ làm việc PWM có thể được thay đổi dựa trên chiết áp. Kiểm tra thêm Video đầy đủ, xoay ở PWM khác nhau, ở cuối.




Như chúng ta có thể thấy thiên thần quay servo được thay đổi dựa trên giá trị chiết áp. Bây giờ chúng ta hãy tiến hành thiết lập phần cứng của mình.

Trong phần thiết lập phần cứng, chúng tôi vừa gỡ bỏ bảng LED và thêm động cơ Servo như trong sơ đồ trên.

Phần cứng được hiển thị trong hình dưới đây:




#define _XTAL_FREQ 20000000

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

//TIMER0    8-bit    $$RegValue = 256-((Delay * Fosc)/(Prescalar*4))$$

char value = 0;
int on_time ;//= 150; //On-Time for the PWM signal
int count; //count gets incremented for every timer overlap
int pot_value;

/*********ADC Functions*********/
void ADC_Init()
{
  ADCON0 = 0x41; //ADC Module Turned ON and Clock is selected
  ADCON1 = 0xC0; //All pins as Analog Input
                //With reference voltages VDD and VSS
}
unsigned int ADC_Read(unsigned char channel)
{
  if(channel > 7) //If Invalid channel selected 
    return 0;     //Return 0

  ADCON0 &= 0xC5; //Clearing the Channel Selection Bits
  ADCON0 |= channel<<3; //Setting the required Bits
  __delay_ms(2); //Acquisition time to charge hold capacitor
  GO_nDONE = 1; //Initializes A/D Conversion
  while(GO_nDONE); //Wait for A/D Conversion to complete
  return ((ADRESH<<8)+ADRESL); //Returns Result
}
  //*************************************************//

void interrupt timer_isr()
{  
    if(TMR0IF==1) // Timer has overflown
    {
        TMR0 = 252;     /*Load the timer Value, (Note: Timervalue is 101 instaed of 100 as the
                         TImer0 needs two instruction Cycles to start incrementing TMR0 */
        TMR0IF=0;       // Clear timer interrupt flag
        count++;
    } 
    
    if (count >= on_time)
    {
        RB0=1;  // complement the value for blinking the LEDs
    }
    
    if (count >= (on_time+(200-on_time)))
    {
        RB0=0;
        count=0;
    }
}

void main()
{    
 /***************I/O PORT Initialization*************/
  TRISB = 0x00; //RB0 used as Servo signal pin
  TRISA = 0xFF; //Analog inputs 
 //*************************************************//

 ADC_Init(); //Initializes ADC Module
  
    OPTION_REG = 0b00000100;  // Timer0 with external freq and 32 as prescaler
    TMR0=251;       // Load the time value for 1us delayValue can be between 0-256 only
    TMR0IE=1;       //Enable timer interrupt bit in PIE1 register
    GIE=1;          //Enable Global Interrupt
    PEIE=1;         //Enable the Peripheral Interrupt

    while(1)
    { 
        pot_value = (ADC_Read(4))*0.039;
        on_time = (170-pot_value);
    }
}















Error No module Onnx opencv

 Error No module Onnx opencv Lệnh :  pip install onnx==1.9 Mã lỗi PS F:\opencv_e\2.video> & C:/Users/youtb/Anaconda3/envs/virtualenv/...