NGUYỄN VĂN SUM

Wednesday, November 15, 2017

Arduino interrupt example

Arduino interrupt example
https://nguyensumiot.wordpress.com/

http://nguyensum.simplesite.com/
Giới thiệu
Ngắt (interrupt) là những lời gọi hàm tự động khi hệ thống sinh ra một sự kiện. Những sự kiện này được nhà sản xuất vi điều khiển thiết lập bằng phần cứng và được cấu hình trong phần mềm bằng những tên gọi cố định.
Vì ngắt hoạt động độc lập và tự sinh ra khi được cấu hình nên chương trình chính sẽ đơn giản hơn. Một ví dụ điển hình về ngắt là hàm millis(). Hàm này tự động chạy cùng với chương trình và trả về 1 con số tăng dần theo thời gian mặc dù chúng ta không cài đặt nó. Việc cài đặt hàm millis() sử dụng đến ngắt và được cấu hình tự động bên trong mã chương trình Arduino.
Vì sao cần phải dùng đến ngắt?
Ngắt giúp chương trình gọn nhẹ và xử lý nhanh hơn. Chẳng hạn, khi kiểm tra 1 nút nhấn có được nhấn hay không, thông thường bạn cần kiểm tra trạng thái nút nhấn bằng hàm digitalRead() trong đoạn chương trình loop(). Với việc sử dụng ngắt, bạn chỉ cần nối nút nhấn đến đúng chân có hỗ trợ ngắt, sau đó cài đặt ngắt sẽ sinh ra khi trạng thái nút chuyển từ HIGH->LOW. Thêm 1 tên hàm sẽ gọi khi ngắt sinh ra. Vậy là xong, biến trong đoạn chương trình ngắt sẽ cho ta biết trạng thái nút nhấn.
Số lượng các ngắt phụ thuộc vào từng dòng vi điều khiển. Với Arduino Uno bạn chỉ có 2 ngắt, Mega 2560 có 6 ngắt và Leonardo có 5 ngắt.
Board
int.0
int.1
int.2
int.3
int.4
int.5
Uno, Ethernet
2
3




Mega2560
2
3
21
20
19
18
Leonardo
3
2
0
1
7
Cú pháp
attachInterrupt(interrupt, ISR, mode);
Thông số
interrupt: Số thứ tự của ngắt. Trên Arduino Uno, bạn có 2 ngắt với số thứ tự là 0 và 1. Ngắt số 0 nối với chân digital số 2 và ngắt số 1 nối với chân digital số 3. Muốn dùng ngắt bạn phải gắn nút nhấn hoặc cảm biến vào đúng các chân này thì mới sinh ra sự kiện ngắt. Nếu dùng ngắt số 0 mà gắn nút nhấn ở chân digital 4 thì không chạy được rồi.
ISR: tên hàm sẽ gọi khi có sự kiện ngắt được sinh ra.
mode: kiểu kích hoạt ngắt, bao gồm
  • LOW: kích hoạt liên tục khi trạng thái chân digital có mức thấp
  • HIGH: kích hoạt liên tục khi trạng thái chân digital có mức cao.
  • RISING: kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp thấp sang mức điện áp cao.
  • FALLING: kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp cao sang mức điện áp thấp.
Lưu ý: với mode LOW và HIGH, chương trình ngắt sẽ được gọi liên tục khi chân digital còn giữ mức điện áp tương ứng.
Trả về
không
Ví dụ
http://k2.arduino.vn/img/2014/06/27/0/594_8821-1403885295-0-interrupted-bb.750x528.jpg
Đoạn chương trình dưới đây sẽ làm sáng đèn led khi không nhấn nút và làm đèn led tắt đi khi người dùng nhấn nút, nếu vẫn giữ nút nhấn thì đèn led vẫn còn tắt. Sau khi thả nút nhấn, đèn led sẽ sáng trở lại.
int ledPin = 13;

void tatled()
{
    digitalWrite(ledPin, LOW); // tắt đèn led
}

void setup()
{
   pinMode(ledPin, OUTPUT);
   pinMode(2, INPUT_PULLUP); // sử dụng điện trở kéo lên cho chân số 2, ngắt 0
   attachInterrupt(0, tatled, LOW); // gọi hàm tatled liên tục khi còn nhấn nút
}

void loop()
{
  digitalWrite(ledPin, HIGH);   // bật đèn led
}
Một ví dụ khác khi sử dụng ngắt, các bạn có thể thoát khỏi các hàm delay để xử lý 1 đoạn chương trình khác
int ledPin = 13;

void tatled()
{
    // tắt đèn led khi nhấn nút, nhả ra led nhấp nháy trở lại
    digitalWrite(ledPin, LOW);
}

void setup()
{
    pinMode(ledPin, OUTPUT);
    pinMode(2, INPUT_PULLUP); // sử dụng điện trở kéo lên cho chân số 2, ngắt 0
    attachInterrupt(0, tatled, LOW);
}

void loop()
{
    // đoạn chương trình này nhấp nháy led sau 500ms
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
}


Using a PIR with Arduino

Reading PIR Sensors

Connecting PIR sensors to a microcontroller is really simple. The PIR acts as a digital output so all you need to do is listen for the pin to flip high (detected) or low (not detected).
Its likely that you'll want reriggering, so be sure to put the jumper in the H position!
Power the PIR with 5V and connect ground to ground. Then connect the output to a digital pin. In this example we'll use pin 2.
proximity_pirardbb.gif
The code is very simple, and is basically just keeps track of whether the input to pin 2 is high or low. It also tracks the state of the pin, so that it prints out a message when motion has started and stopped.
Code
  1. /*
  2. * PIR sensor tester
  3. */
  4. int ledPin = 13; // choose the pin for the LED
  5. int inputPin = 2; // choose the input pin (for PIR sensor)
  6. int pirState = LOW; // we start, assuming no motion detected
  7. int val = 0; // variable for reading the pin status
  8. void setup() {
  9. pinMode(ledPin, OUTPUT); // declare LED as output
  10. pinMode(inputPin, INPUT); // declare sensor as input
  11. Serial.begin(9600);
  12. }
  13. void loop(){
  14. val = digitalRead(inputPin); // read input value
  15. if (val == HIGH) { // check if the input is HIGH
  16. digitalWrite(ledPin, HIGH); // turn LED ON
  17. if (pirState == LOW) {
  18. // we have just turned on
  19. Serial.println("Motion detected!");
  20. // We only want to print on the output change, not state
  21. pirState = HIGH;
  22. }
  23. } else {
  24. digitalWrite(ledPin, LOW); // turn LED OFF
  25. if (pirState == HIGH){
  26. // we have just turned of
  27. Serial.println("Motion ended!");
  28. // We only want to print on the output change, not state
  29. pirState = LOW;
  30. }
  31. }
  32. }


Arduino DTH22 humidity temperature with LCD I2C 16x2



1. Giới thiệu

Bài viết này sẽ hướng dẫn các bạn cách đọc nhiệt độ - độ ẩm từ cảm biến và xuất ra màn hình LCD. Hy vọng rằng qua bài viết này, bạn sẽ dần hiểu được Arduino tạo cho người dùng một sự đơn giản và tiện lợi đến mức nào.

2. Nội dung chính

  • Đọc dữ liệu từ cảm biến nhiệt độ - độ ẩm DHT11.
  • Sử dụng màn hình LCD để xuất thông tin.

3. Phần cứng cần thiết


  • Màn hình LCD 16 x 2
  • Mạch điều khiển màn hình LCD sử dụng giao tiếp I2C
  • Cảm biến nhiệt độ - độ ẩm DHT11
  • Arduino UNO R3 (hoặc tương đương)
  • Breadboard
  • Dây cắm breadboard

4. Cảm biến DHT11


Cảm biến DHT11 đã được tích hợp trong một mạch duy nhất, bạn chỉ việc nối dây nguồn (Vcc, GND) và dây tín hiệu (Signal) vào mạch Arduino là xong.
Thông số kĩ thuật
  • Điện áp hoạt động: 3-5.5V DC
  • Ngưỡng độ ẩm: 20 - 90%
  • Sai số độ ẩm: ± 5%
  • Ngưỡng nhiệt độ: 0 - 55oC
  • Sai số nhiệt độ: ± 2oC
Kết nối cảm biến DHT11 với mạch Arduino
DHT11Arduino UNO R3
GNDGND
Vcc5V
SignalD2
Lập trình
  1. // Gọi thư viện DHT11
  2. #include "DHT.h"
  3.  
  4. const int DHTPIN = 2; //Đọc dữ liệu từ DHT11 ở chân 2 trên mạch Arduino
  5. const int DHTTYPE = DHT11; //Khai báo loại cảm biến, có 2 loại là DHT11 và DHT22
  6.  
  7. DHT dht(DHTPIN, DHTTYPE);
  8.  
  9. void setup() {
  10. Serial.begin(9600);
  11. dht.begin(); // Khởi động cảm biến
  12. }
  13.  
  14. void loop() {
  15. float h = dht.readHumidity(); //Đọc độ ẩm
  16. float t = dht.readTemperature(); //Đọc nhiệt độ
  17.  
  18. Serial.print("Nhiet do: ");
  19. Serial.println(t); //Xuất nhiệt độ
  20. Serial.print("Do am: ");
  21. Serial.println(h); //Xuất độ ẩm
  22. Serial.println(); //Xuống hàng
  23. delay(1000); //Đợi 1 giây
  24. }
Sau khi upload chương trình lên mạch Arduino, bạn hãy bấm Ctrl + Shift + M để mở cửa sổ Serial Monitor và xem kết quả.

 Một lưu ý nho nhỏ cho những bạn lập trình nâng cao, đó là cảm biến DHT11 sẽ "treo" (delay) chương trình của bạn trong quá trình nó đọc nhiệt độ, độ ẩm!

5. Màn hình LCD


Do vậy, để đơn giản hóa công việc, người ta đã tạo ra một loại mạch điều khiển màn hình LCD sử dụng giao tiếp I2C. Nói một cách đơn giản, bạn chỉ tốn ... 2 dây để điều khiển màn hình, thay vì 8 dây như cách thông thường.

Bạn chỉ việc hàn mạch vào như thế này là xong.

2 chân SDA và SCL là 2 chân tín hiệu dùng cho giao tiếp I2C.
Kết nối module màn hình với Arduino
Module màn hình LCD (16x2)Arduino
GNDGND
Vcc5V
SDAA4
SCLA5

Lập trình
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);
//0x27 là địa chỉ màn hình trong bus I2C. Phần này chúng ta không cần phải quá bận tâm vì hầu hết màn hình (20x4,...) đều như thế này!
//16 là số cột của màn hình (nếu dùng loại màn hình 20x4) thì thay bằng 20
//2 là số dòng của màn hình (nếu dùng loại màn hình 20x4) thì thay bằng 4

void setup() {
  lcd.init();       //Khởi động màn hình. Bắt đầu cho phép Arduino sử dụng màn hình, cũng giống như dht.begin() trong chương trình trên
  
  lcd.backlight();   //Bật đèn nền
  lcd.print("Hello world");  //Xuất ra chữ Hello world, mặc định sau khi init thì con trỏ tại cột 0 hàng 0 (trong C, khác với quy ước của tiếng Việt, mọi chỉ số đều bắt đầu bằng số 0, vì vậy bạn cần hiểu rằng, nếu ta kẻ một bảng có 2 hàng và 16 cột thì ô góc trên cùng bên trái là ô (0,0) tương tự với các ô khác, ta cứ tăng dần giá trị lên!
  lcd.setCursor(0,1); //Đưa con trỏ tới hàng 1, cột 0
  lcd.print("I love Arduino !");// Bạn thấy trên màn hình rồi chứ?
}

void loop() {
}

6. Kết hợp đọc nhiệt độ độ - độ ẩm và xuất ra màn hình

Bây giờ bạn đã biết cách đọc nhiệt độ, độ ẩm rồi và cũng đã biết xuất ra màn hình. Vậy bây giờ chúng ta chỉ việc kết hợp cả 2 lại để được một đoạn code như thế này:
#include <DHT.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

const int DHTPIN = 2;
const int DHTTYPE = DHT11;
DHT dht(DHTPIN, DHTTYPE);

byte degree[8] = {
  0B01110,
  0B01010,
  0B01110,
  0B00000,
  0B00000,
  0B00000,
  0B00000,
  0B00000
};

void setup() {
  lcd.init();  
  lcd.backlight();
  
  lcd.print("Nhiet do: ");
  lcd.setCursor(0,1);
  lcd.print("Do am: ");
  
  lcd.createChar(1, degree);

  dht.begin();  
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(t) || isnan(h)) { // Kiểm tra xem thử việc đọc giá trị có bị thất bại hay không. Hàm isnan bạn xem tại đây http://arduino.vn/reference/isnan
  } 
  else {
    lcd.setCursor(10,0);
    lcd.print(round(t));
    lcd.print(" ");
    lcd.write(1);
    lcd.print("C");

    lcd.setCursor(10,1);
    lcd.print(round(h));
    lcd.print(" %");    
  }
}