-
Posts
829 -
Joined
-
Last visited
-
Days Won
7
Posts posted by kharlashkin
-
-
2. Подключаем накопитель к OpenWRT.
Идем на веб страничку установки пакетов:
Обновляем список доступных пакетов, кнопка Update list:
Устанавливаем пакеты - kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb-storage block-mount нажимаем и перегружаемся System - Reboot - Perform reboot
Заходим в настройки точек монтирования System - Mount points и видим нашу флешку, ставим галочку напротив нашего раздела для установки пакетов и жмем кнопку Edit:
Ставим галочку подключать диск, UUID оставляем тот же:
Переходим на вкладку Advanced Settings и выбираем нашу файловую систему из выпадающего меню:
Перегружаемся, после перезагрузки все наши настройки сбросятся, но мы увидим что наш раздел для установки стал намного больше:
Опять устанавливаем нужные пакеты kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb-storage block-mount, и подключаем теперь уже swap раздел и домашний каталог по аналогии.
- 1
-
“Не было бы счастья, да несчастье помогло”
Так вышло, что у родителей вышел из строя HDD, флешку мою, забытую у них в спутниковом тюнере, мне не привезли. Пришлось вытягивать из маршрутизатора и делать из неё загрузочную - чтобы установить ОС на новый HDD, соответственно первоначальную настройку делать сначала. Таким образом появилась эта инструкция.
1. Подготовка носителя в GParted.
Открываем программу и выбираем нашу флешку:Отмонтируем нашу флешку от ОС, ПКМ - Отмонтировать:
Удаляем все что есть на ней, клавиша "delete" или ПКМ - Удалить:
Я решил, что под установочные пакеты отдам 1000 МиБ, под swap раздел 256 МиБ, остальное под мои файлы.
Создаем разделы на флешке как мы задумали: , клавиша "insert" или ПКМ - Новый, для разделов под программы и мои файлы выбираем файловую систему "Ext3", под раздел подкачки "linux-swap":
Применяем нужные нам изменения:
Соглашаемся с применением изменений, ждём окончания операций.
Закрываем GParted и вытягиваем флешку из ПК.
- 1
-
Edited by kharlashkin
Пример вывода данных из sqlite на web-страничку с автоматическим обновлением с помощью json+jquery:
from flask import Flask, render_template, jsonify import sqlite3 app = Flask(__name__) sensor_sqlite_db = 'db_sensor.db' @app.route('/live_data', methods=['GET', 'POST']) def live_data(): return render_template('live_data.html') @app.route('/live_data_json', methods=['GET', 'POST']) def live_data_json(): conn = sqlite3.connect(sensor_sqlite_db, detect_types=sqlite3.PARSE_DECLTYPES) curs_db = conn.cursor() cur = curs_db.execute("select * from sensor order by id desc limit 1") for row in cur.fetchall(): cur_time=row[1] temperature=row[2] humidity=row[3] co2ppm=row[4] sensor_dict = {"cur_time": cur_time, "humidity": humidity, "temperature": temperature, "co2ppm": co2ppm} return jsonify(sensor_dict) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000)
И сама страничка:
{% extends "base.html" %} {% block content %} <script type=text/javascript> function get_data() { $.getJSON("live_data_json", function (data) { $("#Hum").text(data.humidity) $("#Temp").text(data.temperature) $("#Co").text(data.co2ppm) $("#Time").text(data.cur_time); } ); } setInterval('get_data()', 1000); </script> <h3 class="text-center">Параметры микроклимата</h3> <br> <table class="table table-bordered"> <thead> <tr> <th>Параметр</th> <th>Значение</th> <th>Ед.изм.</th> </tr> </thead> <tbody> <tr> <td>Влажность</td> <td id="Hum"></td> <td>%</td> </tr> <tr> <td>Температура</td> <td id="Temp"></td> <td>°С</td> </tr> <tr> <td>Уровень углекислого газа</td> <td id="Co"></td> <td>ppm</td> </tr> </tbody> </table> <br> <p class="text-center">Время последнего измерения</p><p id="Time" class="text-center"></p> <br> <p>Данные обновляются раз в минуту.</p> {% endblock %}
Расширение base.html:
<!DOCTYPE html> <html lang="en"> <head> <title>Свежий воздух</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="static/css/bootstrap.min.css" rel="stylesheet" media="screen"> </head> <body> <div class="container"> <div class="row"> <div class="center-block"> {% block content %} {% endblock %} </div> </div> </div> <script type="text/javascript" src="static/js/jquery-3.2.1.min.js"></script> <script type="text/javascript" src="static/js/bootstrap.min.js"></script> </body> </html>
Ну и как это выглядит:
- 2
-
Edited by kharlashkin
Для таких данных лучше подойдет циклическая база данных.
А как же красивости в виде графиков? Почасово, посуточно и т.д.Прошу прощения. -
Думаю, что скомпилировать AVRDUDE для MIPS легче, чем собрать avr-gcc.
Тем более что avrdude уже есть в репозитории OpenWRT.
-
Пример сбора данных от Arduino в базу данных sqlite3.
Сначала создадим нужную нам нам базу данных, с помощью скрипта create_db.py:
import sqlite3 sqlite_file = 'db_sensor.db' conn = sqlite3.connect(sqlite_file) curs_db = conn.cursor() curs_db.execute("create table sensor (id integer primary key, cur_time datetime, temperature float, humidity float, co2ppm float)") conn.commit() conn.close()
Теперь файл который будет наполнять БД значениями, считываемыми по параллельному порту:
import sqlite3 import serial import datetime ser = serial.Serial('/dev/ttyUSB0', 57600) sqlite_file = 'db_sensor.db' while True: data = ser.readline() sensor_data = data.decode('ascii').split(',') humidity, temperature, co2ppm = [float(s) for s in sensor_data] cur_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") conn = sqlite3.connect(sqlite_file, detect_types=sqlite3.PARSE_DECLTYPES) curs_db = conn.cursor() curs_db.execute("insert into sensor(cur_time, humidity, temperature, co2ppm) values(?, ?, ?, ?)", (cur_time, humidity, temperature, co2ppm)) conn.commit() conn.close()
-
Edited by kharlashkinСказано, сделано - нашелся проект Platformio
Как всегда - "Весело!".
При попытке собрать и залить прошивку в адруинку вывалилась ошибка:
root@OpenWrt:/mnt/pio# platformio run --target upload [Fri Apr 14 01:30:29 2017] Processing nanoatmega328 (platform: atmelavr, board: nanoatmega328, framework: arduino) -------------------------------------------------------------------------------- PlatformManager: Installing atmelavr Downloading [####################################] 100% Unpacking [####################################] 100% atmelavr @ 1.4.5 has been successfully installed! The platform 'atmelavr' has been successfully installed! The rest of packages will be installed automatically depending on your build environment. PackageManager: Installing toolchain-atmelavr @ ~1.40902.0 Error: Could not find a version that satisfies the requirement '~1.40902.0' for your system 'linux_mips'
Если я правильно понял, для того чтобы иметь возможность компилировать прошивку прямо на девайсе - нужно пересобрать Toolchain под Linux MIPS платформу.
Учитывая что инструмент этот хоть и может быть полезным в некоторых случаях, но несколько избыточен для того чтобы пару раз залить скетч. Так что решил пока отложить использование Platformio "на потом".
Может кто подскажет/поможет с реализацией Toolchain.
- 1
-
пока не проверю получаемый данные в паре и по отдельности датчиков выкладывать не буду.
Полностью рабочий скетч, пока без датчика пыли. Крутился у меня круглосуточно и доказал свою стабильность и правподобность:
#include "DHT.h" #include "RBD_Timer.h" #define dhtPin 2 #define dhtTuype DHT22 #define co2Pin 4 DHT dht(dhtPin, dhtTuype); RBD::Timer timer; long highlevel_co2, lowlevel_co2; float ppmco2 = 0; float humidityIn, temperatureIn, humidityOut, temperatureOut; int valco2; void setup() { Serial.begin(57600); dht.begin(); pinMode(co2Pin, INPUT); timer.setTimeout(5000); timer.restart(); } void loop() { if (timer.getValue() == 2000) { humidityIn = dht.readHumidity(); temperatureIn = dht.readTemperature(); Serial.print("HumidityIn:"); Serial.println(humidityIn); Serial.print("TemperatureIn:"); Serial.println(temperatureIn); } if (timer.getValue() == 3000) { do { valco2 = digitalRead(co2Pin); highlevel_co2 = pulseIn(co2Pin, HIGH, 1004000) / 1000; lowlevel_co2 = 1004 - highlevel_co2; ppmco2 = 5000 * (highlevel_co2 - 2) / (highlevel_co2 + lowlevel_co2 - 4); } while (highlevel_co2 == 0); Serial.print("CO2Concentration:"); Serial.println(ppmco2); } if (timer.isExpired()) { timer.restart(); } }
- 1
-
Edited by kharlashkin
Прошил в свою Arduino Nano 3.0 (специально покупал под проект мониторинга воздуха) следующий скетч:
void setup() { Serial.begin(57600); pinMode(LED_BUILTIN, OUTPUT); } void loop() { digitalWrite(LED_BUILTIN, HIGH); Serial.println("Led On"); delay(1000); digitalWrite(LED_BUILTIN, LOW); Serial.println("Led Off"); delay(1000); }
То есть мигаем светодиодом и шлем сообщения. Подключил к маршрутизатору арудинку. Набросал проверочную программку:
import serial ser = serial.Serial('/dev/ttyUSB0', 57600) while True: line = ser.readline() print line
Скопировал её в папку на маршрутизаторе /mnt/test/ с помощью WinSCP. Что получилось:
Никаких перерезаний дорожек и т.п. не потребовалось (тьфу-тьфу, может в будущем нужно будет).
Кстати, у меня нормально так и не получилось подключаться к файловой системе маршрутизатора под Ubuntu. Так что я скачал портативную версию WinSCP распаковал в папку домашнего каталога и тупо запускаю её - через Wine все работает.
Появилась мысль удаленного железного контроля Arduino. Заливка прошивки, монитор порта и т.д. и т.п. Сказано, сделано - нашелся проект Platformio, и был успешно установлен на маршрутизатор. Пока глубоко не копал и не совсем представляю что с ним делать - но команда
platformio serialports monitor -b 57600
грузит процессор почти на 40% но выдает то же что и выше на скриншоте (python скрипт почти не грузит процессор, встроенные счетчики нагрузки в OpenWRT не фиксируют изменений). Для отладки скетчей самое то, прикрутить бы ещё форму заливки скетчей...
-
Edited by kharlashkin
До утра сидел за ноутом, сегодня половину рабочего дня "гуглил" на работе - решил попробовать OpenWRT, так как в ней вроде есть нужный драйвер для китайских ардуин... Если чуть позже запал не пройдет - буду пробовать собрать драйвер для dd-wrt.
решил попробовать OpenWRT
Изначально боялся что придется всё делать в консоли, но оказалось есть неплохой веб-интерфейс. До этого только один раз устанавливал OpenWRT родителям дома из-за глючности заводской прошивки TP-Link, а других вариантов не было.
Подключил флешку, при чем делается проще чем в dd-wrt - практически всё через web.
Установил драйвер для китайской Arduino:
Поставил python, pip, flask, pyserial. вывел себе в браузер "Hello world!" - красота ;)
- 1
-
Edited by kharlashkin
На NAS поднимать простенький сайт надо, где относительно нормальная дисковая подсистема и процессор есть, а не на маршрутизаторах это делать.
Под простеньким сайтом имелось ввиду внутренний домашний, в моем случае мониторинг воздуха дома.
Когда-то у меня дома стоял D-Link DNS-313 который тоже настраивал как и маршрутизатор и могу сказать что скорость работы с ним была на уровне Asus Wl-520GU. Если сейчас посмотреть на характеристики и цены NAS и маршрутизаторов - думаю не всё так однозначно будет - потому как цены на NAS начинаются от $100. Если выпускать наружу сайтик - то лучше уж что нибудь из "пирогов" или VPS за символическую плату.
подключим его к Arduino.Тут у меня другая проблема - оказалось под dd-wrt нет драйвера для китайских Arduino с чипом ch340g.
- 1
-
Edited by kharlashkin
Подключаем флешку/hdd к dd-wrt.
Небольшое отступление. Так как у меня уже есть отдельный постоянно включенный "домашний ПК", мне не понадобиться файлообменник, торрентокачалка, медиа-сервер на маршрутизаторе. Хотя несколько лет назад это всё у меня прекрасно работало, был подключен портативный 2,5" HDD объемом на 1 ТБ к usb и были установлены:
- Transmission;
- Samba;
- Twonky;
- OpenVPN.
Все это несколько лет прекрасно крутилось в круглосуточном бесшумном режиме. Конечно было заметно слабенький процессор - скорость закачки торрентов ≈ 2 МБ/сек, работа с сетевыми папками ≈ 6 МБ/сек. Затем был куплен большой стационарный ПК под телик, туда установлен HDD на 4 ТБ, а портативный HDD подарен.
Как вспомню как, что делалось - дополню темку. Сейчас появилась необходимость сделать свой web-интерфейс типо "вумного дома" и чтобы не городить дополнительно сервер с Raspberry/Orange/Banana Pi пробую завести это все дело на маршрутизаторе ;)
Имеется флешка на 8 ГБ, её и будем использовать. Разметил я её в GParted под Ubuntu как два раздела Ext3, один на 1000 МиБ под /opt раздел - сюда будем устанавливать наши пакеты, второй всё что осталось как /mnt - сюда буду складывать, что там мне может понадобиться. Для Windows можно использовать её же как LiveCD.
Идем в интерфейс маршрутизатора и выставляем нужные галочки.
Подключаем флешку в порт устройства и перегружаем его. Проверить подключилась ли флешка придется из консоли, как выше генерировали ключи сертификаты. Проверяем что у нас включен доступ к маршрутизатору через Telnet-протокол, вкладка "Services - Services"
Включаем в Windows поддержку этого протокола. ПКМ на Пуск - Панель управления - Программы и компоненты - Клиент Telnet.
Запускаем консоль и вводим:
telnet 192.168.1.1
Маршрутизатор спросит у нас логин, и пароль - вводим что там выставлено при первоначальной настройке.
Проверяем подключилась ли наша флешка:
dmesg|grep lun
Ответ должен быть таким:
/dev/scsi/host0/bus0/target0/lun0: p1 p2
И теперь подключаем наши разделы на флешке как и было задумано, первый к /opt и второй к /mnt:
mount -o noatime /dev/discs/disc0/part1 /opt mount -o noatime /dev/discs/disc0/part2 /mnt
Проверить правильно ли все смонтировалось можно командой "df".
Для подключения и отключения наших разделов нужно пройти на вкладку "Administration - Commands" и добавить команды в загрузочный скрипт и выключения:
Следующим этапом мы установим Python на наш маршрутизатор, поднимем простенький сайт на нем и подключим его к Arduino. -
Edited by kharlashkin
Добрый день всем!
Так сложилось, что уже довольно давно использую свой домашний Asus RT-N16 не только по "прямому" назначению. Хочу здесь публиковать свои изыскания относительно использования таких коробочек.
Я как-то уже спрашивал нашу скромную компанию - "Стоит ли делиться опытом?". Конечно стоит!
Так сложилось что мне пришлось обновлять прошивку. Соответственно нужно опять запускать OpenVPN и раз так заодно поделюсь этим опытом с форумчанами.
1. Почему именно DD-WRT?
Как показывает практика, все производители домашних маршрутизаторов спустя рукава относятся к программному обеспечению, установленному на свои железки. А если говорить о таких вещах, как тонкая настройка множества параметров - заводские прошивки не представляют никаких инструментов от слова вообще. Хотя есть некоторые исключения в виде командной строки, но для этого нужно обложиться учебниками и справочниками, "курить манюалы", много гуглить и т.п.
По закону подлости, всего не предусмотришь и часто что-то делая через shh и telnet ошибка приводит к отсутствию интернета так как роутер не может корректно загрузиться и раздать интернет, а практически никто не имеет дома резервный (или открытый соседский) канал интернета для допиливания конфигураций маршрутизатора из консоли.
Я пробовал практически все альтернативные прошивки для своего Asus и только вышеназванная мною имеет возможность редактировать множество параметров "из коробки" в web-интерфейсе. Особенно это касается следующего пункта.
2. Почему OpenVPN?
Тут все довольно просто - приведу пример. Вы с находитесь в гостевой сети (учеба/работа/интернет-кафе и т.п.) где суровым системным администратором запрещено почти всё - он-лайн игры, скачивание торрентов, просмотр потокового видео и т.д. Стандартные VPN обычно используют тоже известные порты и протоколы, таким образом очень сомневаюсь что тот, который настраивал доступ в интернет так же оставил Вам возможность использовать для обхода что-то типа PPTP/L2TP/PPPoE. Но у нас же есть предварительно настроенный OpenVPN, который работает на любом порте и TCP/UDP транспорте. Как пример если наше соединение работает по 443 порту (https) и используется TCP-транспорт, то для маршрутизатора, который нам дает доступ в интернет это будет выглядеть как будто мы просто просматриваем сайт (как google.com или koreanrandom.com). Трафик весь шифруется, и даже с помощью специальных утилит никто не увидит что же мы на этом сайте делаем.
3. Прошивка маршрутизатора.
Идем в соответствующий раздел, вводим название производителя маршрутизатора и нам вываливаются список моделей которые можно прошить.
Небольшое отступление. Так сложилось что мой первый домашний роутер был Asus WL-520gU и первый провайдер предоставлял доступ к интернет с PPPoE Dual Access (Russian PPPoE) - т.е. доступ к локальным ресурсам и отдельно доступ к сети интернет. При чем мой работодатель так же был подключен к этому провайдеру, соответственно я мог получать доступ к своему терминальному рабочему месту (1С, почта, файловое хранилище) и сайту (периодически наполнял его интересными статьями) из дома с наивысшей скоростью, как по локальной сети. Просидев пару вечеров допоздна с dd-wrt я так и не смог корректно настроить одновременную работу интернета и локальной сети провайдера. Вернулся на заводскую прошивку, но всё решил случай. В один летний день грянул гром, т.е. ожидалась гроза и провайдер выключил интернет - на тот момент кое-где между домами использовалась витая пара, и в целях сохранности своего оборудования этот поставщик услуг просто выключал физически электричество на всей своей сети. Поискав доступные беспроводные сети я нашел какую-то соседскую без пароля, подключившись увидел что там доступ к интернету имеется. Зайдя на маршрутизатор соседа глянул что там прописано в настройках - оказалось что другой провайдер, доступный в моем доме, не имеет вышеозначенных проблем с медными кабелями, а раздает интернет статическим адресом. И я просто сменил провайдера ;) А для доступа к ресурсам работодателя подключил себе услугу "Статический IP-адрес" за $2 и попросил системных администраторов разрешить мне доступ извне с этого IP.
Имея статический адрес захотелось получать доступ к домашним ресурсам и более-менее простую установку и настройку как раз можно сделать с помощью OpenVPN и обсуждаемой альтернативной прошивки. В будущем когда стал выбор покупки маршрутизатора, сразу смотрел поддержку устройства на сайте.
На страничке с прошивками для роутеров, мы видим прошивку для первого раза с заводской и несколько других с расширенным функционалом - инструкций для перепрошивки достаточно, я не буду тут описывать что к чему.
4. Подготовка OpenVPN.
Так как большинство используют Windows, сборку ключей и сертификатов будем делать под этой ОС. Сначала идём на официальную страницу загрузки и качаем нужную версию. Установка ничем особо не отличается, кроме необходимости поставить галочку в нужном месте:
Запускаем консоль Windows - ПКМ (правая кнопка мыши) на Пуск - выполнить - "cmd".
Переходим в папку с установленной программой:
cd C:\Program Files\OpenVPN\easy-rsa
и последовательно выполняем команды:
init-config.bat vars.bat clean-all.bat vars.bat build-ca.bat vars.bat build-dh.bat vars.bat build-key-server.bat "имя сервера" vars.bat build-key.bat "имя клиента"
Под полями "имя сервера" и "имя клиента" вводите свои имена для маршрутизатора и подключаемых к нему потом устройств. При создании сертификатов/ключей у нас будут постоянно спрашивать всякое-разное, я вводил ответы "как оно есть".
В итоге у нас в папке C:\Program Files\OpenVPN\easy-rsa\keys множество нам нужных ключей и сертификатов. И мы можем переходить к настройке маршрутизатора.
5. Настройка маршрутизатора.
Идем на web-интерфейс нашего маршрутизатора и переходим на вкладку Services - VPN и включаем наш OpenVPN Daemon:
Затем поочередно заполняем соответствующие поля нашими сертификатами и ключами из папки, просто открывая в текстовом редакторе:
- CA Cert - C:\Program Files\OpenVPN\easy-rsa\keys\ca.crt;
- Public Client Cert - C:\Program Files\OpenVPN\easy-rsa\keys\"имя сервера".crt;
- Private Client Key - C:\Program Files\OpenVPN\easy-rsa\keys\"имя сервера".key;
- DH PEM - C:\Program Files\OpenVPN\easy-rsa\keys\dh1024.pem;
В поле OpenVPN Config, записываем конфигурацию, это пример моей:
mode server tls-server daemon server 192.168.66.0 255.255.255.0 port 443 proto tcp-server dev tun0 ca /tmp/openvpn/ca.crt cert /tmp/openvpn/cert.pem key /tmp/openvpn/key.pem dh /tmp/openvpn/dh.pem push "redirect-gateway def1" push "dhcp-option DNS 192.168.66.1" push "dhcp-option WINS 192.168.66.1" keepalive 10 120 client-to-client persist-key persist-tun verb 3
6. Настройка клиента Windows.
Так как у нас уже есть установленная версия, на ОС под которой мы создавали ключики и сертификаты, то просто редактируем с помощью блокнота "C:\Program Files\OpenVPN\sample-config\client.ovpn" и сохраняем конфигурационный файл в папку "C:\Program Files\OpenVPN\config".
client dev tun proto tcp-client remote "myIP" 443 resolv-retry infinite nobind persist-key persist-tun ca "C:\\Program Files\\OpenVPN\\easy-rsa\\keys\\ca.crt" cert "C:\\Program Files\\OpenVPN\\easy-rsa\\keys\\"имя клиента".crt" key "C:\\Program Files\\OpenVPN\\easy-rsa\\keys\\"имя клиента".key" verb 3
Где "myIP" - это статический адрес нашего маршрутизатора или имя маршрутизатора через службу Динамического DNS. А "имя клиента" то же что и выше.
7. Собственно и всё.
Запускаем OpebVPN GUI нажимаем ПКМ на иконке и подключаемся.
После успешной авторизации значек заполниться зеленым, значит весь ваш интернет-трафик зашифрован и идет через домашний маршрутизатор, то есть никто не сможет увидеть куда вы ходите и что делаете в интернете. Ну кроме просмотра трафика после маршрутизатора.
- 3
-
Edited by kharlashkin
Итак два датчика DTH22, один в КСД (камеры статического давления) на подачу воздуха после кондера, второй на рециркуляцию, библиотека для DTH, два резистора на 10кОм.
Собственно код:
#include "DHT.h" #define dhtInPin 2 #define dhtOutPin 3 #define dhtTuype DHT22 DHT dhtIn(dhtInPin, dhtTuype); DHT dhtOut(dhtOutPin, dhtTuype); void setup() { Serial.begin(9600); dhtIn.begin(); dhtOut.begin(); } void loop() { delay(2000); float humidityIn = dhtIn.readHumidity(); float temperatureIn = dhtIn.readTemperature(); Serial.print("HumidityIn: "); Serial.println(humidityIn); Serial.print("TemperatureIn: "); Serial.println(temperatureIn); delay(2000); float humidityOut = dhtOut.readHumidity(); float temperatureOut = dhtOut.readTemperature(); Serial.print("HumidityOut: "); Serial.println(humidityOut); Serial.print("TemperatureOut: "); Serial.println(temperatureOut); }
Нашлась неплохая библиотека управления событиями по таймеру - Timer. Как говорится "то, что доктор прописал" ;)
Скетч для температурных датчиков:
#include "DHT.h" #include <RBD_Timer.h> #define dhtInPin 2 #define dhtOutPin 3 #define dhtTuype DHT22 DHT dhtIn(dhtInPin, dhtTuype); DHT dhtOut(dhtOutPin, dhtTuype); RBD::Timer timer; void setup() { Serial.begin(115200); dhtIn.begin(); dhtOut.begin(); timer.setTimeout(4000); timer.restart(); } void loop() { if(timer.getValue() == 2000) { float humidityIn = dhtIn.readHumidity(); float temperatureIn = dhtIn.readTemperature(); Serial.print("HumidityIn: "); Serial.println(humidityIn); Serial.print("TemperatureIn: "); Serial.println(temperatureIn); } else if(timer.isExpired()) { float humidityOut = dhtOut.readHumidity(); float temperatureOut = dhtOut.readTemperature(); Serial.print("HumidityOut: "); Serial.println(humidityOut); Serial.print("TemperatureOut: "); Serial.println(temperatureOut); timer.restart(); } }
- 1
-
Так и надо, имхо.
Просто как-то хотелось сделать чуть ли не систему реального времени, а записывать в базу уже средние значения раз в минуту например, но видимо не судьба;)
-
P.S. Заметил глюк, в датчике СО2 стоит LED-нагреватель, который периодически включается/выключается. Во время его работы + так же запитан датчик пыли (тоже со встроенным нагревателем), светодиоды на ардуинке заметно тускнеют - питание просаживается. Если в этот момент времени идет передача данных в Serial - следующее значение ppmco2 будет равно -10, т.е. импульс не был посчитан.
Ну в общем всё не так. И скетч не правильный, непонятно почему меня никто не ткнул носом в мою необразованность. По-порядку.
Контроллер не умеет работать в несколько потоков и параллельно выполнять разные функции. Т.е. при выполнении например этого:
duration = pulseIn(dustPin, LOW);
Код будет ожидать окончания импульса, а в даташите указываются длины импульсов 10-90 мс (страница 3), таким образом весь процесс будет тормозиться. А для этого:
highlevel_co2 = pulseIn(co2Pin, HIGH, 1004000) / 1000; // Получение длины импульса HIGH в мс
Мы вообще тормозим всё на 1004 мс.
Т.е. мне пришлось переделывать почти всё (благо пример для mh-z19 pwm был изначально правильно написан), пока не проверю получаемый данные в паре и по отдельности датчиков выкладывать не буду. У всех прошу прощения за ввод в заблуждение. Сейчас крутиться тестовый скетч, но через сутки начинает врать датчик СО2.
Приехали датчики температуры и влажности dth-22 (даташит). Но все примеры и поиск на github построены с помощью delay(), а это значит что придется опять "изобретать велосипед".
С другой стороны, никто не мешает мне вызывать функции в определенное время, т.е. сначала выполняем подсчет пыли, потом меряем СО2, затем температуру и т.п.
- 1
-
Edited by kharlashkin
Апну темку, приехали датчик уровня СО2 и пыли (MH-Z19 и DSM501A). Несколько вечеров копался в коде/игрался настройками, собственно результат ниже:
// Подключение Pin_3 DSM501A к Arduino 5В // Подключение Pin_5 DSM501A к Arduino GND // Подключение Pin_4 DSM501A к Arduino D8 // Подключение Vin MH-Z19 к Arduino 5В // Подключение GND MH-Z19 к Arduino GND // Подключение PWM MH-Z19 к Arduino D3 #define co2Pin 3 // Назначение пина подключения датчика СО2 #define dustPin 8 // Назначение пина подключения датчика пыли unsigned long duration; unsigned long starttime_dust; unsigned long endtime_dust; unsigned long sampletime_dust = 30000; // Время измерения пыли в мс unsigned long lowpulseoccupancy = 0; long highlevel_co2; long lowlevel_co2; long starttime_co2; long endtime_co2; long sampletime_co2 = 1004; // Время измерения СО2 в мс float ratio_dust = 0; float concentration_dust = 0; float pcsl = 0; float ppmco2 = 0; void setup() { Serial.begin(9600); pinMode(dustPin, INPUT); pinMode(co2Pin, INPUT); starttime_dust = millis(); starttime_co2 = millis(); } void loop() { duration = pulseIn(dustPin, LOW); lowpulseoccupancy = lowpulseoccupancy + duration; // Счетчик продолжительности импульсов endtime_dust = millis(); endtime_co2 = millis(); if ((endtime_dust - starttime_dust) >= sampletime_dust) { dust_concentration(lowpulseoccupancy); // Вызов функции расчета количества частиц на литр lowpulseoccupancy = 0; // Обнуление счетчика starttime_dust = millis(); } if ((endtime_co2 - starttime_co2) >= sampletime_co2) { co2_concentration(); // Вызов функции расчета СО2 starttime_co2 = millis(); } } void dust_concentration(unsigned long lowpulseoccupancy) { ratio_dust = lowpulseoccupancy / (sampletime_dust * 10.0); // Значение в процентах от 0 до 100 concentration_dust = 1.1 * pow(ratio_dust, 3) - 3.8 * pow(ratio_dust, 2) + 520 * ratio_dust + 0.62; // Расчет количества на куб.фут pcsl = concentration_dust / 0.2831685; // Перевод куб.фут в литр Serial.print("pcsl:"); Serial.println(pcsl); } void co2_concentration() { highlevel_co2 = pulseIn(co2Pin, HIGH, 1004000) / 1000; // Получение длины импульса HIGH в мс lowlevel_co2 = sampletime_co2 - highlevel_co2; // Расчет длины импульса LOW в мс ppmco2 = 5000 * (highlevel_co2 - 2) / (highlevel_co2 + lowlevel_co2 - 4); // Расчет концентрации СО2 Serial.print("ppm:"); Serial.println(ppmco2); }
Жду остальные посылки с температурными датчиками и т.д.
P.S. Заметил глюк, в датчике СО2 стоит LED-нагреватель, который периодически включается/выключается. Во время его работы + так же запитан датчик пыли (тоже со встроенным нагревателем), светодиоды на ардуинке заметно тускнеют - питание просаживается. Если в этот момент времени идет передача данных в Serial - следующее значение ppmco2 будет равно -10, т.е. импульс не был посчитан. Хорошо что блок питания 5В у меня отдельный будет для автоматики ;)
- 3
-
Edited by kharlashkin
Добавил в сообщение о модернизации серв фото процесса, прошу камнями сильно не кидать - снимал на телефон.
-
Edited by kharlashkin
Класс!
Спасибо, @Pavel3333! Хотел отметить, что обычным паяльником я бы туда не подлез никак, так что для мелких деталюшек китайская usb-поделка самое оно. Осталось самое интересное теперь - довести до ума платформу, т.е. модернизировать сервы для отдачи значений в Blender, закрепить датчики на основе и платформе. Оформить инструкцию и визуализацию.
Вчера просидел весь вечер с магнитометром, думаю нужно калибровать его ручками и немного изменять математику Arduino скетча. Кстати хорошая ссылка на инструкцию по калибровке. Если все получиться с датчиками, подумываю следующим этапом зачудить отслеживание движений человека ;)
- 1
-
Edited by kharlashkin
Сегодня получил обратную связь от сервопривода.
Фотографии не стал пока делать - буду перепаивать остальные сделаю обязательно.Подопытный с коробком спичек для оценки размера
Вскрыл крышку сервы на 4-х длинных саморезах.
Запустил тестовый скетч "Sweep" из примеров и мультиметром поискал контакт с плавающим значением. Повезло и попал с первого раза :)
Место припайки
С припаянным проводком
Припаял проводок на платку, вывел наружу вместе с остальными 3-мя, опять проверил мультиметром - все работает, показывало плавающие значения по памяти вроде от 0,7 до 2,1 В.
Собственно проверочный код:
#include <Servo.h> Servo myservo; int pos = 0; int analogPin = 3; int val = 0; void setup() { myservo.attach(9); Serial.begin(9600); } void loop() { for (pos = 0; pos <= 180; pos += 1) { myservo.write(pos); val = analogRead(analogPin); Serial.println(val); delay(50); } for (pos = 180; pos >= 0; pos -= 1) { myservo.write(pos); val = analogRead(analogPin); Serial.println(val); delay(50); } }
И вывод в порт:
449 449 449 449 445 444 441 440 438 436 435 433 431 429 428 426 424 423 421 419 417 523 414 522 410 514 407 406 403 401 399 397 396 394 392 390 389 387 385 384 381 380 377 376 374 372 371 369 368 366 422 362 464 358 458 355 369 351 351 348 346 345 343 341 339 337 335 333 331 329 328 327 325 324 321 319 318 316 313 312 310 399 307 398 304 393 299 385 295 295 292 290 286 284 282 280 278 277 275 273 271 269 267 265 263 261 259 257 256 254 288 250 333 245 326 242 240 238 236 233 231 230 228 226 223 222 220 218 216 214 212 210 208 206 204 202 199 199 196 194 192 260 188 261 184 254 180 178 175 173 172 170 168 166 164 161 160 158 155 153 152 150 148 146 144 141 139 137 135 133 132 129 194 125 188 120 181 116 112 111 109 108 108 108 109 113 115 117 120 121 124 127 128 131 132 134 136 139 141 143 145 146 149 224 153 229 157 160 161 164 166 168 169 172 173 175 178 180 181 184 185 188 190 192 194 196 198 200 202 204 206 208 209 211 268 215 218 219 305 223 225 227 229 231 233 236 237 239 240 242 244 247 249 251 252 253 256 259 260 262 264 266 268 271 271 273 276 368 279 376 283 375 286 290 290 293 294 296 298 300 302 303 305 308 310 311 313 315 317 318 320 322 324 326 328 330 331 333 384 337 442 340 446 344 445 348 351 352 354 356 357 359 361 362 365 366 368 370 372 374 376 377 380 381 383 385 386 389 390 392 393 500 396 510 400 509 404 511 407 410 411 413 414 417 419 420 422 423 425 428 428 431 432 434 436 438 439 441 443 444 446 448 448 449
Учитывая, что аналоговый вход в ардуинке понимает 0 В как 0, а 5 вольт как 1023, то можно рассчитать, что забираются с сервы значения от 0,53 до 2,2 вольт или получается точность 0,53 градуса. Видно из лога, что есть неточности - но учитывая стоимость серв лучшего и ждать нельзя было ;)
- 1
-
В последний раз я успешно работал с UART на AVR два или три года назад. С того момента нет ни времени, ни особого желания. Код на ассемблере и C для работы с UART как-то не работал, а поиск причины занял бы очень много времени. И что самое обидное, причиной стала бы какая-нибудь мелочь, которую я пропустил в даташите.
Так успешно или не успешно ;)
-
-
Edited by kharlashkin
Наконец-то заставил Blender корректно отображать все повороты датчика (не хочу снимать видео - поздно уже):
Есть небольшая проблема с данными от магнитометра в кватернионах - при повороте датчика вокруг оси Z, в течении пары секунд параметр этот возвращается обратно. Если же считывать данные магнитометра напрямую - есть конечно плаванье (в пределах 3-10 тысячных Гаусса), но показывает на север стабильно.
Блин не охота всю математику перебирать в Arduino коде...
- 1
-
Юнька не универсальна, как Blender.
Не знаю к лучшему или не совсем так, но благодаря своему низкому порогу вхождения (системный python), открытости и поддержке сообщества - Blender, наверное, один из лучших и простых способов понять общую структурную модель своего проекта. Например в моем случае (платформа) это вообще единственный инструмент позволяющий "из коробки" получить полноценную реализацию общей концепции хотелок ;)
Unity же предназначена в первую очередь для создания игр, даже наверное просто для рекламы своего движка - так как любой более профессиональный функционал сразу же потребует платных плагинов или проф версию за деньги.
Осуществляем задуманное, записываем в файлик 1.txt через строку координаты всех частей тела, а потом можно включить Unity, создать сценку с таким же кол-вом костей, написать скрипт для считывания из 1.txt и творить! :)
Зачем если можно брать и отдавать данные непосредственно из com-порта?
Arduino и аналоги
in DIY & Hand-Made
Posted
Я его всё таки нашел! Готовый модуль для Arduino, позволяющий плавно управлять нагрузкой. Правда цена кусается - $25, буду со своим земноводным договариваться ;)