Hướng dẫn HC SR04 Arduino và màn hình OLED

Trong hướng dẫn trước, IoTZone đã giải thích cách lập trình HC SR04 Arduino để đo khoảng cách và hiển thị kết quả lên màn hình Serial. Trong bài này, hãy nâng cấp một chút: hiển thị kết quả lên màn hình OLED nhé!

Chuẩn bị

  • Cảm biến siêu âm HC SR04
  • ESP32
  • Màn hình OLED 0.96inch
  • Dây Jumper
  • Breadboard

Kết nối

Bạn hãy kết nối các thành phần trên như hình dưới đây:

Kết nối cảm biến HC SR04 Arduino và OLED với ESP32

Cài thư viện và nạp chương trình

Để điều khiển cảm biến HC SR04 Arduino, bạn cần phải cài thư viện Adafruit SSD1306 và Adafruit GFX. Bạn có thể vào mục Arduino Library Manager để tải các thư viện này.

Cụ thể, bạn hãy click vào Sketch >> Library >> Manage Libraries, tìm kiếm dòng chữ “SSD1306” và cái thư viện có tên tương ứng, như hình dưới:

Cài thư viện Adafruit SSD1306
Cài thư viện Adafruit SSD1306

Bạn hãy làm tương tự với thư viện Adafruit để cài nhé!

Sau khi cài xong, bạn hãy upload đoạn code có sẵn bên dưới vào mạch ESP32 của mình:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const int trigPin = 5;
const int echoPin = 18;
//define sound speed in cm/uS
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701
long duration;
int distanceCm;
int distanceInch;
void setup() {
Serial.begin(115200);
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
delay(500);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculate the distance
distanceCm = duration * SOUND_SPEED/2;
// Convert to inches
distanceInch = distanceCm * CM_TO_INCH;
// Prints the distance in the Serial Monitor
Serial.print("Distance (cm): ");
Serial.println(distanceCm);
Serial.print("Distance (inch): ");
Serial.println(distanceInch);
display.clearDisplay();
display.setCursor(0, 25);
//Display distance in cm
display.print(distanceCm);
display.print(" cm");
// Display distance in inches
/* display.print(distanceInch);
display.print(" in");*/
display.display();
delay(500);
}
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); const int trigPin = 5; const int echoPin = 18; //define sound speed in cm/uS #define SOUND_SPEED 0.034 #define CM_TO_INCH 0.393701 long duration; int distanceCm; int distanceInch; void setup() { Serial.begin(115200); pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output pinMode(echoPin, INPUT); // Sets the echoPin as an Input if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for(;;); } delay(500); display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); } void loop() { // Clears the trigPin digitalWrite(trigPin, LOW); delayMicroseconds(2); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH); // Calculate the distance distanceCm = duration * SOUND_SPEED/2; // Convert to inches distanceInch = distanceCm * CM_TO_INCH; // Prints the distance in the Serial Monitor Serial.print("Distance (cm): "); Serial.println(distanceCm); Serial.print("Distance (inch): "); Serial.println(distanceInch); display.clearDisplay(); display.setCursor(0, 25); //Display distance in cm display.print(distanceCm); display.print(" cm"); // Display distance in inches /* display.print(distanceInch); display.print(" in");*/ display.display(); delay(500); }
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

const int trigPin = 5;
const int echoPin = 18;

//define sound speed in cm/uS
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701

long duration;
int distanceCm;
int distanceInch;

void setup() {
  Serial.begin(115200);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(500);
  display.clearDisplay();

  display.setTextSize(2);
  display.setTextColor(WHITE);
}

void loop() {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  
  // Calculate the distance
  distanceCm = duration * SOUND_SPEED/2;
  
  // Convert to inches
  distanceInch = distanceCm * CM_TO_INCH;
  
  // Prints the distance in the Serial Monitor
  Serial.print("Distance (cm): ");
  Serial.println(distanceCm);
  Serial.print("Distance (inch): ");
  Serial.println(distanceInch);

  display.clearDisplay();
  display.setCursor(0, 25);
  //Display distance in cm
  display.print(distanceCm);
  display.print(" cm");
  
  // Display distance in inches
  /* display.print(distanceInch);
  display.print(" in");*/
  display.display(); 

  delay(500);  
}

Giải thích chương trình

Khai báo thư viện cần dùng:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Khai báo chiều dài và chiều rộng của màn hình OLED, như màn hình của mình dùng là loại 128 x 64, mình sẽ khai báo như sau:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Tạo một đối tượng Adafruit_SSD1306 với display để xử lý màn hình OLED:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

Khai báo cổng cắm của HC SR04 Arduino mà bạn đã kết nối:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const int trigPin = 5;
const int echoPin = 18;
const int trigPin = 5; const int echoPin = 18;
const int trigPin = 5;
const int echoPin = 18;

Tạo biến để lưu giá trị khoảng cách, thời gian gửi sóng siêu âm đi và nhận sóng phản hồi về:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
long duration;
int distanceCm;
int distanceInch;
long duration; int distanceCm; int distanceInch;
long duration;
int distanceCm;
int distanceInch;

setup()

Tạo màn hình Serial ở tốc độ 115200 để quan sát kết quả khi cần:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Serial.begin(115200);
Serial.begin(115200);
Serial.begin(115200);

Cấu hình chân Trig là một đầu ra, còn châu Echo là một đầu vào:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input

Khởi tạo màn hình OLED:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for(;;); }
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  Serial.println(F("SSD1306 allocation failed"));
  for(;;);
}

Xác định cỡ chữ là bao nhiêu và màu sắc cho chữ:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
display.setTextSize(2);
display.setTextColor(WHITE);
display.setTextSize(2); display.setTextColor(WHITE);
display.setTextSize(2);
display.setTextColor(WHITE);

loop()

Ở đây, chúng ta sẽ lập trình hiển thị kết quả đo được từ cảm biến siêu âm HC SR04 và hiển thị kết quả này lên màn hình OLED.

Đầu tiên, chúng ta tính khoảng cách bằng dòng lệnh sau (IoTZone đã giải thích công thức chi tiết ở bài viết trước, bạn có thể xem lại tại: Sử dụng cảm biến khoảng cách HC SR04 với ESP32 và Arduino)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculate the distance
distanceCm = duration * SOUND_SPEED/2;
// Convert to inches
distanceInch = distanceCm * CM_TO_INCH;
// Clears the trigPin digitalWrite(trigPin, LOW); delayMicroseconds(2); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH); // Calculate the distance distanceCm = duration * SOUND_SPEED/2; // Convert to inches distanceInch = distanceCm * CM_TO_INCH;
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
  
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
  
// Calculate the distance
distanceCm = duration * SOUND_SPEED/2;
  
// Convert to inches
distanceInch = distanceCm * CM_TO_INCH;

In khoảng cách lên màn hình Serial Monitor để quan sát khi cần:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Prints the distance on the Serial Monitor
Serial.print("Distance (cm): ");
Serial.println(distanceCm);
Serial.print("Distance (inch): ");
Serial.println(distanceInch);
// Prints the distance on the Serial Monitor Serial.print("Distance (cm): "); Serial.println(distanceCm); Serial.print("Distance (inch): "); Serial.println(distanceInch);
// Prints the distance on the Serial Monitor
Serial.print("Distance (cm): ");
Serial.println(distanceCm);
Serial.print("Distance (inch): ");
Serial.println(distanceInch);

Xóa màn hình sau mỗi lần hiển thị kết quả, để kết quả mới không hiển thị đè lên kết quả trước đó:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
display.clearDisplay();
display.clearDisplay();
display.clearDisplay();

Đặt con trỏ hiển thị:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
display.setCursor(0, 25);
display.setCursor(0, 25);
display.setCursor(0, 25);

Hiển thị khoảng cách đo được tính bằng đơn vị cm lên trên màn hình OLED:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Display static text
display.print(distanceCm);
display.print(" cm");
// Display static text display.print(distanceCm); display.print(" cm");
// Display static text
display.print(distanceCm);
display.print(" cm");

Nếu trong trường hợp cần hiển thị kết quả ở đơn vị inch, bạn có thể xóa các dòng sau:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/* Display distance in inches
display.print(distanceInch);
display.print(" in");*/
/* Display distance in inches display.print(distanceInch); display.print(" in");*/
/* Display distance in inches
display.print(distanceInch);
display.print(" in");*/

Và cuối cùng, bạn hãy dùng câu lệnh sau để kết quả được hiển thị rõ trên màn hình OLED:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
display.display();
display.display();
display.display();

Sau mối 500 milli giây (nửa giây), kết quả khoảng cách sẽ được cập nhật 1 lần:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
delay(500);
delay(500);
delay(500);

Demo kết quả

Bây giờ, bạn hãy nạp chương trình trên vào mạch ESP32 của mình nhé!

Mở màn hình Serial ở tốc độ 115200, khởi động lại bo mạch.

Kết quả khoảng cách đo được sẽ đồng thời hiển thị trên cả màn hình OLED lẫn màn hình Serial, ví dụ như hình dưới:

Hướng dẫn đo khoảng cách bằng HC SR04 và hiển thị lên màn hình OLED

Bạn có thể thử đưa tay lại gần hoặc ra xa cảm biến khoảng cách, để quan sát kết quả thay đổi như thế nào nhé!

Lời kết

Cảm biến HC SR04 là module lý tưởng để đo khoảng cách đến một vật thể. Bạn có thể lập trình hiển thị kết quả lên màn hình OLED hoặc màn hình Serial để theo dõi đều được.

IoTZone có cung cấp các hướng dẫn với những module khác như cảm biến nhiệt độ BME280, động cơ Servo, động cơ DC,… bạn có thể theo dõi Blog của IoTZone để làm theo nhé!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *