WeatherStation/DHT22.c

79 lines
1.7 KiB
C
Raw Permalink Normal View History

2023-12-03 13:37:53 +01:00
#include "config.h"
#include <avr/io.h>
#include <util/delay.h>
#include <stdbool.h>
#include "GDM1602K.h"
#define DATAPIN PC0
#define PORT PORTC
#define PIN PINC
#define DDR DDRC
bool is_high() {
return (PIN & (1 << DATAPIN));
}
// Function to read data from the DHT22 sensor
int DHT22_Read(int *temperature, int *humidity)
{
// Set the data pin as output
DDR |= (1 << DATAPIN);
PORT |= (1 << DATAPIN); // Set the pin high, if not already pulled up
_delay_ms(100);
// Send start signal
PORT &= ~(1 << DATAPIN); // Set the pin low
_delay_us(500); // Hold it for a while
PORT |= (1 << DATAPIN); // Set the pin high
DDR &= ~(1 << DATAPIN); // Data direction in
_delay_us(20); // Wait for 40 microseconds
// Sensor should have pulled low here
if(PIN & (1 << DATAPIN)) return -2;
_delay_us(80); // Wait for 80 microseconds
// Sensor should have pulled high here
if(!(PIN & (1 << DATAPIN))) return -1;
// Read data from the sensor
uint8_t data[5] = {0, 0, 0, 0, 0};
uint8_t bitMask = 0x80; // All zeroes with MSB high
uint8_t byteIndex = 0;
for (byteIndex = 0; byteIndex < 5; byteIndex++)
{
for (bitMask = 0x80; bitMask != 0; bitMask >>= 1)
{
// Wait for the data bit to go low
while (!(PIN & (1 << PC0)))
;
// Wait for the data bit to go high
_delay_us(20);
if (PIN & (1 << PC0))
data[byteIndex] |= bitMask;
// Wait for the data bit to go low (end of bit)
while (PIN & (1 << PC0))
;
}
}
// Verify checksum
uint8_t checksum = data[0] + data[1] + data[2] + data[3];
if (checksum != data[4])
return -1;
// Extract temperature and humidity
*humidity = ((data[0] << 8) | data[1]);
*temperature = ((data[2] << 8) | data[3]);
return 0;
}