Senzor teploty a vlhkosti SHT31
Zo stránky SensorWiki
Záverečný projekt predmetu MIPS / LS2024 - Marián Sušina
Zadanie
Mojou úlohou v tomto zadaní bolo zapojiť, naprogramovať a overiť funkčnosť senzoru SHT31 a získané informácie vypísať na LCD displej a aj na obrazovku.
![](/sensorwiki/images/thumb/c/ca/Arduino_NANO_Pinout.jpg/400px-Arduino_NANO_Pinout.jpg.png)
SHT31
SHT31 je digitálny snímač teploty a vlhkosti vyrobený spoločnosťou Sensirion. Používa kombináciu senzorov teploty a vlhkosti, ktoré sú umiestnené na jednom čipe. Tieto senzory merajú teplotu a vlhkosť vzduchu a generujú digitálny výstup, ktorý je následne spracovaný mikrokontrlerom alebo iným zariadením. SHT31 komunikuje cez I2C (Inter-Integrated Circuit) zbernicu, pomocou ktorej môže mikrokontroler komunikovať so snímačom a taktiež si vyžiadať údaje o teplote a vlhkosti. Snímače SHT31 sú známe svojou vysokou presnosťou merania teploty a vlhkosti. Jeho presnosť teploty je typicky +-0,2 stupňa Celzia a presnosť relatívnej vlhkosti sa pohybuje v rozmedzí len +-2%.
![](/sensorwiki/images/thumb/8/89/SENZOR_SHT31_T_H.jpg/400px-SENZOR_SHT31_T_H.jpg)
Literatúra:
Analýza a opis riešenia
Na začiatok si môžeme podľa priloženej schémy pripojiť senzor SHT31 k mikrokontroleru. Na jeho správne používanie musíme použiť pri SCL (časovom kanále) a SDA (dátovom kanále) pull up rezistory.
![](/sensorwiki/images/thumb/d/dc/OBVOD_SHT31.png/400px-OBVOD_SHT31.png)
Po pripojení senzoru si môžeme pripojiť k mikroprocesoru aj LCD displej, ktorý taktiež zapojíme podľa priloženej schémy zapojenia.
![](/sensorwiki/images/thumb/4/49/LCD_schema_zapojenia.png/400px-LCD_schema_zapojenia.png)
Ak sa nám už správne podarilo pripojiť senzor aj displej, hardvérová časť nášho zadania je hotová. Ďalej nasleduje programová časť. Pri tejto časti budeme používať datasheety, priložené vyššie. Ak chceme aby náš senzor vypisoval informácie na displej, budeme potrebovať knižnicu pre LCD displej. Pre výpis cez sériový kanál na obrazovku budeme potrebovať knižnicu UART, a pre použitie samotného senzora budeme ešte potrebovať používať knižnicu pre I2C zbernicu, ktorá slúži na komunikáciu mikroprocesora so senzorom, pomocou ktorej budeme vedieť zo senzoru vyčítať získané dáta. Samotný program budeme písať podľa datasheetu, kde si naštudujeme ako náš senzor komunikuje s mikroprocesorom a ako z neho čítať dáta. Na to nám slúži obrázok priloženy nižšie, ktorý opisuje ako správne komunikovať a vyčítavať informácie zo senzoru.
![](/sensorwiki/images/thumb/c/c0/CITANIE_DAT_SHT31.png/400px-CITANIE_DAT_SHT31.png)
Na začiatku začneme posielať I2C adresu a hodnotu, ktorou nastavíme, že chceme zapisovať dáta. Po prijatí ACK (acknowledge), nastavíme MSB (most significant bit) a s ním si pre jednoduchosť vypneme Clock stretching. Ďalej nastavíme LSB (least significant bit), ktorým si volíme repeatebility. Ďalej pošleme informáciu o adrese a hodnote, a počkáme na ACK, inak posielanie opakujeme v cykle až kým nedostaneme odpoveď. Keď odpoveď dostaneme, môžeme si do bufferu vyčítať dáta ktoré nám prišli zo senzoru. Tieto dáta nám prídu v dvoch častiach. Prvá nám hovorí o teplote a druhá o vlhkosti. Pomocou vzorčekov, ktoré si nájdeme v datasheete si údaje zo senzoru prepočítame a za pomoci nami vytvorenej funkcie na výpočet a výpis ich môžeme vypísať na displej ale aj cez sériovú linku na obrazovku.
Algoritmus a program
Algoritmus programu spočíva v prijímaní informácii zo senzoru, ktoré prekonvertujeme na požadované veličiny (Pre nás stupne Celzia pre teplotu a % pre vlhkosť), a následne ich vypíšeme aby sme si mohli pozrieť, čo sa nám podarilo odmerať a či nám všetko správne funguje.
/*
SHT31D_projekt.c
Autor: Marián Sušina
*/
/* hlavickove subory pre komunikaciu s UART, LCD displejom a I2C zbernicou */
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
#include <stdbool.h>
#include "uart.h"
#include "lcd_ch.h"
#include "i2cmaster.h"
/* Inicializacia funkcie printf() cez UART */
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
/* Adresa senzora v I2C zbernici */
#define SHT31 0x44
/* Funkcia na zobrazenie teploty a vlhkosti na LCD displeji a do Terminalu. Teplota a vlhkost sa formatuje s jednym desatinnym miestom */
void display_temperature_humidity(float temperature, float humidity)
{
char str[20];
int temp_int = (int)(temperature * 10); // Prevod na cele cislo s jednym desatinnym miestom
sprintf(str, "\fTeplota:%d.%d \x04\r", temp_int / 10, temp_int % 10); // Formatovanie teploty s jednym desatinnym miestom
lcd_puts(str); // Vypis teploty na displej
printf("Teplota: %d.%d \x04\r\n", temp_int / 10, temp_int % 10); // Vypis teploty cez seriovu linku
int humi_int = (int)(humidity * 10); // Prevod na cele cislo s jednym desatinnym miestom
sprintf(str, "Vlhkos\x03:%d.%d %%", humi_int / 10, humi_int % 10); // Formatovanie vlhkosti s jednym desatinnym miestom
lcd_puts(str); // Vypis vlhkosti na displej
printf("Vlhkos\x03: %d.%d %%\r\n", humi_int / 10, humi_int % 10); // Vypis vlhkosti cez seriovu linku
}
/* Funkcia na meranie teploty a vlhkosti */
void measure()
{
uint8_t buf[6];
i2c_start_wait(SHT31 << 1 | I2C_WRITE); // posiela I2C adresu a hodnotu na zapis a caka na potvrdenie ACK
i2c_write(0x24); // nastavenie MSB -> vypneme s nim Clock stretching
i2c_write(0x0B); // nastavenie LSB -> nastavyme si repeatebility na medium
i2c_stop();
_delay_ms(1); // pauza 1ms po prikaze (podla datasheetu)
while (i2c_start(SHT31 << 1 | I2C_READ)) // posleme adresu a hodnotu na citanie a pockame na ACK
{
i2c_stop(); // ak prisiel NAK posleme STOP
}
for (uint8_t i = 0; i < 6; i++) // precitame 6 bajtov zo snimaca
{
buf[i] = i2c_read(i != 5); // zapiseme hodnoty zo snimaca do bufferu
}
i2c_stop();
uint16_t T_RAW = buf[0] << 8 | buf[1]; // hodnota teploty
uint16_t RH_RAW = buf[3] << 8 | buf[4]; // hodnota vlhkosti
float T = 175.0 * T_RAW / 0xFFFF - 45; // prepocet na stupne C
float RH = RH_RAW * 100.0 / 0xFFFF; // prepocet na %
display_temperature_humidity(T, RH); // spustenie funkcie na vypis teploty a vlhkosti na displeji a v terminale
}
int main(void)
{
/* inicializacia portov - vstupy / vystupy */
DDRD |= (1 << LCD_EN_pin); // Pin D4 (Enable) PORTD output
DDRD |= (1 << LCD_RW_pin); // Pin D3 (RW) PORTD output
DDRD |= (1 << LCD_RS_pin); // Pin D2 (RS) PORTD output
LCD_DATA_PORT |= (1 << LCD_D4_pin) | (1 << LCD_D5_pin) | (1 << LCD_D6_pin) | (1 << LCD_D7_pin); // Piny 1,2,3,4, PORTB ako output (Data pre display)
/* inicializacia I2C, UARTu a LCD displeja */
i2c_init();
uart_init();
lcd_init();
lcd_cursor(false); //vypnutie kurzora
/* inicializacia specialnych znakov */
def_spec_znaky();
stdout = &mystdout; // funkcia printf();
lcd_puts("Start");
_delay_ms(500);
while (1)
{
measure();
_delay_ms(1000);
}
return (0);
}
Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:
Zdrojový kód: SHT31D.zip
Overenie
Po pripojení senzora SHT31 a LCD displeja si vieme overiť funkčnosť programu. Po jeho spustení sa nám začne na LCD displeji ale aj na obrazovke zobrazovať teplota a vlhkosť v intervaloch jednej sekundy.
![](/sensorwiki/images/thumb/2/2c/REALNE_PRIPOJENE_ZARIADENIE.jpg/400px-REALNE_PRIPOJENE_ZARIADENIE.jpg)
Video: overenie funkčnosti