Skip to content
Snippets Groups Projects
Commit 79238113 authored by Eunchae Lee's avatar Eunchae Lee
Browse files

DHT11.c

parent 82067e3a
Branches
No related tags found
No related merge requests found
DHT11.c 0 → 100644
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <wiringPi.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <math.h>
#define MAX_READING 85 // set the timing 85 for stable data reading
#define PIN 2 // GPIO pin number for the DHT11 sensor
// define server info
#define SERVER_ADDRESS "192.168.45.8"
#define SERVER_PORT 8080
// define variables
int data[5] = {0, 0, 0, 0, 0};
float sum_temp = 0.0;
float sum_humidity = 0.0;
int read_times = 0;
int sample_count = 0;
// read data from sensor
void read_data()
{
int state = HIGH;
int count = 0;
int bit_index = 0;
memset(data, 0, sizeof(data)); // clear the data array as 0
pinMode(PIN, OUTPUT); // set the pin to output mode - 파이의 핀 사용 준비
// DHT11은 PIN을 LOW로 설정하고 18ms동안 유지시 이를 데이터 요청 신호로 인식
digitalWrite(PIN, LOW); // set the pin low for requesting the data transmit
delay(18); // keep the state low for 18ms
// PIN을 HIGH로 설정하고 40ms동안 유지시켜 센서가 데이터를 준비할 수 있는 시간을 제공
digitalWrite(PIN, HIGH); // set the pin high for notifying the completed transmit - 데이터 요청 신호 종료
delayMicroseconds(40); // wait for the sensor to prepare collecting data
pinMode(PIN, INPUT); // ready to get the data from sensor
// reading the data til the max_reading
for (int i = 0; i < MAX_READING; i++)
{
count = 0;
// count the duration of each state
while (digitalRead(PIN) == state)
{
count++;
delayMicroseconds(1);
// to avoid infinite loop
if (count == 255)
{
break;
}
}
// store the current state
state = digitalRead(PIN);
// to avoid infinite loop
if (count == 255)
{
break;
}
/* ignore the first 3 state changes and process every second state change to capture data bits
처음 3번은 연결상태 확인하는 handshake부분
DHT11 센서의 각 비트는 HIGH, LOW 상태 변화 페어로 전달됨
홀수 - HIGH, 짝수 - LOW -> LOW 신호의 길이를 측정해 비트를 결정함
LOW는 비트의 시작을 알림, HIGH의 상태 길이는 비트 값을 나타냄(26-28ms:0, 70ms:1)
=> LOW 상태 이후 HIGH 상태 길이 측정하여 비트 값 결정함
*/
if ((i >= 4) && (i % 2 == 0))
{
int bit_pos = (bit_index / 8); // byte position - 현재 비트가 어느 바이트에 위치하는지
int bit_shift = 7 - (bit_index % 8); // bit shift position - 바이트 내에서의 비트의 위치.
// Store the bit in the correct position - 비트 값 결정 후 바이트와 위치에 저장 , HIGH 상태가 16ms보다 길면 1, 짧으면 0으로 결정
int bit_value;
if (count > 16)
{
bit_value = 1; // HIGH 상태가 16마이크로초보다 크면 비트 값은 1.
}
else
{
bit_value = 0; // HIGH 상태가 16마이크로초보다 작으면 비트 값은 0.
}
int shifted_bit = bit_value << bit_shift;
int current_byte = data[bit_pos];
current_byte |= shifted_bit;
data[bit_pos] = current_byte;
// Move to the next bit
bit_index++;
}
}
// checking the check sum and print the data
if ((bit_count >= 40) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)))
{
float humidity = (float)data[0] + (float)data[1] * 0.1;
float temperature = (float)data[2] + (float)data[3] * 0.1;
// add the humidity to the sum for calculating the average value
sum_humidity += humidity;
sum_temp += temperature;
// check the times of the valid data reading
read_times++;
printf("Humidity = %.1f%% Temperature = %.1f°C\n", humidity, temperature);
}
else
{
printf("Invalid data. skip! \n");
}
}
// calculate the average and send it to the server
void calcu_send_average(int sock)
{
char message[100];
read_data();
sample_count++;
if (sample_count >= 10)
{
if (read_times > 0)
{
float avg_humidity = sum_humidity / read_times;
float avg_temp = sum_temp / read_times;
printf("Average Temperature and Humidity are calculated!\n");
printf("Average Temperature = %.1f°C, Average Humidity = %.1f%%\n", avg_temp, avg_humidity);
snprintf(message, sizeof(message), "%.1f %.1f", avg_temp, avg_humidity);
if (send(sock, message, strlen(message), 0) == -1)
{
perror("Transmission failed");
}
}
else
{
printf("No valid data to calculate averages\n");
}
sample_count = 0;
sum_humidity = 0.0;
sum_temp = 0.0;
read_times = 0;
}
}
// create thread
void *server_thread(void *arg)
{
struct sockaddr_in server_addr;
int sock;
// create the socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
perror("Socket creation error\n");
return NULL;
}
// set server_add as 0
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);
server_addr.sin_port = htons(SERVER_PORT);
// Connect to the server
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("Server connection failed");
close(sock);
return NULL;
}
printf("Connected to server\n");
// calculate and send averages to the server every 2 seconds
while (1)
{
calcu_send_average(sock);
delay(2000); // send the data every 20 seconds
}
close(sock);
return NULL;
}
int main(void)
{
pthread_t thr_id;
printf("Temperature and Humidity Check through DHT11 Sensor\n");
// initialize wiringpi and print the error message in case error has happened
if (wiringPiSetupGpio() == -1)
{
perror("WiringPi initialization failed\n");
return -1;
}
// Create the thread to handle sensor data and server connection
if (pthread_create(&thr_id, NULL, server_thread, NULL) != 0)
{
perror("Thread creation failed\n");
return 1;
}
// Wait for the server_thread to terminate
pthread_join(thr_id, NULL);
return 0;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment