Датчик температуры и влажности на ардуино с отправкой и отрисовкой графика (Часть1)

от автора

Основной задачей проекта является мониторинг температуры в теплице удаленной от дома на 11-15 метров. Без возможности организации прокладки UTP и питания до нее.

Тепличная часть:

  1. Снять температуру/влажность датчиком DHT-11 при помощи pro micro
  2. Отправить fs1000a при помощи pro micro

Домашняя часть:

  1. Принять значения на mx-rm-5v при помощи Uno
  2. Отправить на сервер при помощи Ethernet shield (WIZNET W5100HR911105A)
  3. Записать в базу mysql
  4. Отрисовать график (jpgraph)

Начал немного не по порядку. Для меня данная последовательность оказалась более сложной поэтому решил ее реализовывать вначале.

Список необходимых пакетов не огромен и зависит от дистрибутива, а именно nginx, php-gd, php-mysql, mysql-server. Для jpgraph могут понадобиться ttf шрифты.

Подготовим nginx

server { listen 80; listen [::]:80; root /var/www/html;  location / {                } location ~ \.php$ {     include fastcgi_params;     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;     # With php7.0-cgi alone:     # fastcgi_pass 127.0.0.1:9000;     # With php7.0-fpm:     fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;     fastcgi_buffer_size 128k;     fastcgi_buffers 256 32k;     fastcgi_busy_buffers_size 256k;     fastcgi_temp_file_write_size 256k;     fastcgi_connect_timeout 1s;     fastcgi_ignore_client_abort off;     fastcgi_next_upstream timeout;     fastcgi_read_timeout 5m;     fastcgi_send_timeout 5m;     } } 

Для uno нам нужны следующие библиотеки:
SPI.h
Ethernet.h
DHT.h

Код для UNO

#include <SPI.h> #include <Ethernet.h> #include <DHT.h>  // MAC address for controller byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Адрес шилда byte ip[] = { 192, 168, 156, 192 }; //Маска byte subnet[] = { 255, 255, 255, 0 }; //Шлюз byte gateway[] = { 192, 168, 0, 1 }; //Адрес сервера с базой char server[] = "192.168.156.186"; #define DHTPIN 2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE);   //Запуск клиента EthernetClient client;  void setup()  {  dht.begin();         Serial.begin(9600);     while (!Serial) {         ; // wait for serial port to connect     }     {        Ethernet.begin(mac,ip,gateway,subnet);     }      // give the Ethernet shield a second to initialize     delay(1000);    }  void loop() {   if (client.connect(server, 80))   {   // give the Ethernet shield a second to initialize   float h = dht.readHumidity();   float t = dht.readTemperature();          Serial.println("connected");         // Отправляем GET запрос с данными         client.println(String("GET /index.php?temp=")+ t +"&hum="+h);            client.println();         Serial.println("connection close");       } else Serial.println("connection failed");       delay(60000); }

Cкетч каждую минуту отправляет GET запрос скрипту (index.php):

index.php

<?php /**  * @param string            $message  * @param PDOException|null $exception  */ function writeMessage($message, $exception = null) {     $logfile = '/var/www/html/data/arduino.log';     $datetime = date('d.m.Y H:i:s', time());      if ($exception !== null) {         $message .= ': ' . $exception->getFile() . ' (line: ' . $exception->getLine() . ') - ' . $exception->getMessage();     }      file_put_contents($logfile, '[' . $datetime . '] ' . $message."\n", FILE_APPEND); }  /* Подключение к базе данных MySQL с помощью вызова драйвера */ $dsn = 'mysql:dbname=greenhouse;host=localhost'; $user = 'arduino'; $password = 'парол';  try {     $dbh = new PDO($dsn, $user, $password, [         PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,         PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,         PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',     ]); } catch (PDOException $e) {     writeMessage('Произошла ошибка', $e); }  try {     $sth = $dbh->prepare('INSERT INTO data (sensor, temperature, humidity, created_at) VALUES (?, ?, ?, NOW())');     $sth->execute(['grass', $_REQUEST['temp'], $_REQUEST['hum']]);  } catch (PDOException $e) {     writeMessage('Произошла ошибка', $e); } 

который в свою очередь отправляет значения в базу:

Создание таблицы

CREATE DATABASE `greenhouse` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE `table` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `sensor` varchar(255) DEFAULT NULL,   `temperature` decimal(6,3) DEFAULT '0.00',   `humidity` decimal(6,3) DEFAULT '0.00',   `created_at` datetime DEFAULT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

Добавляем пользователя и выдаем права

CREATE USER 'arduino'@''' IDENTIFIED BY 'парол';

GRANT ALL PRIVILEGES ON * . * TO 'arduino'@'';

FLUSH PRIVILEGES;

Проверяем:

select * from data;

+-----+--------+-------------+----------+---------------------+ | id  | sensor | temperature | humidity | created_at          | +-----+--------+-------------+----------+---------------------+ |   1 | grass  |        NULL |     NULL | 2019-07-15 13:29:13 | |   2 | grass  |      24.100 |   49.000 | 2019-07-15 13:44:44 | |   3 | grass  |      24.100 |   49.000 | 2019-07-15 13:44:54 | |   4 | grass  |      24.000 |   49.000 | 2019-07-15 13:45:04 | |   5 | grass  |      24.000 |   49.000 | 2019-07-15 13:45:15 | |   6 | grass  |      24.100 |   49.000 | 2019-07-15 13:45:25 | |   7 | grass  |      24.100 |   49.000 | 2019-07-15 13:45:35 | |   8 | grass  |      24.100 |   49.000 | 2019-07-15 13:45:45 | |   9 | grass  |      24.100 |   49.000 | 2019-07-15 13:45:55 | |  10 | grass  |      24.100 |   48.000 | 2019-07-15 13:46:47 | |  11 | grass  |      24.100 |   48.000 | 2019-07-15 13:46:58 | |  12 | grass  |      24.100 |   48.000 | 2019-07-15 13:47:08 | 

Данные в базе!

Устанавливаем библиотеку JpGraph

убираем его в /var/www/src

Теперь рисуем график(day.php):

day.php

<?php // content="text/plain; charset=utf-8"   //define('__ROOT__', dirname(dirname())); require_once ('/var/www/src/jpgraph.php'); require_once ('/var/www/src/jpgraph_line.php'); require_once ('/var/www/src/jpgraph_error.php'); require_once ('/var/www/src/jpgraph_date.php');  $x_axis = array(); $y_axis = array(); $i = 0;   $con=mysqli_connect('localhost','arduino','парол','greenhouse'); $result = mysqli_query($con,"SELECT * FROM data"); while($row = mysqli_fetch_array($result)) { $x_axis[$i] =  strtotime($row["created_at"]); $y_axis[$i] = $row["temperature"];     $i++; }     mysqli_close($con); $start = time(); $end = $start+NDATAPOINTS*SAMPLERATE;  for( $i=0; $i < NDATAPOINTS; ++$i ) {     $x_axis[$i] = rand(50,70);     $xdata[$i] = $start + $i * SAMPLERATE; }   $graph = new Graph(1000,400); $graph->img->SetMargin(50,30,30,80);   $graph->img->SetAntiAliasing(); $graph->SetScale('datlin'); $graph->xaxis->scale->SetDateFormat('d:m H:i'); $graph->SetShadow(); $graph->title->Set("Дневной график температуры"); $graph->xaxis->title->Set('время'); $graph->xaxis->SetLabelAngle(45); $graph->yaxis->title->Set('температура'); $graph->xaxis->scale->SetTimeAlign(DAYADJ_1); $graph->title->SetFont(FF_TIMES,FS_BOLD);   // Use 20% "grace" to get slightly larger scale then min/max of // data $graph->yscale->SetGrace(0);  $p1 = new LinePlot($y_axis,$x_axis); $p1->mark->SetType(MARK_FILLEDCIRCLE); $p1->mark->SetFillColor("red"); $p1->mark->SetWidth(4); $p1->SetColor("blue"); $p1->SetCenter(); $graph->Add($p1);   $graph->Stroke(); 

Получаем вот такую красоту:

Вот и все на данный момент. Сейчас тружусь над настройкой связки двух плат по радиоканалу о чем напишу во второй части.


ссылка на оригинал статьи https://habr.com/ru/post/460491/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *