Jump to content
Korean Random

Arduino и аналоги


kharlashkin

Recommended Posts

С другой стороны, никто не мешает мне вызывать функции в определенное время, т.е. сначала выполняем подсчет пыли, потом меряем СО2, затем температуру и т.п.

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

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

Edited by Pavel3333
Link to comment
Short link
Share on other sites

 

 

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

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

Link to comment
Short link
Share on other sites

Просто как-то хотелось сделать чуть ли не систему реального времени

 

Мы и сами не в реальном времени находимся. Передача и обработка изображения в глазах занимает 60 нс, т.е. по факту мы находимся в прошлом. То же самое и тут. Скорость импульса крайне мала. Сравните, ведь 30 микросекунд отображается один кадр на мониторе. 

Edited by Pavel3333
  • Upvote 1
Link to comment
Short link
Share on other sites

Итак два датчика 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();
    }
}
Edited by kharlashkin
  • Upvote 1
Link to comment
Short link
Share on other sites

  • 3 weeks later...

 

 

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

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

#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
Link to comment
Short link
Share on other sites

Пример сбора данных от 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()
Link to comment
Short link
Share on other sites

Для  таких данных лучше подойдет циклическая база данных.

А как же красивости в виде графиков? Почасово, посуточно и т.д. Прошу прощения.

Edited by kharlashkin
Link to comment
Short link
Share on other sites

Пример вывода данных из 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

Edited by kharlashkin
  • Upvote 2
Link to comment
Short link
Share on other sites

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

 

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

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

  • Upvote 1
Link to comment
Short link
Share on other sites

Прошивка скетча в Arduino подключенного к маршрутизатору с помощью flask+avrdude.

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

from flask import Flask, render_template, request, redirect, flash
from werkzeug.utils import secure_filename
import subprocess, os

app = Flask(__name__)
UPLOAD_FOLDER = '/kharlashkin/Flask/uploads'
ALLOWED_EXTENSIONS = set(['hex'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload_file', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file.filename == '':
            flash('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename) == False:
            flash('Incorrect file format')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect('/uploaded_file')
    return render_template("upload_file.html")

@app.route('/uploaded_file', methods=['GET', 'POST'])
def uploaded_file():
    if request.method == 'POST':
        files = os.listdir(UPLOAD_FOLDER)
        for file in files:
            filename = os.path.join(UPLOAD_FOLDER, file)
            if os.path.isfile(filename):
                filename = filename
        cmd = 'avrdude -p m328p -P /dev/ttyUSB0 -b 57600 -c arduino -U flash:w:'+filename
        PIPE = subprocess.PIPE
        p = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=subprocess.STDOUT, close_fds=True)
        while True:
            console = p.stdout.readline()
            if not console: break
            flash(console)
        os.remove(filename)
    return render_template("uploaded_file.html")

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)

'Страница загрузки HEX-файла'

{% extends "base.html" %}
{% block content %}
    <h1>Загрузка скетча на сервер</h1>
    <form method=post enctype=multipart/form-data>
      <p><input type=file name=file></p>
      <br>
      <p><input type=submit value=Загрузка></p>
    </form>
    {% with messages = get_flashed_messages() %}
        {% if messages %}
            <ul class=flashes>
                {% for message in messages %}
                {{ message }}
                {% endfor %}
            </ul>
        {% endif %}
    {% endwith %}
{% endblock %}

'Страница прошивки скетча в Arduino'

{% extends "base.html" %}
{% block content %}
    <h1>Скетч загружен на сервер</h1>
    <form method=post enctype=multipart/form-data>
      <p><input type=submit value=Прошивка></p>
    </form>
{% with messages = get_flashed_messages() %}
    {% if messages %}
{% for message in messages %}
<i>
{{ message }}
<br>
</i>
{% endfor %}
    {% endif %}
{% endwith %}
{% endblock %}

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

post-19155-0-19056500-1492778096_thumb.png

post-19155-0-48093800-1492778114_thumb.png

post-19155-0-60638800-1492778121_thumb.png

post-19155-0-24495400-1492778109_thumb.png

 

P.S. Рассказал бы кто на пальцах как Github подключить...

Edited by kharlashkin
Link to comment
Short link
Share on other sites

Сегодня подумалось, что несколько некорректно выглядит загрузка скетча в адруинку, немного переделал:

'Код'

from flask import Flask, render_template, request, redirect, flash
from werkzeug.utils import secure_filename
import subprocess, os

app = Flask(__name__)
UPLOAD_FOLDER = '/kharlashkin/Flask/uploads'
ALLOWED_EXTENSIONS = set(['hex'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload_file', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file.filename == '':
            flash('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename) == False:
            flash('Incorrect file format')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            cmd = 'avrdude -p m328p -P /dev/ttyUSB0 -b 57600 -c arduino -U flash:w:' + UPLOAD_FOLDER + '/' + filename
            flash(cmd)
            PIPE = subprocess.PIPE
            p = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=subprocess.STDOUT, close_fds=True)
            while True:
                console = p.stdout.readline()
                if not console: break
                flash(console)
            os.remove(UPLOAD_FOLDER + '/' + filename)
    return render_template("upload_file.html")

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000) 

 

'Страничка'

{% extends "base.html" %}
{% block content %}
    <h1>Загрузка скетча в Arduino</h1>
    <form method=post enctype=multipart/form-data>
      <p><input type=file name=file></p>
      <br>
      <p><input type=submit value=Загрузка></p>
    </form>
    {% with messages = get_flashed_messages() %}
        {% if messages %}
                {% for message in messages %}
                <i>
                {{ message }}
                <br>
                </i>
                {% endfor %}
        {% endif %}
    {% endwith %}
{% endblock %} 

  • Upvote 1
Link to comment
Short link
Share on other sites

Что конкретно хочется сделать с помощью котиков?

Ну сейчас процесс написания вот этих простеньких вещей, занимает достаточно много времени в основном из-за отсутствия синхронизации между рабочим местом и домашним ноутбуком. Использую PyCharm, для написания, а TeamViewer для тестирования, нужен какой-то сервис хранения кода.

Edited by kharlashkin
Link to comment
Short link
Share on other sites

Может кто объяснить мне что это такое и как оно работает?

Видимо, это простой датчик света (фоторезистор), на который попадает пучок света, и от этого зависит его сопротивление. Нет света - сопротвление велико. Очень светло - сопротивление мало.

PS. Вроде бы это не так. Это регулировщик яркости света, нет никаких фоторезисторов.

Edited by Pavel3333
Link to comment
Short link
Share on other sites

Видимо, это простой датчик света (фоторезистор), на который попадает пучок света, и от этого зависит его сопротивление. Нет света - сопротвление велико. Очень светло - сопротивление мало.

PS. Вроде бы это не так. Это регулировщик яркости света, нет никаких фоторезисторов.

Да нет, насколько я понимаю - это симисторный регулятор, но без мозгов. Т.е. к нему нужен микроконтроллер для управления.

Link to comment
Short link
Share on other sites

 

 

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

Вы не используете git? По началу он сложный и непонятный, но потом программировать без него невозможно.

 

Синхронизация? Легко и просто: создаете удаленный репозиторий на GitHub или Bitbucket и используете git push/git pull.

 

 

 

нужен какой-то сервис хранения кода
 

GitHub или Bitbucket. Второй позволяет создавать приватные репозитории, но первый удобнее для взаимодействия с другими разработчиками.

  • Upvote 1
Link to comment
Short link
Share on other sites

Ну сейчас процесс написания вот этих простеньких вещей, занимает достаточно много времени в основном из-за отсутствия синхронизации между рабочим местом и домашним ноутбуком. Использую PyCharm, для написания, а TeamViewer для тестирования, нужен какой-то сервис хранения кода.

Так PyCharm имеет же даже GUI для команд систем контроля версий, в том числе и гита. Хотя это и не важно, я лично использую исключительно консоль для взаимодействия с гитом, но признаю что порог вхождения очень высок, и поэтому вам подойдёт GUI гита встроенный в PyCharm. Ещё можно сделать хранение кода не на каком-нибудь сервисе вроде гитхаба, а прям на своей машине, но думаю для знакомства и ваших нужд как раз гитхаб\битбукет подойдёт как нельзя лучше.

 

 

 

Вы не используете git? По началу он сложный и непонятный, но потом программировать без него невозможно.
+

Надо только заставить себя начать.

  • Upvote 2
Link to comment
Short link
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...