pico-dht11/dht11.c

116 lines
No EOL
3 KiB
C

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#define PIN 20
#define MAX_TRANSITIONS 100
void prepare_sensor() {
gpio_set_dir(PIN, GPIO_OUT);
gpio_put(PIN, true);
sleep_ms(1000);
}
void ask_sensor() {
gpio_put(PIN, false);
sleep_ms(20);
gpio_set_dir(PIN, GPIO_IN);
gpio_pull_up(PIN);
}
uint64_t read_bytes(uint32_t *transitions, uint8_t transitions_count) {
uint64_t output = 0;
uint32_t start_time = transitions[2];
int bits = 0;
for (int i=3; i<transitions_count; i++) {
if (i % 2 == 0) { // low state
// bit is 1 if delay before low state is more than 30 ms
output <<= 1;
output |= (transitions[i] - start_time > 50);
bits++;
}
start_time = transitions[i];
}
printf("Bits: %d\n", bits);
return output;
}
bool read_to_variables(uint64_t data, float *humidity, float *temperature) {
uint8_t temp_dec = (data >> 8) & 0xFF;
uint8_t temp_int = (data >> 16) & 0xFF;
uint8_t hum_dec = (data >> 24) & 0xFF;
uint8_t hum_int = (data >> 32) & 0xFF;
*temperature = temp_int + (temp_dec / 255.0);
*humidity = hum_int + (hum_dec / 255.0);
uint8_t calculated_checksum = hum_int + hum_dec + temp_int + temp_dec;
uint8_t checksum = data & 0xFF;
return checksum == calculated_checksum;
}
int main() {
stdio_init_all();
printf("Initializing sensor...\n");
gpio_init(PIN);
prepare_sensor();
while (true) {
printf("\n");
uint32_t transitions[MAX_TRANSITIONS];
uint8_t transitions_count = 0;
bool state = true;
ask_sensor();
uint32_t start = time_us_32();
uint32_t time_now = start;
while (time_now - start < 100000) {
time_now = time_us_32();
bool new_state = gpio_get(PIN);
if (new_state != state) {
transitions[transitions_count++] = time_now;
state = new_state;
}
}
if (transitions_count > 0) {
printf("Transitions: %d\n", transitions_count);
printf("Time taken: %dus\n", transitions[transitions_count - 1] - start);
for (int i=0; i<transitions_count; i++) {
printf("#%d to %s after %dus\n", i, (i % 2 == 0 ? "low" : "high"), transitions[i] - start);
start = transitions[i];
}
uint64_t output = read_bytes(transitions, transitions_count);
float temperature, humidity;
bool valid = read_to_variables(output, &temperature, &humidity);
printf("Temperature: %f\n", temperature);
printf("Humidity: %f\n", humidity);
printf("Valid: %s\n", valid ? "yes" : "no");
int d = humidity / 10;
if (d > 10) d = 10;
} else {
printf("Error reading\n");
}
prepare_sensor();
sleep_ms(1000);
}
return 0;
}