Lập trình điều khiển động cơ sử dụng Timer/Counter

Một phần của tài liệu Nghiên cứu thiết kế và chế tạo robot cung cấp nguyên vật liệu tự động cho các trạm sản xuất lắp ráp trong nhà máy công nghiệp (Trang 50)

Timer/Counter (T/C) là các module độc lập với CPU. Chức năng chính của các bộ Timer/Counter là định thời và đếm sự kiện. Trên các chip AVR hay Arduino, các bộ Timer/Counter còn có thêm chức năng tạo ra các xung điều rộng PWM (Pulse Width Modulation), ở một số dòng AVR, một số Timer/Counter còn được dùng như các bộ căn chỉnh thời gian trong các ứng dụng thời gian thực. Các bộ Timer/Counter được chia theo độ rộng thanh ghi chứa giá trị định thời hay giá trị đếm của chúng đó là Timer 8 bit và 16 bit. Chế độ hoạt động và phương pháp điều khiển của từng Timer/Counter cũng không hoàn toàn giống nhau. Và ở đề tài này tác giả sử dụng một bộ T/C để đếm xung encoder xác định số vòng quay động cơ từ đó xác định được vị trí của robot, Và 1 bộ T/C để tạo các xung PWM điều khiển các động cơ của robot. Module Arduino Uno có 3 bộ timer và Arduino Mega 2560 có 6 bộ timer. Để có thể sử dụng các T/C này phải hiểu rõ về chúng.

Nguyễn Văn Xô 51

Bảng 2. Bố trí chân PWM trên Arduino

Đối với các T/C 8 bit thì các thanh ghi cũng là các thanh ghi 8 bit. Còn đối với các T/C 16 bit thì cần dùng những cặp thanh ghi 8bit tạo thành 1 thanh ghi 16bit và 2 thanh ghi 8bit này sẽ có tên kết thúc bằng ký tự L(Low) và H(High) trong đó L là thanh ghi chứa 8 bit thấp và H là thanh ghi chứa 8bit cao của giá trị 16 bit mà chúng tạo thành.

• TCNTx(H/L)- là thanh ghi chứa các giá trị vận hành của T/C. Thanh ghi này cho phép đọc và ghi giá trị trực tiếp.

• TIMSK - là thanh ghi cho phép ngắt của tất cả các T/C.

• OCRx(A/B/C) (Ouput Compare Register A, B hoặc C): Trong lúc T/C hoạt động, giá trị thanh ghi TCNTx tăng, giá trị này được liên tục so sánh độc lập với từng thanh ghi OCRx(A/B/C) và việc so sánh gọi là Ouput Compare. Khi giá trị so sánh bằng nhau thì 1 “Match” xảy ra, khi đó một ngắt hoặc 1 sự thay đổi trên chân OCx(A/B/C) xảy ra chính là cách tạo xung PWM.

• ICRx (InputCapture Register): Khi có 1 sự kiện trên chân ICPx, thanh ghi ICRxsẽ “capture” giá trị của thanh ghi đếm TCNTx. Một ngắt có thể xảy ra trong trường hợp này, vì thế Input Capture có thể được dùng để cập nhật giá trị “TOP” của T/Cx.

• TIFR (Timer/Counter Interrupt Flag Register): là thanh ghi cờ nhớ cho tất cả các bộ T/C.

Nguyễn Văn Xô 52

• TCCRxA và TCCRxB (Timer/Counter Control Register): là 2 thanh ghi điều khiển hoạt động của T/C. Tất cả các mode hoạt động của T/C đều được xác định thông qua các bit trong 2 thanh ghi này. Đây không phải là 2 byte cao và thấp của một thanh ghi mà là 2 thanh ghi hoàn toàn độc lập. Các bit trong 2 thanh ghi này bao gồm các bit chọn mode hay chọn dạng sóng (Waveform Generating Mode – WGM), các bit quy định dạng ngõ ra (Compare Output Match – COM), các bit chọn giá trị chia prescaler cho xung nhịp (Clock Select – CS) Cấu trúc của 2 thanh ghi được trình bày như bên dưới:

Bảng 3. Bảng chế độ chọn xung nhịp của bộ timer

Có đến 16 chế độ điều khiển PWM. Để có thể sử dụng các chế độ này cần hiểu một số định nghĩa quan trọng:

BOTTOM: là giá trị thấp nhất mà một T/C có thể đạt được, giá trị này luôn là 0. MAX: là giá trị lớn nhất mà một T/C có thể đạt được, giá trị này được quy định bởi bởi giá trị lớn nhất mà thanh ghi đếm của T/C có thể chứa được. Đối một bộ T/C 8 bit thì giá trị MAX luôn là 0xFF tức 255 trong hệ thập phân, và với bộ T/C 16 bit thì MAX bằng 0xFFFF (65535)

TOP: là giá trị mà khi T/C đạt đến nó sẽ thay đổi trạng thái, giá trị này không nhất thiết là số lớn nhất 8 bit hay 16 bit như MAX, giá trị của TOP có thể thay đổi

Nguyễn Văn Xô 53

bằng cách điều khiển các bit điều khiển tương ứng hoặc có thể nhập trừ tiếp thông qua một số thanh ghi.

Bảng 4. Các chế độ điều khiển PWM

Về chế độ hoạt động: Chế độ hoạt động đơn giản nhất của T/C là chế độ thường. Ở chế độ này thanh ghi đếm TCNTx đếm tăng từ Bottom đến Top rồi quay về 0 nhưng không phát sinh xung PWM trên các chân. Chế độ thứ 2 là Fast PWM. Trong chế độ Fast PWM, 1 chu kỳ được tính trong 1 lần TCNTx đếm từ BOTTOM lên TOP rồi được reset về 0 và sẽ có 1 xung tín hiệu được sinh ra nên còn được gọi là 1 sườn – singleslope, vì thế mà chế độ này gọi là Fast PWM (PWM nhanh). Chế độ tiếp theo là Phase Correc, ở chế độ này TCNTx đếm tăng từ 0 đến TOP sau đó không reset mà đếm giảm về 0 nên nó có 2 sườn lên và xuống. Vì vậy người ta còn gọi Phase Correct là dual slope, tín hiệu này có tính đối xứng và thích hợp cho các ứng dụng điều khiển động cơ. Chính vì thế ở đề tài này tác giả sử dụng phương pháp này để lập trình điều khiển các động cơ robot.

Nguyễn Văn Xô 54

Hình 3.9. Chế độ Fast PWM và Phase Correct PWM.

Việc cài đặt sử dụng các chế độ này thì ta phải sử dụng các lệnh setup các bit trong thanh ghi TCCRx theo như các giá trị ở bảng 5. Như đã nói ở trên Arduino có tới 6 bộ T/C. Giả sử ở đây sử dụng timer 2 thì việc setup có thể sử dụng :

TCCR2A=_BV(COM2A1)|_BV(COM2A0) | _BV(COM2B1) | _BV(WGM20); TCCR2B = _BV(CS22) | _BV(CS20);

Xung clock cài đặt ở đây sẽ bằng nguồn xung clock bên trong của Arduino chia cho 1024. Tín hiệu PWM output trên 2 kênh A và B (chân 9 và chân 10 của Arduino) là tín hiệu Phase correct 8 bit.

Sau khi thực hiện các khai báo này thì ta có thể dễ dàng điều chỉnh độ rộng

xung để thay đổi tốc độ động cơ bằng lệnh: analogWrite(pin,tocdo); với pin ở đây là

chân PWM và ‘tocdo’ ở đây là độ rộng xung điều chỉnh. Vì là chế độ phase correct 8 bit nên ‘tocdo’ sẽ có giá trị từ 0-255

Như vậy ta đã có thể điều khiển được tốc độ động cơ. Vấn đề còn lại là phản hồi lại tốc độ hoặc số vòng quay về cho vi xử lý. Từ đó ta có thể xác định được tốc độ, quãng đường di chuyển hay vị trí robot. Như đã nói ở trên tác giả sử dụng đếm tín hiệu từ các encoder của chính động cơ servo-DC. Phương pháp đếm có thể là:

Dùng Input Capture: một số bộ timer-counter trên Arduino có chức năng Input capture, mỗi khi có một tín hiệu thay đổi trên chân Input Capture Pin(ICP), giá trị thời gian của timer được tự động gán cho thanh ghi Input Capture Register(ICR). So sánh giá trị thanh ghi ICR trong 2 lần liên tiếp sẽ đọc được chu kỳ của tín hiệu kích chân ICP. Từ đó suy ra tần số tín hiệu. Nếu một kênh của encoder được nối với chân ICP thì chúng ta có thể đo được tần số tín hiệu của kênh này, từ đó ta sẽ tính được vận tốc của động cơ, ta có thể dùng ngắt Input capture và khi ngắt xảy ra, để biết được góc quay motor, cũng có thể xác định được hướng quay thông qua xác định mức kênh B trong trình phục vụ ngắt input capture.

Nguyễn Văn Xô 55

Dùng chức năng counter: đặt các kênh của encoder vào các chân đếm của các bộ timer chúng ta sẽ đếm được số lượng xung của các kênh. Đây là phương pháp sử dụng đơn giản nhất tốn ít thời gian xử lý. Nhưng có nhược điểm là không xác định được chiều quay, và không ổn định khi vận tốc động cơ có sự thay đổi lớn. (adsbygoogle = window.adsbygoogle || []).push({});

Cuối cùng là sử dụng ngắt ngoài: đây là phương pháp dễ nhưng chính xác để đọc encoder. Nối kênh A của encoder với 1 ngắt ngoài và kênh B với một chân nào đó bất kỳ không phải chân ngắt. Cứ mỗi lần ngắt ngoài xảy ra, tức có 1 xung xuất hiện trên ở kênh A thì trình phục vụ ngắt ngoài tự động được gọi. Trong trình phục vụ ngắt này chúng ta kiểm tra mức của kênh B, tùy theo mức của kênh B chúng ta sẽ tăng biến đếm xung lên 1 hoặc giảm đi 1, từ đó xác định được chiều quay của động cơ. Ở đề tài này tác giả sử dụng phương pháp này để đếm số vòng và chiều quay của động cơ. Trên Arduino Mega 2560 có tới 6 ngắt ngoài có thể sử dụng.

Board int.0 int.1 int.2 int.3 int.4 int.5 Uno, Ethernet 2 3

Mega2560 2 3 21 20 19 18

Leonardo 3 2 0 1 7

Bảng 5. Ngắt ngoài trên Arduino.

Trong đó ngắt 0 trên chân số 2 được sử dụng để ngắt truyền nhận tín hiệu nRF24L01+; ngắt số 2 và 3 trên chân 21 và 20 đồng thời là chân giao tiếp I2C. Vì vậy ta có thể sử dụng các ngắt 1,4,5 trên các chân 3,18,19 của Arduino Mega 2560. Với Arduino việc sử dụng ngắt vô cùng đơn giản, chỉ cần gọi hàm khai báo sử dụng ngắt

trong phần setup(): attachInterrupt(number,HamNgat,mode); Với các thông số number là số thứ tự của ngắt(0-5), HamNgat là chương trình sẽ được gọi khi có sự kiện ngắt xảy ra. Mode là kiểu kích hoạt ngắt. Đối với encoder thì trạng thái chân A và

B sẽ liên tục thay đổi trạng thái. Ta có thể sử dụng FALLING hoặc RISING. Còn đối với module nRF24L01 thì chân tín hiệu ngắt IRQ là chân có tín hiệu tích cực mức thấp. Tức là bình thường chân này ở mức cao. Khi có yêu cầu chuyển hoặc nhận dữ liệu thì chân IRQ sẽ chuyển trạng thái xuống mức thấp yêu cầu vi điều khiển ngắt để

Nguyễn Văn Xô 56 3.2.5 Lập trình giao tiếp ngoại vi để điều khiển robot.

a. Serial.

Đây là chuẩn giao tiếp nối tiếp được dùng rất phổ biến trên các bo mạch Arduino. Mỗi bo có trang bị một số cổng Serial cứng. Bên cạnh đó, tất cả các cổng digital còn lại đều có thể thực hiện giao tiếp nối tiếp bằng phần mềm theo thư viện chuẩn, người dùng không cần phải viết code đây chính là điểm rất mạnh của module arduino. Mức tín hiệu của các cổng này là TTL 5V. Lưu ý cổng nối tiếp RS-232 trên các thiết bị hoặc PC có mức tín hiệu là UART 12V. Để giao tiếp được giữa hai mức tín hiệu, cần phải có bộ chuyển mức, ví dụ như chip MAX232. Số lượng cổng Serial cứng của Atmega328 là 1 và của Atmega2560 là 4. Với tính năng giao tiếp nối tiếp, các bo Arduino có thể giao tiếp được với rất nhiều thiết bị như PC, touchscreen, các game console…

b. USB

Các bo Arduino tiêu chuẩn đều có trang bị một cổng USB để thực hiện kết nối với máy tính dùng cho việc tải chương trình. Tuy nhiên các chip AVR không có cổng USB, do đó các bo Ardunino phải trang bị thêm phần chuyển đổi từ USB thành tín hiệu UART. Do đó máy tính nhận diện cổng USB này là cổng COM chứ không phải là cổng USB tiêu chuẩn.Vì vậy ta sử dụng cổng này giao tiếp với máy tính như cổng Serial thông thường.

Trong đề tài này tác giả sử dụng cổng này vừa để kết nối máy tính dùng cho việc tải chương trình vừa truyền dữ liệu giao tiếp giữa robot và hệ thống điều khiển trên máy tính. Để sử dụng cổng serial này truyền nhận dữ liệu với chương trình điều khiển trên máy tính tác giả sử dụng thư viện Serial có sẵn trong chương trình Arduino IDE. Muốn sử dụng ta phải thực hiện việc setup tốc độ baud rates (số bit truyền nhận

trên 1 giây) bằng hàm Serial.begin(speed). Thông số speed ở đây chính là tốc độ baud

rates và có thể là 1 trong các số sau: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 hoặc 115200.

Sau đi đã khai báo, ta có thể sử dụng cổng này một cách đơn giản: Khi cần gửi

dữ liệu ta chỉ cần gọi hàm Serial.print(biến, định dạng) trong đó ‘biến’ ở đây là bất kỳ định dạng nào còn ‘định dạng’ thì có thể có hoặc không, nó là các dạng BIN, HEX, DEC,… Khi nào cần đọc dữ liệu thì sử dụng hàm Serial.read(). Hàm này đọc từng ký

Nguyễn Văn Xô 57

tự trong bộ nhớ đệm của serial. Nếu muốn đọc hết phải sử dụng kết hợp với các vòng

lặp với điều kiện là hàm Serial.available() hàm này trả về số byte còn lại trong bộ

đệm.

c. SPI(Serial Peripheral Bus)

Đây là một chuẩn truyền thông nối tiếp đồng bộ tốc độ cao có bus gồm có 4 dây do hãng Motorola đề xuất. Với tính năng này các bo Arduino có thể kết nối với các thiết bị như LCD, bộ điều khiển video game, bộ điều khiển cảm biến các loại, đọc thẻ nhớ. Ở đề tài này tác giả sử dụng chuẩn giao tiếp này để giao tiếp giữa các robot và hệ thống điều khiển. Tác giả sẽ trình bày rõ hơn về chuẩn giao tiếp này và cách điều khiển module nRF24L01+.

Đây là kiểu truyền thông Master-Slave, trong đó có 1 chip Master điều phối quá trình tuyền thông với các chip Slave. SPI là một cách truyền song công (full duplex) nghĩa là tại cùng một thời điểm quá trình truyền và nhận có thể xảy ra đồng thời. SPI đôi khi được gọi là chuẩn truyền thông “4 dây” vì có 4 đường giao tiếp trong chuẩn này đó là:

SCK: Xung giữ nhịp cho giao tiếp SPI, vì SPI là chuẩn truyền đồng bộ nên cần 1 đường giữ nhịp, mỗi nhịp trên chân SCK báo 1 bit dữ liệu đến hoặc đi. Đây là điểm khác biệt với truyền thông không đồng bộ mà chúng ta đã biết trong chuẩn UART. Sự tồn tại của chân SCK giúp quá trình tuyền ít bị lỗi và vì thế tốc độ truyền của SPI có thể đạt rất cao. Xung nhịp chỉ được tạo ra bởi chip Master.

MISO_Master Input / Slave Output: Đây là đường chip Slave truyền dữ liệu cho chip Master.

MOSI_Master Output / Slave Input: Đây là đường chip Master truyền dữ liệu cho chip Slave.

SS_Slave Select: SS là đường chọn Slave cần giap tiếp, trên các chip Slave đường SS sẽ ở mức cao khi không làm việc. Nếu chip Master kéo đường SS của một Slave nào đó xuống mức thấp thì việc giao tiếp sẽ xảy ra giữa Master và Slave đó. Chỉ có 1 đường SS trên mỗi Slave nhưng có thể có nhiều đường điều khiển SS trên Master, tùy thuộc vào thiết kế của người dùng.

Nguyễn Văn Xô 58 (adsbygoogle = window.adsbygoogle || []).push({});

Hoạt động: mỗi chip Master hay Slave có một thanh ghi dữ liệu 8 bits. Cứ mỗi xung nhịp do Master tạo ra trên đường giữ nhịp SCK, một bit trong thanh ghi dữ liệu của Master được truyền qua Slave trên đường MOSI, đồng thời một bit trong thanh ghi dữ liệu của chip Slave cũng được truyền qua Master trên đường MISO.

Module SPI trong các arduino hầu như hoàn toàn giống với chuẩn SPI mô tả ở trên.Các chân SPI của arduino:

Arduino Board MOSI MISO SCK SS

Uno 11 12 13 10

Mega 51 50 52 53

Điểm mạnh của module arduino là ta có thể sử dụng các thư viện có sẵn để có thể dễ dàng lập trình điều khiển ngoại vi. Đối với chuẩn giao tiếp SPI cũng vậy, có thể sử dụng thư viện SPI có sẵn để lập trình điều khiển các thiết bị ngoại vi.

Để điều khiển thiết bị qua SPI thì cần xác định các thông số:

- Tốc độ truyền dữ liệu lớn nhất của thiết bị cần giao tiếp với arduino; Arduino sẽ tự động sử dụng tốc độ tốt nhất trong quá trình truyền dữ liệu. Tốc độ này bằng hoặc nhỏ hơn tốc độ cài đặt trong thông số đầu tiên của hàm SPISettings.

- Trong quá trình truyền dữ liệu thì bít có trọng số cao nhất(MSB) hay bít có trọng số thấp nhất(LSB) sẽ được truyền trước; điều này được thiết lập bởi thông số thứ 2 trong hàm SPISetting. Hầu hết chíp SPI sử dụng phương pháp truyền MSB trước.

- Dạng xung clock điều khiển truyền dữ liệu. Điều này được thiết lập bởi thông số thứ 3 trong hàm SPISetting. SPI có 4 chế độ truyền dữ liệu: SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3. Các chế độ này điều khiển dữ liệu được

Một phần của tài liệu Nghiên cứu thiết kế và chế tạo robot cung cấp nguyên vật liệu tự động cho các trạm sản xuất lắp ráp trong nhà máy công nghiệp (Trang 50)