Jump to content
Korean Random

kharlashkin

User
  • Posts

    829
  • Joined

  • Last visited

  • Days Won

    7

Posts posted by kharlashkin

  1. Тиристором можно управлять средствами самой Arduino.

     

    Я его всё таки нашел! Готовый модуль для Arduino, позволяющий плавно управлять нагрузкой. Правда цена кусается - $25, буду со своим земноводным договариваться ;)

    post-19155-0-38596700-1492685856_thumb.jpg

    • Upvote 1
  2. 2. Подключаем накопитель к OpenWRT.

    Идем на веб страничку установки пакетов:

    post-19155-0-21811300-1492513958_thumb.png

    Обновляем список доступных пакетов, кнопка Update list:

    post-19155-0-32199000-1492515198_thumb.png

    Устанавливаем пакеты - kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb-storage block-mount нажимаем и перегружаемся System  - Reboot - Perform reboot

    post-19155-0-60117800-1492514275_thumb.png

    Заходим в настройки точек монтирования System - Mount points и видим нашу флешку, ставим галочку напротив нашего раздела для установки пакетов и жмем кнопку Edit:

    post-19155-0-25783600-1492514823_thumb.png

    Ставим галочку подключать диск, UUID оставляем тот же:

    post-19155-0-93725700-1492515005_thumb.png

    Переходим на вкладку Advanced Settings и выбираем нашу файловую систему из выпадающего меню:

    post-19155-0-66958700-1492515115_thumb.png

    Перегружаемся, после перезагрузки все наши настройки сбросятся, но мы увидим что наш раздел для установки стал намного больше:

    post-19155-0-65433300-1492515400_thumb.png

    Опять устанавливаем нужные пакеты kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb-storage block-mount, и подключаем теперь уже swap раздел и домашний каталог по аналогии.

    • Upvote 1
  3. “Не было бы счастья, да несчастье помогло”
    Так вышло, что у родителей вышел из строя HDD, флешку мою, забытую у них в спутниковом тюнере, мне не привезли. Пришлось вытягивать из маршрутизатора и делать из неё загрузочную - чтобы установить ОС на новый HDD, соответственно первоначальную настройку делать сначала. Таким образом появилась эта инструкция.
    1. Подготовка носителя в GParted.
    Открываем программу и выбираем нашу флешку:

    post-19155-0-40265000-1492423592_thumb.png

    Отмонтируем нашу флешку от ОС, ПКМ - Отмонтировать:

    post-19155-0-20749100-1492424011_thumb.png

    Удаляем все что есть на ней, клавиша "delete" или ПКМ - Удалить:

    post-19155-0-62853800-1492424183_thumb.png

    Я решил, что под установочные пакеты отдам 1000 МиБ, под swap раздел 256 МиБ, остальное под мои файлы.

    Создаем разделы на флешке как мы задумали: , клавиша "insert" или ПКМ - Новый, для разделов под программы и мои файлы выбираем файловую систему "Ext3", под раздел подкачки "linux-swap":

    post-19155-0-81924500-1492424526_thumb.png

    Применяем нужные нам изменения:

    post-19155-0-87474800-1492424641_thumb.png

    Соглашаемся с применением изменений, ждём окончания операций.

    post-19155-0-59278000-1492424741_thumb.png

    Закрываем GParted и вытягиваем флешку из ПК.

    • Upvote 1
  4. 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> 

    Ну и как это выглядит:

    post-19155-0-74843200-1492291189_thumb.png

    • Upvote 2
  5. Пример сбора данных от 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()
    
  6. 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.

    • Upvote 1
  7.  

     

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

    Полностью рабочий скетч, пока без датчика пыли. Крутился у меня круглосуточно и доказал свою стабильность и правподобность:

    #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();
      }
    }
    
    • Upvote 1
  8. 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. Что получилось:

    post-19155-0-50787100-1492079581_thumb.png

    Никаких перерезаний дорожек и т.п. не потребовалось (тьфу-тьфу, может в будущем нужно будет).

     

    Кстати, у меня нормально так и не получилось подключаться к файловой системе маршрутизатора под Ubuntu. Так что я скачал портативную версию WinSCP распаковал в папку домашнего каталога и тупо запускаю её - через Wine все работает.


    Появилась мысль удаленного железного контроля Arduino. Заливка прошивки, монитор порта и т.д. и т.п. Сказано, сделано - нашелся проект Platformio, и был успешно установлен на маршрутизатор. Пока глубоко не копал и не совсем представляю что с ним делать - но команда

    platformio serialports monitor -b 57600
    

    грузит процессор почти на 40% но выдает то же что и выше на скриншоте (python скрипт почти не грузит процессор, встроенные счетчики нагрузки в OpenWRT не фиксируют изменений). Для отладки скетчей самое то, прикрутить бы ещё форму заливки скетчей...

  9. Edited by kharlashkin

    До утра сидел за ноутом, сегодня половину рабочего дня "гуглил" на работе - решил попробовать OpenWRT, так как в ней вроде есть нужный драйвер для китайских ардуин... Если чуть позже запал не пройдет - буду пробовать собрать драйвер для dd-wrt.


    решил попробовать OpenWRT

     

    Изначально боялся что придется всё делать в консоли, но оказалось есть неплохой веб-интерфейс. До этого только один раз устанавливал OpenWRT родителям дома из-за глючности заводской прошивки TP-Link, а других вариантов не было.

    Подключил флешку, при чем делается проще чем в dd-wrt - практически всё через web.

    Установил драйвер для китайской Arduino:

    post-19155-0-17473700-1492076447_thumb.png

    Поставил python, pip, flask, pyserial. вывел себе в браузер "Hello world!" - красота ;)

    post-19155-0-47262900-1492032720_thumb.png

    • Upvote 1
  10. Edited by kharlashkin

    На NAS поднимать простенький сайт надо, где относительно нормальная дисковая подсистема и процессор есть, а не на маршрутизаторах это делать.

    Под простеньким сайтом имелось ввиду внутренний домашний, в моем случае мониторинг воздуха дома.

    Когда-то у меня дома стоял D-Link DNS-313 который тоже настраивал как и маршрутизатор и могу сказать что скорость работы с ним была на уровне Asus Wl-520GU. Если сейчас посмотреть на характеристики и цены NAS и маршрутизаторов - думаю не всё так однозначно будет - потому как цены на NAS начинаются от $100. Если выпускать наружу сайтик - то лучше уж что нибудь из "пирогов" или VPS за символическую плату.

     

     

    подключим его к Arduino.

    Тут у меня другая проблема - оказалось под dd-wrt нет драйвера для китайских Arduino с чипом ch340g.

    • Upvote 1
  11. 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.

     

    Идем в интерфейс маршрутизатора и выставляем нужные галочки.

    post-19155-0-19359100-1491978095_thumb.png

    Подключаем флешку в порт устройства и перегружаем его. Проверить подключилась ли флешка придется из консоли, как выше генерировали ключи сертификаты. Проверяем что у нас включен доступ к маршрутизатору через Telnet-протокол, вкладка "Services - Services"

    post-19155-0-37238800-1491978397_thumb.png

    Включаем в Windows поддержку этого протокола. ПКМ на Пуск - Панель управления - Программы и компоненты - Клиент Telnet.

    post-19155-0-74297600-1491978636_thumb.png

    Запускаем консоль и вводим:

    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" и добавить команды в загрузочный скрипт и выключения:

    post-19155-0-50803800-1491980798_thumb.png

     

    Следующим этапом мы установим Python на наш маршрутизатор, поднимем простенький сайт на нем и подключим его к Arduino.

  12. 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. Прошивка маршрутизатора.

    Идем в соответствующий раздел, вводим название производителя маршрутизатора и нам вываливаются список моделей которые можно прошить.

    post-19155-0-12429900-1491844853_thumb.png

    Небольшое отступление. Так сложилось что мой первый домашний роутер был Asus WL-520gU и первый провайдер предоставлял доступ к интернет с PPPoE Dual Access (Russian PPPoE) - т.е. доступ к локальным ресурсам и отдельно доступ к сети интернет. При чем мой работодатель так же был подключен к этому провайдеру, соответственно я мог получать доступ к своему терминальному рабочему месту (1С, почта, файловое хранилище) и сайту (периодически наполнял его интересными статьями) из дома с наивысшей скоростью, как по локальной сети. Просидев пару вечеров допоздна с dd-wrt я так и не смог корректно настроить одновременную работу интернета и локальной сети провайдера. Вернулся на заводскую прошивку, но всё решил случай. В один летний день грянул гром, т.е. ожидалась гроза и провайдер выключил интернет - на тот момент кое-где между домами использовалась витая пара, и в целях сохранности своего оборудования этот поставщик услуг просто выключал физически электричество на всей своей сети. Поискав доступные беспроводные сети я нашел какую-то соседскую без пароля, подключившись увидел что там доступ к интернету имеется. Зайдя на маршрутизатор соседа глянул что там прописано в настройках - оказалось что другой провайдер, доступный в моем доме, не имеет вышеозначенных проблем с медными кабелями, а раздает интернет статическим адресом. И я просто сменил провайдера ;) А для доступа к ресурсам работодателя подключил себе услугу "Статический IP-адрес" за $2 и попросил системных администраторов разрешить мне доступ извне с этого IP.

    Имея статический адрес захотелось получать доступ к домашним ресурсам и более-менее простую установку и настройку как раз можно сделать с помощью OpenVPN и обсуждаемой альтернативной прошивки. В будущем когда стал выбор покупки маршрутизатора, сразу смотрел поддержку устройства на сайте.

    На страничке с прошивками для роутеров, мы видим прошивку для первого раза с заводской и несколько других с расширенным функционалом - инструкций для перепрошивки достаточно, я не буду тут описывать что к чему.

     

    4. Подготовка OpenVPN.

    Так как большинство используют Windows, сборку ключей и сертификатов будем делать под этой ОС. Сначала идём на официальную страницу загрузки и качаем нужную версию. Установка ничем особо не отличается, кроме необходимости поставить галочку в нужном месте:

    post-19155-0-15413600-1491912643_thumb.png

    Запускаем консоль 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:

    post-19155-0-96677200-1491915822_thumb.png

    Затем поочередно заполняем соответствующие поля нашими сертификатами и ключами из папки, просто открывая в текстовом редакторе:

    • 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 нажимаем ПКМ на иконке и подключаемся.

    post-19155-0-48617100-1491918171.png

    После успешной авторизации значек заполниться зеленым, значит весь ваш интернет-трафик зашифрован и идет через домашний маршрутизатор, то есть никто не сможет увидеть куда вы ходите и что делаете в интернете. Ну кроме просмотра трафика после маршрутизатора.

    • Upvote 3
  13. Edited by kharlashkin

    Итак два датчика DTH22, один в КСД (камеры статического давления) на подачу воздуха после кондера, второй на рециркуляцию, библиотека для DTH, два резистора на 10кОм.

     

    post-19155-0-06324300-1490639842_thumb.png

    Собственно код:

    #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();
        }
    }
    
    • Upvote 1
  14.  

     

    Так и надо, имхо.

    Просто как-то хотелось сделать чуть ли не систему реального времени, а записывать в базу уже средние значения раз в минуту например, но видимо не судьба;)

  15.  

     

    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, затем температуру и т.п.

    • Upvote 1
  16. 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В у меня отдельный будет для автоматики ;)

    • Upvote 3
  17. Edited by kharlashkin

    :no1:

    Класс!

    Спасибо, @Pavel3333! Хотел отметить, что обычным паяльником я бы туда не подлез никак, так что для мелких деталюшек китайская usb-поделка самое оно. Осталось самое интересное теперь - довести до ума платформу, т.е. модернизировать сервы для отдачи значений в Blender, закрепить датчики на основе и платформе. Оформить инструкцию и визуализацию.

    Вчера просидел весь вечер с магнитометром, думаю нужно калибровать его ручками и немного изменять математику Arduino скетча. Кстати хорошая ссылка на инструкцию по калибровке. Если все получиться с датчиками, подумываю следующим этапом зачудить отслеживание движений человека ;)

    • Upvote 1
  18. Edited by kharlashkin

    Сегодня получил обратную связь от сервопривода. Фотографии не стал пока делать - буду перепаивать остальные сделаю обязательно.

    Подопытный с коробком спичек для оценки размера

    post-19155-0-38586800-1486239159_thumb.jpg

    Вскрыл крышку сервы на 4-х длинных саморезах.

    post-19155-0-71708600-1486239173_thumb.jpgpost-19155-0-35516300-1486239184_thumb.jpg

    Запустил тестовый скетч "Sweep" из примеров и мультиметром поискал контакт с плавающим значением. Повезло и попал с первого раза :)

    Место припайки

    post-19155-0-33835900-1486239194_thumb.jpg

    С припаянным проводком

    post-19155-0-14847500-1486239206_thumb.jpg

    Припаял проводок на платку, вывел наружу вместе с остальными 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 градуса. Видно из лога, что есть неточности - но учитывая стоимость серв лучшего и ждать нельзя было ;)

    • Upvote 1
  19. В последний раз я успешно работал с UART на AVR два или три года назад. С того момента нет ни времени, ни особого желания. Код на ассемблере и C для работы с UART как-то не работал, а поиск причины занял бы очень много времени. И что самое обидное, причиной стала бы какая-нибудь мелочь, которую я пропустил в даташите.

    Так успешно или не успешно ;)

  20. Edited by kharlashkin

    Нашел похожий проект платформы в blender на просторах - буду изучать.

    @Azbuka, Как-то давно не появлялся... Так уверенно писал о вводе/выводе в/из arduino, хотел спросить о примере реализации.

    • Upvote 1
  21. Edited by kharlashkin

    Наконец-то заставил Blender корректно отображать все повороты датчика (не хочу снимать видео - поздно уже):

    post-19155-0-86507200-1485899993_thumb.png

    Есть небольшая проблема с данными от магнитометра в кватернионах - при повороте датчика вокруг оси Z, в течении пары секунд параметр этот возвращается обратно. Если же считывать данные магнитометра напрямую - есть конечно плаванье (в пределах 3-10 тысячных Гаусса), но показывает на север стабильно.

    Блин не охота всю математику перебирать в Arduino коде...

    • Upvote 1
  22. Юнька не универсальна, как Blender.

    Не знаю к лучшему или не совсем так, но благодаря своему низкому порогу вхождения (системный python), открытости и поддержке сообщества - Blender, наверное, один из лучших и простых способов понять общую структурную модель своего проекта. Например в моем случае (платформа) это вообще единственный инструмент позволяющий "из коробки" получить полноценную реализацию общей концепции хотелок ;)

    Unity же предназначена в первую очередь для создания игр, даже наверное просто для рекламы своего движка - так как любой более профессиональный функционал сразу же потребует платных плагинов или проф версию за деньги.

    Осуществляем задуманное, записываем в файлик 1.txt через строку координаты всех частей тела, а потом можно включить Unity, создать сценку с таким же кол-вом костей, написать скрипт для считывания из 1.txt и творить! :)

    Зачем если можно брать и отдавать данные непосредственно из com-порта?

×
×
  • Create New...