CÁCH SỬ DỤNG DHT11 SENSORĐịnh dạng dữ liệu trên một dây được sử dụng để giao tiếp và đồng bộ hóa giữa MCU và cảm biến DHT11.. Nếu truyền dữ liệu đúng, checksum sẽ là 8 bit cuối cùng của
Trang 1Học viện Công nghệ Bưu chính Viễn Thông Ngành Công Nghệ Thông Tin
Đào Quang Hưng - B21DCVT219
Giảng viên hướng dẫn: Vũ Hoài Nam
Hà Nội, năm 2023
Trang 2I LINH KIỆN CẦN THIẾT LÀM MẠCH CẢM BIẾN DHT11 GIAO TIẾP
STM32 3
1.1 VI ĐIỀU KHIỂN STM TRONG MẠCH CẢM BIẾN DHT11 GIAO TIẾP STM32 3
1.1.1 GIỚI THIỆU 4
1.1.2 SƠ LƯỢC VỀ STM32: 4
1.1.3.THÔNG SỐ KỸ THUẬT STM32 5
1.1.4 CẤU HÌNH 6
1.1.5.BỘ NHỚ 7
1.2 CẢM BIẾN DHT11 GIAO TIẾP STM32 7
1.2.1 GIỚI THIỆU DHT11 GIAO TIẾP STM32 7
1.2.2 THÔNG SỐ KỸ THUẬT DHT11 GIAO TIẾP STM32 8
1.3 OLED CHO CẢM BIẾN DHT11 GIAO TIẾP STM32 8
1.3.1 GIỚI THIỆU 8
1.3.2 THÔNG SỐ KỸ THUẬT 9
II CÁCH SỬ DỤNG DHT11 SENSOR 10
III CÁCH NỐI DÂY 11
IV GIẢI THÍCH PHẦN MỀM 11
4.1 Cài đặt trong stm32cubeide: 11
4.2 Lập trình stm32: 13
4.2.1 Các thư viện/ mã nguồn mở: 13
4.2.2 Mã ngôn ngữ C: 13
4.2.3 Giải thích các hàm: 18
Trang 3I LINH KIỆN CẦN THIẾT LÀM MẠCH CẢM BIẾN DHT11 GIAO TIẾP STM32
1.1 VI ĐIỀU KHIỂN STM TRONG MẠCH CẢM BIẾN DHT11 GIAO TIẾP STM32
1.1.1 GIỚI THIỆU
STM32 là một trong những dòng chip phổ biến của ST với nhiều họ thôngdụng như F0,F1,F2,F3,F4… Stm32f103 thuộc họ F1 với lõi là ARM COTEX M3 STM32F103 là vi điều khiển 32 bit, tốc độ tối đa là 72Mhz Giá thành cũng khá rẻ so với các loại vi điều khiển có chức năng tương tự Mạch nạp cũng như công cụ lập trình khá đa dạng và dễ sử dụng Một số ứng dụng chính: dùng cho driver để điều khiển ứng dụng, điều khiển ứng dụng thông thường, thiết bị cầm tay và thuốc, máy tính và thiết bị ngoại vi chơi game, GPS cơ bản, các ứng dụngtrong công nghiệp, thiết bị lập trình PLC, biến tần, máy in, máy quét, hệ thống cảnh báo, thiết bị liên lạc nội bộ… Phần mềm lập trình: có khá nhiều trình biên dịch cho STM32 như IAR Embedded Workbench, Keil C… Ở đây mình sử dụng Keil C nên các bài viết sau mình chỉ đề cập đến Keil C
Trang 41.1.2 SƠ LƯỢC VỀ STM32:
1 cổng Mini USB dùng để cấp nguồn, nạp cũng như debug
2 MCU bao gồm 1 MCU nạp và 1 MCU dùng để lập trình
Có chân Output riêng cho các chân mạch nạp trên MCU1
Có chân Output đầy đủ cho các chân MCU2
Chân cấp nguồn ngoài riêng cho MCU2 nếu không sử dụng nguồn từ USB.Thạch anh 32,768khz dùng cho RTC và Backup
Chân nạp dùng cho chế độ nạp boot loader
Nút Reset ngoài và 1 led hiển thị trên chân PB9, 1 led báo nguồn cho MCU2
Trang 5programmable voltage detector (PVD).
Trong trường hợp điện áp thấp:
Có các mode :ngủ, ngừng hoạt động hoặc hoạt động ở chế độ chờ
Cấp nguồn ở chân Vbat bằng pin để hoạt động bộ RTC
và sử dụng lưu trữ data khi mất nguồn cấp chính
2 bộ ADC 12 bit với 9 kênh cho mỗi bộ
Khoảng giá trị chuyển đổi từ 0 – 3.6V
Có cảm biến nhiệt độ nội
Trang 6 DMA: bộ chuyển đổi này giúp tăng tốc độ xử lý do không có sự can thiệp quá sâu của CPU.
7 timer
3 timer 16 bit hỗ trợ các mode IC/OC/PWM
1 timer 16 bit hỗ trợ để điều khiển động cơ với các mode bảo vệ như ngắt input, dead-time
2 watdog timer dùng để bảo vệ và kiểm tra lỗi
1 sysTick timer 24 bit đếm xuống dùng cho các ứng dụng như hàm Delay…
Hỗ trợ 9 kênh giao tiếp bao gồm:
capability, modem control)
2 SPIs (18 Mbit/s)
1 bộ CAN interface (2.0B Active)
USB 2.0 full-speed interface
Kiểm tra lỗi CRC và 96-bit ID
1.1.5.BỘ NHỚ
Vi điều khiển ATmega328:
64 KB bộ nhớ Plash: trong đó bootloader chiếm 0.5KB.
20 KB cho SRAM: (Static Random Access Menory): giá trị các biến khai
báo sẽ được lưu ở đây Khai báo càng nhiều biến thì càng tốn nhiều bộ nhớ RAM Khi mất nguồn dữ liệu trên SRAM sẽ bị mất
1 KB cho EEPROM: (Electrically Eraseble Programmable Read Only
Memory): Là nơi có thể đọc và ghi dữ liệu vào đây và không bị mất dữ liệu khi mất nguồn
1.2 CẢM BIẾN DHT11 GIAO TIẾP STM32
1.2.1 GIỚI THIỆU DHT11 GIAO TIẾP STM32
Trang 8Cảm biến độ ẩm và nhiệt độ DHT11 là cảm biến rất thông dụng hiện nay
vì chi phí rẻ và rất dễ lấy dữ liệu thông qua giao tiếp 1 wire (giao tiếp digital 1 dây truyền dữ liệu duy nhất) Bộ tiền xử lý tín hiệu tích hợp trong cảm biến giúpbạn có được dữ liệu chính xác mà không phải qua bất kỳ tính toán nào So với cảm biến đời mới hơn là DHT22 thì DHT11 cho khoảng đo và độ chính xác kémhơn rất nhiều
Cảm biến nhiệt độ, độ ẩm DHT11
1.2.2 THÔNG SỐ KỸ THUẬT DHT11 GIAO TIẾP STM32
Nguồn: 3 -> 5 VDC
Dòng sử dụng: 2.5mA max (khi truyền dữ liệu)
Đo tốt ở độ ẩm 2080%RH với sai số 5%
Đo tốt ở nhiệt độ 0 to 50°C sai số ±2°C
Tần số lấy mẫu tối đa 1Hz (1 giây 1 lần)
4 chân, khoảng cách chân 0.1”
1.3 OLED CHO CẢM BIẾN DHT11 GIAO TIẾP STM32
1.3.1 GIỚI THIỆU
Màn hình Oled 1.3 inch giao tiếp I2C cho khả năng hiển thị đẹp, sang trọng, rõ nét vào ban ngày và khả năng tiết kiệm năng lượng tối đa với mức chi phí phù hợp, màn hình sử dụng giao tiếp I2C cho chất lượng đường truyền ổn định và rất dễ giao tiếp chỉ với 2 chân GPIO Màn hình OLED SH1106 với kích
TÀI LIỆU THI TÍN HIỆUHỆ THỐNG
Kỹ thuật vi
xử lý 100% (2)
11
BÀI TẬP TÌNH HUỐNG MÔN KỸ NĂNG LÀM…
Kỹ thuật vi
xử lý 71% (14)
4
Sách hướng dẫn học tập vật lý đại cươn…
Kỹ thuật vi
xử lý 100% (1)
60
Trang 9thước 1.3 inch, cho khả năng hiển thị hình ảnh tốt với khung hình 128×64 pixel Ngoài ra, màn hình còn tương thích với hầu hết các vi điều khiển hiện nay thôngqua giao tiếp SPI Màn hình sử dụng driver SH1106 cùng thiết kế nhỏ gọn sẽ giúp bạn phát triển các sản phẩm DIY hoặc các ứng dụng khác một cách nhanh chóng.
Màn hình Oled chuẩn truyền I2C
Trang 10 Độ rộng màn hình: 1.3 inch.
Màu hiển thị: Trắng / Xanh Dương
Giao tiếp: I2C hoặc SPI tùy loại
Dữ liệu bao gồm phần thập phân và phần nguyên Một chuỗi dữ liệu hoàn chỉnh
là 40 bit, và cảm biến gửi bit dữ liệu cao trước
Định dạng dữ liệu: 8 bit phần nguyên RH + 8 bit phần thập phân RH + 8 bit phần nguyên T + 8 bit phần thập phân T + 8 bit checksum Nếu truyền dữ liệu đúng, checksum sẽ là 8 bit cuối cùng của "8 bit phần nguyên RH + 8 bit phần thập phân RH + 8 bit phần nguyên T + 8 bit phần thập phân T"
2.1 Quy trình Giao tiếp Toàn diện (Hình 2, dưới đây)
Khi MCU gửi một tín hiệu bắt đầu, DHT11 chuyển từ chế độ tiêu thụ điện năng thấp sang chế độ chạy, đợi MCU hoàn thành tín hiệu bắt đầu Ngay khi nó hoàn thành, DHT11 gửi một tín hiệu phản hồi của 40 bit dữ liệu bao gồm thông tin độ
ẩm tương đối và nhiệt độ cho MCU Người dùng có thể chọn thu thập (đọc) một
số dữ liệu Nếu không có tín hiệu bắt đầu từ MCU, DHT11 sẽ không phản hồi tín hiệu cho MCU Ngay sau khi dữ liệu được thu thập, DHT11 sẽ chuyển sang chế độ tiêu thụ điện năng thấp cho đến khi nó nhận được một tín hiệu bắt đầu từ MCU lại
2.2 MCU Gửi Tín Hiệu Bắt Đầu đến DHT (Hình 3, dưới đây)
Trạng thái tự do của Dữ liệu Single-bus ở mức điện áp cao Khi giao tiếp giữa MCU và DHT11 bắt đầu, chương trình của MCU sẽ đặt mức điện áp của Dữ
Trang 11liệu Single-bus từ cao xuống thấp và quá trình này phải mất ít nhất 18ms để đảmbảo DHT phát hiện tín hiệu của MCU, sau đó MCU sẽ kéo lên điện áp và đợi 20-40us để đợi phản hồi từ DHT.
2.3 DHT Phản Hồi đến MCU (Hình 3, ở trên)
Khi DHT phát hiện tín hiệu bắt đầu, nó sẽ gửi ra một tín hiệu phản hồi ở mức điện áp thấp, kéo dài trong 80us Sau đó, chương trình của DHT đặt mức điện ápcủa Dữ liệu Single-bus từ thấp lên cao và giữ nó trong 80us để DHT chuẩn bị gửi dữ liệu
Khi DATA Single-Bus ở mức điện áp thấp, điều này có nghĩa là DHT đang gửi tín hiệu phản hồi Ngay sau khi DHT gửi ra tín hiệu phản hồi, nó kéo lên điện áp
và giữ nó trong 80us để chuẩn bị cho truyền dữ liệu
Khi DHT đang gửi dữ liệu cho MCU, mỗi bit dữ liệu bắt đầu với mức điện áp thấp trong 50us và độ dài của tín hiệu mức điện áp cao tiếp theo xác định xem bit dữ liệu là "0" hay "1" (xem Hình 4 và 5 dưới đây)
Trang 13III CÁCH NỐI DÂY
Nối đầu B7 với đầu SDA
IV GIẢI THÍCH PHẦN MỀM
4.1 Cài đặt trong stm32cubeide:
4.1.1 Trong RCC chọn High Speed Clock (HSE) to Crystal/Ceramic Resonator:
- RCC (Reset and Clock Control) cung cấp các cài đặt liên quan đến các nguồn xung clock và các tham số đồng hồ khác của vi điều khiển
- "HSE" trong cài đặt này đề cập đến "High-Speed External" (bên ngoài tốc độ cao), một nguồn xung clock có thể được sử dụng bên ngoài vi điều khiển
từ một tinh thể (crystal) hoặc bộ kích thích sự rung (ceramic resonator) để cung cấp xung clock cho vi điều khiển
- chọn "High Speed Clock (HSE) to Crystal/Ceramic Resonator" trong càiđặt của vi điều khiển để cấu hình vi điều khiển sử dụng tinh thể hoặc ceramic resonator như nguồn xung clock chính cho hệ thống
Trang 144.1.2 Trong Clock Configuration tab chọn HCLK (MHz) bằng 72:
- HCLK (High-Speed Bus Clock) là một tro ng các bus chính trong vi điều khiển STM32 Nó cung cấp tín hiệu clock cho nhiều phần khác nhau trong
vi điều khiển, bao gồm CPU, bus định hướng, bộ nhớ, các module ngoại vi và các chức năng khác
- cấu hình HCLK lên 72MHz để đáp ứng nhu cầu xử lý tốc độ cao 4.1.3 Trong Pinout and Configuration tab chọn Timer → TIM1 →Clock Source set to Internal Clock:
"Clock Source set to Internal Clock" đề cập đến việc thiết lập nguồn xung clock cho Timer 1 là nguồn xung clock nội (internal clock) của vi điều khiển Điều này có nghĩa là Timer 1 sẽ sử dụng tín hiệu xung clock được tạo bởi bộ sinh xung nội của vi điều khiển, không phụ thuộc vào bất kỳ nguồn xung clock ngoại vi (ví dụ như tinh thể hoặc nguồn clock ngoại khác)
4.1.4 Configuration → Parameter Settings → Prescaler set to 71:
- Trong các vi điều khiển như STM32, Prescaler (bộ chia tần số) thường được sử dụng để chia tần số của clock đầu vào của một bộ chức năng như Timer(bộ đếm thời gian) Việc này giúp thay đổi tốc độ đếm của bộ đếm thời gian
- Khi Prescaler được thiết lập thành 71, nó sẽ chia tần số đầu vào của Timer đi một tỉ lệ 1:71 trước khi Timer bắt đầu đếm Điều này có nghĩa là số xung clock từ nguồn đầu vào sẽ được chia nhỏ hơn 71 lần trước khi được sử dụng để đếm Khi Prescaler được thiết lập thành 71, nó sẽ chia tần số đầu vào của Timer đi một tỉ lệ 1:71 trước khi Timer bắt đầu đếm Điều này có nghĩa là sốxung clock từ nguồn đầu vào sẽ được chia nhỏ hơn 71 lần trước khi được sử dụng để đếm Ví dụ, nếu tần số nguồn đầu vào của Timer là 1 MHz và bạn đặt Prescaler là 71, thì thay vì Timer đếm theo tần số 1 MHz, nó sẽ chỉ đếm với tần
Trang 154.1.7 Trong Configuration > Parameter Settings > For I2C speed selectFast Mode: Giao thức I2C có thể hoạt động ở nhiều tốc độ khác nhau, và một trong những tốc độ phổ biến là "Fast Mode" Fast Mode I2C có tốc độ truyền dữliệu lên đến 400kHz.
4.2 Lập trình stm32:
4.2.1 Các thư viện/ mã nguồn mở:
- fonts: chứa thông tin về các font như kích thước, các ký tự và các ký hiệu được định nghĩa dưới dạng các ma trận (bitmap) dùng cho màn hình
- ssd1306: chứa mã nguồn (code) được viết bằng ngôn ngữ lập trình C để điều khiển và tương tác với màn hình OLED thông qua driver SSD1306 Trong file này, bạn có thể tìm thấy các hàm để gửi lệnh và dữ liệu tới màn hình, cấu hình hiển thị,vẽ hình ảnh hoặc ký tự lên màn hình, và các hàm điều khiển khác liên quan đến việc sử dụng màn hình OLED SSD1306
/* USER CODE END Includes */
/* USER CODE BEGIN 0 */
#define DHT11_PORT GPIOB
#define DHT11_PIN GPIO_PIN_9
uint8_t RHI RHD TCI TCD SUM, , , , ;
uint32_t pMillis cMillis, ;
float tCelsius =0;
float tFahrenheit =0;
Trang 16HAL_TIM_SET_COUNTER(&htim1,0);
while( HAL_TIM_GET_COUNTER(&htim1) < delay);
GPIO_InitStructPrivate Pin DHT11_PIN = ;
GPIO_InitStructPrivate Mode GPIO_MODE_OUTPUT_PP = ; GPIO_InitStructPrivate Speed GPIO_SPEED_FREQ_LOW = ; GPIO_InitStructPrivate Pull GPIO_NOPULL = ;
HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStructPrivate);// set the pin as output
HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN ,0); // pull the pinlow
HAL_Delay(20); // wait for 20ms
HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN ,1); // pull the pinhigh
microDelay (30); // wait for 30us
GPIO_InitStructPrivate Mode GPIO_MODE_INPUT = ;
GPIO_InitStructPrivate Pull GPIO_PULLUP = ;
HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStructPrivate);// set the pin as input
Trang 18HAL_GPIO_ReadPin if(!( (DHT11_PORT, DHT11_PIN ))) // if the pin is low
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim1);
SSD1306_Init();
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while( )1
if(DHT11_Start())
{
RHI DHT11_Read = ();// Relative humidity integral
RHD DHT11_Read = ();// Relative humidity decimal
TCI DHT11_Read = ();// Celsius integral
TCD DHT11_Read = ();// Celsius decimal
Trang 19SUM DHT11_Read = ();// Check sum
RHI RHD TCI TCD if( + + + == SUM)
RH = (float)RHI + (float)(RHD/10.0);
// Can use tCelsius, tFahrenheit and RH for any purposes TFI tFahrenheit = ; // Fahrenheit integral
TFD tFahrenheit= * -10TFI*10;// Fahrenheit decimal
sprintf(strCopy,"%d %d C ", TCI TCD, );
SSD1306_GotoXY ( ,0 0);
SSD1306_Puts (strCopy,&Font_11x18,1);
sprintf(strCopy,"%d %d F ", TFI TFD, );
SSD1306_GotoXY ( ,0 20);
SSD1306_Puts (strCopy,&Font_11x18,1);
sprintf(strCopy,"%d %d %% ", RHI RHD, );
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
Trang 204.2.3 :
4.2.3.1 microDelay: cung cấp chức năng trì hoãn thời gian rất ngắn (microseconds) trong quá trình thực thi chương trình bằng cách sử dụng một timer có sẵn trong vi điều khiển Hàm này thực hiện việc trì hoãn thời gian bằng cách kiểm tra giá trị của bộ đếm trong timer để xác định khi nào đã trôi qua khoảng thời gian tương ứng với tham số delay
4.2.3.2 DHT11_start: có mục đích thực hiện quá trình khởi động (start)
để chuẩn bị việc giao tiếp với cảm biến nhiệt độ và độ ẩm DHT11 thông qua giao diện GPIO của vi điều khiển
Cụ thể, mục đích của hàm này là:
Cấu hình chân GPIO của vi điều khiển để tương tác với cảm biến DHT11:
Sử dụng cấu trúc GPIO_InitStructPrivate để thiết lập chân GPIO là chế độ đầu
ra (output) để gửi tín hiệu và chế độ đầu vào (input) để nhận phản hồi từ cảm biến
Tạo tín hiệu khởi động cho cảm biến DHT11: Đặt chân GPIO kết nối với cảm biến thành mức logic thấp, sau đó chuyển sang mức logic cao Quá trình này tạo ra một tín hiệu bắt đầu giao tiếp với cảm biến và chuẩn bị cảm biến để trả lời yêu cầu từ vi điều khiển
Kiểm tra phản hồi từ cảm biến: Đoạn code kiểm tra xem cảm biến có trả
về phản hồi sau khi được khởi động không Nếu cảm biến phản hồi bằng việc đọc mức logic cao từ chân dữ liệu của nó, biến Response được gán giá trị 1 để chỉ ra rằng cảm biến đã phản hồi và sẵn sàng cho việc truyền/nhận dữ liệu Ngược lại, nếu không có phản hồi, Response giữ giá trị ban đầu là 0
Tóm lại, mục đích chính của hàm DHT11_Start() là chuẩn bị việc giao tiếp với cảm biến DHT11 bằng cách khởi động và kiểm tra xem cảm biến đã sẵnsàng cho việc truyền/nhận dữ liệu hay không Hàm này không đọc dữ liệu cụ thể
từ cảm biến, mà chỉ chuẩn bị môi trường cho việc truyền/nhận dữ liệu trong các bước tiếp theo của quá trình giao tiếp
Trang 214.2.3.3 DHT11_Read: đọc dữ liệu nhị phân từ cảm biến theo một giao thức cụ thể của DHT11 Cảm biến DHT11 truyền dữ liệu theo một chuỗi bit, mỗi bit được biểu diễn bằng mức logic thấp hoặc cao trên chân dữ liệu (data pin)của cảm biến Đoạn code trên thực hiện việc đọc 8 bit này từ cảm biến và gom chúng lại để tạo thành một byte (8 bit) dữ liệu.
Quá trình đọc dữ liệu từ cảm biến DHT11 được thực hiện qua các bước sau:
Đoạn code đọc 8 bit từ cảm biến DHT11 và lưu vào biến b Mỗi bit được đọc trong vòng lặp for (a = 0; a < 8; a++)
Trong quá trình đọc từng bit:
Đầu tiên, chờ đợi tín hiệu "start" từ cảm biến DHT11 Điều này được thựchiện trong vòng lặp while (!(HAL_GPIO_ReadPin(DHT11_PORT,
DHT11_PIN)) && pMillis + 2 > cMillis)
Tiếp theo, đợi 40 micro giây bằng hàm microDelay(40)
Đọc mức logic của chân GPIO của cảm biến DHT11, nếu mức logic là LOW, bit tương ứng trong biến b sẽ được xóa (set thành 0), ngược lại nó sẽ được đặt (set thành 1) Điều này được thực hiện trong đoạn code if (!
4.2.3.4 Bên trong vòng while: