lap trinh robot don gian voi pic 16f877a

14
Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team © http://em-bot.tk (Feb 2010) DEMO VERSION Trang 1/14 LẬP TRÌNH ROBOT TỰ ĐỘNG ĐƠN GIẢN VỚI VI ĐIỀU KHIỂN PIC16F877A Cao Hoàng Long, EM-BOT Robot Team [email protected] ; [email protected] Khoa Công nghệ, Đại học Cần Thơ Tóm tắt Tài liệu hướng dẫn lập trình cho robot tự động đường theo vạch trắng và điều khiển các cơ cấu (nâng hạ, gắp nhả quà) một cách cơ bản nhất.Vi điều khiển được sử dụng trong tài liệu là PIC16F877A của Microchip.Lập trình bằng ngôn ngữ C với trình biên dịch CCS. 1 TÓM TẮT VỀ THIẾT KẾ ROBOT TỰ ĐỘNG Robot tự động trong các cuộc thi Robocon gồm 3 thành phần chính: Cơ khí, Mạch điện tử, Lập trình. 1.1 Cơ khí Một robot đơn giản gồm 2 động cơ truyền động cho 2 bánh xe bên trái và bên phải giúp robot di chuyển. Phía trước có thể là 1 hoặc 2 bánh tự do (bánh tlựa, omni, mắt trâu,…). Để thực hiện được các công việc như nâng hạ trục, gắp nhả đẩy quá, robot được trang bị thêm các động cơ khác để truyền động cho các cơ cấu này. Tất cả các bộ phận trên được bố trí trên một khung bằng nhôm, sắt,… Phần hướng dẫn chi tiết về thiết kế cơ khí sẽ được trình bày trong một tài liệu khác. Tài liệu này chỉ tập trung vào phần lập trình. Hình 1: Mô hình robot dò dường đơn giản 1.2 Mạch điện tử Hình 2: Sơ đồ hoạt động của robot tự động

Upload: tuan-hien-nguyen

Post on 03-Jul-2015

421 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 1/14

LẬP TRÌNH ROBOT TỰ ĐỘNG ĐƠN GIẢNVỚI VI ĐIỀU KHIỂN PIC16F877A

Cao Hoàng Long, EM-BOT Robot Team

[email protected] ; [email protected]

Khoa Công nghệ, Đại học Cần ThơTóm tắtTài liệu hướng dẫn lập trình cho robot tự động dò đường theo vạch trắng và điều khiểncác cơ cấu (nâng hạ, gắp nhả quà) một cách cơ bản nhất.Vi điều khiển được sử dụngtrong tài liệu là PIC16F877A của Microchip.Lập trình bằng ngôn ngữ C với trình biêndịch CCS.

1 TÓM TẮT VỀ THIẾT KẾ ROBOT TỰ ĐỘNGRobot tự động trong các cuộc thi Robocon gồm 3 thành phần chính: Cơ khí,Mạch điện tử, Lập trình.

1.1 Cơ khíMột robot đơn giản gồm 2 động cơ truyền động cho 2 bánh xe bên trái và bênphải giúp robot di chuyển. Phía trước có thể là 1 hoặc 2 bánh tự do (bánh tựlựa, omni, mắt trâu,…). Để thực hiện được các công việc như nâng hạ trục,gắp nhả đẩy quá, robot được trang bị thêm các động cơ khác để truyền độngcho các cơ cấu này.Tất cả các bộ phận trên được bố trí trên một khung bằng nhôm, sắt,…Phần hướng dẫn chi tiết về thiết kế cơ khí sẽ được trình bày trong một tàiliệu khác. Tài liệu này chỉ tập trung vào phần lập trình.

Hình 1: Mô hình robot dò dường đơn giản

1.2 Mạch điện tử

Hình 2: Sơ đồ hoạt động của robot tự động

Page 2: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 2/14

1.2.1 Mạch ngõ vào (cảm biến, nút ấn, công tắc hành trình)Với robot đơn giản, ngõ vào thường là mức logic lấy từ cảm biến quang(quang trở, quang diode), nút ấn hoặc công tắc hành trình. Từ đó mạch viđiều khiển xử lý các tín hiệu này để xuất ngõ ra (thường là động cơ DC) chophù hợp.Cảm biến quang phải được che chắn cẩn thận để hạn chế ảnh hưởng từ cácnguồn ánh sáng bên ngoài.

C1

104

CTHT

SW2BIT0

5V

R310K

Hình 3: Mạch cảm biến, nút ấn và công tắc hành trình

1.2.2 Mạch vi điều khiểnMạch sử dụng vi điều khiển PIC16F877A của Microchip. Mạch nhận tínhiệu từ ngõ vào, xử lý và xuất ngõ ra qua một mạch cách ly bằng opto ramạch công suất.

RA5RA4

RC7

RC0

RA2RA3

RA0RA1

RB1RB2

RB4RB5

RB0

RB6RB7

RB3

RE0RE1

RC3RC4

RE2

RC5RC6

RD4

RD0RD1RD2RD3

RD5

Y1CRYSTAL

PIC16F877A

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT6

RA5/AN4/SS*/C2OUT7

RB0/INT33

RB134

RB235

RB3/PGM36

RB437

RB538

RB6/PGC39

RB7/PGD40

RC0/T1OSO/T1CKI15

RC1/T1OSI/CCP216

RC2/CCP117

RC3/SCK/SCL18

RC4/SDI/SDA23

RC5/SDO24

RC6/TX/CK25

RC7/RX/DT26

RD0/PSP019

RD1/PSP120

RD2/PSP221

RD3/PSP322

RD4/PSP427

RD5/PSP528

RD6/PSP629

RD7/PSP730

OSC1/CLKIN13

OSC2/CLKOUT14

VDD32VDD11

VSS31 VSS12

MCLR*/VPP1

RE0/RD*/AN58

RE1/WR*/AN69

RE2/CS*/AN710

C5 30p

C6 30p5V

RC1RC2

RESET

MCU MODULE

RD6RD7

Hình 4: Mạch vi điều khiển1.2.3 Mạch công suất điều khiển động cơ DC

Một số mạch thông dụng:

D141N5819

D13

1N581924V

C2104

MOTOR2

CON2

12

M2IRF540

R12330 2W

LS2RELAY

32

4

67

518

P-DIR2

P-PWM2

Q5B562

Q4D468

D121N5819

12V

D3QUANG TRO

D2LED

R1330

R233K

VCCVCC

-

+ U1A

LM324

3

21

R4 100K

CAMBIEN1

Vạch trắng: mức 1Nền: mức 0

Page 3: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 3/14

Hình 5: Mạch công suất sử dụng 1 FET và 1 relay

U3

IR 2184

COM3

LO4

VB8

IN1

VCC5

SD2

VS6

HO7

U4

IR2184

COM3

LO4

VB8

IN1

VCC5

SD2

VS6

HO7

+C54.7u

+C1

4.7u

C6100n

C2100n

D1

DIODE

R4 4.7R

R6 4.7R R7

4.7R

R5

4.7R

D2

DIODE

+ C34.7u

C4100n

12V

IN2

Q1

IRF540

Q3

IRF540

Q2IRF540

Q4IRF540

24V

C7470n

+ C8470u

J1

MOTOR

12C14

104

IN1

Hình 6: Mạch cầu H điều khiển động cơ với Half Bridge Driver IR2184

Phần hướng dẫn chi tiết về mạch điện tử sẽ được trình bày trong một tàiliệu khác. Tài liệu này chỉ tập trung vào phần lập trình.

Page 4: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 4/14

1.3 Lập trìnhĐây là phần chính của tài liệu này. Ngôn ngữ lập trình được sử dụng là C, vớitrình biên dịch CCS cho vi điều khiển PIC của Microchip.Kiến thức ban đầu: Lập trình C căn bảnCác tài liệu tham khảo:

Tài liệu CCS tiếng Việt: http://www.mediafire.com/?hd2ugmmzvwf Hướng dẫn lập trình PIC-DKS:http://www.mediafire.com/?e0ioxeideyx Giáo trình PIC (ĐH Reading): http://www.mediafire.com/?iyewnoldyjk Lập trình C cho PIC 8bit: http://www.mediafire.com/?tnjlztmmzdm CCS Manual (tra cứu lệnh): http://www.mediafire.com/?htljg1jg2mn

Đây là các tài liệu cần đọc qua trước khi vào lập trình cho PIC để có thể biết cáchàm nhận tín hiệu ngõ vào, xuất tín hiệu ngõ ra, ngắt, timer, counter, PWM,…Các hàm quan trọng sẽ được nhắc lại ở phần 2.

2 LẬP TRÌNH CHO ROBOT TỰ ĐỘNG DÒ ĐƯỜNG ĐƠN GIẢNChương trình giúp robot chạy theo vạch trắng trên nền màu sậm.

2.1 Phần cứng 8 cảm biến quang dò đường Mạch công suất điều khiển 2 động cơ Mạch vi điều khiển:

o PORTD: nối với tín hiệu ra của 8 cảm biếno Động cơ trái:

Chân C0: điều khiển chiều (DIR_LEFT) Chân C1: điều khiển cho phép chạy (EN_LEFT)

o Động cơ phải: Chân C3: điều khiển chiều (DIR_RIGHT) Chân C2: điều khiển cho phép chạy (EN_RIGHT)

(Các ngõ vào và ngõ ra có thế nối với bất cứ PORT và chân nào của vi điều khiển)

2.2 Nguyên tắc điều khiển2.2.1 Điều khiển động cơ

Trạng thái DIRECTION ENABLEThuận 1 1Ngược 0 1Dừng x 0

Tương tự đối với các động cơ điều khiển các cơ cấu.2.2.2 Hướng di chuyển của robot

Trạng thái Động cơ trái Động cơ phảiThẳng Thuận Thuận

Quay trái Thuận Ngược (Dừng)Quay phải Ngược (Dừng) Thuận

Page 5: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 5/14

2.2.3 Xử lý tín hiệu cảm biến (xem hình vẽ)Mục đích của việc dò đường là hướng cho robot đi theo 1 vạch thẳng màu trắngtrên một nền màu đậm (đen, xanh,…)Cảm biến được đặt ở giữa robot.

o Khi cảm biến số 3,4 nằm trên vạch trắng (mức 1): robot chạy thẳngo Khi robot lệch sang trái: quay phải để điều chỉnh robot về đúng vạcho Khi robot lệch sang phải: quay trái để điều chỉnh robot về đúng vạch

7 6 5 4 3 2 1 0 Trạng thái cảmbiến

Giữa vạch

Lệch trái mức 1

Lệch trái mức 2

Lệch trái mức 3

Lệch trái mức 4

Ngoài vạch

Lệch phải mức 1

Lệch phải mức 2

Lệch phải mức 3

Lệch phải mức 4

Ngoài vạch

Hình 7: Các mức độ lệch ra khỏi vạch trắng của robot

2.3 Chương trình điều khiển

#include <16f877A.h>#include <def_877A.h>#fuses HS,NOWDT,NOPROTECT,NOLVP#use delay(clock=20000000)

/* ĐỊNH NGHĨA CÁC CHÂN VÀ PORT */#define DIR_LEFT RC0#define EN_LEFT RC1

#define DIR_RIGHT RC3#define EN_RIGHT RC2

0

0

000000 0 0

000000 0 0

01

0 01 0 0 00

0 011 0 0 00

0011 0 0 00

1 0 0 00 0

1 1 0 0 00 0 0

10

0 1

000 0 0

00 10 0 0

00 11

0 1

00 0 0

1 0 00 0 0

Page 6: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 6/14

#define SENSOR PORTD/* KHAI BÁO CÁC CHƯƠNG TRÌNH CON */

void motor_left_forward();void motor_left_reverse();void motor_left_stop();

void motor_right_forward();void motor_right_reverse();void motor_right_stop();

void forward();void reverse();void stop();void turn_left();void turn_right();

/* CÁC CHƯƠNG TRÌNH CON */// Động cơ trái chạy thuậnvoid motor_left_forward(){DIR_LEFT=1; // chiều thuậnEN_LEFT=1; // cho phép chạy}// Động cơ trái chạy ngượcvoid motor_left_reverse(){DIR_LEFT=0; // chiều ngượcEN_LEFT=1; // cho phép chạy}// Động cơ trái dừngvoid motor_left_stop(){EN_LEFT=0; // không cho phép chạy}// Động cơ phải chạy thuậnvoid motor_right_forward(){DIR_RIGHT=1;// chiều thuậnEN_RIGHT=1; // cho phép chạy}// Động cơ phải chạy ngượcvoid motor_right_reverse(){DIR_RIGHT=0;// chiều ngượcEN_RIGHT=1; // cho phép chạy}// Động cơ phải dừngvoid motor_right_stop(){EN_RIGHT=0; // không cho phép chạy}// Chạy thẳngvoid forward()

Page 7: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 7/14

{motor_left_forward();motor_right_forward();}

// Chạy lùivoid reverse(){motor_left_reverse();motor_right_reverse();}// Dừngvoid stop(){motor_left_stop();motor_right_stop();}// Quay tráivoid turn_left(){motor_left_forward();motor_right_reverse(); // hoặc motor_right_stop();}// Quay phảivoid turn_right(){motor_left_reverse(); // hoặc motor_left_stop();motor_right_forward();}

/* CHƯƠNG TRÌNH CHÍNH */void main (){

TRISC=0x00; // PORTC là ngõ ra ( động cơ)TRISD=0x00; // PORTD là ngõ vào (cảm biến quang)PORTC=0x00; // Khởi tạo giá trị ban đầu 0x00 cho PORTCwhile(1){switch (SENSOR){case 0b00011000: forward(); break;case 0b00001100: turn_left(); break;case 0b00000110: turn_left(); break;case 0b00000011: turn_left(); break;case 0b00000001: turn_left(); break;case 0b00110000: turn_right(); break;case 0b01100000: turn_right(); break;case 0b11000000: turn_right(); break;case 0b10000000: turn_right(); break;}}

}

Page 8: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 8/14

3 CẢI TIẾN CHƯƠNG TRÌNH DÒ ĐƯỜNG3.1 Điều khiển tốc độ động cơ với các trạng thái lệch khỏi vạch trắng3.1.1 Nguyên lý

Đối với chương trình dò đường đơn giản, khi robot lệch trái hoặc lệch phải,robot sẽ quay phải hoặc quay trái để điều chỉnh cho dù lệch ít hay lệch nhiều.Như vậy, trong quá trình di chuyển, robot sẽ lắc liên tục vì phải quay trái, quayphải liên tục. Do đó, với các mức độ lệch ra khỏi vạch trắng khác nhau, ta điềuchỉnh tốc độ 2 bánh trái, phải cho phù hợp để quá trình di chuyển theo vạchcủa robot được “nhuyễn” và “mượt” hơn.Bảng giá trị tham khảo tốc độ động cơ trái và động cơ phải tương ứng với cáctrạng thái lệch khỏi vạch trẳng của robot (xem lại hình 7):

Trạng thái Tốc độ động cơ trái Tốc độ động cơ phảiGiữa vạch 100% 100%

Lệch trái mức 1 90% 80%Lệch trái mức 2 80% 70%Lệch trái mức 3 70% 60%Lệch trái mức 4 60% 50%Lệch phải mức 1 80% 90%Lệch phải mức 2 70% 80%Lệch phải mức 3 60% 70%Lệch phải mức 4 50% 60%

3.1.2 Điều khiển tốc độ động cơ DC bằng phương pháp PWMĐối với điều khiển tốc độ động cơ DC trong robot, phương pháp được sử dụngphổ biến nhất là điều biến độ rộng xung (Pulse Width Modulation) hay đượcgọi tắt là điều xung, băm xung hoặc PWM.Nguyên lý của phương pháp này là bật tắt nhanh nguồn điện cấp vào động cơtạo ra một tín hiệu xung. Khi việc bật tắt ở tần số đủ lớn (thường sử dụng từ1kHz đến 20kHz), động cơ sẽ chạy với 1 tốc độ ổn định nhờ moment quay.Thời gian cấp nguồn cho động cơ là T-on, thời gian tắt nguồn động cơ là T-off.Việc thay đổi thời gian T-on và T-off làm thay đổi điện áp hiệu dụng cấp chođộng cơ. Đối với động cơ DC, tốc độ động cơ tương đối tỉ lệ thuận với điện ápcấp cho động cơ. Vì vậy, bằng cách thay đổi độ rộng của xung, ta đã thay đổiđược tốc độ của động cơ DC.Đại lượng biểu diễn mối quan hệ giữa T-on và T-off được gọi là duty cycle

offon

on

TT

Tcycleduty

_

Ví dụ: Ta cấp nguồn động cơ trong 0.8ms, sau đó tắt 0.2ms.Như vậy: T-on = 0.8ms; T-off = 1ms. Tần số PWM là

kHzmsmsmsTT

foffon

11

1

2.08.0

11

Page 9: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 9/14

%808.02.08.0

8.0_

offon

on

TT

Tcycleduty

Vì tốc độ động cơ DC tỉ lệ với duty cycle nên tốc độ động cơ đạt tươngđương 80% tốc độ tối đa.

Hình 8: Tính toán duty cycle để điều khiển tốc độ động cơ DC3.1.3 Điều xung PWM dùng vi điều khiển

Điều xung PWM bằng phần mềm:Điều xung PWM một cách đơn giản là đưa 1 chân nào đó của vi điều khiểnlên mức 1, sau đó đưa xuống mức 0. Công việc này được lặp đi lặp lại liêntục sẽ tạo ra xung, và tốc độ của động cơ sẽ tương ứng với duty cycle.Ví dụ: Điều xung trên chân A0 :CodeRA0=1;Delay_ms(Ton);RA0=0;Delay_ms(Toff);

Tuy nhiên, nếu thực hiện bằng cách này thì vi điều khiển sẽ luôn dành thờigian cho việc điều xung PWM. Do đó, các công việc khác như nhận tín hiệutừ cảm biến, điều khiển các cơ cấu sẽ bị ảnh hưởng.

Điều xung PWM bằng phần cứngĐể giải quyết vấn đề việc điều xung PWM bằng phần mềm chiếm phần lớnthời gian hoạt động của vi điều khiển, PIC16F877A có hỗ trợ 2 kênh điềuxung bằng phần cứng ở 2 chân C1 (CCP2) và C2(CCP1) sử dụngTIMER2. Nghĩa là, khi ta khai báo điều xung PWM ở một tần số và dutycycle nào đó thì vi điều khiển sẽ thực hiện công việc xuất xung một cáchliên tục và tự động cho đến khi ta thay đổi các giá trị đã khai báo. Khi đó, tacó thể làm các công việc khác một cách dễ dàng mà không phải mất thờigian cho việc duy trì xung PWM.

Các hàm hỗ trợ việc điều xung bằng phần cứng của CCS:Ghi chú: Chỉ đề cập đến các đối số của các hàm được phục vụ cho việc điềuxung PWM.

o setup_timer_2 (mode, period, postscale) mode: T2_DIV_BY_1, T2_DIV_BY_4, T2_DIV_BY_16

period: 0-255postscale: 1

Page 10: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 10/14

Tần số điều xung PWM:1)odmode.(peri.4

oscff

o setup_ccp1(mode) và setup_ccp2(mode) mode:

CCP_PWM: chọn chế độ PWM.CCP_OFF: tắt chế độ PWM.

o set_pwm1_duty(value) và set_pwm2_duty(value) Nếu value là giá trị kiểu int 8bit:

1_

period

valuecycleduty

Nếu value là giá trị long int 16bit:

)1(*4

1023&_

period

valuecycleduty

Nếu không cần điều xung quá “mịn” thì nên điều xung ở giátrị value 8bit cho đơn giản.

Ví dụ: Ta muốn điều xung PWM với tần số 10kHz với tần số thạch anh(fosc) sử dụng là 20MHz (value 8bit).

500)1dmode(perio1)odmode.(peri.4

2000000010000

1)odmode.(peri.4

oscf

f

Với mode = [1,4,16] và period = 0-255 ta có thể chọno mode = 4; period = 124o mode = 16; period = 32

Để cho việc điều xung được “mịn” (chọn được nhiều giá trị duty cycle) tachọn mode = 4 và period = 124.Như vậy, để duty_cycle từ 0% đến 100% ta cho value từ 0 đến 125.

o value = 30 %3232.01124

30_

cycleduty

o value = 63 %4,50504.01124

63_

cycleduty

o value = 113 %4,90904.01124

113_

cycleduty

Code: setup_timer_2(T2_DIV_BY_4,124,1); setup_ccp1(CCP_PWM); set_pwm1_duty(30);

Sử dụng CCP1 và CCP2 cho động cơ trái và động cơ phải, ta có thể điềukhiển được tốc độ của 2 động cơ phù hợp trạng thái lệch khỏi vạch trắngcủa robot.

Các chương trình con tham khảo:Để việc lập trình được dễ dàng, ta nên tạo các chương trình con xử lý tốcđộ. Sau đây là chương trình tham khảo của hàm speed.

o Speed (tốc độ động cơ trái, tốc độ động cơ phải) Tốc độ: -100 đến 100 (chạy ngược 100% đến chạy thuận 100%) Ví dụ: speed(80,60) động cơ trái chạy 80%, phải 60%

Page 11: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 11/14

// Các hàm hỗ trợvoid left_motor_forward(int value){ MOTOR_LEFT_DIR=0; setup_timer_2(T2_DIV_BY_4,124,1); // Dieu xung 10kHz setup_ccp2(CCP_PWM); set_pwm2_duty(value);}void right_motor_forward(int value){ MOTOR_RIGHT_DIR=0; setup_timer_2(T2_DIV_BY_4,124,1); // Dieu xung 10kHz setup_ccp1(CCP_PWM); set_pwm1_duty(value);}void left_motor_reverse(int value){ MOTOR_LEFT_DIR=1; setup_timer_2(T2_DIV_BY_4,124,1); // Dieu xung 10kHz setup_ccp2(CCP_PWM); set_pwm2_duty(value);}void right_motor_reverse(int value){ MOTOR_RIGHT_DIR=1; setup_timer_2(T2_DIV_BY_4,124,1); // Dieu xung 10kHz setup_ccp1(CCP_PWM); set_pwm1_duty(value);}void left_motor_stop(){ setup_ccp1(CCP_OFF);}void right_motor_stop(){ setup_ccp1(CCP_OFF);}// Chương trình xử lý tốc độ 2 động cơ// 0:Stop,100:FORWARD 100%,-100:Reverse 100%void speed (signed int left_motor_speed, signed int right_motor_speed){ int left_pwm_value=0,right_pwm_value=0; /* Left motor */ if( left_motor_speed >= 0 ) { left_pwm_value = 1.25*left_motor_speed; // (125*left_motor_speed/100) left_motor_forward(left_pwm_value); } else { left_motor_speed = -left_motor_speed; left_pwm_value = 1.25*left_motor_speed; // (125*left_motor_speed/100) left_motor_reverse(left_pwm_value);

Page 12: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 12/14

} /* Right motor */ if( right_motor_speed >= 0 ) { right_pwm_value = 1.25*right_motor_speed; // (125*left_motor_speed/100) right_motor_forward(right_pwm_value); } else { right_motor_speed = -right_motor_speed; right_pwm_value = 1.25*right_motor_speed; // (125*left_motor_speed/100) right_motor_reverse(right_pwm_value); }}

3.2 Nhận biết vạch ngangTrong quá trình di chuyển của robot, sẽ có các vạch ngang màu trắng. Nhờ cácvạch ngang này, robot biết được mình đang đi đến đâu và sẽ thực hiện côngviệc gì tiếp theo (quay trái, quay phải, nâng hạ trục, gắp nhả quà,…) Một cách đơn giản, khi robot đến vạch trắng, tất cả 8 cảm biến sẽ lên mức 1

ứng với giá trị đọc được của cảm biến là 0b11111111 hay 0xFF. Ta dùngmột biến đếm để biết thứ tự của vạch ngang đang gặp và thực hiện côngviệc mong muốn.Code:int n // đặt n là số vạch ngang đã nhậnif (SENSOR==0xFF){

n++; // tăng giá trị n lên 1 khi gặp vạch ngangswitch (n){case 1: (công việc 1) break;case 2: (công việc 2) break;….case n: (công việc n) break;}

}else (chương trình dò đường)

Tuy nhiên, vì nhiều lý do khác nhau (nhiễu do ánh sáng bên ngoài, các cảmbiến có độ nhạy không đều nhau hoặc robot tiếp cận với vạch ngang khôngtheo phương vuông góc), một vài cảm biến khi tiếp xúc với màu trắngnhưng không nhận biết (vẫn giữ trạng thái mức 0 – màu sậm). Điều này gâykhó khăn cho việc nhận biết vạch ngang. Vì vậy, khi 4/8 cảm biến ở mức 1,ta nhận đó là một vạch ngang để khắc phục các ảnh hưởng này.Code://KIEM TRA VACH NGANG: 1: co vach, 0:khong co vachint check_cross_line(){ int temp_sensor=0,led_in_line=0,i=0; temp_sensor=SENSOR; for (i=0;i<8;i++) {

Page 13: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 13/14

if ((temp_sensor&0x01)==0x01) led_in_line++; if (led_in_line==4) break; temp_sensor=temp_sensor>>1; } if (led_in_line==4) return 1; else return 0;}

Do chương trình nhận vạch ngang được gọi liên tục để kiểm tra có vạchngang xuất hiện hay không nên sẽ dẫn đến tình trạng khi robot đến vạchngang, biến đếm số vạch tăng thêm 1. Sau đó, khi robot chưa kịp chạy quavạch ngang mà hàm kiểm tra được gọi dẫn đến việc biến đếm tăng liên tục.Việc này khiến cho robot thực hiện sai công việc.Hướng giải quyết tình huống này như sau:

o Khi robot gặp vạch ngang: chạy thẳngo Khi hết vạch ngang: biến đếm số vạch tăng thêm 1o Thực hiện công việc tương ứng

Code:while (check_cross_line() == 1) // gặp vạch ngang{

speed(100,100); // chạy thẳng}number_cross_line++; // tăng biến đếm số vạch ngang thêm 1

3.3 Xử lý khi robot lệch hoàn toàn khỏi vạchTrường hợp robot lệch ra khỏi vạch (quay quá mạnh hoặc bị va chạm), giá trịcảm biến đọc được là 0x00, như vậy robot sẽ bị mất phương hướng.Để giải quyết trường hợp này, ta đặt một biến trạng thái là biến toàn cục.Gọi biến này là line_status:

o Line_status=0: giữa vạch;o Line_status=1: lệch trái;o Line_status=2: lệch phải;

Khi đọc giá trị cảm biến để dò đường (tham khảo hình 7), ta gán luôn giá trịcho biến này. Như vậy khi robot lệch hẳn ra khỏi vạch, ta vẫn biết được trạngthái trước đó để biết quay trái hoặc quay phải để hướng robot di chuyển vềphía line.Code

switch (SENSOR){case 0b00000000: // lệch ra hẳn khỏi vạch{

if (line_status==1) // trạng thái cũ là lệch tráiturn_right(); break; // quay phải để di chuyển về phía vạchif (line_status==2) // trạng thái cũ là lệch phảiturn_left(); break; // quay trái để di chuyển về phía vạch

}// Trạng thái lệch thông thườngcase 0b00011000: forward(); line_status=0; break;case 0b00001100: turn_left(); line_status=1; break;

Page 14: Lap Trinh Robot Don Gian Voi PIC 16F877A

Lập trình Robot tự động đơn giản với PIC16F877A Biên soạn: EM-BOT Robot Team

© http://em-bot.tk (Feb 2010) DEMO VERSION Trang 14/14

case 0b00000110: turn_left(); line_status=1; break;case 0b00000011: turn_left(); line_status=1; break;case 0b00000001: turn_left(); line_status=1; break;case 0b00110000: turn_right(); line_status=2 ;break;case 0b01100000: turn_right(); line_status=2 ;break;case 0b11000000: turn_right(); line_status=2 ;break;case 0b10000000: turn_right(); line_status=2 ;break;}

3.4 Ứng dụng encoder3.4.1 Kiến thức cơ bản về encoder

Tham khảo tại diễn đàn PICVietnam:http://www.picvietnam.com/forum/showthread.php?p=1062#post1062Trong Robocon, ta thường sử dụng incremental encoder (encoder tương đối)hay còn gọi là rotary encoder. Mục đích của việc sử dụng encoder trongrobot là đếm số vòng quay để tính số vòng quay của động cơ (bánh xe), từđó suy ra quãng đường di chuyển và tốc độ của robot.

Hình 10: Encoder thường được sử dụng trong Robocon3.4.2 Sử dụng PIC để nhận và đếm xung từ encoder

Để nhận xung từ encoder, ta có thể sử dụng ngắt ngoài, ngắt timer hoặc đơngiản là tham dò mức logic của các chân vi điều khiển một cách liên tục.Phần sau đây giới thiệu cách nhận và đếm xung của PIC16F877A dùng ngắtngoài B0 (nối với kênh A của encoder) và chân B1 (nối với kênh B củaencoder). Ta có thể làm tương tự đối với các cách nhận xung khác.

Khởi tạo ngắt ngoài theo cạnh lên tại chân B0:Code:ext_int_edge(0,L_TO_H); // Ngắt cạnh lên tại RB0enable_interrupts(INT_EXT); // Cho phép ngắt ngoàienable_interrupts(GLOBAL); // Cho phép ngắt toàn cục

Chương trình con phục vụ ngắt:Code:#int_EXTvoid EXT_isr(void) //Chương trình được gọi khi có tác động cạnh lên tại chân B0{ if (RB1==1) pulse++; // Nếu kênh B mức cao thì tăng giá trị xung thêm 1 else pulse--; // Nếu kênh B mức cao thì giảm giá trị xung xuống 1}

Từ giá trị xung tính được tại các thời điểm ta có thể tính ra các thông sốmong muốn.