GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC NÔNG LÂM THÀNH PHỐ HỒ CHÍ MINH
KHOA CƠ KHÍ – CÔNG NGHỆ
¯
BÁO CÁO THỰC HÀNH CẢM BIẾN TRONG ĐIỀU KHIỂN
ĐỌC XUNG ENCODER
GVHD : Ths. LÊ VĂN BẠN
SVTH : Trần Đức Bảo
LỚP
: DH12TD
MSSV : 12138017
Tháng 6 năm 2015
I.
GIỚI THIỆU ENCODER:
II.
SƠ ĐỒ NGUYÊN LÝ:
III.
LẬP TRÌNH TRÊN ARDUINO:
/*
Chương trình ngắt cho Encoder quay
Một encoder quay thông thường có 3 chân, nhìn từ mặt trước là A C B
Quay theo chiều kim đồng hồ A(on)>B(on)>A(off)->B(off)
Quay ngược chiều kim đồng hồ B(on)>A(on)>B(off)->A(off)
Ngoài ra còn có một chân có nút nhấn và 2 chân nguồn
*/
#define encoderPinA 2 // Tương ứng chân DT trên Encoder: right (labeled DT
on our decoder, yellow wire)
#define encoderPinB 3 // Tương ứng chân CLK trên Encoder: left (labeled
CLK on our decoder, green wire)
#define clearButton 8 // Chân của nút nhấn switch (labeled SW on our decoder,
orange wire)
// Chân + nối nguồn 5V và chân GND nối cực âm connect the +5v and gnd
appropriately
volatile unsigned int encoderPos = 0; // Cho vị trí đầu bằng 0 a counter for the
dial
unsigned int lastReportedPos = 1; // Vị trí cuối bằng 1 i change management
static boolean rotating=false; // Quản lý debounce (giống như là chống nhiễu)
debounce management
// các biến cho trình phục vụ ngắt interrupt service routine vars
boolean A_set = false;
boolean B_set = false;
void setup() {
pinMode(encoderPinA, INPUT_PULLUP); // INPUT-PULLUP tương đương
Mode INPUT và tự động nhận trạng thái HIGH hoặc LOW
pinMode(encoderPinB, INPUT_PULLUP);
pinMode(clearButton, INPUT_PULLUP);
// Chân encoder trên ngắt 0 (chân 2): encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, doEncoderA, CHANGE);
// Chân encoder trên ngắt 1 (chân 3) encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, doEncoderB, CHANGE);
Serial.begin(9600); // chuyển dữ liệu lên cổng Serial Port
}
// Vòng lặp chính, công việc được thực hiện bởi trình phục vụ ngắt: main loop,
work is done by interrupt service routines, this one only prints stuff
void loop() {
rotating = true; // Khởi động bộ debounce (có thể hiểu như bộ chống nhiễu):
reset the debouncer
if (lastReportedPos != encoderPos) {
Serial.print("Index:");
Serial.println(encoderPos, DEC);
lastReportedPos = encoderPos;
}
if (digitalRead(clearButton) == LOW ) {
encoderPos = 0;
}
}
// Ngắt khi chuyển trạng thái của A: Interrupt on A changing state
void doEncoderA(){
// debounce
if ( rotating ) delay (1); // Chờ 1 chút wait a little until the bouncing is done
// Kiểm tra việc chuyển đổi trạng thái, xem có thật sự thay đổi trạng thái chưa:
Test transition, did things really change?
if( digitalRead(encoderPinA) != A_set ) { // debounce một lần nữa: debounce
once more
A_set = !A_set;
// Cộng 1 nếu có tín hiệu A rồi có tín hiệu B: adjust counter + if A leads B
if ( A_set && !B_set )
encoderPos += 1;
rotating = false; // Không cần debounce nữa cho đến khi được nhấn lần nữa: no
more debouncing until loop() hits again
}
}
// Ngắt khi thay đổi trạng thái ở B, tương tự như ở A: Interrupt on B changing
state, same as A above
void doEncoderB(){
if ( rotating ) delay (1);
if( digitalRead(encoderPinB) != B_set ) {
B_set = !B_set;
// Trừ 1 nếu B rồi đến A: adjust counter - 1 if B leads A
if( B_set && !A_set )
encoderPos -= 1;
rotating = false;
}
}