Tecnologia dei sensori di temperatura

Sonda del sensore di temperatura (Progettazione del circuito funzionale di DS18B20 e PT100)

Schema DS18B20 e configurazione CUBEMAX

Confronto tra Sensore di temperatura PT100 sonda e Modulo DS18B20
1) Principio base dell'acquisizione del segnale
① La resistenza del PT100 cambia proporzionalmente alla temperatura (Maggiore è la temperatura, maggiore è la resistenza), ma la variazione di resistenza è molto piccola, Di 0.385 OH / grado;
② L'intervallo di misurazione della temperatura del PT100 è -200℃ -200℃, e a 0 ℃, la resistenza è esattamente uguale a 100 OH;
③ La corrente di lavoro del PT100 dovrebbe essere inferiore a 5 mA;
④ Sebbene la resistenza del PT100 cambi proporzionalmente alla temperatura, il suo tasso di variazione (questo è, Valore K Valore K Valore K) è diverso in diversi intervalli di temperatura.

2) Tabella di modifica della resistenza alla temperatura PT100

Tabella di modifica della resistenza alla temperatura PT100

3. Circuito di pilotaggio PT100

Circuito di pilotaggio PT100

Circuito di pilotaggio PT100

1) Attraverso il metodo della divisione di tensione, AD raccoglie la tensione PT100 per ottenere il valore di resistenza per calcolare la temperatura
Il valore di resistenza di PT100 in acqua a temperatura ambiente (25℃25℃25℃) riguarda 109.89 OH.
Il microcontrollore emette una tensione di 3,3 V, e la tensione divisa per PT100 è approssimativamente:
109.89 ∗ 0.005 = 0.54945 V

Il valore AD convertito secondo la formula di conversione AD è approssimativamente:
0.54945 / 3.3 ∗ 4096 = 681.98 ≈ 682

Quando la temperatura aumenta di un grado, presupponendo che la resistenza del PT100 aumenti appena 0.385 OH, il valore di variazione della tensione divisa è approssimativamente uguale a:
0.385 ∗ 0.005 = 0.001925 V

Il valore AD convertito secondo la formula di conversione AD è approssimativamente:
0.001925 / 3.3 ∗ 4096 = 2.39 ≈ 2

Nell'esperimento, si è riscontrato che a causa della tensione instabile di 3,3 V dell'alimentatore stm32, l'ADC ha raccolto le fluttuazioni di tensione del PT100 e l'errore di divisione della tensione era ampio. La soluzione di ottimizzazione consiste nel progettare un circuito con sorgente di corrente costante. Raccogliendo la tensione di PT100 e la corrente della sorgente di corrente costante, si può ottenere la resistenza PT100, e quindi è possibile ottenere il valore della temperatura.

2) Circuito di sorgente di corrente costante basato sul regolatore LDO (MD5333)
Esistono molti circuiti di pilotaggio per testare PT100 su Internet, come il circuito a ponte CC, circuito sorgente di corrente costante basato su amplificatore operazionale, ecc. L'autore ha dedicato molto tempo anche alla scelta del circuito di guida, considerando la difficoltà di realizzazione della scheda e il numero di componenti, e infine ha scelto il circuito con sorgente di corrente costante basato sul regolatore LDO (MD5333). Lo schema elettrico è il seguente:

Circuito di sorgente di corrente costante del regolatore LDO (MD5333)

Circuito di sorgente di corrente costante del regolatore LDO (MD5333)

A questo punto, la selezione dell'hardware è stata sostanzialmente completata. La scheda di sviluppo utilizzata è la scheda Zhengdian Atom F10ZET6 Elite

Modulo DS18B20
Per testare la temperatura in tempo reale e il confronto della temperatura PT100, viene aggiunto il modulo DS18B20 per il test comparativo di calibrazione

1) Introduzione a DS18B20
DS18B20 è un sensore di temperatura a bus singolo con un intervallo di temperatura di prova di -55~+125℃ e una precisione di ±0,5℃. La temperatura sul campo viene trasmessa direttamente in modo digitale a bus singolo, che migliora notevolmente la capacità anti-interferenza del sistema. Può leggere direttamente la temperatura misurata, e può realizzare un metodo di lettura del valore digitale a 9 ~ 12 bit attraverso una semplice programmazione in base ai requisiti effettivi. Il suo intervallo di tensione operativa è 3 ~ 5,5 V, e utilizza una varietà di forme di imballaggio, rendendo l'impostazione del sistema flessibile e conveniente. La risoluzione impostata e la temperatura di allarme impostata dall'utente vengono memorizzate nella EEPROM e vengono ancora salvate dopo un'interruzione di corrente.

Progettazione del circuito DS18B20

Progettazione del circuito DS18B20

2) Introduzione ai tempi di funzionamento del DS18B20
Tutti i dispositivi a bus singolo richiedono una rigorosa temporizzazione del segnale per garantire l'integrità dei dati. DS18B20 ha 6 tipi di segnale: resettare l'impulso, impulso di risposta, scrivere 0, scrivere 1, Leggere 0 e leggere 1. Tutti questi segnali, tranne l'impulso di risposta, sono segnali sincroni inviati dall'host. E tutti i comandi e i dati vengono inviati prima con il bit basso del byte.

Impulso di ripristino e impulso di risposta DS18B20

Impulso di ripristino e impulso di risposta DS18B20

① Resettare l'impulso e l'impulso di risposta
Tutte le comunicazioni sul bus singolo iniziano con una sequenza di inizializzazione. L'host emette un livello basso e mantiene il livello basso per almeno 480us per generare un impulso di reset. Quindi l'host rilascia l'autobus, e il resistore pull-up da 4,7K porta in alto il singolo bus, con un tempo di ritardo di 15~60us, ed entra nella modalità di ricezione (Rx). Quindi DS18B20 abbassa il bus per 60~240us per generare un impulso di risposta di basso livello.

DS18B20 tempi di scrittura

DS18B20 tempi di scrittura

② Scrivi i tempi
La tempistica di scrittura include la scrittura 0 tempismo e scrivere 1 tempistica. Tutti i tempi di scrittura richiedono almeno 60us, ed è richiesto un tempo di ripristino di almeno 1us tra due tempi di scrittura indipendenti. Entrambi i tempi di scrittura iniziano con l'host che abbassa l'autobus. Scrivere 1 tempistica: l'host emette un livello basso, ritardi per 2us, e poi rilascia l'autobus, ritardando 60us. Scrivere 0 tempistica: l'host emette un livello basso, ritardi per 60us, e poi rilascia l'autobus con un ritardo di 2us.

DS18B20 Lettura dei tempi

DS18B20 Lettura dei tempi

③ Leggi i tempi
I dispositivi a bus singolo trasmettono i dati all'host solo quando l'host emette un tempo di lettura. Perciò, dopo che l'host ha emesso un comando di lettura dei dati, è necessario generare immediatamente una temporizzazione di lettura affinché lo slave possa trasmettere i dati. Tutti i tempi di lettura richiedono almeno 60us, ed è richiesto un tempo di recupero di almeno 1us tra due tempi di lettura indipendenti. Ogni tempo di lettura viene avviato dall'host, che tira giù l'autobus per almeno 1 noi. L'host deve rilasciare il bus durante la temporizzazione di lettura e campionare lo stato del bus entro 15us dall'inizio della temporizzazione. Il tipico processo di timing di lettura è: l'host emette un ritardo di basso livello di 2us, quindi l'host passa al ritardo della modalità di input di 12us, poi legge il livello attuale del singolo bus, e poi ritarda 50us.

DS18B20 apre la porta seriale per stampare le informazioni sulla temperatura

DS18B20 apre la porta seriale per stampare le informazioni sulla temperatura

Dopo aver compreso la tempistica del singolo bus, diamo un'occhiata al tipico processo di lettura della temperatura del DS18B20. Il tipico processo di lettura della temperatura di DS18B20 è: reset → invia SKIPROM (0Xcc) → invia il comando di avvio conversione (0x44) → ritardo → reset → invia comando SKIPROM (0Xcc) → invia comando di memoria (0Xbe) → leggere due byte di dati (i.e. temperatura) continuamente → fine.

3) Diagramma schematico e configurazione CUBEMAX
Dal diagramma schematico, si può vedere che DS18B20 è abilitato dalla porta PG11 per aprire la porta seriale per stampare le informazioni sulla temperatura

Schema DS18B20 e configurazione CUBEMAX

Schema DS18B20 e configurazione CUBEMAX

Interfaccia sensore di temperatura e umidità DS18B20

Interfaccia sensore di temperatura e umidità DS18B20

4) Parte del codice
La parte di codice trapianta la libreria ds18b20 di Zhengdian Atom e apporta lievi modifiche

#ifndef __DS18B20_H
#definire __DS18B20_H

#includere “tim.h”
/***********************************************************************************/
/* Definizione pin DS18B20 */

#definire DS18B20_DQ_GPIO_PORT GPIOG
#definire DS18B20_DQ_GPIO_PIN GPIO_PIN_11
#definire DS18B20_DQ_GPIO_CLK_ENABLE() Fare{ __HAL_RCC_GPIOG_CLK_ENABLE(); }Mentre(0) /* Abilitazione orologio porta PG */

/**********************************************************************************************/

/* Funzione operativa IO */
#definire DS18B20_DQ_OUT(X) Fare{ X ? \
HAL_GPIO_WritePin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN, GPIO_PIN_RESET); \
}Mentre(0) /* Uscita porta dati */
#definire DS18B20_DQ_IN HAL_GPIO_ReadPin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN) /* Ingresso porta dati */

uint8_t ds18b20_init(vuoto); /* Inizializza DS18B20 */
uint8_t ds18b20_check(vuoto); /* Controlla se DS18B20 esiste */
breve ds18b20_get_temperature(vuoto);/* Ottieni la temperatura */

#endif

5. Modulo telecomando a infrarossi
1) Protocollo di codifica del modulo wireless

I metodi di codifica ampiamente utilizzati per il telecomando a infrarossi sono: Protocollo NEC di PWM (modulazione dell'ampiezza dell'impulso) e il protocollo RC-5 di Philips PPM (modulazione della posizione degli impulsi). Il telecomando fornito con la scheda di sviluppo utilizza il protocollo NEC, che ha le seguenti caratteristiche:

1. 8-indirizzo bit e lunghezza dell'istruzione a 8 bit;

2. L'indirizzo e il comando vengono trasmessi due volte (per garantire affidabilità);

3. Modulazione della posizione dell'impulso PWM, con il ciclo di lavoro della portante infrarossa trasmessa che rappresenta “0” E “1”;

4. La frequenza portante è 38Khz;

5. Il bit time è 1,125 ms o 2,25 ms;

Nel protocollo NEC, come impostare i dati nel protocollo su ‘0’ o "1"? Qui, il ricevitore e il trasmettitore a infrarossi sono separati.

Trasmettitore a infrarossi: Invia dati protocollo '0' = 560us di trasmissione del segnale portante + 560noi di nessuna trasmissione del segnale portante

Invia dati di protocollo "1" = 560us di trasmissione del segnale portante + 1680noi di nessuna trasmissione del segnale portante

La definizione di bit del trasmettitore a infrarossi è mostrata nella figura seguente

Ricevitore a infrarossi: Ricevi i dati del protocollo "0" = 560us livello basso + 560noi di alto livello

Ricevi i dati del protocollo "1" = 560us livello basso + 1680noi di alto livello

Il formato dei dati del comando di controllo remoto NEC è: terminale di sincronizzazione, codice indirizzo, indirizzare il codice inverso, codice di controllo, controllare il codice inverso. Il codice di sincronizzazione è composto da un livello basso di 9 ms e un livello alto di 4,5 ms. Il codice dell'indirizzo, indirizzare il codice inverso, codice di controllo, e il codice inverso di controllo sono tutti formati di dati a 8 bit. Vengono inviati nell'ordine: prima il bit basso e ultimo il bit alto. Il codice inverso viene utilizzato per aumentare l'affidabilità della trasmissione.

Perciò, l'acquisizione dell'ingresso può essere utilizzata per misurare l'ampiezza dell'impulso di alto livello per ottenere la decodifica del controllo remoto.
2) Diagramma schematico e configurazione CUBEMAX

Dal diagramma schematico, possiamo vedere che il modulo wireless è abilitato tramite il pin PB9 e raccoglie tramite il 4 canali di TIM4:

Il pin predefinito di TIM4_CH4 non è PB9, quindi è necessario impostarlo manualmente, e contemporaneamente viene attivata l'impostazione di interruzione

3) Parte del codice
Cattura il fronte di salita attraverso la funzione tim callback

In questo momento, è possibile ottenere il segnale decodificato:

In questo momento, i dati sono più complessi e possono essere leggermente elaborati:

L'effetto è il seguente:
Le ultime due cifre sono il codice decodificato e il suo inverso. In questo momento, può essere definita come una macro per regolare la soglia di temperatura:

L'effetto è il seguente:

Codice parte a infrarossi:

/* CODICE UTENTE INIZIO Intestazione */
/**
******************************************************************************
* @file : principale.c
* @breve : Corpo principale del programma
******************************************************************************
* @Attenzione
*
* <h2><centro>&copia; Copyright (C) 2024 STMicroelettronica.
* Tutti i diritti riservati.</centro></h2>
*
* Questo componente software è concesso in licenza dalla ST con licenza BSD a 3 clausole,
* IL “Licenza”; Non è possibile utilizzare questo file se non in conformità con il
* Licenza. È possibile ottenere una copia della licenza all'indirizzo:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Intestazione FINE CODICE UTENTE */
/* Include ——————————————————————*/
#includere “principale.h”
#includere “tim.h”
#includere “USART.H”
#includere “gpio.h”

/* Il privato include ———————————————————-*/
/* CODICE UTENTE INIZIO Include */
#includere “stdio.h”
#includere “stringa.h”
#definire MAXUP 157
#definire MAXDOWN 87
#definire MINUP 221
#definire MINDOWN 61
/* FINE CODICE UTENTE Include */

/* Typedef privata ———————————————————–*/
/* CODICE UTENTE INIZIO PTD */

/* CODICE UTENTE FINE PTD */

/* Definire privato ————————————————————*/
/* CODICE UTENTE INIZIO PD */
/* FINE CODICE UTENTE PD */

/* Macro privata ————————————————————-*/
/* CODICE UTENTE INIZIO PM */

/* CODICE UTENTE FINE PM */

/* Variabili private ———————————————————*/

/* CODICE UTENTE INIZIO PV */
uint32_t upCount=0;
uint16_t ValoreUp=0;
uint16_t ValoreDown=0;
uint8_t isUpCapt=1;
uint16_t larghezza=0;
buffer uint16_t[128]={0};
uint16_t bufferId=0;
uint8_t rcvFalg=0;
/* CODICE UTENTE FINE PV */

/* Prototipi di funzioni private ———————————————–*/
void SystemClock_Config(vuoto);
/* CODICE UTENTE INIZIO PFP */

/* CODICE UTENTE FINE PFP */

/* Codice utente privato ———————————————————*/
/* INIZIO CODICE UTENTE 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
upCount++;
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
Se(isUpCapt)//Se si tratta di una cattura del fronte di salita
{
ValueUp=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_4);
isUpCapt=0;
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_4,TIM_ICPOLARITY_FALLING);
conteggio su=0;
}
altro{
ValueDown=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_4);
isUpCapt=1;
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_4,TIM_ICPOLARITY_RISING);
larghezza=ValoreGiù+ConteggioSu*65536-ValoreSu;
Se(larghezza>4400&&larghezza<4600)
{
bufferId=0;
respingente[bufferId++]=larghezza;
}
altrimenti se(bufferId>0)
{
respingente[bufferId++]=larghezza;
Se(bufferId>32)
{
rcvFalg=1;
bufferId=0;
}
}
}
}
void bitBuffer2num(carattere num[])
{
numero[0]=0;
numero[1]=0;
numero[2]=0;
numero[3]=0;
per(intero i=0;io<32;I ++)
{
Se(respingente[io+1]<1000)
{
numero[io/8]=num[io/8]<<1;
}
altro
{
numero[io/8]=num[io/8]<<1;
numero[io/8]|=0x01;
}
}
}
/* FINE CODICE UTENTE 0 */

/**
* @brief Il punto di ingresso dell'applicazione.
* @retval int
*/
int principale(vuoto)
{
/* INIZIO CODICE UTENTE 1 */
char printbuff[128]={0};
carattere num[4]={0};
chiave carattere=0;
/* FINE CODICE UTENTE 1 */

/* Configurazione dell'MCU——————————————————–*/

/* Reset di tutte le periferiche, Inizializza l'interfaccia Flash e il Systick. */
HAL_Init();

/* INIZIO CODICE UTENTE Init */

/* FINE CODICE UTENTE Init */

/* Configura l'orologio di sistema */
SystemClock_Config();

/* CODICE UTENTE INIZIO SysInit */

/* CODICE UTENTE FINE SysInit */

/* Inizializza tutte le periferiche configurate */
MX_GPIO_Init();
MX_TIM4_Init();
MX_USART1_UART_Init();
/* INIZIO CODICE UTENTE 2 */

/* FINE CODICE UTENTE 2 */

/* Ciclo infinito */
/* IL CODICE UTENTE INIZIA MENTRE */
HAL_GPIO_TogglePin(LED0_GPIO_Porta,LED0_Pin);
HAL_TIM_Base_Start_IT(&htim4);//L'aggiornamento del timer genera un'interruzione
HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_4);//
Mentre (1)
{
Se(rcvFalg)
{
per(intero i=0;io<4;I ++)
{
bitBuffer2num(numero);
sprintf(printbuff,”0xx “,numero[io]);
HAL_UART_Trasmissione(&huart1,appassionato di stampa,stren(printbuff),HAL_MAX_DELAY);
}
// sprintf(printbuff,”%tu “,respingente[io]);
// HAL_UART_Trasmissione(&huart1,appassionato di stampa,stren(printbuff),HAL_MAX_DELAY);
// }
HAL_UART_Trasmissione(&huart1,”\rn”,2,HAL_MAX_DELAY);
rcvFalg=0;
}
printf(“%drn”,numero[3]);
Se(numero[3]==157)
{
printf(“111111\rn”);
}
HAL_Ritardo(1000);
/* CODICE UTENTE FINE MENTRE */

/* INIZIO CODICE UTENTE 3 */
}
/* FINE CODICE UTENTE 3 */
}

/**
* @breve configurazione dell'orologio di sistema
* @retval Nessuno
*/
void SystemClock_Config(vuoto)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};