Jump to content
Korean Random
kharlashkin

Arduino и аналоги

Recommended Posts

Модернизировал страничку загрузки скетча:

post-19155-0-07771300-1493237137_thumb.png

'run.py'

from flask import Flask, render_template, request, flash, redirect
import forms
from flask_wtf.csrf import CSRFProtect
from werkzeug import secure_filename
import os, subprocess


app = Flask(__name__)
csrf = CSRFProtect(app)

app.secret_key = '9\xd8\xcc\xdb\x9d(\x94\xbex\xc4*\xd5\x17\xcet\xad\xc7\xe7i\x92\xaf\xf1x\xa8'

@app.route('/upload_sketch', methods=['GET', 'POST'])
def upload_sketch():
    form = forms.Avrdude()
    if form.validate_on_submit():
        partno = request.form['partno']
        port = request.form['port']
        baudrate = request.form['baudrate']
        programmer = request.form['programmer']
        sketch = form.sketch.data
        filename = secure_filename(sketch.filename)
        sketch.save(os.path.join('/kharlashkin/Flask/uploads', filename))
        cmd = 'avrdude -p ' + partno + ' -P ' + port + ' -b ' + baudrate + ' -c ' + programmer + ' -U flash:w:' + 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('/kharlashkin/Flask/uploads' + '/' + filename)
        return redirect(request.url)
    elif form.errors:
        for fieldName, errorMessages in form.errors.iteritems():
            for error in errorMessages:
                flash(error)
        return redirect(request.url)
    return render_template('upload_sketch.html', form=form)

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

'forms.py'

from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileRequired, FileAllowed
from wtforms import SelectField
import glob

ports = glob.glob('/dev/tty[A-Za-z]*')

class Avrdude(FlaskForm):
    partno = SelectField('partno', choices=[('m328', 'ATmega328'),
                                               ('m328p', 'ATmega328P'),
                                               ('m168',	'ATmega168'),
                                               ('m168p', 'ATmega168P'),
                                               ('m2560', 'ATmega2560 (**)'),
                                               ('m32u4', 'ATmega32U4'),
                                               ('t85', 'ATtiny85')])
    baudrate = SelectField('baudrate', choices=[('9600', '9600'),
                                                ('19200', '19200'),
                                                ('38400', '38400'),
                                                ('57600', '57600'),
                                                ('74880', '74880'),
                                                ('115200', '115200'),
                                                ('230400', '230400'),
                                                ('250000', '250000')])
    programmer = SelectField('programmer', choices=[('avrisp', 'Atmel AVR ISP'),
                                                    ('avrispmkII', 'Atmel AVR ISP mkII'),
                                                    ('arduino', 'Arduino'),
                                                    ('usbtiny', 'USBtiny simple USB programmer'),
                                                    ('usbasp', 'USBasp')])
    sketch = FileField(validators=[FileRequired('No selected file'), FileAllowed(['hex'], 'Incorrect file format')])
    port = SelectField('port', choices=[(i, i) for i in ports]) 

'upload_sketch.html'

{% extends "base.html" %}
{% block content %}
<h1>Загрузка скетча в Arduino</h1>
<br>
<form method="post" enctype="multipart/form-data">
    {{ form.csrf_token }}
    {{ form.sketch }}
    <br>
    <strong>Микроконтроллер</strong>
    {{ form.partno }}
    <strong>Порт</strong>
    {{ form.port }}
    <strong>Скорость</strong>
    {{ form.baudrate }}
    <strong>Программатор</strong>
    {{ form.programmer }}
    <input type="submit" value="Загрузка">
</form>
{% with messages = get_flashed_messages() %}
    {% if messages %}
        {% for message in messages %}
        <i>
        <br>
        {{ message }}
        </i>
        {% endfor %}
    {% endif %}
{% endwith %}
{% endblock %} 

'base.html'

<!DOCTYPE html>
<html lang="en">
<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Свежий воздух</title>

    <!-- Bootstrap Core CSS -->
    <link href="static/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom CSS -->
    <style>
    body {
        padding-top: 70px;
        /* Required padding for .navbar-fixed-top. Remove if using .navbar-static-top. Change if height of navigation changes. */
    }
    </style>

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>

<body>

    <!-- Navigation -->
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
        <div class="container">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/index">Свежий воздух</a>
            </div>
            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <li>
                        <a href="#">About</a>
                    </li>
                    <li>
                        <a href="#">Services</a>
                    </li>
                    <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Arduino<span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="/serial_monitor">Монитор порта</a></li>
                        <li><a href="/upload_sketch">Загрузка скетча</a></li>
                    </ul>
                    </li>
                </ul>
            </div>
            <!-- /.navbar-collapse -->
        </div>
        <!-- /.container -->
    </nav>

    <!-- Page Content -->
    <div class="container">
{% block content %}
{% endblock %}
    </div>
    <!-- /.container -->

    <!-- jQuery Version 1.11.1 -->
    <script src="static/js/jquery.js"></script>

    <!-- Bootstrap Core JavaScript -->
    <script src="static/js/bootstrap.min.js"></script>

</body>
</html> 

Нужно попробовать монитор порта прикрутить ;)

Edited by kharlashkin
  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

 

 

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

Приехала железка, дополнительно к ней заказал микроконтроллер, который будет отслеживать "0" и рулить напряжением, но мой ноут не захотел видеть платку, а хаба под рукой не оказалось. Стационарный ПК под Win7 увидел нормально, буду пробовать завести что к чему.

Share this post


Link to post

Short link
Share on other sites

буду пробовать

 

Наступил на некоторое количество граблей - опишу свой опыт.

post-19155-0-36178700-1494583966_thumb.jpg

Грабли №1.

Нормальной вменяемой инструкции "для чайников" нет, AliExpress дает вроде как две ссылки на RobotDyn, но они неправильные, в русском сегменте вообще нет этой железки, правильная ссылка на международный сайт - http://robotdyn.com/~jZEda. В свою очередь в качестве документации дается ссылка на instructables - Arduino Controlled Light Dimmer, где уважаемый diy_bloke, всесторонне довольно подробно расписывает что к чему. В принципе, данный пост я несколько раз прочел на этапе размышлений как же мне плавно управлять вентилятором. Но, может правда это только в моем случае, ни один из приведенного скетча у Вас не заработает! Пробовал это все дело подключать к Arduino Uno R3.

Грабли №2.

После 2-х ночей, и прочтения вот этой информации со "Школы для электриков", я подумал что вообще зря купил эту железку:

Наиболее широкое применение в силовых электронных аппаратах получили фазовое (рис. 4,а,б) и широтно-импульсное управление тиристорами (рис. 4,в).

post-19155-0-16432400-1494585607.jpg

Рис. 5. Вид напряжения на нагрузке при: а) – фазовом управлении тиристором; б) – фазовом управлении тиристором с принудительной коммутацией; в) – широтно-импульсном управлении тиристором

В названии этого модуля явно указано PWM, соответственно только широтно-импульсном управление платка может. У меня уже был модуль с твердотельным реле, который можно примерно таким же образом использовать. В общем и целом пичалька. Код который заточен работать для пропуска полупериодов уже не помню где взял. Основная идея там счетчик перехода синусоиды через 0, и закрытие / открытие тиристора и обнуление счетчика. Как работает с вентилятором не понравилось - например, в течении 5 циклов, 4 идет на 100% и 1 цикл на 0% мощности. За счет инерции двигателя вентилятора возможно он и крутиться на 80% максимальной мощности. Но меня этот вариант не устраивал. Думаю, он хорош только для нагревателей.

Грабли №3.

Устав топтаться на одном месте и не высыпаясь, перешел ко второй части "Марлезонского балета", а именно к платке Digispark ATtiny85 MicroUSB. Практически сразу нашлась тема, где на этом чипе уже делали диммер. Захотелось попробовать прошить соответствующий скетч, но сработала "защита от дурака", подробнее в этом сообщении. Покопав исходники и погуглив - оказалось, что прошив данный скетч в ATtiny85, я потеряю возможность использовать функционал Digispark, и прошивать нужно только программатором или вот так незатейливо по инструкции с официального форума Arduino. Я так понимаю, что приведенный скетч использует внутренний таймер процессора, который так же используют Digispark для связи по usb с ПК.

 

Самое интересное что я для себя вынес из этих уроков - ссылка в скетче ;) Voltage controlled dimmer with an ATtiny85. Которая привела меня куда нужно - AC Phase Control.

post-19155-0-79748200-1494587925_thumb.png

Ко времени прочтения уже было полное понимание работы, тиристоров, схем, приведенных скетчей и инструкций. Именно эта картинка и дала толчок к правильному написанию нужного мне скетча:

#define ControlSimistor 3 //  Выход на симистор
#define ControlZero 2 //  Вход контроля перехода через 0
volatile byte dimming = 0; //  Начальное значение мощности

void setup()
{
  pinMode(ControlSimistor, OUTPUT);
  digitalWrite(ControlZero, 1); // Активируем контроль перехода через 0
  Serial.begin(57600);  //  Значения мощности через порт
  attachInterrupt(0, zero, RISING); //  Внешнее прерывание контроля перехода через ноль
}

void zero() //  Если есть переход через 0
{
  if (dimming >= 255) // Если задано максимальное значение
  {
    digitalWrite(ControlSimistor, HIGH); // Тиристор постоянно открыт
  }
  else if (dimming <= 0) // Если минимум
  {
    digitalWrite(ControlSimistor, LOW); // Тиристор закрыт
  }
  else if (dimming > 0 && dimming < 255) // Если не минимум и не максимум
  {
    digitalWrite(ControlSimistor, LOW); // Сначала закрываем
    delayMicroseconds((5100 - dimming * 20)); // Ждем
    digitalWrite(ControlSimistor, HIGH); // Открываем тиристор
  }
}

void loop()
{
  if (Serial.available()) // Если порт открыт
  {
    dimming = Serial.parseInt();  // Считываем данные и находим в них целое число
  }
}

Ну, могу себя поздравить, на Arduino все работает как нужно! Буду пробовать прошивать в ATtiny85.

Хочу кое-что прояснить. Изначально я испытывал полный цикл в 10 мс на полупериод, но учитывая особенности вентиляторов он начинает более-менее нормально крутить крыльчатку где-то с 45% мощности, именно поэтому задается такая задержка в начале полупериода до открытия тиристора + в дальнейшем буду использовать analogRead().

Edited by kharlashkin
  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

 

 

Буду пробовать прошивать в ATtiny85.
 

Чет мне кажется спалил я тиньку или сбросил память в "0" - перепутал "+" с землей. Пока гуглю как прошить в неё загрузчик Digispark с помощью ардуинки. Имхо, управлять тиристором и считывать значения датчиков параллельно, наверное не самый лучший вариант - ресурсов не хватит.

  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

http://micropython.org/live/

Что-то очень прикольная штука для поиграться)))

Читал когда-то на хабре про эту платку - отзывы были неоднозначны, ведь можно использовать те же малины, апельсины, бананы с полноценной операционной системой и полноценным python - примерно за те же деньги. На странице проекта выложены бинарники для ESP8266 и STM32F4 - а это уже интереснее :)

 

 

Чет мне кажется спалил я тиньку или сбросил память в "0" - перепутал "+" с землей.

Пробовал прошить загрузчик Digispark в плату несколькими способами - умерла так умерла.

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

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Прочел книгу про кватернионы и трехмерную геометрию, начал заново копать ориентацию в пространстве с помощью MPU-9250. Набаловавшись до "не могу" со всякими фильтрами Маджвика, Махони и Калмана и так и не получив внятную картинку в Blender - пошел по пути наименьшего сопротивления. А если быть точным решил попробовать DMP (digital motion process), который по-умолчанию есть в датчике. Результат на видео.

Если я правильно понимаю, то для более точного позиционирования (а кубик гуляет по оси Z где то секунд 10, в самом начале), нужно дополнительно забирать данные магнитометра и корректировать полученный из DMP кватернион.

Edited by kharlashkin
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Чет, не могу считать данные магнитометра. Код для получения кватерниона с помощью DMP брал отсюда (улыбнуло размещение сайта - kr).

Относительно управления платформой кватернионами, нашел интересную статью - "Применение кватернионов в задачах наведения антенной системы ретранслятора связи на беспилотном летательном аппарате". Решается задача подобная моей для антенны с 3-мя степенями свободы, а чтобы получить 6 степеней нужно наверное будет использовать бикватернионы. Кому интересно статья во вложении.

primenenie-kvaternionov-v-zadachah-navedeniya-antennoy-sistemy-retranslyatora-svyazi-na-bespilotnom-letatelnom-apparate.pdf

Share this post


Link to post

Short link
Share on other sites

Сегодня получилось уделить немного времени подключению ардуинки по Bluetooth. Платка где-то месяц уже у меня не все никак руки не доходили.

Итак, платка вот такая HC-06 (фото не мое):

post-19155-0-38778300-1497963929_thumb.jpg

Перво-наперво нужно настроить модуль для работы, думаю понятно что скорость 9600 б/с будет маловата. Инструкций в интернетах несколько, попробовав некоторые - привожу что и как получилось у меня. В качестве транслятора команд для настройки модуля я использовал саму ардуинку.

post-19155-0-68747800-1497966883_thumb.png

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

#include <SoftwareSerial.h>
#include <Time.h>

int gLedPin = 13; 
int gRxPin = 10; // Pin-ы подключения модуля
int gTxPin = 11;

SoftwareSerial BTSerial(gRxPin, gTxPin);

void setup() {
  // Настраиваем скорости обмена от ПК в ардуину и в модуль
  BTSerial.begin(9600);
  Serial.begin(38400);
  delay(500);
}

void loop() {
  if (BTSerial.available()) {
    Serial.write(BTSerial.read());
  }
  if (Serial.available()) {
    BTSerial.write(Serial.read());
  }
}

Для работы с модулем корректно завелась программка терминала HMComAssistant (архив приложил). Остальные могли только одну команду "AT", т.е. не поменять ни скорость, ни пин-код, ни посмотреть версию прошивки не смогли.

post-19155-0-28834700-1497966154_thumb.png

Так же прилагаю документ с AT-командами.

 

P.S. Собственно я уже попробовал крутить кубик в Blender через беспроводной интерфейс ;) Жду в течении 7/10 дней портативный аккумулятор и буду делать более корректное видео кручения автономного кубика (привет Portal/Portal2) + причесывать код.

HMComAssistant.7z

AT_HC05.pdf

Edited by kharlashkin

Share this post


Link to post

Short link
Share on other sites
умерла так умерла.

Приехала новая "тинька". Как не странно, всё завелось "с пол пинка".

'Код Digispark'

#include "SoftSerial.h"
#include "TinyPinChange.h"

SoftSerial mySerial(3, 4);

#define ControlSimistor 1 //  Выход на симистор, физический порт P1
#define ControlZero 2 // Вход контроля перехода через 0, физический порт P2

volatile byte dimming = 0; //  Начальное значение мощности

void setup()
{
  mySerial.begin(9600);
  pinMode(ControlSimistor, OUTPUT); // Включаем работу выхода на симистор
  pinMode(ControlZero, INPUT); // Переключаем контроль перехода через 0 на выход
  digitalWrite(ControlZero, HIGH); // Активируем контроль перехода через 0
  attachInterrupt(0, zero, RISING); //  Внешнее прерывание контроля перехода через ноль
}

void zero() //  Если есть переход через 0
{
  if (dimming >= 255) // Если задано максимальное значение
  {
    digitalWrite(ControlSimistor, HIGH); // Тиристор постоянно открыт
  }
  else if (dimming <= 10) // Если минимум
  {
    digitalWrite(ControlSimistor, LOW); // Тиристор закрыт
  }
  else if (dimming > 10 && dimming < 255) // Если не минимум и не максимум
  {
    digitalWrite(ControlSimistor, LOW); // Сначала закрываем
    delayMicroseconds((5100 - dimming * 20)); // Ждем
    digitalWrite(ControlSimistor, HIGH); // Открываем тиристор
  }
}

void loop()
{
  if (mySerial.available())
  {
    dimming = mySerial.read();
  }
} 

'Код Arduino'

#include "SoftwareSerial.h"

SoftwareSerial mySerial(10, 11); // Задаем программный порт на 10 и 11 портах

volatile byte dimming = 0; // Начальное значение мощности

void setup()
{
  Serial.begin(57600);  // Включаем порт с ПК
  mySerial.begin(9600); // Включаем порт с Attiny85
}

void loop()
{
  if (Serial.available()) // Если порт открыт
  {
    dimming = Serial.parseInt(); // Считываем данные и находим в них целое число
    mySerial.write(dimming); // Отправляем значение мощности в Attiny85
  }
} 

Есть багофича - значения менее 17 тинька отрабатывает но вентилятор не крутится. Думаю переделать на более вменяемые значения мощности :)

P.S. Думаю что первоначальная платка имела брак - потому как новая завелась под Ubuntu на рабочем ноуте без "бубна";)

Edited by kharlashkin
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

После отпуска по доставал свои игрушки, взялся с новыми силами за положения в пространстве датчика MPU-9250.

 

Чет, не могу считать данные магнитометра.

 

Получилось заставить DMP обрабатывать данные от магнитометра, дополнительно включил математику в обработку кватерниона от DMP по этой статье. В принципе получилось очень даже ничего, особенно учитывая что данные от магнитометра без калибровки. Есть лишь небольшое подергивание кубика в блендер, но зато практически полностью пропал дрифт. Видео чуть позже добавлю.

Залил проект на github.

Имхо, будет неплохо наложить фильтр Калмана на данные от магнетометра, повысить точность позиционирования например на 4 знака после запятой (сейчас, как видно 2).

test.7z

Edited by kharlashkin
  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

класс.

Спасибо Вам, Павел, за поддержку. Очень часто, именно вот таких простых слов от окружающих в отношении того, что ты делаешь - не хватает ;)

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

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

Share this post


Link to post

Short link
Share on other sites

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

Думаю что настоящему программисту, а не поделке в моем лице, работы было бы на пару дней. Мне больше для души нравится копошиться в этом всём, математику пришлось подтянуть для понимания общего процесса. Ну уже с Вами обсуждалось какую диковинку :)

Сейчас у меня лежит 3 датчика 9250, 3 платки Arduino Pro Mini + едет батарейка с платкой именно для продолжение проекта.

post-19155-0-01512300-1502688162_thumb.jpg

Думаю попробовать сделать подобие отслеживания руки (плечо, предплечье и кисть). Ломал на дня голову с корпусами - решил использовать обычные двойные телефонные розетки, сразу вопрос с соединениями отпадёт - все таки разъемные с нормальным проводом это плюс ;)

post-19155-0-71736800-1502688393_thumb.jpg

Тестировал дома код для MPU-9250 чет не такой стабильный оказался на столе, но выявилась проблема с домашней экспериментальной Uno - рандомно ложится передача данных. Пробовал на ноуте/ПК под разными ОС - идет передача данных 2-5-10-20 сек и потом всё замирает. Хотя после повторной инициализации соединения - все работает нормально. На работе где экспериментирую с Nano - все более-менее стабильно.

  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

Гы.

Создал в MakeHuman персонажа со скелетом, набросал скриптик для забора данных из Arduino и отправки кватернионов для положения кости головы персонажа. Весело получилось - крутить на usb-шнуре коробок с датчиком и ардуинкой и смотреть как голова сходит с ума.

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

@kharlashkin, красава!!!

это то, что я хотел! весело получилось.

 

еще бы физ. движок подключить с мультиплАером, классно бы было. 

  • Upvote 1

Share this post


Link to post

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...