* Giới thiệu: Chuẩn giao tiếp truyền thông nối tiếp UART trên Arduino (hay còn được biết đến với tên gọi Serial) là chuẩn giao tiếp được sử dụng rất nhiều trong các ứng dụng hệ thống nhúng. Trong bài viết này sẽ hướng dẫn tiếp cận và lập trình với giao tiếp UART một cách đơn giản nhất
*Mục tiêu: Sau khi học xong bài học này, người học có khả năng:
- Trình bày được chức năng, nguyên lý hoạt động của giao tiếp UART trong Arduino
-Vẽ được sơ đồ nguyên lý mạch giao tiếp UART
- Mô phỏng được chương trình mạch giao tiếp UART bằng phần mềm mô phỏng
- Kết nối được phần cứng mạch giao tiếp UART đúng yêu cầu kỹ thuật.
- Viết, nạp và chạy được chương trình giao tiếp UART .
- Rèn luyện tính tư duy và tác phong công nghiệp , đảm bảo an toàn cho người và thiết bị
*Nội dung:
154 trang |
Chia sẻ: Tiểu Khải Minh | Ngày: 23/02/2024 | Lượt xem: 59 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Giáo trình mô đun Vi điều khiển (Trình độ: Cao đẳng) - Trường Cao đẳng Nghề Kỹ thuật Công nghệ Bà Rịa Vũng Tàu, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
trong Arduino
- Vẽ đƣợc sơ đồ nguyên lý mạch Led 7 đoạn sử sụng ngắt timer
- Mô phỏng đƣợc chƣơng trình mạch Led 7 đoạn sử sụng ngắt timer bằng
phần mềm mô phỏng
- Kết nối đƣợc phần cứng mạch Led 7 đoạn sử sụng ngắt timer đúng yêu cầu
kỹ thuật.
-Viết, nạp và chạy đƣợc chƣơng trình Led 7 đoạn sử sụng ngắt timer
Arduino
*Nội dung:
1. Giới thiệu bộ timer- counter
Trên chip Atmega328p của Arduino có 3 bộ Timer/Counter là:
Timer/Counter0 (8bit), Timer/Counter1 (16 bit), Timer/Counter2 (8 bit).
Để không làm ảnh hƣởng đến hàm delay() và millis() của Arduino, mình sẽ không
đề cập đến Timer/Counter0.
Nhƣ đã giới thiệu, Timer/Count có chức năng: Đếm sự kiện, Định thời và tạo
xung PWM, để giữ mọi thứ đơn giản, trong bài này chỉ giới thiệu chức năng cơ bản
của Timer/Counter khi lập trình trên Arduino là "Định thời" (Arduino đã hỗ trợ
hàm built-in analogWrite để tạo xung PWM nên chúng ta cũng không đề cập đến
nữa).
Timer/Counter1: là 1 bộ Timer/Counter đa năng 16 bit, gồm 5 chế độ hoạt
động.
Timer/Counter2: là 1 bộ Timer/Counter 8 bit, gồm 4 chế độ.
Trong pham vi bài viết mình sẽ giới thiệu Normal Mode và Clear Timer on
Compare Match (CTC) mode trên Timer/Counter1 và Timer/Counter2.Để thuận
tiện viết tắt Timer/Counter thành T/C.
Trƣớc khi bắt đầu, có 1 số định nghĩa quan trong chúng ta cần rõ:
BOTTOM: là giá trị thấp nhất mà 1 T/C đạt đƣợc, tất nhiên BOTTOM luôn bằng
0.
107
MAX: là giá trị lớn nhất mà 1 T/C có thể đạt đƣợc, ở thanh ghi 8 bit giá trị MAX =
2^8 -1 = 255, ở thanh ghi 16 bit giá trị MAX = 2^16 - 1 = 65535. Và tất nhiên giá
trị MAX cũng là cố định với từng T/C.
TOP: là giá trị đỉnh mà tại có T/C thay đổi trạng thái, giá trị TOP không nhất thiết
phải bằng MAX mà có thể thay đổi bằng các thanh ghi. Chúng ta sẽ tìm hiểu sau.
Interrupt: (còn gọi là Ngắt) là 1 chƣơng trình có độ ƣu tiên cao nhất, đƣợc thực
hiện ngay lập tức khi có tín hiệu Interrupt.
Bảng 10.1: Interrupt Vectors của Timer/Counter trên ATmega328
1.1. Timer/Counter 1
1.1.1 Giới thiệu các thanh ghi
* Thanh ghi TCNT1 (Timer/Counter 1 Register)
Là thanh ghi 16 bit, lƣu giữ giá trị của Timer/Counter1, cho phép đọc-ghi trực tiếp,
do đó, chúng ta có thể thực hiện các phép gán hoặc thay đổi giá trị của TCNT1.
* Thanh ghi TCCR1B (Timer/Counter 1 Control Register B)
Là 1 trong 2 thanh ghi điều khiển hoạt đông của Timer/Counter1 (cùng
với TCCR1A, nhƣng với những mục đích đơn giản, chúng ta chỉ cần thanh
ghi TCCR1B).
108
Bảng 10.2: Thanh ghi TCCR1B
Trong thanh ghi TCCR1B chúng ta chỉ cần sử dụng 3 bit CS10, CS11, CS12 để
lựa chọn xung nhịp cho T/C1. Chúng ta sẽ tham khảo bảng này:
Bảng10. 3: Mô tả Clock Select Bit trên thanh ghi TCCR1B
Theo mặc định, chip Atmega328p trên Arduino chạy ở 16MHz, prescaler = 64.
Điều này có nghĩa là: theo mặc định, các bộ T/C trên Arduino sẽ có tần số hoạt
động là 16MHz/64 = 250kHz.
* Thanh ghiTIMSK1 (Timer/Counter1 Interrupt Mask Register)
Là thanh ghi lƣu giữ các Interrupt Mask của T/C1. Đây là thanh ghi giúp chúng ta
thực hiện các Timer Interrupt. Trên thanh ghi TIMSK1 chúng ta cần chú ý các bit
sau:
109
Bảng10. 4: Thanh ghi TIMSK1 (Timer/Counter1)
bit 5 - ICIE1: Input Capture Interrupt Enable - Cho phép ngắt khi dùng Input
Capture.
bit 2 - OCIE1B: Output Compare Interrupt Enable 1 channel B - Cho phép ngắt
khi dùng Output Compare ở channel B.
bit 1 - OCIE1A: Output Compare Interrupt Enable 1 channel A - Cho phép ngắt
khi dùng Output Compare ở channel A.
bit 0 - TOIE1: Overflow Interrupt Enable 1 - Cho phép ngắt khi xảy ra tràn trên
T/C.
(Cáctacứ bình tĩnh, những cái nhƣ Output Compare, Input Capture, Overflow mình
sẽ giới thiệu ở bên dƣới).
* Thanh ghi OCR1A và OCR1B (Output Compare Register channel A và channel
B)
Lƣu giữ giá trị so sánh ở kênh A và kênh B: khi T/C1 hoạt động, giá trị TCNT1
đƣợc tăng dần, giá trị này liên tục đƣợc so sánh với các giá trị trong thanh ghi
OCR1A và OCR1B, việc so sánh này chính là "Output Compare", khi giá trị của
TCNT1 bằng giá trị của OCR1A (hoặc OCR1B) thì "Match" xảy ra, lúc này sẽ có 1
Interrupt đƣợc thực hiện ( nếu đã đƣợc Enable ở thanh ghi TIMSK1).
* Thanh ghi ICR1 (Input Capture Register 1)
Giá trị của thanh ghi ICR1 sẽ đƣợc cập nhật theo thanh ghi TCNT1 mỗi lần có sự
kiện xảy ra trên chân ICP1 (tƣơng ứng là chân digital 8 của Arduino). Chức năng
này mình sẽ giới thiệu trong 1 bài viết khác.
1.1.2 Các chế độ của Timer/Counter 1
110
Bảng 10.5: Waveform Generation Mode Bit (Timer/Counter1)
ở đây sẽ giới thiệu 2 mode cơ bản nhất của T/C1 là: Normal Mode và CTC Mode.
*Normal Mode
Đây là chế độ hoạt động đơn giản nhất của T/C1 (mode 0), giá trị của thanh ghi
TCNT1 sẽ tăng từ 0 (BOTTOM) đến 65535 (MAX) và quay về 0. Nếu chúng ta
gán trƣớc cho TCNT1 một giá trị nào đó thì TCNT1 sẽ bắt đầu đếm từ giá trị này.
Ví dụ:tamuốn viết 1 chƣơng trình để đọc dữ liệu từ cảm biến nhiệt mỗi 0.1s, nhƣng
trong thân chƣơng trình lại có vài hàm delay(), do đó sẽ không đảm bảo làtacập
nhật đƣợc giá trị nhiệt độ mỗi 0.1s nếu chỉ dùng hàm if và hàm millis(). Phƣơng án
ở đây là chúng ta sẽ dùng Interrupt của Timer/Counter.
Theo mặc định, chip Atmega328p trên Arduino chạy ở 16MHz, prescaler = 64, vì
vậy thời gian để TCNT1 tăng lên 1 đơn vị là 64/16MHz = 4us, thời gian để T/C1
đếm từ 0 đến 65535 là 4us*65536 = 0.262144s, mà thời gian chúng ta cần tạo là
0.1s (thỏa mãn vì 0.1 < 0.262144), do đó ta cần 0.1s/4us = 25000 lần đếm. Giá trị
ban đầu của TCNT1 = 65536 - 25000 = 40536.
Ví dụ ở chế độ Normal Mode:
#include
#define sensor A0
volatile int temp;
void setup()
{
Serial.begin(9600)
cli(); // tắt ngắt toàn cụ
111
/* Reset Timer/Counter1 *
TCCR1A = 0
TCCR1B = 0
TIMSK1 = 0
/* Setup Timer/Counter1 *
TCCR1B |= (1 << CS11) | (1 << CS10); // prescale = 6
TCNT1 = 40536
TIMSK1 = (1 << TOIE1); // Overflow interrupt enable
sei(); // cho phép ngắt toàn cụ
}
void loop()
{
/* add main program code here *
}
ISR (TIMER1_OVF_vect)
{
TCNT1 = 40536
temp = analogRead(sensor)
Serial.print(F("Temp:"))
Serial.println(temp)
}
Giải thích
- #include là thƣ viện Interrupt của AVR.
- Biến temp cần đƣợc khai báo volatile vì nó đƣợc sử dụng cả ở chƣơng trình chính
và ở chƣơng trình ngắt.
- cli() dùng để tắt ngắt toàn cục.
- Tham khảo bảng Waveform Generation Mode Bit, chúng ta thấy rằng để cài đặt
T/C1 ở mode 0, các bit cần đƣợc set nhƣ sau: WGM13 = 0, WGM12 = 0, WGM11
= 0, WGM10 = 0, vì mặc định các bit này là 0 nên chúng ta không cần quan tâm
đến nó ở thanh ghi TCCR1B nữa.
- TCCR1B |= (1 << CS11) | (1 << CS10) đƣợc dùng để cài đặt prescaler = 64.
(tham khảo bảng Clock Select Bit).
- sei() dùng để bật ngắt toàn cục.
các biểu thức nhƣ (1 << CS11) đƣợc dùng để set bit CS11 lên 1.
112
- ISR (Vector_name) là các trình phục vụ ngắt, trong đó ISR là keyword,
Vector_name ở chƣơng trình này là TIMER1_OVF_vect, có nghĩa là "Ngắt tràn trên
Timer/Counter1".
Ở trong trình phục vụ ngắt, chúng ta cần gán lại giá trị ban đầu cho TCNT1 =
40536 vì lúc này T/C1 đã đếm tràn qua 65535 và về lại 0. Nếu không gán lại
TCNT1 = 40536, chúng ta sẽ không tạo đƣợc 0.1s nhƣ mong muốn.
* Clear Timer on Compare Match (CTC) mode
Có 2 CTC mode trên T/C1 là mode 4 và mode 12
- Đầu tiên ta sẽ giới thiệu mode 4 trƣớc. Để chọn mode 4, chúng ta cần set các bit
nhƣ sau: WGM13 = 0, WGM12 = 1, WGM11 = 0, WGM10 = 0.
- CTC mode hoạt động nhƣ sau: thanh ghi OCR1A lƣu giữ giá trị TOP, thanh ghi
TCNT1 bắt đầu đếm từ 0, khi giá trị TCNT1 = OCR1A thì "Compare Match", lúc
này ngắt Compare Match có thể xảy ra nếu bit OCIE1A đã đƣợc set ở thanh ghi
TIMSK1.
Chú ý: là chỉ có thanh ghi OCR1A được sử dụng để lưu giá trị COMPARE trong
CTC mode Trở lại VD ở Normal Mode, mình sẽ thực hiện với CTC Mode nhƣ sau:
- Vi dụ:
#include
#define sensor A0
volatile int temp;
void setup()
{
Serial.begin(9600)
cli(); // tắt ngắt toàn cục
/* Reset Timer/Counter1 *
TCCR1A = 0
TCCR1B = 0
TIMSK1 = 0
/* Setup Timer/Counter1 *
TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); // prescale = 64 and
CTC mode
OCR1A = 24999; // initialize OCR1
TIMSK1 = (1 << OCIE1A); // Output Compare Interrupt Enable
Timer/Counter1 channel
sei(); // cho phép ngắt toàn cục
}
113
void loop()
{
/* add main program code here *
}
ISR (TIMER1_COMPA_vect)
{
temp = analogRead(sensor)
Serial.print(F("Temp:"))
Serial.println(temp)
}
Giải thích
Để chọn mode 4, trong phần cài đặt cho thanh ghi TCCR1B ta cần set bit WGM12
lên 1, tức là (1 << WMG12).
Để tạo đƣợc 0.1s (ở 16MHz, prescaler = 64) ta cần T/C1 đếm 25000 lần, do đó giá
trị TOP = OCR1A = 24999.
Để enable Compare Match Interrupt Timer/Counter 1 channel A, chúng ta cần set
bit OCIE1A của thanh ghi TIMSK1 lên 1.
Ở phần hàm ngắt, ta thay đổi thành ISR (TIMER1_COMPA_vect) cho phù hợp với
Compare Match Interrupt T/C1
1.2. Timer/Counter 2
1.2.1. Các thanh ghi
Trên T/C2 cũng có những thanh ghi tƣơng tự T/C1
1.2.2. Thanh ghi TCNT2 (Timer/Counter 2 Register)
Là thanh ghi 8 bit, lƣu giữ giá trị của Timer/Counter2.
1.2.3. Thanh ghi TCCR2A và TCCR2B (Timer/Counter 2 Control Register A và
B) Là 2 thanh ghi điều khiển hoạt động của Timer/Counter2.
Bảng 10.6: Thanh ghi TCCR2A và TCCR2B (Timer/Counter 2)
114
Bảng10.7: Mô tả Clock Select Bit
1.2.4. Thanh ghi TIMSK2 (Timer/Counter2 Interrupt Mask Register)
Là thanh ghi lƣu giữ các Interrupt Mask của T/C2.
Bảng 10.8: Thanh ghi TIMSK2 (Timer/Counter 2)
1.2.5 Thanh ghi OCR2A và OCR2B (Output Compare Register channel A và
channel B)
Lƣu giữ giá trị so sánh ở kênh A và kênh B khi T/C2 hoạt động.
Bảng10. 9: Lưu giữ giá trị so sánh ở kênh A và kênh B khi T/C2 hoạt động.
1.2.6 Các chế độ hoạt động
115
Theo bảng Waveform Generation Mode bit, T/C2 có Normal Mode
0 và CTC mode 2.
Để không trùng lặp nội dụng với T/C1, mình chỉ giới thiệu cách set thanh ghi trong
T/C2.
Ở Normal Mode, cáctachỉ cần set các bit CS20, CS21, CS22 trong thanh ghi
TCCR2B để chọn prescaler.
Ở CTC Mode: ngoài set các bit trong thanh ghi TCCR2B để chọn prescaler,
cáctacần set bit WGM21 lên 1 bằng dòng: TCCR2A |= (1 << WGM21);
Cách set thanh ghi TIMSK2 tƣơng tự nhƣ TIMSK1: OCIE2A (Output Compare
Interrupt Enable 2 Channel A), OCIE2B, TOIE2 (Timer Overflow Interrupt 2
Enable).
2.Phần cứng
Muốn đặt ngắt, ta phải đặt lệnh trong hàm setup(){}.
Thƣ viện đính kèm gồm có thƣ viện timer cho Timer 1, Timer 3. Ta copy vào thƣ
mục thƣ viện của Arduino IDE.
Gồm có các hàm:
initialize(): // Khởi động ngắt Timer.
start() : // Khởi động lại sau khi sửa đổi.
startBottom() : // Cho Timer bắt đầu đếm lại từ giá trị 0 (Chú ý đây là giá
trị đếm của Timer chứ không phải giá trịtađặt).
read() : // Đọc giá trị hiện tại của Timer
stop(): //Dừng Timer.
attachInterrupt(): // Thêm địa chỉ hàm để gọi khi xảy ra ngăt và bắt đầu
đếm.
detachInterrupt(): // Hủy địa chỉ ngắt
pwm(char pin, int duty, long microseconds) : // Băm xung ra chân pin với số
chu kỳ là duty. Xung có độ rộng là microseconds.
disablePwm(char pin) : //Hủy băm xung.
3. Lập trình và giải thích
Ví dụ: nháy LED 0.15s
// Ví dụ này dùng ngắt Timer để nháy LED
// và sử dụng biến chia sẻ giữa hàm ngắt và chƣơng trình chính
const int led = LED_BUILTIN; // định nghĩa chân LED, Biến LED_BUILTIN
dùng để chỉ LED đƣợc gắn trên Board mạch.Ví dụ với Arduino UNO thì
LED_BUILTIN=13.
116
void setup(void)
{
pinMode(led, OUTPUT);
Timer1.initialize(150000); //Khởi động ngắt, thời gian đặt cho nó là
150000us=0.15s.
Timer1.attachInterrupt(blinkLED); //Khi xảy ra ngắt chƣơng trình sẽ gọi hàm
blinkLED().
Serial.begin(9600);
}
int ledState = LOW;
volatile unsigned long blinkCount = 0; // Biến dùng chung giữa CT chính và CT
ngắt.
void blinkLED(void)
{
if (ledState == LOW) {
ledState = HIGH;
blinkCount = blinkCount + 1; // tăng lên 1 mỗi lần LED sáng
} else {
ledState = LOW;
}
digitalWrite(led, ledState);
}
// Xuất số lần sáng ra Serial0.
// to the Arduino Serial Monitor
void loop(void)
{
unsigned long blinkCopy;
noInterrupts(); //Hủy các ngắt trƣớc đó.
blinkCopy = blinkCount;
interrupts(); //Cho phép ngắt
Serial.print(blinkCount = );
Serial.println(blinkCopy);
delay(100); }
Câu hỏi ôn tập
Câu 1: Thế nào là timer – counter?
Câu 2: Viết chƣơng trình điều khiển led sáng 5 giây rồi tắt ?
117
BÀI 12: PWM -ĐIỀU CHỈNH ĐỘ SÁNG CỦA BÓNG ĐÈN
* Giới thiệu: Điều chỉnh độ rộng xung là điều chế / thay đổi chiều rộng của xung
(Không phải là tần số). Để hiểu rõ nhất PWM là gì, đầu tiên chúng ta hãy xem một
số thuật ngữ cơ bản.
Vi điều khiển là các thành phần kỹ thuật số thông minh hoạt động trên các tín hiệu
nhị phân. Biểu diễn của một tín hiệu nhị phân là một dải sóng vuông. Sơ đồ dƣới
đây giải thích các thuật ngữ cơ bản liên quan đến tín hiệu sóng vuông.
Nhƣ đã trình bày trong sơ đồ trên, điều quan trọng cần lƣu ý trong tín hiệu PWM là
thời gian, tần số luôn luôn cố định. Chỉ có thời gian ON và OFF của xung (chu kỳ
làm việc) thay đổi. Bằng kỹ thuật này, chúng ta có thể điều chỉnh điện áp cho trƣớc.
Sự khác biệt giữa tín hiệu sóng vuông và tín hiệu PWM là tín hiệu sóng vuông có
cùng thời gian ON và OFF (chu kỳ làm việc đều là 50%), trong khi một tín hiệu
PWM có chu kỳ biến đổi. Các sóng vuông có thể đƣợc xem là một trƣờng hợp đặc
biệt của tín hiệu PWM có chu kỳ làm việc 50% (ON = OFF).
*Mục tiêu: Sau khi học xong bài học này, ngƣời học có khả năng:
- Trình bày đƣợc chức năng, nguyên lý hoạt động của điều chế xung PWM
trong Arduino.
- Vẽ đƣợc sơ đồ nguyên lý mạch điều chỉnh độ sáng của bóng đèn
- Mô phỏng đƣợc chƣơng trình mạch điều chỉnh độ sáng của bóng đèn bằng
phần mềm mô phỏng
- Kết nối đƣợc phần cứng mạch điều chỉnh độ sáng của bóng đèn đúng yêu
cầu kỹ thuật.
- Viết, nạp và chạy đƣợc chƣơng trình điều chỉnh độ sáng của bóng đèn
*Nội dung:
1. Giới thiệu PWM
1.1. Kiến thức cơ bản
118
- Xung là các trạng thái cao / thấp (HIGH/LOW) về mức điện áp đƣợc lặp đi
lặp lại. Đại lƣợng đặc trƣng cho 1 xung PWM (Pulse Width Modulation) bao
gồm tần số (frequency) và chu kì xung (duty cycle).
- Tần số là gì?
Tần số là số lần lặp lại trong 1 đơn vị thời gian. Đơn vị tần số là Hz, tức là số lần
lặp lại dao động trong 1 giây.
Lấy ví dụ, 1Hz = 1 dao động trong 1 giây. 2Hz = 2 dao động trong 1 giây. 16MHz
= 16 triệu dao động trong 1 giây.
- Nhƣ vậy theo quy tắc tam suất: 16 triệu dao động - 1 giây --> 1 dao động tốn
1/16.000.000 (giây) = 0,0625 (micro giây)
- Cách xác định 1 dao động nhƣ thế nào? Đa phần chúng ta mới nghiên cứu điện tử
thƣờng mắc sai lầm ở việc xác định 1 dao động. Dao động đƣợc xác định từ trạng
thái bắt đầu và kết thúc ngay trƣớc khi trạng thái bắt đầu đƣợc lặp lại.
Hình 12.1 Xung Vuông
* Cách xác định 1 dao động
Nhƣ vậy thông thƣờng, 1 dao động sẽ bao gồm 2 trạng thái điện: mức cao (x
giây) và mức thấp (y giây). Tỉ lệ phần trăm thời gian giữa 2 trạng thái điện này
chính là chu kì xung.
Với x/y = 0% ta có xung chứa toàn bộ điện áp thấp (khái niệm xung nên hiểu
mở rộng)
Với x/y = 50% thì 50% thời gian đầu, xung có điện áp cao, 50% sau xung có
điện áp thấp.
Với x/y=100% ta có xung chứa toàn bộ điện áp cao.
- Tóm lại, với 1 xung ta có:
Tần số: để tính toán ra đƣợc thời gian của 1 xung
Chu kì xung: bao nhiêu thời gian xung có mức áp cao, bao nhiêu thời gian xung có
mức áp thấp.
1.2.Liên hệ với Arduino:
Với kiến thức cơ bản về xung, chúng ta sẽ hiểu rõ hơn về xung trong thực tế
nhƣ thế nào.
119
Hình 12.2 Đồ thị dạng xung điều chế PWM (Pulse Width Modulation)
Xung khi sử dụng với hàm analogWrite trong Arduino
Giữa 2 vạch màu xanh lá cây là 1 xung.
analogWrite tỉ lệ chu kì xung
analogWrite(0) 0/255 0%
analogWrite(64) 64/255 25%
analogWrite(127) 127/255 50%
analogWrite(191) 191/255 75%
analogWrite(255) 255/255 100%
Hàm analogWrite() trong Arduino giúp việc tạo 1 xung dễ dàng hơn. Hàm
này truyền vào tham số cho phép thay đổi chu kì xung, ta có thể tính toán ra đƣợc
chu kì xung nhƣ ở bảng trên. Tần số xung đƣợc Arduino thiết lập mặc định.
Đối với board Arduino Uno, xung trên các chân 3,9,10,11 có tần số là
490Hz, xung trên chân 5,6 có tần số 980Hz.
Làm thế nào để tạo ra các xung có tần số nhanh hơn? ta có thể tham khảo
thêm các thƣ viện riêng hỗ trợ việc này. Trong mã nguồn Arduino gốc không hỗ trợ
phần này.
Lưu ý: xung điều khiển servo có tên gọi PPM (Pulse Position Modulation) khác
với xung PWM.
120
Phương pháp để chuyển đổi thông tin thành những xung để truyền dẫn
- PWM (Pulse Width Modulation): Độ rộng xung tỷ lệ với biên độ tín hiệu tƣơng
tự.
- PPM (Pulse Position Modulation): Vị trí xung thay đổi theo biên độ tín hiệu
tƣơng tự trong một khe thời gian.
- PAM (Pulse Amplitude Modulation): Biên độ xung thay đổi theo biên độ của tín
hiệu tƣơng tự.
- PCM (Pulse Code Modulation): chuyển đổi chuỗi xung điều chế biên độ thành
dạng tín hiệu nhị phân. PCM là phƣơng pháp phổ biến trong hệ thống viễn thông,
chủ yếu là trong mạng PSTN
2. Phần cứng
- Chuẩn bị:
+ 1 Arduino Uno r3
+ 1 Breadboard
+ Dây cắm breadboard
+ 1 điện trở 560 Ohm (hoặc 220 Ohm hoặc 1kOhm)
+ 1 đèn LED siêu sáng.
- Lắp mạch:
Hình 12.3 Giao tiếp bo Arduino với bóng đèn
121
3. Lập trình và giải thích
int led = 9; // khai báo chân sử dụng
int brightness = 0; // khai báo độ sáng
int fadeAmount = 5; // khai báo mức thay đổi độ sáng
// sau khi cấp nguồn thì hàm setup() chạy 1 lần duy nhất:
void setup() {
// khai báo chân 9 là lối ra
pinMode(led, OUTPUT);
}
// vòng lặp thực hiện các đoạn mã tuần tự là lặp lại:
void loop() {
// đặt độ sáng ban đầu:
analogWrite(led, brightness);
// thay đổi độ sáng sau từng vòng lặp:
brightness = brightness + fadeAmount;
// đảo chiều độ sáng khi hết vòng tối --> sáng và sáng --> tối
if (brightness = 255) {
fadeAmount = -fadeAmount;
}
//chờ 30 milliseconds để quan sát
delay(30);
}
Câu hỏi ôn tập
Câu 1: Thế nào là điều chế PWM ?
Câu 2: Viết chƣơng trình điều khiển độ sáng của bóng đèn sáng 75% ?
122
BÀI 13: GIAO TIẾP I2C -ĐỌC THỜI GIAN THỰC.
* Giới thiệu: Đầu năm 1980 Phillips đã phát triển một chuẩn giao tiếp nối tiếp 2
dây đƣợc gọi là I2C. I2C là tên viết tắt của cụm từ Inter-Intergrated Circuit. Đây là
đƣờng Bus giao tiếp giữa các IC với nhau. I2C mặc dù đƣợc phát triển bới Philips,
nhƣng nó đã đƣợc rất nhiều nhà sản xuất IC trên thế giới sử dụng. I2C trở thành
một chuẩn công nghiệp cho các giao tiếp điều khiển, có thể kể ra đây một vài tên
tuổi ngoài Philips nhƣ: Texas Intrument(TI), MaximDallas, analog Device,
National Semiconductor ... Bus I2C đƣợc sử dụng làm bus giao tiếp ngoại vi cho
rất nhiều loại IC khác nhau nhƣ các loại Vi điều khiển 8051, PIC, AVR, ARM...
chip nhớ nhƣ: RAM tĩnh (Static Ram), EEPROM, bộ chuyển đổi tƣơng tự số
(ADC), số tƣơng tự(DAC), IC điểu khiển LCD, LED...
*Mục tiêu: Sau khi học xong bài học này, ngƣời học có khả năng:
- Trình bày đƣợc cấu tạo, chức năng và nguyên lý hoạt động của I2C trong
Arduino.
- Vẽ đƣợc sơ đồ nguyên lý mạch của I2C
- Mô phỏng đƣợc chƣơng trình mạch của I2C bằng phần mềm mô phỏng
- Kết nối đƣợc phần cứng mạch của I2C đúng yêu cầu kỹ thuật.
- Viết, nạp và chạy đƣợc chƣơng trình của I2C
*Nội dung:
1. Giới thiệu I2C
1.1.Khái niệm:
I²C, viết tắt của từ tiếng Anh “Inter-Integrated Circuit”, là một loại bus nối
tiếp đƣợc phát triển bởi hãng sản xuất linh kiện điện tử Philips. Ban đầu, loại bus
này chỉ đƣợc dùng trong các linh kiện điện tử của Philips. Sau đó, do tính ƣu việt
và đơn giản của nó, I²C đã đƣợc chuẩn hóa và đƣợc dùng rộng rãi trong các mô đun
truyền thông nối tiếp của vi mạch tích hợp ngày nay.
1.2 Cấu tạo và nguyên lý hoạt động:
I²C sử dụng hai đƣờng truyền tín hiệu:
Một đƣờng xung nhịp đồng hồ(SCL) chỉ do Master phát đi ( thông thƣờng
ở 100kHz và 400kHz. Mức cao nhất là 1Mhz và 3.4MHz).
Một đƣờng dữ liệu(SDA) theo 2 hƣớng.
Sơ đồ kết nối nhƣ hình dƣới.
123
Hình 13.1 Đường dữ liệu(SDA) theo 2 hướng
lƣu ý: về xung clock. Bản chất của I2C là dữ liệu trên đƣờng SDA chỉ đƣợc ghi
nhận ở sƣờn lên của chân CLK. Do vậy xung clock có thể không cần chính xác tốc
độ là 1MHz hay 3.4Mhz. Lợi dụng điểm này có thể sử dụng 2 chân GPIO để làm
chân giao tiếp I2C mềm mà không nhất thiết cần một chân CLK tạo xung với tốc
độ chính xác (có thể chỉ cần dùng delay và bật tắt mức logic) SCL và SDA luôn
đƣợc kéo lên nguồn bằng một điện trở kéo lên có giá trị xấp xỉ 4,7 KOhm (tùy vào
từng thiết bị và chuẩn giao tiếp, có thể dao động trong khoảng 1KOhm đến 4.7
Kohm.
Chú ý: theo cấu hình này, một thiết bị có thể ở mức logic LOW hay cao trở nhƣng
ko thể ở dạng HIGH => Chính trở pull up tạo ra mức logic HIGH).
2. Phần cứng
- Chuẩn bị:
Arduino UNO
Module RTC DS1307
- Lắp mạch :
Sơ đồ đấu nối
Arduino UNO Module RTC DS1307
GND GND
5V GND
A4 SDA
A5 SCL
124
Hình 13.2 Giao tiếp bo Arduino UNO với Module RTC DS1307
3. Lập trình và giải thích
- Code:
#include
#include "RTClib.h"
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
void setup ()
{
Serial.begin(9600);
if (! rtc.begin())
{
Serial.print("Couldn't find RTC");
while (1);
}
if (! rtc.isrunning())
{
Serial.print("RTC is NOT running!");
Serial.println();
}
125
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
void loop ()
{
DateTime now = rtc.now();
if(now.hour()<=9)
{
Serial.print("0");
Serial.print(now.hour());
}
else {
Serial.print(now.hour());
}
Serial.print(':');
if(now.minute()<=9)
{
Serial.print("0");
Serial.print(now.minute());
}
else {
Serial.print(now.minute());
}
Serial.print(':');
if(now.second()<=9)
{
Serial.print("0");
Serial.print(now.second());
}
else {
Serial.print(now.second());
}
Serial.println();
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(",");
126
if(now.day()<=9)
{
Serial.print("0");
Serial.print(now.day());
}
else {
Serial.print(now.day());
}
Serial.print('/');
if(now.month()<=9)
{
Serial.print("0");
Serial.print(now.month());
}
else {
Serial.print(now.month());
}
Serial.print('/');
if(now.year()<=9)
{
Serial.print("0");
Serial.print(now.year());
}
else {
Serial.print(now.year());
}
Serial.println();
delay(1000);
}
- Giải thích code
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
"Sat"};
Ban đầu chúng ta tạo một đối tƣợng của thƣ viện RTClib là rtc và xác định mảng
ký tự daysOfTheWeek để lƣu trữ thông tin ngày trong tuần.
- Hàm rtc.begin() và rtc.isrunning()
127
Hàm rtc.begin() là hàm khởi tạo để đảm bảo module RTC đƣợc kết nối.
Hàm rtc.isrunning() là hàm đọc các thanh ghi bên trong I2C của DS1307 để kiểm
tra xem chip có trả về thời gian hay không. Nếu hàm trả về giá trị False thì đặt lại
thời gian.
- Hàm rtc.adjust()
Hàm rtc.adjust() là hàm đặt ngày và giờ.
Chúng ta có 2 cách đặt ngày giờ:
DateTime(F(__DATE__), F(__TIME__)) cách này chúng ta cập nhật thời
gian tự động từ máy tính.
DateTime(YYY, M, D, H, M, s) cách này chúng ta thiết lập giờ thủ công.
Ví dụ: Đặt ngày 12 tháng 5 năm 2019 vào lúc 14:07 thì chúng ta sẽ gọi
hàm DateTime(2019, 5, 12, 14, 07, 00).
Một số hàm khác:
Hàm rtc.now()
Trả về ngày & giờ hiện tại. Giá trị trả về của nó thƣờng đƣợc lƣu
trữ trong biến của kiểu dữ liệu DateTime.
Hàm year() Trả về năm hiện tại.
Hàm month() Trả về tháng hiện tại.
Hàm day() Trả về ngày hiện tại.
Hàm daysOfTheWeek() Trả về ngày hiện tại trong tuần.
Hàm hour() Trả về giờ hiện tại.
Hàm minute() Trả về phút hiện tại.
Hàm second() Trả về giây hiện tại.
Câu hỏi ôn tập:
Câu 1:Trình bày nguyên lý hoạt động của I2C?
Câu 2: Kết nối phần cứng và viết chƣơng trình điều khiển Đọc nhiệt độ - độ ẩm và
xuất ra màn hình LCD?
128
BÀI 14: ĐIỀU KHIỂN ĐỘNG CƠ DC
*Giới thiệu
Điều khiển động cơ DC (DC Motor) là một ứng dụng thuộc dạng cơ bản nhất
của điều khiển tự động vì DC Motor là cơ cấu chấp hành (actuator) đƣợc dùng
nhiều nhất trong các hệ thống tự động (ví dụ robot). Điều khiển đƣợc DC Motor là
ta đã có thể tự xây dựng đƣợc cho mình rất nhiều hệ thống tự động.
*Mục tiêu: Sau khi học xong bài học này, ngƣời học có khả năng:
- Trình bày đƣợc cấu tạo, chức năng và nguyên lý hoạt động của mạch L298.
- Vẽ đƣợc sơ đồ nguyên lý mạch điều khiển động cơ DC
- Mô phỏng đƣợc chƣơng trình mạch điều khiển động cơ DC bằng phần mềm
mô phỏng
- Kết nối đƣợc phần cứng mạch điều khiển động cơ DC đúng yêu cầu kỹ
thuật.
- Viết, nạp và chạy đƣợc chƣơng trình điều khiển động cơ DC
- Rèn luyện tính tƣ duy và tác phong công nghiệp , đảm bảo an toàn cho
ngƣời và thiết bị
*Nội dung:
1. Giới thiệu động cơ DC
Động cơ điện 1 chiều là thiết bị ngoại vi đƣợc sử dụng rất rộng rãi do điều
khiển đơn giản, giá cả phải chăng.
Hình 14.1. Động cơ DC
1.1. Định nghĩa
Động cơ một chiều DC ( DC là từ viết tắt của "Direct Current Motors") là
Động cơ điều khiển bằng dòng có hƣớng xác định hay nói dễ hiểu hơn thì đây là
loại động cơ chạy bằng nguồn điện áp DC- điện áp 1 chiều(Khác với điện áp AC
xoay chiều). Đầu dây ra của đông cơ thƣờng gồm hai dây (dây nguồn- VCC và dây
tiếp đất- GND). DC motor là một động cơ một chiều với cơ năng quay liên tục.
Khi ta cung cấp năng lƣợng, động cơ DC sẽ bắt đầu quay, chuyển điện năng
thành cơ năng. Hầu hết các động cơ DC sẽ quay với cƣờng độ RPM rất cao ( số
129
vòng quay/ phút). Tốc độ không tải của động cơ DC nếu không giảm tốc có thể đạt
từ 1000RPM tới 40.000RPM.
Ví dụ: Một động cơ DC RS775-9009 có tốc độ quay 22.000RPM cùng với
hộp giảm tốc Planet.
Ứng dụng của động cơ DC cũng rất đa dạng và hầu hết trong mọi lĩnh vực của đời
sống. Trong tivi, trong đài FM, ổ đĩa DC, máy in- photo, máy công nghiệp...v...v.
Đối với động cơ điện 1 chiều có loại không chổi than (Brussless DC Motor-
BLDC) và động cơ có chổi than (Brush DC Motor- DC Motor). Do động cơ BLDC
thực chất là động cơ điện 3 pha không đồng bộ vì vậy mình chỉ xét động cơ điện 1
chiều có chổi than.
1.2. Phân loại động cơ điện một chiều (đây là cách phân loại theo cách kích từ)
Động cơ điện 1 chiều phân loại theo kích từ thành những loại sau:
-Kích từ độc lập.
-Kích từ song song.
-Kích từ nối tiếp.
-Kích từ hỗn hợp.
Với mỗi 1 loại động cơ điện 1 chiều nhƣ trên thì có các ứng dụng khác nhau.
Nhƣng trên thực tế, ta chủ yếu tiếp xúc với loại động cơ DC công suất thấp có phần
Stator sử dụng nam châm vĩnh cửu nên thông thƣờng là không cần đến phần kích từ
cho động cơ. Ta nói đến và quan tâm tới kích từ cho động cơ DC khi nói đến các
loại động cơ DC công suất lớn, Stator của động cơ không phải là nam châm vĩnh
cửu mà là nam châm điện. Phần nam châm điện này cũng gồm lõi thép kỹ thuật và
các bó dây. Để Stator biến thành nam châm điện ta cần phải cấp điện cho phần
Startor của nó, khi đó ta gọi nó là kích từ. Nhƣ vậy với những loại động cơ DC
chúng ta tiếp cận không cần phải quan tâm tới "kích từ" của nó.
1.3. Cấu tạo và nguyên tắc hoạt động
- Cấu tạo:
Gồm có 3 phần chính stator( phần cảm), rotor ( phần ứng), và phần cổ góp- chỉnh
lƣu
Hình 14.2. Cấu tạo Động cơ DC
130
Cấu tạo chi tiết động cơ DC với phần than lộ và phần rotor dây đồng
- Stator của động cơ điện 1 chiều thƣờng là 1 hay nhiều cặp nam châm vĩnh
cửu, hay nam châm điện.
- Rotor có các cuộn dây quấn và đƣợc nối với nguồn điện một chiều.
- Bộ phận chỉnh lƣu, nó có nhiệm vụ là đổi chiều dòng điện trong khi chuyển
động quay của rotor là liên tục. Thông thƣờng bộ phận này gồm có một bộ cổ góp
và một bộ chổi than tiếp xúc với cổ góp.
- Nguyên lý hoạt động
Pha 1: Từ trƣờng của rotor cùng cực với stator, sẽ đẩy nhau tạo ra chuyển
động quay của rotor.
Pha 2: Rotor tiếp tục quay
Pha 3: Bộ phận chỉnh điện sẽ đổi cực sao cho từ trƣờng giữa stator và rotor
cùng dấu, trở lại pha
1.4.Điều chỉnh tốc độ động cơ điện một chiều
Các phƣơng trình điều chỉnh tốc độ.
131
-Thay đổi điện áp phần ứng.
-Thay đổi điện trở mạch rotor.
-Thay đổi từ thông.
Trên thực tế phƣơng pháp đƣợc sử dụng nhiều nhất là thay đổi điện áp phần ứng.
Trong đó điển hình là phƣơng pháp thay đổi độ rộng xung PWM.
2. Phần cứng
* Chuẩn bị:
- Động cơ DC 12 V
- Board Arduino
- Breadboard và dây nối
- Bộ điều khiển L298N
Hình 14.3. Bo mạch L298
- Thông số kỹ thuật:
Driver: L298N tích hợp hai mạch cầu H.
Điện áp điều khiển: +5 V ~ +12 V
Dòng tối đa cho mỗi cầu H là: 2A (=>2A cho mỗi motor)
Điện áp của tín hiệu điều khiển: +5 V ~ +7 V
Dòng của tín hiệu điều khiển: 0 ~ 36mA (Arduino có thể chơi đến 40mA nên
khỏe re nhé các bạn)
Công suất hao phí: 20W (khi nhiệt độ T = 75 ℃)
Nhiệt độ bảo quản: -25 ℃ ~ +130 ℃
132
- L298 chức năngcác chân:
- 12V power, 5V power.: Đây là 2 chân cấp nguồn trực tiếp đến động cơ. Ta
có thể cấp nguồn 9-12V ở 12V.
- jumper 5V, nếu để nhƣ hình ở trên thì sẽ có nguồn 5V ra ở cổng 5V power,
ngƣợc lại thì không. Ta để nhƣ hình thì ta chỉ cần cấp nguồn 12V vào ở 12V power
là có 5V ở 5V power, từ đó cấp cho Arduino
- Power GND chân này là GND của nguồn cấp cho Động cơ.
Chú ý: Nếu dùng Arduino thì nối với GND của Arduino
- 2 Jump A enable và B enable, để nhƣ hình
- Gồm có 4 chân Input. IN1, IN2, IN3, IN4.
- Output A: nối với động cơ A.tachú ý chân +, -. Nếu nối ngƣợc thì động cơ
sẽ chạy ngƣợc. Và chú ý nếu ta nối động cơ bƣớc, ta phải đấu nối các pha cho phù
hợp.
Board này gồm 2 phần điều khiển động cơ. Và có thể điều khiển cho 1 động
cơ bƣớc 6 dây hoặc 4 dây
* Lắp mạch :
Hình 14.4. Giao tiếp UNO với động cơ DC
3. Lập trình và giải thích
const int motorA1=9; //Khai báo chân IN
const int motorA2=10;
void setup()
{
pinMode(motorA1,OUTPUT); //Khai báo dạng INPUT
pinMode(motorA2,OUTPUT);
133
}
void loop()
{
digitalWrite(motorA1,HIGH); //Quay tới
digitalWrite(motorA2,LOW);
delay(1000); //Dừng 1s
digitalWrite(motorA1,LOW); //Quay lui
digitalWrite(motorA2,HIGH);
delay(1000); //Dừng 1s
}
CÂU HỎI VÀ BÀI TẬP
Câu 1: Trình bày cấu tạo và nguyên lý hoạt động của động cơ DC
Câu 2: Viết chƣơng trình điều khiển động cơ DC ?
134
BÀI 15: ĐIỀU KHIỂN ĐỘNG CƠ SERVO
* Giới thiệu:
Điều khiển động cơ DC (DC Motor) là một ứng dụng thuộc dạng cơ bản nhất
của điều khiển tự động vì DC Motor là cơ cấu chấp hành (actuator) đƣợc dùng
nhiều nhất trong các hệ thống tự động (ví dụ robot). Điều khiển đƣợc DC servo
motor là ta đã có thể tự xây dựng đƣợc cho mình rất nhiều hệ thống tự động. Khái
niệm Servo mà tôi dùng trong bài học này để chỉ một hệ thống hồi tiếp. DC servo
motor là động cơ DC có bộ điều khiển hồi tiếp
*Mục tiêu: Sau khi học xong bài học này, ngƣời học có khả năng:
- Trình bày đƣợc cấu tạo, chức năng và nguyên lý hoạt động của động cơ
servo
- Vẽ đƣợc sơ đồ nguyên lý mạch điều khiển động cơ servo
- Mô phỏng đƣợc chƣơng trình mạch điều khiển động cơ servo bằng phần
mềm mô phỏng
- Kết nối đƣợc phần cứng mạch điều khiển động cơ servo đúng yêu cầu kỹ
thuật.
- Viết, nạp và chạy đƣợc chƣơng trình điều khiển động cơ servo
*Nội dung:
1. Giới thiệu động cơ servo
1.1. Động cơ Servo nghĩ là gì ?
Hình 15.1 Động cơ Servo
Động cơ Servo là một bộ phận của hệ thống điều khiển chuyển động của
máy móc. Một trong các bộ phận không thể thiếu giúp Động cơ Servo có thể hoạt
động đó chính là Driver servo. Tƣơng tự nhƣ driver của máy tính. Động cơ Servo
cung cấp lực chuyển động cần thiết cho các thiết bị máy móc khi vận hành
1.2.Phân loại động cơ Servo.
135
Nhìn chung động cơ servo có 2 loại chính là: Động cơ DC Servo và động cơ
AC Servo.
- AC servo là loại động cơ cho phép xử lý các dòng điện cao nên thƣờng
đƣợc sử dụng trong máy móc công nghiệp đặc biệt là các loại máy CNC.
- DC servo không đƣợc thiết kế cho các dòng điện cao và thƣờng phù hợp
hơn cho các ứng dụng nhỏ hơn. Động cơ DC còn đƣợc chia làm 2 loại động cơ 1
chiều có chổi than và động cơ 1 chiều không chổi than.
Nhờ sự phát triển vƣợt bậc công nghệ điều khiển điện nên hiện nay hầu hết ngƣời
ta đều sử dụng động cơ AC Servo.
1.3.Cấu tạo của động cơ Servo.
* Động cơ DC Servo.
-Động cơ DC có chổi than: gồm 4 cấu tạo chính stato, rotor, chổi than và
cuộn cảm lõi.
- Ưu điểm: của động cơ DC có chổi than là tƣơng đối dễ điều khiển, giá thành
tƣơng đối rẻ.
- Nhược điểm: Khi vận hành thƣơng gây ra tiếng ồn, nhiệt độ cao khi vậ hành và
quán tính cao khi giảm tốc độ. Để khắc phục đƣợc vân đề này thì ngƣời ta hay dùng
động cơ DC không chổi than.
Hình 15.2 cấu tạo động cơ Servo
Động cơ DC không chổi than: Cấu trúc của nó tƣơng đối giống với động cơ có
chổi than. Điều khác biệt là các cuộn pha đƣợc lắp ở rotor là động cơ vĩnh cữu.
* Động cơ AC Servo
Động cơ AC Servo đƣợc sử dụng trong các ngành công nghiệp đa phần là
động cơ một chiều không chổi than. Động cơ Servo có cấu tạo 2 phần chính giống
với động cơ bƣớc là Rotor và Stator.
Rotor là một nam châm vĩnh cửu có từ trƣờng mạnh.
Stator là một cuộn dây đƣợc cuốn riên biệt, đƣợc cấp nguồn để làm quay Rotor.
136
- Ưu điểm: Điều khiển có tốc độ tốt, và trơn tru hầu nhƣ không giao động. Hiệu
suất có thể đạt hơn 90%.
Quá trình vận hành tạo ra ít nhiệt với tốc độ cao. Độ chính xác cao (tùy thuộc vào
độ chính xác của bộ mã hóa).
Mô-men xoắn, quán tính thấp, tiếng ồn thấp, không có bàn chải mặc.
- Nhược điểm: Hệ điều chỉnh tốc độ động cơ tƣơng đối phức tạp. Giá thành lại khá
cao.
Nguyên lý hoạt động.
Động cơ servo đƣợc hình thành bởi những hệ thống hồi tiếp vòng kín. Tín hiệu ra
của động cơ đƣợc nối với một mạch điều khiển. Khi động cơ vận hành thì vận tốc
và vị trí sẽ đƣợc hồi tiếp về mạch điều khiển này. Khi đó bầt kỳ lý do nào ngăn cản
chuyển động quay của động cơ, cơ cấu hồi tiếp sẽ nhận thấy tín hiệu ra chƣa đạt
đƣợc vị trí mong muốn. Mạch điều khiển tiếp tục chỉnh sai lệch cho động cơ đạt
đƣợc điểm chính xác nhất.
* Ứng dụng.
- Ứng dụng trong ngành điện điện tử:
Các máy móc lắp ráp tƣờng đòi hỏi tốc độ cao thì động cơ Servo đáp ứng
đƣợc yêu cầu này. Đặc biệt là đối với AC Servo.
- Ứng dụng trong ngành gia công cơ khí:
Hiện nay ngành gia công cơ khí đặc biệt là đối với việc gia công các sản
phẩm có độ chính xác cao ví dụ nhƣ máy cắt laser hay một số máy cắt khác thì
ngƣời ta sẽ lựa chọn động cơ Servo thay vì động cơ bƣớc nhƣ trƣớc đây. Bên cạnh
đó nó còn đƣợc ứng dụng rất nhiều trong các loại máy cắt CNC PLasma khác.
137
Ứng dụng trong ngành may mặc, ngành giấy, bao bì: Trong việc điều khiển các
máy cuộn vải, giấy, bao bì để cắt hoặc in ấn
2. Phần cứng
* Chuẩn bị :
- Mạch Arduino UNO.
- Breadboard còn gọi testboard.
- Dây cắm test board.
- 1 module servo SG90:
Hình 15.3 Động cơ Servo MG90
Động cơ servo cũng đƣợc chia làm nhiều loại, phụ thuộc vào góc quay tối đa
của chúng, 2 loại phổ biến hay sử dụng là:
Động cơ servo quay 180°: Futaba S3003, MG90[S] ...
Động cơ servo quay 360°: MG995, MG996R ...
Nhƣ đã đề cập bên trên, động cơ servo là loại động cơ cho phép ta điều khiển
một cách cực kì chính xác. Vì vậy, khác với động cơ thông thƣờng ta chỉ cần cấp
nguồn cho động cơ là có thể vận hành đƣợc. Động cơ servo yêu cầu ta phải cấp
nguồn (2 dây) và nhận điều khiển từ mạch chính (1 dây), mỗi dây thƣờng đƣợc
đánh màu nhƣ sau:
+ Đỏ: nhận điện nguồn, tuỳ vào loại động cơ mà giá trị này có thể khác nhau
+ Nâu: nối với cực âm của mạch
+ Vàng: nhận tín hiệu từ mạch điều khiển
* Lắp mạch :
138
Hình 15.3 Giao tiếp bo arduino UNO với động cơ Servo MG90
3. Lập trình và giải thích
#include
#define SERVO_PIN 9 // chan tin hieu cua servo noi voi chan so 9 arduino
Servo gServo;
void setup()
{
gServo.attach(SERVO_PIN);
}
void loop()
{
gServo.write(0); // điều chỉnh góc xoay của servo.
delay(1000);
gServo.write(90); // điều chỉnh góc xoay của servo.
delay(1000);
gServo.write(180); // điều chỉnh góc xoay của servo.
delay(1000);
}
CÂU HỎI VÀ BÀI TẬP
Câu 1: Trình bày cấu tạo và nguyên lý hoạt động của động cơ DC servo
Câu 2: Viết chƣơng trình điều khiển động cơ DC servo ?
139
BÀI 16: ĐIỀU KHIỂN ĐỘNG CƠ BƢỚC
* Giới thiệu:
Điều khiển động cơ DC (DC Motor) là một ứng dụng thuộc dạng cơ bản nhất
của điều khiển tự động vì DC Motor là cơ cấu chấp hành (actuator) đƣợc dùng
nhiều nhất trong các hệ thống tự động (ví dụ robot). Điều khiển đƣợc động cơ bƣớc
là ta đã có thể tự xây dựng đƣợc cho mình rất nhiều hệ thống tự động.
*Mục tiêu: Sau khi học xong bài học này, ngƣời học có khả năng:
- Trình bày đƣợc cấu tạo, chức năng và nguyên lý hoạt động của động cơ
bƣớc, mạch ULN 2003.
- Vẽ đƣợc sơ đồ nguyên lý mạch điều khiển động cơ bƣớc
- Mô phỏng đƣợc chƣơng trình mạch điều khiển động cơ bƣớc bằng phần
mềm mô phỏng
- Kết nối đƣợc phần cứng mạch điều khiển động cơ bƣớc đúng yêu cầu kỹ
thuật.
- Viết, nạp và chạy đƣợc chƣơng trình điều khiển động cơ bƣớc
- Rèn luyện tính tƣ duy và tác phong công nghiệp , đảm bảo an toàn cho
ngƣời và thiết bị
*Nội dung:
1. Giới thiệu động cơ bƣớc
1.1. Động cơ bƣớc là gì?
Động cơ bƣớc (stepper motor), thực chất là một động cơ đồng bộ dùng để
biến đổi các tín hiệu điều khiển dƣới dạng các xung điện rời rạc kế tiếp nhau thành
các chuyển động góc quay.
Hình 16.1. Động cơ bước
1.2 Cấu tạo động cơ bƣớc
Về cấu tạo động cơ bƣớc gồm có các bộ phận là stato, roto là nam châm vĩnh
cửu hoặc trong trƣờng hợp của động cơ biến từ trở là những khối răng làm bằng vật
liệu nhẹ có từ tính. Động cơ bƣớc đƣợc điều khiển bởi bộ điều khiển bên ngoài.
Động cơ bƣớc và bộ điều khiển đƣợc thiết kế sao cho động cơ có thể giữ nguyên
bất kỳ vị trí cố định nào cũng nhƣ quay đến một vị trí bất kỳ nào.
140
Động cơ bƣớc có thể sử dụng trong hệ thống điều khiển vòng hở đơn giản,
hoặc vòng kín, tuy nhiên khi sử dụng động cơ bƣớc trong hệ điều khiển vòng hở
khi quá tải, tất cá các giá trị của động cơ đều bị mất và hệ thống cần nhận diện lại.
Hình 16.2. Cấu tạo động cơ bước
1.3. Đặc điểm của động cơ bƣớc
Động cơ bƣớc hoạt động dƣới tác dụng của các xung rời rạc và kế tiếp nhau.
Khi có dòng điện hay điện áp đặt vào cuộn dây phần ứng của động cơ bƣớc làm
cho roto của động cơ quay một góc nhất định gọi là bƣớc của động cơ.
Góc bƣớc là góc quay của trục động cơ tƣơng ứng với một xung điều khiển.
Góc bƣớc đƣợc xác định dựa vào cấu trúc của động cơ bƣớc và phƣơng pháp điều
khiển động cơ bƣớc.
Tính năng mở máy của động cơ đƣợc đặc trƣng bởi tần số xung cực đại có
thể mở máy mà không làm cho roto mất đồng bộ.
Chiều quay động cơ bƣớc không phụ thuộc vào chiều dòng điện mà phụ
thuộc vào thứ tự cấp xung cho các cuộn dây.
1.4 Phân loại động cơ bƣớc
Động cơ bƣớc đƣợc chia thành 3 loại chính là:
Động cơ bƣớc biến từ trở.
Động cơ bƣớc nam châm vĩnh cửu
Động cơ bƣớc hỗn hợp/lai.
1.5. Phƣơng pháp điều khiển động cơ bƣớc
Hiện nay có 4 phƣơng pháp điều khiển động cơ bƣớc.
141
Hình 16.3. xung điều khiển động cơ bước
* Phương pháp điều khiển động cơ bước
- Điều khiển dạng sóng (Wave): là phƣơng pháp điều khiển cấp xung điều
khiển lần lƣợt theo thứ tự chon từng cuộn dây pha.
- Điều khiển bƣớc đủ (Full step): là phƣơng pháp điều khiển cấp xung đồng
thời cho 2 cuộn dây pha kế tiếp nhau.
- Điều khiển nửa bƣớc (Half step): là phƣơng pháp điều khiển kết hợp cả 2
phƣơng pháp đều khiển dạng sóng và điều khiển bƣớc đủ. Khi điều khiển theo
phƣơng pháp này thì giá trị góc bƣớc nhỏ hơn hai lần và số bƣớc của động cơ bƣớc
tăng lên 2 lần so với phƣơng pháp điều khiển bƣớc đủ tuy nhiên phƣơng pháp này
có bộ phát xung điều khiển phức tạp.
- Điều khiển vi bƣớc (Microstep): là phƣơng pháp mới đƣợc áp dụng trong
việc điều khiển động cơ bƣớc cho phép động cơ bƣớc dừng và định vị tại vị trí nửa
bƣớc giữa 2 bƣớc đủ.
Ƣu điểm của phƣơng pháp này là động cơ có thể hoạt động với góc bƣớc
nhỏ,độ chính xác cao. Do xung cấp có dạng sóng nên động cơ hoạt động êm
hơn,hạn chế đƣợc vấn đề cộng hƣởng khi động cơ hoạt động.
2. Phần cứng
*Chuẩn bị:
- Mạch Arduino UNO
- Breadboard còn gọi testboard.
- Dây cắm test board.
- 1 bộ nguồn ngoài (5V đến 12V) ( trong bài này chúng ta có thể sử dụng
nguồn 5Vdc của arduino nhƣng khuyến cáo hạn chế sử dụng để tránh việc hư
board arduino).
- 1 module điều khiển động cơ bƣớc ULN2003.
142
Hình 16.4. module điều khiển động cơ bước
+ Thông số kỹ thuật:
Điện áp cung cấp: 5 ~ 12VDC.
Tín hiệu ngõ vào: 4 chân in1, in2, in3, in4.
Tìn hiệu ngõ ra: Jack cắm động cơ bƣớc 28BYJ-48.
4 led hiển thị trạng thái hoạt động của động cơ.
- 1 động cơ bƣớc stepper 28BYJ-48:
143
Thông số kỹ thuật:
Điện thế hoạt động 5V
Số pha 4
Tỉ lệ bánh răng *64
Một bƣớc tƣơng đƣơng 5.625° (64 bƣớc)
Tần số 100Hz
Điện trở trong 50Ω±7%(25℃)
Động cơ bƣớc sử dụng trong phần này là động cơ bƣớc 4 pha (thực ra là 2
pha đƣợc chia ra làm 2 ở mỗi pha ngay tại vị trí giữa) (gồm 5 dây), 4 trong 5 dây
này đƣợc kết nối với 2 cuộn dây trong động cơ và 1 dây là dây nguồn chung cho cả
2 cuộn dây. Mỗi bƣớc của động cơ quét 1 góc 5.625 độ, vậy để quay 1 vòng động
cơ phải thực hiện 64 bƣớc.
* Lắp mạch:
Hình 16.5. Giao tiếp UNO với động cơ bước
3. Lập trình và giải thích
#define IN1 8 // IN1 nối với chân D8 của arduino
#define IN2 9 // IN2 nối với chân D9 của arduino
#define IN3 10 // IN3 nối với chân D10 của arduino
#define IN4 11 // IN4 nối với chân D11của arduino
int Steps = 4096;
int cstep = 0;
void setup()
{
144
Serial.begin(9600);
pinMode(IN1, OUTPUT); // các chân IN quy định là các chân ra
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
void loop()
{
for(int x=0;x<Steps;x++)
{
step1();
//delay(1);
delayMicroseconds(2500);
}
delay(1000);
}
void step1()
{
//stepp
switch(cstep)
{
case 0:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
break;
case 1:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, HIGH);
break;
case 2:
digitalWrite(IN4, LOW);
145
break;
}
cstep=cstep+1;
if(cstep==8)
{cstep=0;}
}
CÂU HỎI VÀ BÀI TẬP
Câu 1: Trình bày cấu tạo và nguyên lý hoạt động của động cơ bƣớc?
Câu 2: Viết chƣơng trình điều khiển động cơ bƣớc?
146
BÀI 17: UART-GIAO TIẾP GIỮA 2 ARDUINO
* Giới thiệu: Chuẩn giao tiếp truyền thông nối tiếp UART trên Arduino (hay còn
đƣợc biết đến với tên gọi Serial) là chuẩn giao tiếp đƣợc sử dụng rất nhiều trong
các ứng dụng hệ thống nhúng. Trong bài viết này sẽ hƣớng dẫn tiếp cận và lập trình
với giao tiếp UART một cách đơn giản nhất
*Mục tiêu: Sau khi học xong bài học này, ngƣời học có khả năng:
- Trình bày đƣợc chức năng, nguyên lý hoạt động của giao tiếp UART
trong Arduino
-Vẽ đƣợc sơ đồ nguyên lý mạch giao tiếp UART
- Mô phỏng đƣợc chƣơng trình mạch giao tiếp UART bằng phần mềm mô
phỏng
- Kết nối đƣợc phần cứng mạch giao tiếp UART đúng yêu cầu kỹ thuật.
- Viết, nạp và chạy đƣợc chƣơng trình giao tiếp UART .
- Rèn luyện tính tƣ duy và tác phong công nghiệp , đảm bảo an toàn cho
ngƣời và thiết bị
*Nội dung:
1. Giới thiệu UART
Hình 17.1. Chân giao tiếp Uart trên Arduino UNO
* Khai báo UART:
Có 2 cách để khai báo sử dụng UART trên Arduino, nhƣng phổ biến nhất là
Serial.begin(9600), trong đó 9600 là tốc độ baud và sử dụng khung truyền mặc
định 8-N-1 (8 bit dữ liệu, không sử dụng bit kiểm tra chẵn lẻ, 1 bit kết thúc). Ta có
thể tìm hiểu kĩ hơn tại đây. Đồng thời việc khai báo này cũng chuyển chân digital
0 và digital 1 thành chức năng truyền nhận dữ liệu: Chân digital 0 đƣợc gắn với bộ
147
nhận dữ liệu bên trong vi điều khiển và chân digiatal 1 đƣợc nối với bộ truyền dữ
liệu bên trong vi điều khiển.
Example Code
Void setup()
{
Serial.begin(9600);// mở cổng giao tiếp và cài đặt dữ liệu
}
Void loop()
{
}
* Nối dây 2 thiết bị:
Nếu ta sử dụng Board Arduino để giao tiếp với máy tính (sử dụng cửa sổ
Serial monitor trên ARDUINO IDE) thì không cần phải nối thêm vì trên board
Arduino đã thực hiện sẵn việc đó, chỉ cần cắm cab USB vào là đƣợc.
Nếu ta sử dụng Arduino để giao tiếp với 1 thiết bị, 1 module khác thì tanối
chéo, TX – RX và RX – TX và đừng quên 1 điều là kiểm tra xem 2 thiết bị đã
chung GND chƣa, vì nếu chƣa thì chúng sẽ không hiểu mức logic của nhau ==>
không giao tiếp đƣợc.
Phức tạp hơn nữa là nếu nhƣ 2 thiết bị khác mức logic, ví dụ nhƣ 1 thiết bị
5v giao tiếp với 1 thiết bị 3.3V thì ta cần thêm các mạch để chuyển đổi điện áp cho
phù hợp.
Hình 17.1. giao tiêp giữa 2 thiết bị
* Truyền dữ liệu:
Để truyền dữ liệu thì tasử dụng hàm Serial.print(x); trong đó x là cái mà
tamuốn in lên ở bất kì kiểu dữ liệu gì cũng đƣợc, rất tiện lợi. Nếu ta muốn truyền
148
thêm ký tự kết thúc câu (\r) và ký tự xuống dòng (\n) thì sử dụng Serial.println(x)
là đƣợc.
* Nhận dữ liệu:
Nền tảng Arduino đã hỗ trợ ngƣời dùng rất nhiều khi đã xây dựng sẵn 1 bộ
đệm UART (buffer) có kích cỡ 64byte(Arduino Uno). Mỗi lần nhận 1 ký tự thì ký
tự này sẽ đƣợc tự động chuyển vào bộ đệm. Ngƣời dùng muốn đọc dữ liệu chỉ cần
làm việc với bộ đệm là đƣợc.
+ Kiểm tra bộ đệm: Trƣớc khi thực hiện thao tác đọc và xử lý dữ liệu của
thiết bị khác gửi đến thì nên kiểm tra bộ đệm trƣớc. Câu lệnh Serial.available() sẽ
trả về cho tasố kí tự (byte) hiện có trong bộ đệm. ==>Ta sử dụng lệnh:
if(Serial.available())
{đọc và xử lý dữ liệu khi có dữ liệu}
+ Đọc dữ liệu: Để đọc 1byte từ bộ đệm tasử dụng lệnh Serial.read(); Tuy
nhiên trong thực tế thì hầu hết chúng ta cần đọc 1 chuỗi ký tự. Tacó thể đọc từng ký
tự, sau đó ghép chúng lại thành 1 chuỗi hoặc sử dụng kiểu dữ liệu String mà
Arduino hỗ trợ (lƣu ý String chữ S viết hoa). Lệnh Serial.readString() sẽ giúp tađọc
đƣợc tất cả các kí tự có trong bộ đệm.
+ Lƣu ý: Bộ đệm UART sẽ mất dữ liệu ngay sau khi tađọc. Vì vậy ta nên đọc
và lƣu ra 1 biến và làm việc với biến đó.
- Kiểu String:
Kiểu String trong Arduino giúp cho ngƣời dùng thao tác với chuỗi đơn giản
hơn với rất nhiều hàm hỗ trợ.
- myString.indexOf(val):
Hàm này sẽ giúp ta tìm đƣợc vị trí của 1 ký tự hoặc 1 chuỗi (val) trong 1
chuỗi khác (myString).
- myString.toInt():
Từ trên màn hình Serial Monitor ta bấm 168 để gửi đi thì Arduino sẽ nhận
đƣợc chuỗi “168”, để khôi phục lại thành số 168 thì tasử dụng hàm toInt().
- substring(): Trong một chuỗi dữ liệu lớn nhận đƣợc thì sẽ có phần dữ liệu nằm
trong chuỗi đó mà tacần tách ra để sử dụng. Lúc này hàm substring sẽ là trợ thủ đắc
lực cho ta.
- myString.toCharArray():
Hàm này giúp tachuyển chuỗi ở kiểu String thành 1 mảng kiểu char. Khi làm
việc với một số thƣ viện, ngƣời phát triển đã khai báo sẵn các hàm có các tham số
kiểu char *, lúc này tacó thể truyền vào char * hoặc char array, còn String thì không
đƣợc chấp nhận, vì vậy việc chuyển đổi kiểu dữ liệu là cần thiết. Khi chuyển String
149
thành mảng thì tacó thể sử dụng thêm hàm length() để xác định đƣợc số lƣợng phần
tử của mảng (sau đó nhớ cộng thêm 1 vì sử dụng mảng kiểu char để lƣu chuỗi thì
cần có ký tự Null sau cùng).
2. Phần cứng
*Chuẩn bị:
- Mạch Arduino (ở đây mình sử dụng Arduino UNO) (Truyền dữ liệu).
- Mạch Arduino hoặc Nano, (ở đây mình sử dụng Arduino UNO) (Nhận
dữ liệu).
- Breadboard còn gọi testboard.
- Dây cắm test board.
- 1 led đơn.
- trở 220Ohm.
*Lắp mạch:
Hình 17.1. giao tiêp giữa 2 bo arduino UNO
150
3. Lập trình và giải thích
* Chương trình ( code) upload cho Arduino Truyền lệnh:
void setup() {
Serial.begin(9600); // Bạn khởi tạo một cổng Serial tại baudrate 9600.
}
int Step = 0; void loop() {
if (Step == 0) {
Serial.println("LED_RED 1"); // Đèn đỏ sáng. 1 == HIGH
}
else if (Step == 1) {
Serial.println("LED_RED 0"); // Đèn đỏ tắt . 0 == LOW
}
Step = (Step + 1) % 2; //Step sẽ tuần tự tuần hoàn các giá trị trong khoảng từ 0 --
> 1
delay(500); // Dừng 1/2 giây giữa các lần gửi
}
* Chương trình ( code) upload cho Arduino nhận lệnh:
#include
#include // Khai báo biến sử dụng thƣ viện Serial Command
SerialCommand sCmd;
int red = 8; void setup() {
Serial.begin(9600); / /Khởi tạo Serial ở baudrate 9600 .
pinMode(red,OUTPUT);
// Một số hàm trong thƣ viện Serial Command
sCmd.addCommand("LED_RED",led_red); // Khi có câu lệnh tên là LED_RED
sẽ chạy hàm led_red
}
void loop() { sCmd.readSerial();
//Ta không cần phải thêm bất kỳ dòng code nào trong hàm loop này cả
}
// hàm led_red sẽ đƣợc thực thi khi gửi hàm LED_RED
void led_red() {
//Đoạn code này dùng để đọc từng tham số. Các tham số mặc định có kiểu dữ liệu
là "chuỗi"
151
char *arg;
arg = sCmd.next();
int value = atoi(arg); // Chuyển chuỗi thành số
digitalWrite(red,value);
}
Câu hỏi ôn tập
Câu 1: Nêu công dụng của UART ?
Câu 2: Kết nối phần cứng và viết chƣơng trình điều khiển led đơn qua giao tiếp
serial giữa Arduino và PC?
Tài liệu tham khảo:
[1]Dự án Giáo dục kỹ thuật và Dạy nghề (VTEP), Tổng cục Dạy Nghề, Hà Nội,
2003
[2]Walter H. Buchbaum. Sc.D, Microprocessor and IC families
[3]HPI Fachbuchreihen Pflaum Verlag Munchen - Mikrocompute Lehrbuch
[4] I. Scott Makenzie - The avr Atmega16 microcontroller
[5] Ngô Diên tập - lập trinhc với vi điều khiển avr
Các file đính kèm theo tài liệu này:
- giao_trinh_mo_dun_vi_dieu_khien_trinh_do_cao_dang_truong_cao.pdf