126 lines
No EOL
3.2 KiB
C
126 lines
No EOL
3.2 KiB
C
#include <stdio.h>
|
|
#include "pico/stdlib.h"
|
|
#include "hardware/gpio.h"
|
|
|
|
#include "display.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();
|
|
|
|
initialize_display();
|
|
display_digit(11);
|
|
int disp = 11;
|
|
|
|
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;
|
|
display_animate(disp, d);
|
|
disp = d;
|
|
} else {
|
|
display_animate(disp, 10);
|
|
disp = 10;
|
|
printf("Error reading\n");
|
|
}
|
|
|
|
prepare_sensor();
|
|
sleep_ms(1000);
|
|
}
|
|
|
|
return 0;
|
|
} |