Привет, друзья.
Продолжаю строить умный дом под свое оборудование. После того, как мне удалось подключить Arduino к NAS Synology, нужно научить их общаться. Для начала попробуем читать из Arduino и записывать в БД. Сделаем это на примере проекта Погодной станции. К Arduino цепляю датчики из тех что сейчас есть. Это гигрометр и термометр DHT-21/AM2301, у него в отличие от DHT-11 хороший рабочий температурный диапазон до -40 градусов. Вторым подключаю датчик давления BMP180 (BMP085), он же второй источник температуры. Таким образом, можно установить барометр дома, а гигрометр DHT-21 установить за окном. Получим температуру снаружи и внутри, влажность и давление. Схем подключения их в интернете миллион, поэтому сразу показываю результат.
Быстро из стандартных примеров написал скетч для Arduino, который периодически считывает показания с датчиков и отправляет в UART.
#include <Wire.h>
#include <Adafruit_BMP085.h> // https://github.com/adafruit/Adafruit-BMP085-Library
#include <dht.h> // https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib
dht DHT;
Adafruit_BMP085 bmp;
// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
#define DHT21_PIN 5
void setup()
{
Serial.begin(115200);
}
void loop()
{
// READ DATA
Serial.println("START TRANSLATION");
if (DHT.read21(DHT21_PIN) == DHTLIB_OK)
{
// DISPLAY DATA
Serial.print("DATA\tDHT21_H\t");
Serial.println(DHT.humidity, 1);
Serial.print("DATA\tDHT21_T\t");
Serial.println(DHT.temperature, 1);
}
if (bmp.begin()) {
Serial.print("DATA\tBM180_T\t");
Serial.println(bmp.readTemperature());
Serial.print("DATA\tBM180_P\t");
Serial.println(bmp.readPressure() * 7.5006e-3); // mm.hg
}
Serial.println("STOP TRANSLATION");
delay(30000);
}
В качестве протокола передачи данных принято, что каждое значение передается отдельной строкой, которая должна начинаться со слова DATA. Дальше через табуляцию следует уникальное название параметра. Я использую название датчика и букву измеряемого значения. Следом через tab само значение. Строки «START/STOP TRANSLATION» помогают отличить новые данные от старых.
Включаем на Synology протокол SSH. Подключаемся, например, при помощи PUTTY как root и пробуем.
dsgena> cat /dev/ttyUSB0
DATA DHT21_H 29.6
DATA DHT21_T 23.9
DATA BM180_T 22.20
DATA BM180_P 740.38
Теперь нужно принять эти данные на стороне сервера. Думал изначально воспользоваться PHP. Однако на Synology по-умолчанию вебсервер работает в safemode. Это хорошо для безопасности, но ему закрыт прямой доступ к любым папкам и файлам. Функция exec не работает для стандартных программ linux, а значит нельзя запустить stty для настройки COM-порта и нет доступа к самому порту. Остается BASH, а точнее его урезанная версия ash, ведь на Synology используется BusyBox. Значит особо не разгуляешься. Можно написать и скомпилировать программу на СИ, но это слишком сложно — придется где-то разворачивать среду программирования на linux, ведь для Synology это слишком тяжелая задача. Остается Perl или Python. Я выбрал второй вариант просто потому, что давно хотел попробовать его.
Для начала устанавливаем в Synology пакеты с Python 3 и Python Module.
Пакет с модулями содержит модуль serial, который позволит выполнить чтение из /dev/ttyUSB0, но сделать это сможет только пользователь root.
Эти данные нужно куда-то складывать. Просто записывать в файл бесперспективно. Будем писать в БД. В Synology есть пакет MariaDB. Ставим его. И тут выясняется, что в стандартном наборе модулей Python нет модуля для работы с mysql. Нужно ставить самому. Для облегчения процедуры ставим pip.
dsgena> ls /usr/lib/python2.7/|grep sql
sqlite3
dsgena> wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
dsgena> python get-pip.py
dsgena> python -m pip install pymysql
После всех мучений, мы наконец-то можем написать программу на python, которая сможет прочитать и записать данные из Arduino в MySQL.
import time
import serial
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='test', passwd=None, db='test')
cur = conn.cursor()
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=115200,
parity=serial.PARITY_ODD,
stopbits=serial.STOPBITS_TWO,
bytesize=serial.SEVENBITS
)
#ser.open()
ser.isOpen()
out = ''
while 1 :
time.sleep(1)
sql = ''
while ser.inWaiting() > 0:
s = ser.read(1)
if s == '\n':
spl = out.split('\t')
if spl[0] == 'DATA':
sql += "INSERT INTO test (DateT,param,val) VALUES (@DT, '"+spl[1] + "'," + spl[2] +"); "
out = ''
else:
out += s
if sql <> '':
cur.execute("SET @DT=Now(); " + sql)
conn.commit()
time.sleep(10)
Запустить программу на выполнение в фоне, причем так, чтобы можно было разорвать соединение SSH и она продолжила работу можно так:
dsgena> nohup python ttytomysql.py &
Я же добавил в файл /etc/crontab строчку и перезапустил crond:
dsgena> cat /etc/crontab
#minute hour mday month wday who command
*/30 * * * * root ps|grep -v grep| grep ttytomy.py > /dev/null || /usr/bin/python /volume1/web/arduino/ttytomy.py > /dev/null &
dsgena> synoservicecfg --restart crond
Теперь каждые 30 мин Synology сам проверяет жив ли процесс и при необходимости запускает его.
Собственно осталось лишь написать красивое отображение данных из БД в виде таблицы или графика. Я использовал библиотеку pChart на php. В результате получилась такая картинка.
Сегодня ночью обещали первый день зимы. Видно что днем давление быстро падало — приближался фронт. А с 23 часов резко поднялась влажность — это за окном пошел снег. Сегодня синоптики не подвели.
Осталось доделать наш анемометр и дополнить данные до полноценной метеостанции. Тогда можно будет уже определять какой фронт идет к нам — теплый или холодный. И не стыдно будет транслировать эти данные в проекте narodmon.ru.
Последнее обновление 29.03.2022 в 10:40
можно по подробнее объяснить как запускать программу на synology, в какую директорию ее сохранять
Andrey, боюсь сильно подробнее не получится, т.к. само решение не очень-то простое.
ttytomysql.py можно положить в любое место. У меня он лежит в папке веб-сервера. Главное прописать путь к этому файлу в /etc/crontab
Я прописал в crontab, но у меня он не запускает процесс
Нужно заходить через ssh админимтратором и вручную пытаться запустить. Тогда будет видно что за ошибку он выдает.
при запуске программы выдает ошибку:
line 20
sql = »
^
IndentationError: unindent does not match any outer indentation level
При копировании с сайта у вас кавычки изменились. Есть разница между
» и "
Добрый день, нужна помощь по данному девайсу.
Hi there,
I really like this project of yours, but did you ever try to send serial data from Synology to Arduino?
Kind regards,
Viktor
No, I didn’t try send data back. But I think it is possible.
echo «Hello world» > /dev/ttyUSB0
Hi gena,
Thank you for your fast feedback! 😉
Is that example of yours in Python language or bash command?
Can you maybe tell me if you know, how I can send the CPU usage, RAM usage and HDD space from Python?
Can you give me some information from where I can start?
Kind regards,
Viktor
You can find a lot of answers with examples on site https://stackoverflow.com/search?q=python+ram+usage
Thank you for the link!
Also I would like to tell you that your post was the ONLY ONE that I had found on the internet regarding Arduino and Synology interaction!
So, thank you again for this great project! <3 😉
Kind regards,
Viktor