Làm máy đo nhiệt độ cầm tay như thế nào, có khó không?

Giới thiệu

Đúng như tiêu đề mình đã trình bày, hôm nay chúng ta sẽ đi tìm lời giải cho bài toán trên. Qua bài viết này ngoài việc tự trả lời câu hỏi vừa được nêu ra, mình còn mong muốn hướng các bạn đến khái niệm "Học để ứng dụng và đọc để sáng tạo"! Từ đó, bạn sẽ học thêm một kĩ năng mềm đó là "bóc tách" vấn đề của một "bài toán thực tế".

Vấn đề hôm nay là gì?

Như tiêu đề đã nêu, chúng ta cần giải quyết vấn đề "làm một máy đó nhiệt độ cầm tay"! Vậy vấn đề này bao gồm những vấn đề nhỏ gì? Hãy cùng mình liệt kê nhé.

Thứ nhất, chúng ta đang làm một máy và vì vậy chúng ta cần một nguồn năng lượng! Để biết năng lượng cho một dự án Arduino là như thế nào thì bạn có thể tham khảo bài viết Pin - Năng lượng cho mọi dự án Arduino. Nói nôm na là chúng ta cần một bộ pin vừa tầm cho một máy cầm tay.

Thứ hai, làm thế nào để đọc được nhiệt độ? Rất đơn giản, chúng ta sẽ xử dụng cảm biến LM35, nếu bạn chưa biết cảm biến LM35 là gì, và làm thế nào để đọc nhiệt độ từ đó, hãy tham khảo bài viết Cảm biến nhiệt độ LM35 và cách sử dụng nó trong môi trường Arduino. Khi đã nghiên cứu xong bài viết này, chúng ta sẽ biết cảm biến LM35 rất dễ sử dụng, chỉ cần sử dụng hàm analogRead() và một công thức cực kì đơn giản và ngắn gọn!

Thứ ba, đã là máy cầm tay thì ta phải hiển thị được nhiệt độ một cách nhanh chóng nhất hay còn gọi là "thời gian thực nhiệt độ"! Vậy ta sẽ làm như thế nào? Không khó, khi đã có đươc nhiệt độ, chúng ta sẽ dùng 2 LED 7 đoạn đơn và dùng IC HC595 để shiftout ra 2 LED này, nếu chưa biết về khái niệm shiftout bạn hãy tham khảo tại đây.

Thứ tư, lựa chọn vi điều khiển cho máy cầm tay này như thé nào để hợp lý hóa giá thành và đơn giản hóa việc lắp đặt? Chúng ta sẽ thống kê số chân sẽ dùng trong dự án này, đó là 1 chân analog để đọc tín hiệu từ cảm biến LM35, 3 chân digital để shiftout ra IC HC595. Tóm lại là có 4 chân, như vậy, ta có thể dùng rất nhiều loại vi điều khiển với giá thành khác nhau để hoàn thiện dự án này. Tuy nhiên, theo mình nghỉ thì chúng ta chỉ nên dùng vi điều khiển ATtiny13 để lập trình vì nó đáp ứng được các yêu cầu mà chúng ta vừa liệt kê nãy giờ. Nếu chưa biết về vi điều khiển ATtiny13, bạn hãy tham khảo bài viết Bài 2: Attiny13 - Trợ thủ đắc lực của Arduino - Lập trình nó?

Tổng kết

Chúng ta tạm thời đã liệt kê được là 4 vấn đề có thể dễ dàng nhìn thấy ngay được nếu muốn giải quyết bài toán "làm máy đo nhiệt độ cầm tay". Vì vậy hãy giải quyết từng vấn đề và nếu có phát sinh thêm vấn đề này thì hãy cùng nhau giải quyết nó nhé!

Tuy nhiên, đầu tiên, để dễ dàng hoàn thành bài viết này, các bạn hãy chuẩn bị cho mình một số phần cứng sau:

Phần cứng

Vấn đề 1 - Pin

Nói về pin, đây là một vấn đề nhỏ trong dự án này, vì sao?

  • Thứ nhất, trong máy của chúng ta sẽ làm, nó không có nhiều phần cứng đòi công suất cao và chúng đều hoạt động tốt ở mức điện áp 5V đến 6V.
  • Thứ hai, chúng ta hướng đến việc xây dựng một máy cầm tay nên kích thước pin và khung pin phải ở một mức nào đó mà con người cầm được. Trên thị trường đã có sẵn loại khung này (khung pin 4 viên hình lăng trụ) và việc tìm kiếm rất đơn giản.

Nói tóm lại, bạn chỉ cần tím cách đáp ứng được nhu cầu về hiệu điện thế (5V hoặc 6V) cho sản phẩm của mình là ok! Ở dự án này, chúng ta chưa quan tâm về công suất và hiệu suất của pin.

Bạn thấy đấy, phân tích một vấn đề không có gì phức tạp cả, nhiều khi nó còn rất đơn giản là đằng khác. Vậy bạn hãy bắt đầu suy ngẫm về câu hỏi sau: "làm máy đo nhiệt độ cầm tay có khó không nhé?"

 Vấn đề 2 + 4 - Làm thế nào để đọc được nhiệt độ của LM35 trên ATTiny13

Bạn có ngạc nhiên vì sao tớ lại ghi là "2+4" mà không phải là "2+3"? Bởi vì khi chúng ta làm một dự án, sau bước liệt kê những vấn đề có thể cần được giải quyết thì không có nghĩa chúng ta phải giải quyết những vấn đề đó theo thứ tự vừa được liệt kê. Bạn phải vận dụng sự liên kết giữa các phần cứng (nếu có thể) để góp nhiều vấn đề con thành một vấn đề trung gian từ đó giải quyết luôn một lần. Như vậy chúng ta sẽ tăng được tốc độ làm việc và giảm thời gian làm việc cho dự án này, từ đó có thời gian làm những dự án khác hoặc có thời gian để tối ưu hóa những dòng code của mình.

Bây giờ, chúng ta đi vào nội dung chính của chủ đề này nhé.

Thứ nhất, bạn cần biết cách đọc nhiệt độ của IC LM35 trên Arduino, vì vậy, bạn cần đọc bài viết Cảm biến nhiệt độ LM35 và cách sử dụng nó trong môi trường Arduino ngay.

Thứ hai, bạn chưa biết ATTiny13 là gì? Như vậy bạn cần phải đọc và ngẫm nghĩ các bài viết về ATTiny13 trên Cộng đồng Arduino Việt Nam tại đây.

Như vậy, sau khi đã có được kiến thức về việc lập trình ATTiny13, bạn sẽ thấy vấn đề này của chúng ta sẽ hơi hơi khó nhằn, phải không? Vì dung lượng chương trình của ATTiny13 chỉ có 1KB trong khi đó code của chúng ta sẽ rất là dài (vừa đọc nhiệt độ, sau đó lại shiftout ra nữa mà). Nhưng đừng lo lắng, đó chỉ là những gì mà suy nghĩ của bạn đang cố gắng thuyết phục bạn. Hãy dập tắt nó và tiến hành, đừng lo lắng những thứ của tương lai vì chính chúng ta quyết định tương lai nó như thế nào! Vì vậy, đừng lo lắng sẽ không đủ dung lượng bộ nhớ flash, chính chúng ta sẽ quyết định code của chúng ta sẽ như thế nào mà lị cool!

Bây giờ, chúng ta sẽ tìm hiểu xem ATTiny13 có bao nhiêu chân Analog nhé.

Gợi ý: Những chân nào có chữ ADCx (x là một số nguyên) không âm) thì đó là chân analog đấy!

Như vậy, chúng ta có 4 chân Analog nhưng trong đó có một chân là chân ADC0 trùng với chân RESET nên rất khó dùng, nên ta hãy bỏ nó ra. Như vậy ta có 3 chân Analog có thể dễ dàng dùng được, đó là ADC1 (pin 7), ADC2 (pin 3), ADC3 (pin 2).

Vậy còn chần chừ gì nữa, hãy cùng tớ mắc mạch thôi!

Đầu tiên, bạn hãy mắc mạch như thế này nhé.

Mạch vừa rồi là mạch để chúng ta lập trình ATTiny13 qua giao thức SPI. Nếu bạn chưa biết giao thức này và cách lập trình cho ATTiny13 thì bắt buộc bạn phải xem bài viết Bài 2: Attiny13 - Trợ thủ đắc lực của Arduino - Lập trình nó?

Nếu có điều kiện và thời gian, bạn nên tự làm cho mình một mạch nạp ATTiny13 sẵn (như hình dưới), và mỗi lần cần dùng ta chỉ cần gắn nó vào.

Bây giờ, việc tiếp theo của bạn không có gì khó khăn cả. Bạn chỉ việc gắn bé LM35 như trong bài viết Cảm biến nhiệt độ LM35 và cách sử dụng nó trong môi trường Arduino. Nhưng vấn đề mới đặt ra cho bạn là: Làm thế nào để đọc tín hiểu Analog từ ATTiny13? Vâng, câu hỏi này không khó trả lời đâu bạn nhé. Bạn hãy kéo lên xem ảnh các chân của ATTiny13 và nhìn vào thông tin về các chân của nó. Nếu đã có thêm những kiến thức sâu hơn về VĐK (vi điều khiển) các loại, thì bạn sẽ nhận ra ngay ở ATTiny13 chân nào là chân Analog. Nếu chưa, thì bạn hãy để ý đến những chân có thông tin là ADCx (trong đó x là một số nguyên dương). Ở đây mình dùng chân ADC2 (chân số 3).

Câu hỏi tiếp theo mà mình nghĩ bạn sẽ thắc mắc, đó là "làm thế nào để đọc được tín hiệu điện Analog của cảm biến LM35?". Vâng, câu hỏi này khá hay và mới, bạn chỉ việc sử dụng cái số x ở trên với hàm analogRead là được ngay thôi mà devil.

//đọc cảm biến LM35
int lm35Pin = 2;//ADC2

void setup() {
    //Cài đặt Analog reference. Trang 91 của datasheet.
    /*
        cảm biến LM35 chỉ đo được lên đến 150 độ C (max = 1.5V).
        Nhưng mình nghĩ ta không có gì để đảm bảo độ bền của sản phẩm này
        nếu đưa nó vào nơi nào có nhiệt độ khá cao như vậy. Vì vậy, mình
        đã đặt lại analog reference của ATTiny13 ở mức 1.1 V để việc đo chính 
        xác hơn và đảm bảo được dung lượng của sketch khi upload lên ATTiny13
        khi hoàn thiện dự án.
    */
    ADMUX |= _BV(REFS0);
}

void loop() { 
    int temperature =  analogRead(lm35Pin) * 111UL / 1024;
}

Tại sao lại là 111UL / 1024UL? Nó không hề giống với công thức đã nêu ở bài Cảm biến nhiệt độ LM35 và cách sử dụng nó trong môi trường Arduino. Vâng, chúng ta sẽ cùng phân tích vấn đề này nhé. Nếu bạn dùng đồng hồ đo điện sẽ thấy chân tín hiệu của cảm biến LM35 chỉ ở mức 0.xx vol mà thôi. Như vậy nếu ta dùng analog reference là 5V thì khoảng đo của chúng ta sẽ rất nhỏ và như vậy máy của chúng ta sẽ hoạt động không chính xác! Vì thế, chúng ta sẽ chỉnh lại mức analog reference đó thành 1.1 V (thường thì bạn sẽ không đo được những thứ quá nóng nên mức 1.1 V là ổn - tuy nhiên LM35 có thể đo đến 150 độ C).

Lúc này, ta sẽ phát triển công thức từ bài trước và được công thức sau

float temperature = (1.1*analogRead(2)*100.0/1024.0);

Vì ATTiny13 khá nhỏ nên thực hiện các phép tính trên số thực sẽ làm ta tốn khá nhiều bộ nhớ. Vì thế, ta phải tối ưu hóa công thức thành các phép nhân và chia các số nguyên. Ở đây, 1.1*100 ta sẽ cho thành 110, rồi sau đó đem chia cho 1024 (các số vừa rồi là các số nguyên). Như vậy công thức sẽ trở thành.

int temperature = analogRead(2)*110/1024;

Nhưng, nếu nhìn sâu hơn một tí, bạn sẽ thấy đoạn code này lỗi ngay! Vì sao lỗi? Thứ nhất, ta đã chỉnh lại analog reference là 1.1 Vol nên hàm analogRead bình thường cũng cho một số khá lớn và tập xác định của nó là đoạn từ 0-1023. Như vậy, nếu đem giá trị đó nhân với 110 thì ta sẽ được một giá trị nằm trong khoảng từ 0-1023*110 (0-112530). Như vậy, ta sẽ có một số vượt quá khoảng xác định của int. Như vậy, ta cần dùng một kiểu dữ liệu lớn hơn để lưu trữ giá trị của phép tính này, vì vậy, mình đã viết công thức như trên. Đoạn này hơi khó giải thích, vì nó cần giải thích khá dài và trước đó mình đã có giải thích trong loạt bài về các kiểu dữ liệu số nguyêntoán tử số học trong mục Tài liệu tham khảo. Vì vậy, nếu muốn biết được chi tiết tại làm sao nó phải như thế, mình khuyên bạn nên đọc thêm những bài vừa rồi.

À, ngoài ra, ATTiny13 không có Serial Monitor nên bạn không thể debug (Tìm lỗi) một cách dễ dàng trên ATTiny13 đâu nhé. Vì vậy, để debug, bạn phải viết code lại cho Arduino Uno và test trên Arduino Uno.

Vấn đề 3 - làm thế nào để xuất giá trị của LM35 qua shiftOut bé 595

Vấn đề này vừa khó lại vừa dễ. Khó vì nó nhiều dây nhợ, dễ vì nó đơn giản chỉ là việc gắn dây devil!

Bạn cần lắp mạch như ở bài Cách lập trình nhiều con LED 7 đoạn (loại đơn) và bài Dùng ATTiny13 để shiftOut ra IC 595 điều khiển nhiều LED để tập lắp mạch trước và từ đó ta sẽ dùng cơ sở 2 mạch ấy để lắp thành mạch dưới đây.

Hơi khó nhìn, nhưng nếu làm 2 bài trước thì sẽ không hề khó đâu bạn. Vấn đề tiếp theo là phần lập trình. Nếu như làm 2 bài mình đã nêu ở trước thì chắc hẳn bây giờ bạn sẽ có những kinh nghiệm riêng. Nên việc đọc các dòng code dưới đây sẽ dễ hiểu hơn. Vì vậy, nếu chưa đọc 2 bài trước thì bạn nên đọc! Không vòng vo nữa, tiếp tục đến phần code nào.

//đọc cảm biến LM35
int lm35Pin = 2;//ADC2

/*
shiftOut ra 1 Module LED 7 đoạn đơn
*/
//chân ST_CP của 74HC595
int latchPin = 1;//PB1
//chân SH_CP của 74HC595
int clockPin = 0;//PB0
//Chân DS của 74HC595
int dataPin = 2;//PB2

//Timer để chỉnh lại đồng hồ của ATTiny13
int timer = 150;



// Ta sẽ xây dựng mảng hằng số với các giá trị cho trước
// Các bit được đánh số thứ tự (0-7) từ phải qua trái (tương ứng với A-F,DP)
// Vì ta dùng LED 7 đoạn chung cực dương nên với các bit 0
// thì các đoạn của LED 7 đoạn sẽ sáng
// với các bit 1 thì đoạn ấy sẽ tắt

//mảng có 10 số (từ 0-9) và 
const byte Seg[10] = {
  0b11000000,//0 - các thanh từ a-f sáng
  0b11111001,//1 - chỉ có 2 thanh b,c sáng
  0b10100100,//2
  0b10110000,//3
  0b10011001,//4
  0b10010010,//5
  0b10000010,//6
  0b11111000,//7
  0b10000000,//8
  0b10010000,//9
};


void setup() {
  
  //Cài đặt timer 
  TCCR0B |=  _BV(CS02);
  
  //Cài đặt Analog reference. Trang 91 của datasheet.
  /*
    cảm biến LM35 chỉ đo được lên đến 150 độ C (max = 1.5V).
    Nhưng mình nghĩ ta không có gì để đảm bảo độ bền của sản phẩm này
    nếu đưa nó vào nơi nào có nhiệt độ khá cao như vậy. Vì vậy, mình
    đã đặt lại analog reference của ATTiny13 ở mức 1.1 V để việc đo chính 
    xác hơn và đảm bảo được dung lượng của sketch khi upload lên ATTiny13
    khi hoàn thiện dự án.
  */
  ADMUX |= _BV(REFS0);
  
  //Bạn BUỘC PHẢI pinMode các chân này là OUTPUT
  
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}
void _delay(word time = 1) { // Xây dựng lại hàm delay
  for (word i = 1; i<=time;i++) {
    delayMicroseconds(timer);
  }
}
void HienThiLED7doan(int Giatri) {
   digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, Seg[Giatri / 10]); 
  shiftOut(dataPin, clockPin, MSBFIRST, Seg[Giatri % 10]); 
   digitalWrite(latchPin, HIGH);
}


void loop() { 
  int temperature =  analogRead(lm35Pin) * 111UL / 1024;
  HienThiLED7doan(temperature);
  _delay(500);
  
}

Như các bạn đã thấy, mình đã xây dựng lại hàm HienThiLED7doan cho nânó đơn giản hơn phù vớp với vấn đề bài toán là ta chỉ shiftout ra 2 bé 595 để điều khiển 2 bé led 7 đoạn. Vì nhiệt độ của nó máy cần đo là một số nguyên dương có 2 chữ số nên nếu mình đem số chia cho 10 sẽ được chữ số hàng chục và phần dư là hàng đơn vị.

Không hề khó phải không nào các bạn!

Video nguyên lý mình đã làm xong, bạn hãy hoàn thiện nó thành một sản phẩm nhé

Kết luận

Qua quá trình làm vừa rồi, mình nghĩ bạn có thể dễ dàng làm được dự án này và nhiều dự án hơn nữa. Thực chất các bước mình vừa làm cũng không có gì khó cả. Chỉ là việc ta phân tích vấn đề ban đầu rồi liệt kê những gì cần tìm hiểu, sau đó tiến hành giải quyết các vấn đề cần liệt kê theo thứ tự từ dễ đến khó, rồi giải quyết các vấn đề nhỏ nảy sinh ở từng phần. Cuối cùng là bước hoàn thiện sản phẩm thành những mô hình nhỏ nhỏ xinh xinh!

Làm một dự án Arduino không hề khó, nó chỉ khó khi bạn không dám đam mê và không dám tìm kiếm. Đừng nên đặt quá nhiều câu hỏi cho mình, chỉ cần nghĩ đơn giản và tìm kiếm theo những gì mình nghĩ, dần dà nó sẽ ra. Khi bí quá thì mới đặt câu hỏi. Vì hầu hết các vấn đề đều có trên mạng Internet này hết đấy, bạn ơi!

Về vấn đề "Học để ứng dụng và đọc để sáng tạo", mình xin giải thích như sau (rất mong nhận được những phản hồi tích cực của các bạn):

  1. Học để ứng dụng

    • Khi làm một việc nào đó, nếu bạn không có mục đích thì sẽ không thể nào làm một cách hoàn hảo được. Ở Việt Nam, học sinh cấp 3 học rất nhiều thứ, như đạo hàm, tích phân, vi phân,... nhưng hầu hết khi được hỏi, các bạn nói rằng: chúng tớ học để thi đại học, chúng tớ học để thi học sinh giỏi chơi cho vui,... Như thế thì giúp ích gì cho các bạn sau này? Nói thẳng ra là không giúp ích được gì cả. Vì sau này, khi lên đại học và những cấp cao hơn, các giảng viên sẽ cung cấp lại một cách khoa học và hệ thống hóa các kiến thức giúp bạn giải quyết được các vấn đề trong môn học của mình. Khi đó, bạn sẽ tự yêu thích môn học mà mình đang học và học nó thật tốt.
    • Vì sao lại như vậy? Bởi vì, lúc đấy, bạn đã có một mục đích cao cả cho việc học. Đó là, học để ứng dụng. Có thể bạn sẽ phản bác ý kiến của tôi cho rằng, bạn học tốt nhưng không phải học để ứng dụng mà là học để ... (kiếm tiền, vì gia đình quá khó khăn,...). Nhưng theo quan điểm của mình, để làm được những việc đó, bạn phải ứng dụng được những kiến thức được học trong trường và tự học trong quá trình tiếp xúc cọ xát với xã hội, từ đó hoàn thiện những ước mơ cao đẹp!
    • Vậy, nếu học có mục đích và nếu mục đích của nó là để ứng dụng cộng với nghị lực vượt quá thì bạn sẽ dễ dàng vượt qua mọi khó khăn!
  2. Đọc để sáng tạo
    • Bạn đã bao giờ đọc những bài giải dài dòng trong sách tham khảo và tự thấy mình có thể rút gọn nó cho dễ hiểu hơn chưa? Chắc hẳn là đa số các bạn đều đã nghĩ như vậy đúng không! Rất tốt, hãy tiếp tục suy nghĩ như vậy nhé, đó là mầm móng của sự sáng tạo.
    • Bây giờ, bạn nghĩ mình sẽ giải tốt bài tập đó hơn sách, và biết đâu được sau này mình sẽ làm được một chiếc vệ tinh nhẹ hơn, to hơn và do chính con người Việt Nam chế tạo,... Trong môi trường tự nhiên, mọi cây đều xuất phát từ những hạt giống (trong tự nhiên không có ghép, chiết,... nhé), và những sản phẩm sáng tạo, những ý tưởng thông minh đều bắt nguồn từ bạn. Bạn chính là hạt giống của sự sáng tạo, và trong điều kiện thuận lợi, bạn sẽ nảy chồi và phát triển mạnh mẽ.
    • Vậy, tại sao phải đọc? Đọc để biết, đọc để hiểu, đọc để sáng tạo. Ta cần phải biết "họ" làm được gì! Phải hiểu họ làm những gì! Và từ đó sáng tạo để làm cho nó tốt hơn, nó bá đạo hơn! Như vậy, nếu chịu khó đọc và suy nghĩ, những ý tưởng sáng tạo sẽ dạt dào đến với bạn. Và lúc này, như một người nông dân trồng (đọc) cây ăn quả đã đến mùa trái (sáng tạo), bạn chỉ việc hái và lựa ra những trái (ý tưởng) tốt nhất để tiến hành đem bán (hoàn thiện sản phẩm và đem bán)
  3. Tóm tại, nếu bạn có mục đích học và dám đọc để sáng tạo thì ắc hẳn không có gì có thể cản bước bạn ngoại trừ bản thân lười biếng!
  4. Và Cộng đồng Arduino Việt Nam sẽ luôn đồng hành cùng bạn, chia sẻ những tri thức và giúp bạn đi đến thành công!

Chúc bạn thành công!

lên
15 thành viên đã đánh giá bài viết này hữu ích.
Các dự án được truyền cảm hứng

Bộ điều khiển PID - ứng dụng phần 2 - xe dò line dùng thuật toán PID

Tiép nối bài viết về xe dò line cảm ơn Đỗ Hữu Toàn đã viết hộ mình phần 4. hôm nay mình sẽ làm cho chiếc xe dò line đi mượt và có hồn hơn 

lên
34 thành viên đã đánh giá bài viết này hữu ích.
Các bài viết cùng tác giả

millis()

millis() có nhiệm vụ trả về một số - là thời gian (tính theo mili giây) kể từ lúc mạch Arduino bắt đầu chương trình của bạn. Nó sẽ tràn số và quay số 0 (sau đó tiếp tục tăng) sau 50 ngày.

lên
18 thành viên đã đánh giá bài viết này hữu ích.

Ra mắt thư viện iNut cho Arduino, điều khiển từ xa qua Internet bằng mạch iNut cảm biến

Bạn muốn làm thiết bị điện điều khiển từ xa, quản lý hệ thống cảm biến nhà vườn, nhà kính của mình qua Internet? Hay bạn muốn làm các startup liên quan đến nông nghiệp thông minh, nhà máy thông minh hay thành phố thông minh mà không biết bắt đầu từ đâu? Và đây, iNut Platform chính là giải pháp dành cho bạn. Qua bài viết này này, thư viện iNut cho Arduino sẽ giúp bạn thực hiện hóa vấn đề này, cùng khám phá nhé.

Nếu bạn đã từng làm qua sóng bluetooth với thư viện SerialCommand thì bạn sẽ thấy cực kỳ quen thuộc khi sử dụng thư viện iNut này!

lên
10 thành viên đã đánh giá bài viết này hữu ích.