콘텐츠로 바로가기

now0930 일지

이런저런 생각

  • 홈
  • 비공개
  • 강좌
  • 잔여 작업 조회
  • 위치

라즈베리 파이4 온도/습도센서 홈페이지에 연결(그래프 추가)

프린터 서버로 동작하는 라즈베리 파이에 온도, 습도를 측정하는 dht11 센서를 달았다. 센서는 1,500원인데 배송비 포함 4,000원에 구매했다. 인터넷에서 바로 사용할 수 있는 python 코드를 찾았지만 동작하지 않아 gcc로 된 코드를 사용했다. 아래 그림과 같이 구성했다.

111에러가 홈 서버 접속 시도를 차단했다. 찾아보니 서버 내 my.cnf 파일 bind 설정을 수정해야 함을 알았다.

워드 프레스 테마 디렉토리 안 functions.php를 보면 사용자 정의 함수를 만들고, 데이터베이스를 조회할 수 있다. functions.php 파일을 수정하기 보다, header.php를 간단하게 수정했다. 스타일 등 html을 잘 모르기 때문에 가장 간단한 정보만 표시했다. 아래는 header.php 파일이다. 마지막에 4줄 정도만 넣었다.

<?php
/**
 * The header for our theme
 *
 * This is the template that displays all of the <head> section and everything up until <div id="content">
 *
 * @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
 *
 * @package WordPress
 * @subpackage Twenty_Seventeen
 * @since Twenty Seventeen 1.0
 * @version 1.0
 */

?><!DOCTYPE html>
<html <?php language_attributes(); ?> class="no-js no-svg">
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="https://gmpg.org/xfn/11">

<?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<div id="page" class="site">
	<a class="skip-link screen-reader-text" href="#content"><?php _e( 'Skip to content', 'twentyseventeen' ); ?></a>

	<header id="masthead" class="site-header" role="banner">

		<?php get_template_part( 'template-parts/header/header', 'image' ); ?>

		<?php if ( has_nav_menu( 'top' ) ) : ?>
			<div class="navigation-top">
				<div class="wrap">
					<?php get_template_part( 'template-parts/navigation/navigation', 'top' ); ?>
				</div><!-- .wrap -->
			</div><!-- .navigation-top -->
		<?php endif; ?>

	</header><!-- #masthead -->

	<?php

	/*
	 * If a regular post or page, and not the front page, show the featured image.
	 * Using get_queried_object_id() here since the $post global may not be set before a call to the_post().
	 */
	if ( ( is_single() || ( is_page() && ! twentyseventeen_is_frontpage() ) ) && has_post_thumbnail( get_queried_object_id() ) ) :
		echo '<div class="single-featured-image-header">';
		echo get_the_post_thumbnail( get_queried_object_id(), 'twentyseventeen-featured-image' );
		echo '</div><!-- .single-featured-image-header -->';
	endif;
	?>


	<div class="site-content-contain">
		<div id="content" class="site-content">

/*여기 추가*/
<div align="center">
<?php
$mydb = new wpdb('????','?????','???','???');$results = $mydb->get_results("SELECT * FROM `dataTemperatureAndHumidity` ORDER BY `dataTemperatureAndHumidity`.`time` DESC limit 1");foreach($results as $result){echo "온도: "; echo $result->temperature; echo ", 습도: "; echo $result->humidity;echo ", 수집시각: ";echo $result->time;}
?></div>

다음은 라즈베리안에서 돌아가는 gcc 파일이다. 인터넷 파일 그대로 사용했고, crobtab으로 30분에 한번 실행하도록 했다. 다음 컴파일 할 때 mysql과 wiringPi 옵션을 주어야 한다.

/* mysql connect and query sample */
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>
#include <time.h>
#include <unistd.h>
#include <wiringPi.h>
#include <stdint.h>
#define MAXTIMINGS 83
#define DHTPIN 0 
int dht11_dat[5] = {0, } ;

void read_dht11_dat()
{
	uint8_t laststate = HIGH ;
	uint8_t counter = 0 ;
	uint8_t j = 0, i ;
	uint8_t flag = HIGH ;
	uint8_t state = 0 ;
	float f ;
	dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0 ;
	pinMode(DHTPIN, OUTPUT) ;
	digitalWrite(DHTPIN, LOW) ;
	delay(18) ;
	digitalWrite(DHTPIN, HIGH) ;
	delayMicroseconds(30) ;
	pinMode(DHTPIN, INPUT) ;
	for (i = 0; i < MAXTIMINGS; i++) {
		counter = 0 ;
		while ( digitalRead(DHTPIN) == laststate) {
			counter++ ;
			delayMicroseconds(1) ;
			if (counter == 200) break ;
		}
		laststate = digitalRead(DHTPIN) ;
		if (counter == 200) break ; // if while breaked by timer, break for
		if ((i >= 4) && (i % 2 == 0)) {
			dht11_dat[j / 8] <<= 1 ;
			if (counter > 20) dht11_dat[j / 8] |= 1 ;
			j++ ;
		}
	}
	if ((j >= 40) && (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] +
						dht11_dat[3]) & 0xff))) {
		printf("humidity = %d.%d %% Temperature = %d.%d *C \n", dht11_dat[0],
				dht11_dat[1], dht11_dat[2], dht11_dat[3]) ;
	}
	else printf("Data get failed\n") ;
}

float RandomFloat(float a, float b) {
	//seed 값 현재 시각으로 초기화
	srand(time(NULL));
    float random = ((float) rand()) / (float) RAND_MAX;

    float diff = b - a;
    float r = random * diff;
    return a + r;
}
 
int main(int argc, char **argv)
{
		if (wiringPiSetup() == -1) exit(1) ;
		char temp[10];
		char humidity[10];

		read_dht11_dat();

		sprintf(temp, "%d.%d", dht11_dat[2], dht11_dat[3]);
		sprintf(humidity, "%d.%d",dht11_dat[0], dht11_dat[1]);

		MYSQL mysql;
		MYSQL *conn;
        MYSQL_RES *result;
        MYSQL_ROW row;

		//printf("now: %d-%d-%d %d:%d:%d\n",tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,tm.tm_hour,tm.tm_min, tm.tm_sec);
 
        char query_buffer[2048];
		conn = mysql_init(&mysql);

		//float temper, centerVal;		//온도, 중심값.
		//centerVal=25;
		//한글을 사용하기 위해 utf-8로 설정.
		mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8");
		mysql_options(conn, MYSQL_INIT_COMMAND, "SET NAMES utf8");
		//18, 19행은 한글 사용하기 위해, mysql  옵션 수정..
		//아래는 서버 설정에 맞도록 수정..
		if(!mysql_real_connect(conn, "????", "????", "????", NULL, 3306, NULL, 0)){
				fprintf(stderr,"error %s", mysql_error(conn));
				printf("cannot connect");
				exit(1);
		}
		else{
			//아래는 test_db를 사용하도록 수정..
				if (mysql_select_db(conn, "????")){
						printf("cannot use databases");
						exit(1);
				}
		}

			time_t t =time(NULL);
			struct tm tm = *localtime(&t);

			sprintf(query_buffer, "select * from dataTemperatureAndHumidity");
			mysql_query(conn, query_buffer);
			result = mysql_store_result(conn);

			while( (row = mysql_fetch_row(result)) != NULL){
				printf("row[0],%s, %s, %s",row[0], row[1], row[2]);
			}
			sprintf(query_buffer, "INSERT INTO `dataTemperatureAndHumidity`(`time`, `temperature`, `humidity`) VALUES ('%d-%d-%d %d:%d:%d', %s, %s);",tm.tm_year+1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min, tm.tm_sec, temp, humidity);



			if (mysql_query(conn, query_buffer)){
					printf("query faild : %s\n", query_buffer);
					exit(1);
			}

		mysql_close(conn);
 
}

마누라에게 자랑하니, 왜 만들었냐고 한다. 아래 그림과 같이 잘 나온다.

(업데이트)그래프를 그릴 수도 있다.

https://stackoverflow.com/questions/32005229/how-do-i-generate-a-graph-in-mysql-and-php-based-on-my-sql-statement-result

jpgraph 모듈을 설치해야 한다. 아래 사이트에서 jpgraph를 다운로드 받아 적당한 web page에 넣어 준다.

https://jpgraph.net/doc/

header.php에 graph를 직접 넣으면 안된다. JpGraph Error: HTTP headers have already been sent 이런 에러가 난다. php가 파일로 변환 후 html이 이미지로 표시하게 한다.

https://stackoverflow.com/questions/10487796/jpgraph-error-http-headers-have-already-been-sent

header.php

<?php
/**
 * The header for our theme
 *
 * This is the template that displays all of the <head> section and everything up until <div id="content">
 *
 * @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
 *
 * @package WordPress
 * @subpackage Twenty_Seventeen
 * @since Twenty Seventeen 1.0
 * @version 1.0
 */

?><!DOCTYPE html>
<html <?php language_attributes(); ?> class="no-js no-svg">
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="https://gmpg.org/xfn/11">

<?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<div id="page" class="site">
	<a class="skip-link screen-reader-text" href="#content"><?php _e( 'Skip to content', 'twentyseventeen' ); ?></a>

	<header id="masthead" class="site-header" role="banner">

		<?php get_template_part( 'template-parts/header/header', 'image' ); ?>

		<?php if ( has_nav_menu( 'top' ) ) : ?>
			<div class="navigation-top">
				<div class="wrap">
					<?php get_template_part( 'template-parts/navigation/navigation', 'top' ); ?>
				</div><!-- .wrap -->
			</div><!-- .navigation-top -->
		<?php endif; ?>

	</header><!-- #masthead -->

	<?php

	/*
	 * If a regular post or page, and not the front page, show the featured image.
	 * Using get_queried_object_id() here since the $post global may not be set before a call to the_post().
	 */
	if ( ( is_single() || ( is_page() && ! twentyseventeen_is_frontpage() ) ) && has_post_thumbnail( get_queried_object_id() ) ) :
		echo '<div class="single-featured-image-header">';
		echo get_the_post_thumbnail( get_queried_object_id(), 'twentyseventeen-featured-image' );
		echo '</div><!-- .single-featured-image-header -->';
	endif;
	?>


	<div class="site-content-contain">
		<div id="content" class="site-content">

<div align="center">
<?php


		$ydata = array();
		$y2data = array();
		$xdata = array();
		$mydb = new wpdb('???','???','???','???');
		$results = $mydb->get_results("SELECT * FROM `dataTemperatureAndHumidity` ORDER BY `dataTemperatureAndHumidity`.`time` DESC limit 30");
		foreach($results as $result){
			$ydata[] = $result->temperature;
			$y2data[] = $result->humidity;
			$xdata[] = strtotime($result->time);
			#echo $result->time;
		};
		#echo gettype($xdata[0]);

// Create graph instance
require_once ('jpgraph/src/jpgraph.php');
require_once ('jpgraph/src/jpgraph_line.php');
require_once ('jpgraph/src/jpgraph_date.php');

// Some (random) data
#$ydata = array(11,3,8,12,5,1,9,13,5,7);

// Size of the overall graph
$width=400;
$height=100;

// Create the graph and set a scale.
// These two calls are always required
$graph = new Graph($width,$height);
$graph->SetScale('datlin');
$graph->title->Set("Temperature");

$graph2 = new Graph($width,$height);
$graph2->SetScale('datlin');
$graph2->title->Set("Humidity");

// Create the linear plot
$lineplot=new LinePlot($ydata, $xdata);
$lineplot2=new LinePlot($y2data, $xdata);

// Add the plot to the graph
$graph->Add($lineplot);
$graph2->Add($lineplot2);

// Display the graph
$graph->Stroke("./temperature.jpg");
$graph2->Stroke("./humidity.jpg");

?></div>
<div align = "center"><img src = "./temperature.jpg"/> <img src = "./humidity.jpg" /> </div>

잘 표시된다. 홈 페이지가 갈수록 괴상하게 변한다.

이 글 공유하기:

  • Tweet
발행일 2021-01-15글쓴이 이대원
카테고리 생활코딩 태그 jpgraph, php, raspberry, wordpress, 습도, 온도

댓글 남기기응답 취소

이 사이트는 Akismet을 사용하여 스팸을 줄입니다. 댓글 데이터가 어떻게 처리되는지 알아보세요.

글 내비게이션

이전 글

모기(The Mosquito)

다음 글

개인은 역사를 바꿀 수 있는가?

2025 5월
일 월 화 수 목 금 토
 123
45678910
11121314151617
18192021222324
25262728293031
4월    

최신 글

  • common mode, differential mode 2025-05-11
  • signal conditioner, 신호 처리기 2025-05-10
  • strain gage 2025-05-09
  • 칼만 필터 2025-05-01
  • positioner(I/P) 2025-04-26

카테고리

  • 산업계측제어기술사
  • 삶 자국
    • 책과 영화
    • 투자
  • 생활코딩
    • LEGO
    • ROS
    • tensorflow
  • 전기기사
  • 피아노 악보

메타

  • 로그인
  • 엔트리 피드
  • 댓글 피드
  • WordPress.org

페이지

  • 소개
  • 잔여 작업 조회
    • 작업 추가
    • 작업의 사진 조회
    • 작업 수정 페이지
  • 사진
    • GPS 입력된 사진
    • 사진 조회
  • 위치
    • 하기 휴가 방문지
    • 해외 출장

태그

android bash c docker driver FSM gps java kernel LEGO linux mysql network program opcua open62541 plc programmers python raspberry reinforcementLearning ros state space system program tensorflow transfer function 경제 미국 민수 삼국지 세계사 실기 에너지 역사 유전자 일본 임베디드 리눅스 전기기사 조선 중국 채윤 코딩 테스트 통계 한국사 한국어

팔로우하세요

  • Facebook
now0930 일지
WordPress로 제작.
 

댓글 로드중...