Let’s go!

  • 라즈베리 파이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>
    

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

  • 모기(The Mosquito)

    모기(The Mosquito)

    isbn: 9791135447693

    모기를 거의 700 페이지 넘게 썼다. 신대륙, 구대륙(유럽)에 대해 너무나 자세하게 기록하여 읽기 괴롭다. 거의 모든 전쟁이 모기로 인한 전염병에 영향 받았다. 특히 저자는 습지에 주둔한 여러 군대를 주목했다. 모기로 인한 결원으로 전쟁 결과를 결정했고, 전쟁 결과가 역사를 만들었음을 보면 모기가 여러 원인 중 하나였음은 확실하다. 모기가 서식하기 좋은 습지를 손자병법이 어떻게 판단했는지 모르겠다. 서양사 위주 기록하여 동양에서 어떤 영향을 미쳤는지 구체적으로 알 수 없다.

    모기가 역사에만 영향을 주지 않았다. 공룡이 운석 충돌로 결정적으로 망했음은 확실하다. 그 전에 모기로 인해 쇠약해졌다고 한다.

    잔인한 신대륙 정착에도 모기가 영향을 주었다. (더러운) 유럽인이 신대륙으로 천연두와 말라리아를 옮길 수 있는 모기를 노예무역으로 옮겼다. 천연두, 말라리아, 흑토병이 신대륙 원주민을 몰살시켜 커피, 목화, 사탕수수에 필요한 노동력을 없앴다. 말라리아에 적응하지 못한 초기 노예가 죽어 나가자 이를 보충하려 아프리카에서 노예를 더 수입했다. 노예 무역이 금지되자 노동력을 증가시키기 위해 여성 노예를 강간하여 노예를 늘렸다고 한다. 세균전, 노예제, 대학살 등 단어를 생각하면 신대륙 발견 후 역사가 너무 잔인하다.

    초기 신대륙 정착지가 성공한 이유가 몸에 좋지않은 담배 수출 때문이다. 초기 역사 사실로 마리화나, 담배에 대한 거부감이 낮아져 지금 미국이 마리화나 사용을 법으로 금지하지 않았나 싶다.

    대 모기 전쟁 중 DDT를 발명한 점은 흥미롭다. 악마의 물질로 알았는데, 말라리아로 고통받았던 시기 그 탁월한 효과로 여러 부분에 DDT를 사용했다. 이제 DDT가 크리스퍼 유전자 가위로 바뀌었다. 과거 DDT 경험에 비춰보아 유전자 가위는 어떤 영향을 미칠지 판단하기 어렵다.

  • 대구(COD)

    대구(COD)

    isbn: 9788925552163

    아메리카, 유럽, 아프리카 삼각 무역에 한 품목으로 노예들에게 소, 돼지 대신 단백질로 대구를 수출하여 지급했다고 한다. 힘든 사탕수수 재배 노동을 대구를 먹고 했다면 단백질 공급원으로 충분했다. fish and chips에서 살이 두툼한 대구살을 튀겨 만든다. 해저에서 생활하여 잡기도 쉽고, 한 지역에 오래 머무르고, 잡식성이라 크기도 커 단백질 공급원으로 훌륭한 식품이다. 메이플라워를 탄 사람이 신(God)이 아닌 대구(Cod)를 보고 갔다는 말도 이해할 수 있다.

    그러나 최근 주낙 대신 저인망 트롤로 대구를 잡으면서 대구 개체수가 많이 줄었다. 어부들이 저인망 트롤이 무차별로 잡은 물고기가 값싸다면 바다에 버리고 다시 잡는점은 충격이다. 이 또한 통신 발달로 출항 전 물고기 시세를 알면서 발생했다. 부에 대한 엄청난 집념이다. 대구를 잡는 위험을 생각하면 충분히 그럴만도 하지만, 환경을 1도 생각하지 않는 행태다. 저인망 그물코 크기를 제한해도 배 뒤로 끌고 가는 방식이라 작은 물고기도 큰 물고기에 걸려 빠져나갈 수 없다. 저인망 그물 자체를 금지해야 할 듯하다. 남획에서 양식으로 바꿔 환경에 주는 충격을 줄여야 한다.

    소금에 절인 대구를 먹다 냉동 기술, 물고기를 저미는 기술(어묵??)로 본격적인 산업으로 발달했다. 그러나 대구 어획량 감소로 발달했던 산업이 축소되었다. 한번 축소한 산업은 언제 다시 클지 모르겠다. 앞으로 추세를 보면 어부 직업 자체가 줄어들 듯 하다. 직업을 선택할 때 그 업종이 환경에 부정적 영향을 주는지 생각해야 한다.

    명태도 대구에 속한 한 종이라고 한다!!

  • 세상을 뒤흔든 전투의 역사

    세상을 뒤흔든 전투의 역사

    isbn: 9791159253928

    인간 갈등을 극단적으로 해결하는 수단이 전쟁이라고 한다. 이런 점에서 전쟁 배경, 경과, 전쟁 결과, 이후 사건을 보면 세계사가 어떻게 흘러갔는지 쉽게 알 수 있다한다. 국방방송에서 했던 토크멘터리 전쟁사가 이런 방식으로 접근했지만, 20년 4월 어이없게 종방했다. 이 책역시 전쟁으로 역사를 돌아봤다. 유필하가 지었는데 배경 지식, 전투를 설명하여 대단하다 생각한다.

    알렉산더가 처음 보병을 모루로, 기병을 망치로 활용했다고 한다. 한니발이 망치와 모루 전술을 정확하게 구현하여 로마군에 상대로 승리했다. 그러나 이후 자마 전투에서 스키피오에게 패했다. 이 결과로 나중에 카르타고가 로마에 멸망하게 된다. 전에 읽은 귀곡자가 정확하게 집었다. 일을 시작함기 전에 충분히 준비하고, 내부 결속이 중요한데, 한니발은 로마를 상대로 혼자 전쟁을 시작했다. 결국 충분한 지원을 받지 못하여 칸나에 전투에서 승리했지만 큰 성과 없이 돌아와야 했다.

    저자는 할리드 이븐 알 왈리드, 한신, 알렉산더를 위대한 장군으로 언급했다. 빈약한 군대로 항상 승리하여 높이 평가했다. 잔인한 정복자로 알려진 코르테스가 아즈텍을 상대로 1:100 열세를 극복한 점도 높이 평가했다.

    세계 2차대전을 겪으며 몇 십만명이 사상자에 기록된다. 최근 전쟁인데 많은 사상자가 나온 점에서 고대와 현대에 전쟁을 수행함은 큰 변화가 없는 듯 하다.

  • (김서형의 빅 히스토리)Fe 연대기

    (김서형의 빅 히스토리)Fe 연대기

    isbn: 9788962621839

    철(Fe)로 태양, 지구, 인류 역사?를 살펴본다. 태양이 수소를 연료로 태워 헬륨을 만듦은 알았으나, 온도에 따라 연료가 달라진다 한다. 가장 무거운 연료가 철이라고 한다. 또한 지구가 우주 방사선, 태양풍으로부터 안전할 수 있는 이유가 철로 구성된 핵이 움익이면서 자기장을 만들기 떄문이다. 태양풍에 대기가 날아가는 화성을 보면 생명이 살기 적절한 행성을 만들기? 어렵다.

    130억년 우주 역사에 비하면 45억년 지구 역사도 짧고, 수만년도 안되는 인류 역사는 더 짧다. 우리가 볼 때 그 엄청난 시간이 공백으로 구성된다. 그러나 무에서 유를 만들기까지 그 인고를 겪어야 한다 생각하면 이해한다. 지구에서 처음 생명이 나타난 시각, 인류가 지구에서 역사를 기록한 시각을 보면 비율이 비슷하다. 혁명? 이라고 하는 대단한 변화를 겪으려면 무수히 많은 시간을 기다려야 한다. 그럼에 급격한 변화를 겪는 우리는 행운을 타고났다.