kharlashkin 239 #386812 Posted April 25, 2017 (edited) @norkas, @Azbuka, Да вот как-то внятной инструкции не могу найти. Edited April 25, 2017 by kharlashkin Quote Share this post Link to post Short link Share on other sites
Azbuka 278 #386815 Posted April 25, 2017 @norkas, @Azbuka, Да вот как-то внятной инструкции не могу найти.Есть такая книга. 1 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #386818 Posted April 25, 2017 Есть такая книга. Спасибо. Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #386956 Posted April 26, 2017 (edited) Модернизировал страничку загрузки скетча: '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 April 26, 2017 by kharlashkin 2 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #389704 Posted May 8, 2017 Может кто объяснить мне что это такое и как оно работает? Приехала железка, дополнительно к ней заказал микроконтроллер, который будет отслеживать "0" и рулить напряжением, но мой ноут не захотел видеть платку, а хаба под рукой не оказалось. Стационарный ПК под Win7 увидел нормально, буду пробовать завести что к чему. Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #390315 Posted May 12, 2017 (edited) буду пробовать Наступил на некоторое количество граблей - опишу свой опыт. Грабли №1. Нормальной вменяемой инструкции "для чайников" нет, AliExpress дает вроде как две ссылки на RobotDyn, но они неправильные, в русском сегменте вообще нет этой железки, правильная ссылка на международный сайт - http://robotdyn.com/~jZEda. В свою очередь в качестве документации дается ссылка на instructables - Arduino Controlled Light Dimmer, где уважаемый diy_bloke, всесторонне довольно подробно расписывает что к чему. В принципе, данный пост я несколько раз прочел на этапе размышлений как же мне плавно управлять вентилятором. Но, может правда это только в моем случае, ни один из приведенного скетча у Вас не заработает! Пробовал это все дело подключать к Arduino Uno R3. Грабли №2. После 2-х ночей, и прочтения вот этой информации со "Школы для электриков", я подумал что вообще зря купил эту железку: Наиболее широкое применение в силовых электронных аппаратах получили фазовое (рис. 4,а,б) и широтно-импульсное управление тиристорами (рис. 4,в). Рис. 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. Ко времени прочтения уже было полное понимание работы, тиристоров, схем, приведенных скетчей и инструкций. Именно эта картинка и дала толчок к правильному написанию нужного мне скетча: #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 May 12, 2017 by kharlashkin 2 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #391031 Posted May 18, 2017 Буду пробовать прошивать в ATtiny85. Чет мне кажется спалил я тиньку или сбросил память в "0" - перепутал "+" с землей. Пока гуглю как прошить в неё загрузчик Digispark с помощью ардуинки. Имхо, управлять тиристором и считывать значения датчиков параллельно, наверное не самый лучший вариант - ресурсов не хватит. 2 Quote Share this post Link to post Short link Share on other sites
SkepticalFox 1,445 #392404 Posted May 29, 2017 (edited) . Edited January 9, 2021 by SkepticalFox 2 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #392413 Posted May 30, 2017 http://micropython.org/live/ Что-то очень прикольная штука для поиграться))) Читал когда-то на хабре про эту платку - отзывы были неоднозначны, ведь можно использовать те же малины, апельсины, бананы с полноценной операционной системой и полноценным python - примерно за те же деньги. На странице проекта выложены бинарники для ESP8266 и STM32F4 - а это уже интереснее :) Чет мне кажется спалил я тиньку или сбросил память в "0" - перепутал "+" с землей. Пробовал прошить загрузчик Digispark в плату несколькими способами - умерла так умерла. Как нагулилось - я в принципе всё делал правильно за некоторым исключением, нужно было после получения некорректной работы погуглить ещё, а не тыкать проводки. В этой теме на официальном форуме по ардуинке есть и полученные мною симптомы и решение проблемы. Наверное буду всё-таки побеждать тиньку ;) Но уже придется заказать новую - благо стоит копейки. 1 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #394460 Posted June 9, 2017 (edited) Прочел книгу про кватернионы и трехмерную геометрию, начал заново копать ориентацию в пространстве с помощью MPU-9250. Набаловавшись до "не могу" со всякими фильтрами Маджвика, Махони и Калмана и так и не получив внятную картинку в Blender - пошел по пути наименьшего сопротивления. А если быть точным решил попробовать DMP (digital motion process), который по-умолчанию есть в датчике. Результат на видео. Если я правильно понимаю, то для более точного позиционирования (а кубик гуляет по оси Z где то секунд 10, в самом начале), нужно дополнительно забирать данные магнитометра и корректировать полученный из DMP кватернион. Edited June 9, 2017 by kharlashkin 1 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #394897 Posted June 12, 2017 Чет, не могу считать данные магнитометра. Код для получения кватерниона с помощью DMP брал отсюда (улыбнуло размещение сайта - kr). Относительно управления платформой кватернионами, нашел интересную статью - "Применение кватернионов в задачах наведения антенной системы ретранслятора связи на беспилотном летательном аппарате". Решается задача подобная моей для антенны с 3-мя степенями свободы, а чтобы получить 6 степеней нужно наверное будет использовать бикватернионы. Кому интересно статья во вложении. primenenie-kvaternionov-v-zadachah-navedeniya-antennoy-sistemy-retranslyatora-svyazi-na-bespilotnom-letatelnom-apparate.pdf Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #395753 Posted June 20, 2017 (edited) Сегодня получилось уделить немного времени подключению ардуинки по Bluetooth. Платка где-то месяц уже у меня не все никак руки не доходили. Итак, платка вот такая HC-06 (фото не мое): Перво-наперво нужно настроить модуль для работы, думаю понятно что скорость 9600 б/с будет маловата. Инструкций в интернетах несколько, попробовав некоторые - привожу что и как получилось у меня. В качестве транслятора команд для настройки модуля я использовал саму ардуинку. Собственно код, который позволяет обмен данными между ПК и модулем: #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", т.е. не поменять ни скорость, ни пин-код, ни посмотреть версию прошивки не смогли. Так же прилагаю документ с AT-командами. P.S. Собственно я уже попробовал крутить кубик в Blender через беспроводной интерфейс ;) Жду в течении 7/10 дней портативный аккумулятор и буду делать более корректное видео кручения автономного кубика (привет Portal/Portal2) + причесывать код. HMComAssistant.7z AT_HC05.pdf Edited June 20, 2017 by kharlashkin Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #396213 Posted June 26, 2017 (edited) умерла так умерла. Приехала новая "тинька". Как не странно, всё завелось "с пол пинка". 'Код 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 June 26, 2017 by kharlashkin 1 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #400448 Posted August 11, 2017 (edited) После отпуска по доставал свои игрушки, взялся с новыми силами за положения в пространстве датчика MPU-9250. Чет, не могу считать данные магнитометра. Получилось заставить DMP обрабатывать данные от магнитометра, дополнительно включил математику в обработку кватерниона от DMP по этой статье. В принципе получилось очень даже ничего, особенно учитывая что данные от магнитометра без калибровки. Есть лишь небольшое подергивание кубика в блендер, но зато практически полностью пропал дрифт. Видео чуть позже добавлю. Залил проект на github. Имхо, будет неплохо наложить фильтр Калмана на данные от магнетометра, повысить точность позиционирования например на 4 знака после запятой (сейчас, как видно 2). test.7z Edited August 13, 2017 by kharlashkin 2 Quote Share this post Link to post Short link Share on other sites
Pavel3333 1,148 #400669 Posted August 13, 2017 класс. 1 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #400685 Posted August 14, 2017 класс. Спасибо Вам, Павел, за поддержку. Очень часто, именно вот таких простых слов от окружающих в отношении того, что ты делаешь - не хватает ;) 1 Quote Share this post Link to post Short link Share on other sites
Pavel3333 1,148 #400687 Posted August 14, 2017 всегда рад, проект сложный, по крайней мере для меня. продолжайте в том же духе, авось получится какая-нибудь полезная диковинка. Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #400688 Posted August 14, 2017 всегда рад, проект сложный, по крайней мере для меня. продолжайте в том же духе, авось получится какая-нибудь полезная диковинка. Думаю что настоящему программисту, а не поделке в моем лице, работы было бы на пару дней. Мне больше для души нравится копошиться в этом всём, математику пришлось подтянуть для понимания общего процесса. Ну уже с Вами обсуждалось какую диковинку :) Сейчас у меня лежит 3 датчика 9250, 3 платки Arduino Pro Mini + едет батарейка с платкой именно для продолжение проекта. Думаю попробовать сделать подобие отслеживания руки (плечо, предплечье и кисть). Ломал на дня голову с корпусами - решил использовать обычные двойные телефонные розетки, сразу вопрос с соединениями отпадёт - все таки разъемные с нормальным проводом это плюс ;) Тестировал дома код для MPU-9250 чет не такой стабильный оказался на столе, но выявилась проблема с домашней экспериментальной Uno - рандомно ложится передача данных. Пробовал на ноуте/ПК под разными ОС - идет передача данных 2-5-10-20 сек и потом всё замирает. Хотя после повторной инициализации соединения - все работает нормально. На работе где экспериментирую с Nano - все более-менее стабильно. 2 Quote Share this post Link to post Short link Share on other sites
kharlashkin 239 #400768 Posted August 15, 2017 Гы. Создал в MakeHuman персонажа со скелетом, набросал скриптик для забора данных из Arduino и отправки кватернионов для положения кости головы персонажа. Весело получилось - крутить на usb-шнуре коробок с датчиком и ардуинкой и смотреть как голова сходит с ума. 1 Quote Share this post Link to post Short link Share on other sites
Pavel3333 1,148 #401249 Posted August 20, 2017 @kharlashkin, красава!!! это то, что я хотел! весело получилось. еще бы физ. движок подключить с мультиплАером, классно бы было. 1 Quote Share this post Link to post Short link Share on other sites