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

* 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:

pdf154 trang | Chia sẻ: Tiểu Khải Minh | Ngày: 23/02/2024 | Lượt xem: 59 | Lượt tải: 0download
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:

  • pdfgiao_trinh_mo_dun_vi_dieu_khien_trinh_do_cao_dang_truong_cao.pdf