Working safe reading
This commit is contained in:
parent
62349be40c
commit
d6f911bf4f
149
main.c
149
main.c
@ -21,108 +21,103 @@
|
|||||||
#pragma config DEBUG = ON
|
#pragma config DEBUG = ON
|
||||||
#pragma config PLLEN = 0
|
#pragma config PLLEN = 0
|
||||||
|
|
||||||
|
// Pins define
|
||||||
#define DHT22_PIN_DIR TRISAbits.TRISA4
|
#define DHT22_PIN_DIR TRISAbits.TRISA4
|
||||||
#define DHT22_DATA PORTAbits.RA4
|
#define DHT22_DATA PORTAbits.RA4
|
||||||
#define CTRL_1 PORTAbits.RA5
|
#define CTRL_1 PORTAbits.RA5
|
||||||
#define CTRL_2 PORTAbits.RA2
|
#define CTRL_2 PORTAbits.RA2
|
||||||
|
|
||||||
|
// Clock frequency (used for __delay_xx)
|
||||||
#define _XTAL_FREQ 8000000
|
#define _XTAL_FREQ 8000000
|
||||||
|
|
||||||
|
// Utils macro for waiting a pin state for DHT22_DATA, returning 1 if timed out.
|
||||||
|
#define waitDHTOrRet(up) TMR0 = 0; while(DHT22_DATA != (up)){ if(TMR0 > 240) return 1; }
|
||||||
|
|
||||||
void startSignal() {
|
uint8_t dhtBytes[5]; // 2 first bytes: humidity, 2 following: temperature, 5th: checksum
|
||||||
__delay_ms(5); // Attendre 5 ms pour stabiliser. Durée trame = 4ms
|
// Reads the DHT, returns 0 if error
|
||||||
|
int readDHT() {
|
||||||
|
// Empty old payload
|
||||||
|
for(uint8_t i = 0; i < 5; i++){
|
||||||
|
dhtBytes[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for an old payload eventually aborted to end (lasts about 4ms)
|
||||||
|
__delay_ms(5);
|
||||||
|
|
||||||
// Signal de départ : bas pendant au moins 1 ms
|
// Sends the start signal: low for at least 1ms, then high for 20 to 40us
|
||||||
DHT22_PIN_DIR = 0; // 0 = sortie donc à 0
|
DHT22_PIN_DIR = 0; // configure as output, then set it as 0 (= LATAbits.LATA4).
|
||||||
__delay_ms(1); // Attendre 1 ms
|
__delay_ms(2);
|
||||||
|
DHT22_PIN_DIR = 1; // configure as input, then set it as 1 (through pullup).
|
||||||
|
__delay_us(40);
|
||||||
|
|
||||||
|
// Check DHT start response
|
||||||
|
waitDHTOrRet(0); // DHT pulls low
|
||||||
|
waitDHTOrRet(1); // DHT pulls high for 80ms
|
||||||
|
__delay_us(40);
|
||||||
|
waitDHTOrRet(0); // DHT pulls low
|
||||||
|
|
||||||
|
// Read the 5 DHT payload bytes in dhtBytes
|
||||||
|
for (uint8_t n = 0; n < 5; n++) {
|
||||||
|
for (int8_t i = 7; i >= 0; i--) {
|
||||||
|
waitDHTOrRet(1); // Wait for up
|
||||||
|
CTRL_1 = 1;
|
||||||
|
waitDHTOrRet(0); // Wait for low. Waited time is TMR0.
|
||||||
|
CTRL_1 = 0;
|
||||||
|
|
||||||
// Signal de départ : haut pendant 20-40 µs
|
if (TMR0 > 50) { // Low: 26-28us High: 70us
|
||||||
DHT22_PIN_DIR = 1; // 1 = entrée donc haut grace au pullup
|
dhtBytes[n] |= 1 << i;
|
||||||
__delay_us(30); // Attendre 30 µs
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fonction pour lire un octet du DHT22
|
|
||||||
uint8_t readByte(int n) {
|
|
||||||
uint8_t byte = 0;
|
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
|
||||||
TMR1H = 0; // Réinitialise le Timer1
|
|
||||||
TMR1L = 0;
|
|
||||||
while (!DHT22_DATA);
|
|
||||||
CTRL_1 = 1;
|
|
||||||
//T1CONbits.TMR1ON = 1;
|
|
||||||
TMR0 = 0;
|
|
||||||
while (DHT22_DATA);
|
|
||||||
//T1CONbits.TMR1ON = 0;
|
|
||||||
CTRL_1 = 0;
|
|
||||||
//uint16_t pulseWidth = (uint16_t) (TMR1H << 8) | (uint16_t) TMR1L; // Lit la valeur du Timer1
|
|
||||||
//byte <<= 1; // Décale le byte de 1 bit à gauche
|
|
||||||
if (TMR0 > 50) { // Si l'impulsion est supérieure à 50 µs, c'est un 1
|
|
||||||
byte |= 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return byte;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Fetches humidity & temp from DHT, returns 0 if error
|
||||||
// Fonction pour lire l'humidité et la température
|
int fetchClimate(int8_t* humidity, int8_t* temperature) {
|
||||||
uint8_t lire(signed char* humidite, signed char* temp) {
|
if(readDHT()) return 1;
|
||||||
startSignal();
|
|
||||||
uint8_t humidityHigh = readByte(1);
|
uint8_t checksum = dhtBytes[0] + dhtBytes[1] + dhtBytes[2] + dhtBytes[3];
|
||||||
uint8_t humidityLow = readByte(2);
|
if (dhtBytes[4] != checksum) {
|
||||||
uint8_t temperatureHigh = readByte(3);
|
return 1; // Checksum error
|
||||||
uint8_t temperatureLow = readByte(4);
|
|
||||||
uint8_t checksum = readByte(5);
|
|
||||||
|
|
||||||
if (checksum != (humidityHigh + humidityLow + temperatureHigh + temperatureLow)) {
|
|
||||||
return 1; // Erreur de checksum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t hum = (((uint16_t) (dhtBytes[0])) << 8) | ((uint16_t) dhtBytes[1]);
|
||||||
|
*humidity = (int8_t) (hum / 10);
|
||||||
|
|
||||||
uint16_t humidity = (uint16_t) (humidityHigh << 8) | (uint16_t) humidityLow;
|
uint16_t temp = (((uint16_t) (dhtBytes[2])) << 8) | ((uint16_t) dhtBytes[3]);
|
||||||
*humidite = (signed char)(humidity / 10);
|
if (temp & 0x8000) { // If high bit is 1, temperature is negative.
|
||||||
|
*temperature = - (int8_t) ((temp & 0x7FFF) / 10);
|
||||||
uint16_t temperature = (uint16_t) (temperatureHigh << 8) | (uint16_t) temperatureLow;
|
}else {
|
||||||
if (temperature & 0x8000) { // Si le bit de signe est à 1, la température est négative
|
*temperature = (int8_t) (temp / 10);
|
||||||
temperature = -(temperature & 0x7FFF);
|
|
||||||
}
|
}
|
||||||
*temp = (signed char)(temperature / 10);
|
|
||||||
|
return 0;
|
||||||
return 0; // Lecture réussie
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Configuration de l'horloge interne à 1MHz
|
// 8MHz internal clock
|
||||||
OSCCON = 0b01110000;
|
OSCCON = 0b01110000;
|
||||||
|
|
||||||
// Configuration des broches
|
// Ping config
|
||||||
APFCONbits.T1GSEL = 0b0; // Timer1 sur RA4
|
TRISA = 0b11011011; // Declare RA2 and RA5 as output (bit = 0)
|
||||||
TRISA = 0b11011011; // Configure RA2 et RA5 en sortie 0 = sortie
|
ANSELA = 0b00000011; // Declare used pins as digital I/O (bit = 0)
|
||||||
ANSELA = 0b00000011; // Configure les broches utiles digital I/O
|
|
||||||
WPUA = 0b00010000; // Active la résistance de pull-up sur RA4
|
WPUA = 0b00010000; // Active la résistance de pull-up sur RA4
|
||||||
LATAbits.LATA4 = 0b0; // RA4 est en sortie
|
LATAbits.LATA4 = 0; // Declare RA4 output value as 0 (only effective when DHT22_PIN_DIR = 0)
|
||||||
|
|
||||||
// Configuration du Timer1
|
|
||||||
T1CON = 0b00000000; // Timer1 est éteint initialement
|
|
||||||
T1CONbits.TMR1CS = 0b01; // Source d'horloge est Fosc => 1MHz
|
|
||||||
T1CONbits.T1CKPS = 0b11; // Pas de division de l'horloge
|
|
||||||
T1GCONbits.T1GSS = 0b00; // Timer1 gate pin T1G
|
|
||||||
T1GCONbits.T1GPOL = 0b1; // Polarité du gate control est active haut
|
|
||||||
T1GCONbits.T1GTM = 0b0; // Mode du gate toggle désactivé
|
|
||||||
T1GCONbits.T1GSPM = 0b1; // Single gate désactivé
|
|
||||||
T1GCONbits.TMR1GE = 0; // Pas de gate control
|
|
||||||
T1CONbits.TMR1ON = 0; // Démarrage du Timer1
|
|
||||||
PIR1bits.TMR1GIF = 0; // Efface le flag d'interruption du gate control
|
|
||||||
|
|
||||||
OPTION_REGbits.PSA = 0; // Prescaler pour T0
|
// Timer 0 config
|
||||||
|
OPTION_REGbits.PSA = 0; // Enable prescaler
|
||||||
|
OPTION_REGbits.PS = 0b000; // 1/2 prescaler
|
||||||
|
OPTION_REGbits.TMR0CS = 0; // Use internal clock
|
||||||
|
OPTION_REGbits.TMR0SE = 0; // Increment on rising edge
|
||||||
|
|
||||||
|
|
||||||
// Boucle principale
|
|
||||||
while (1) {
|
while (1) {
|
||||||
signed char humidite = 0;
|
int8_t hum = 0;
|
||||||
signed char temperature = 0;
|
int8_t temp = 0;
|
||||||
|
|
||||||
lire(&humidite, &temperature);
|
int is_error = fetchClimate(&hum, &temp);
|
||||||
|
if(is_error){
|
||||||
int x = 0;
|
__delay_ms(5000);
|
||||||
|
}
|
||||||
__delay_ms(100);
|
__delay_ms(200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user