Operácie

Senzor teploty a vlhkosti SHT31: Rozdiel medzi revíziami

Z SensorWiki

 
(28 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 4: Riadok 4:
 
== Zadanie ==
 
== Zadanie ==
  
Sem príde text zadania, ak bolo len voľne formulované, rozpíšte ho podrobnejšie
+
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.
  
[[Obrázok:ard.jpg|400px|thumb|center|Vývojová doska ACROB.]]
+
[[Obrázok:Arduino_NANO_Pinout.jpg|400px|thumb|center|Arduino NANO.]]
 +
 
 +
=== 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%.
 +
 
 +
[[Obrázok:SENZOR_SHT31_T_H.jpg|400px|thumb|center|Senzor teploty a vlhkosti SHT31.]]
  
 
'''Literatúra:'''  
 
'''Literatúra:'''  
* [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k doske Acrob]
 
* [http://www.humanbenchmark.com/tests/reactiontime/index.php Vyskúšajte si zmerať reakciu on-line]
 
 
* [https://sensirion.com/media/documents/213E6A3B/63A5A569/Datasheet_SHT3x_DIS.pdf Datasheet SHT31]
 
* [https://sensirion.com/media/documents/213E6A3B/63A5A569/Datasheet_SHT3x_DIS.pdf Datasheet SHT31]
 
+
* [https://www.vishay.com/docs/37484/lcd016n002bcfhet.pdf Datasheet 16x2 Character LCD]
 +
* [https://docs.arduino.cc/resources/datasheets/A000005-datasheet.pdf Datasheet Arduino NANO]
 +
* [https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf Datasheet ATmega328P]
  
 
__TOC__
 
__TOC__
Riadok 18: Riadok 24:
 
== Analýza  a opis riešenia ==
 
== Analýza  a opis riešenia ==
  
Opíšte sem čo a ako ste spravili, ak treba, doplňte obrázkami...
+
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. 
 +
 
 +
[[Súbor:Schema_SHT31.png|400px|thumb|center|Schéma zapojenia sensoru SHT31.]]
 +
 
 +
Po pripojení senzoru si môžeme pripojiť k adruinu aj LCD displej, ktorý taktiež zapojíme podľa priloženej schémy zapojenia.
  
[[Súbor:ledRGB.jpg|400px|thumb|center|RGB LED.]]
+
[[Súbor:LCD_schema_zapojenia.png|400px|thumb|center|Schéma zapojenia LCD displeja.]]
  
Nezabudnite doplniť schému zapojenia!
+
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.
  
[[Súbor:schd.png|400px|thumb|center|Schéma zapojenia LCD displeja.]]
+
[[Súbor:CITANIE_DAT_SHT31.png|400px|thumb|center|Algoritmus čítania dát zo senzoru.]]
  
 +
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 a program ===
  
Algoritmus programu je....
+
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.
 +
 
 +
<tabs>
 +
<tab name="SHT31D_projekt.c"><source lang="c++" style="background: LightYellow;">
 +
/*
 +
SHT31D_projekt.c
 +
Autor: Marián Sušina
 +
*/
  
  
<tabs>
+
/* hlavickove subory pre komunikaciu s UART, LCD displejom a I2C zbernicou */
<tab name="AVR C-code"><source lang="c++" style="background: LightYellow;">
 
 
#include <avr/io.h>
 
#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)
 
int main(void)
 
{
 
{
  unsigned int measuredValue;
 
  
  while (1)
+
/* inicializacia portov - vstupy / vystupy */
  {
+
 
    /* relax */   
+
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
  
  return(0);
+
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)
}
 
  
</source></tab>
+
/* inicializacia I2C, UARTu a LCD displeja */
<tab name="filename.h"><source lang="c++" style="background: LightYellow;">
+
i2c_init();
#include <avr/io.h>
+
uart_init();
 +
lcd_init();
 +
 +
lcd_cursor(false); //vypnutie kurzora
 +
 +
/* inicializacia specialnych znakov */
 +
def_spec_znaky();
 +
 +
stdout = &mystdout; // funkcia printf();
  
void adc_init(void);                                   // A/D converter initialization
+
lcd_puts("Start");
 +
_delay_ms(500);
 +
 +
while (1)
 +
{
 +
measure();
 +
_delay_ms(1000);
 +
}
  
unsigned int adc_read(char a_pin);
+
return (0);
 +
}
 
</source></tab>
 
</source></tab>
 
</tabs>
 
</tabs>
  
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: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
+
Zdrojový kód obsahujúci všetky použité knižnice: [[Médiá:projektSHT31MarianSusina.zip|SHT31D.zip]]
  
  
 
=== Overenie ===
 
=== Overenie ===
  
Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia.  
+
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.
Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.  
 
  
[[Súbor:fotka.jpg|400px|thumb|center|Aplikácia.]]
+
[[Súbor:REALNE_PRIPOJENE_ZARIADENIE_SHT31.jpg|400px|thumb|center|Zapojenie v realite.]]
  
'''Video:'''
+
'''Video: overenie funkčnosti'''
<center><youtube>_l02MBu41n0</youtube></center>
+
<center><youtube>https://youtu.be/UQCB-i0sPlg?si=hrC4AC80-KYkaX24</youtube></center>
  
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.
 
  
 
[[Category:AVR]] [[Category:MIPS]]
 
[[Category:AVR]] [[Category:MIPS]]

Aktuálna revízia z 17:37, 28. apríl 2024

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.

Arduino NANO.

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%.

Senzor teploty a vlhkosti SHT31.

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.

Schéma zapojenia sensoru SHT31.

Po pripojení senzoru si môžeme pripojiť k adruinu aj LCD displej, ktorý taktiež zapojíme podľa priloženej schémy zapojenia.

Schéma zapojenia LCD displeja.

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.

Algoritmus čítania dát zo senzoru.

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);
}


Zdrojový kód obsahujúci všetky použité knižnice: 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.

Zapojenie v realite.

Video: overenie funkčnosti