Пример № 1. Визуализация входящих данных. (Много текста)
- Войдите на сайт для отправки комментариев
«Вата»
Урок рассчитан на пользователей, ознакомленных с языком программирования Processing, если его можно так назвать. Для тех же, кто еще не в курсе, что это такое, милости просим на http://processing.org/. Будем так же надеяться что на http://arduino.ru появится раздел с переводом как для Arduino IDE.
«Вкратце»
Processing, весьма специфический инструмент визуализации, рассчитанный, изначально, на гик-дизайнеров и «Инсталляторов». Но так уж сложилось, что в его основу лег язык программирования – wiring. Хотя если честно тут очень много споров о том как же все таки появился Processing. Ну и ладно.
Специфичность же заключается в том что прежде чем что то сделать нужно четко понимать как пишется «скетч» и как он выполняется. В нашем случае важно как раз второе. В момент когда я изучил Arduino IDE и добрался до Processing мне было все понятно и не вызывало вопросов. Но когда я решил совместить нечто графическое с железным – произошел конфуз. Как раз потому что я не учел особенностей выполнения «скетча», а именно его строгую последовательность. Думаю что многие с этим столкнулись и потому хочу поделиться тем как я справился с некоторыми задачами.
«Красим забор»
Не пугайтесь читать полностью. Я плавно приведу вас к решению задачи поставленной в названии.
А пока немного нюансов….
Первое на что стоит обратить внимание это на структуру скетча. Она похожа на Arduino IDE, с той лишь разницей, что в Processing (далее P) вместо функции loop() прописывается функция draw(). Ну и в P само собой имеется набор функций для работы с графикой. Таким образом наша структура имеет вид:
void setup(){} void draw(){}
Все просто, но именно здесь и зарыта «маска дауна». Объясню на примере.
Нам нужно сделать фон нашего проекта черным, и тут есть два пути - вставить команду background(0); в функцию setup() как настройку нашего проекта, либо вставить ее в draw() и у нас появится возможность оперировать параметром цвета динамически:
void setup(){} void draw(){ background(mouseX); }
Второй способ привлекателен и может нам пригодиться в дальнейшем . И мы тем самым копнув глубже все ближе к «маске дауна». Да что ж за маска то такая дурацкая? Спрсите вы. Да дело все в том, что применив этот прием, вы сразу отсекаете кучу возможностей, которые могут вам понадобиться гораздо больше, чем изменяющий цвет фон. Суть такова что команда background(0); или по русски «фон» , является таковой только в том случае когда она находится в setup(), в любом другом случае это покадровое закрашивание фона. Давайте уже, наконец, разберем реальный случай и решение задачи «Визуализации входящих данных», что поможет нам четко усвоить эти нюансы.
«Суть да дело»
Предположим я хочу отображать с помощью текста, координату курсора мыши в окне проекта. Напишем небольшой код:
int y; void setup(){ size (500, 200); // устанавливаем размер окна } void draw(){ y=mouseY; // пишем в переменную у значение положения курсора мыши по оси Y textSize(32); // размер текста text("Y= "+y, 10, 30); // пишем Y= и подставляем полученное значение }
Логично было бы подумать, что мы получим окошко, в котором будет выводиться постоянно изменяющееся число, отражающее положение курсора относительно оси Y. Запускаем программу и получаем следующее:
Опа! И на вас маска дауна (я в первый раз подумал, что P очень плохой язык программирования).
Все дело в том, что в P, каждый следующий кадр накладывается на предыдущий, не затирая его. Или, проще говоря, предыдущий кадр не стирается. Казалось бы проблема. Тут то, как раз, к нам на помощь приходит функция background();, которая будучи размещенной в draw() будет закрашивать наш фон каждый проход или кадр. Давайте попробуем:
int y; void setup(){ size (500, 200); // устанавливаем размер окна } void draw(){ y=mouseY; // пишем в переменную у значение положения курсора мыши по оси Y background(0); // цвет заливки черный textSize(32); // размер текста text("Y= "+y, 10, 30); // пишем Y= и подставляем полученное значение }
И «вуале» все получилось:
Ну что же отлично. Что хотели - получили. Усложним задачу. Давайте добавим к текстовому формату еще и графический, например, выведем график изменения значения по оси Y с каким либо интервалом. В теории я хочу получить окно, в котором будет отображаться постоянно изменяющееся число, в зависимости от положения курсора, и чтобы еще график рисовался на основании этих данных. Как же это сделать?
Не будем усложнять критерии построения графика, определим лишь, что пиками графика (даже наверно диаграммы) будут максимальные значения Y в момент времени. С этим разобрались. Линия, соединяющая пики, должна быть именно линией, а не кривой, т.к. у нас линейно изменяющаяся координата. Тут я для себя определил, что буду рисовать диаграмму линиями при помощи команды line();. Начало линии будет концом предыдущей линии, где координата конца будет определяться положением курсора. Координата X будет увеличиваться на 1 в каждом проходе, а Y конца в зависимости от положения курсора мыши. Все логично и легко. Пишем код:
int xn=0; // переменная координаты X начала int yn=0; // переменная координаты Y начала int xk=0; // переменная координаты X конца int yk=0; // переменная координаты Y конца void setup(){ size (500, 200); // устанавливаем размер окна } void draw(){ background(0); // цвет заливки черный yk=mouseY; // определяем конец нашей линии по оси Y textSize(32); // размер текста text("Y= "+yk, 10, 30); // пишем Y= и подставляем полученное значение stroke(255); // цвет будущей линии белый line (xn, yn, xk, yk); // рисуем линию xn=xk; // после того как нарисовали линию присваиваем Xначала значение Хконца yn=yk; // после того как нарисовали линию присваиваем Yначала значение Yконца xk++; // смещаем Xконца на единицу }
Запускаем код и ……. Опять двадцать пять. У нас не диаграмма а бегающая точка. Не получилось.
Конечно же, все из-за background(0);- эта команда стирает наши предыдущие линии. Стоит выделить –«Заливает нарисованные в предыдущем кадре линии». Решить легко – перенесем background(0); в setup():
int xn=0; // переменная координаты X начала int yn=0; // переменная координаты Y начала int xk=0; // переменная координаты X конца int yk=0; // переменная координаты Y конца void setup(){ size (500, 200); // устанавливаем размер окна background(0); // цвет заливки черный } void draw(){ yk=mouseY; // определяем конец нашей линии по оси Y textSize(32); // размер текста text("Y= "+yk, 10, 30); // пишем Y= и подставляем полученное значение stroke(255); // цвет будущей линии белый line (xn, yn, xk, yk); // рисуем линию xn=xk; // после того как нарисовали линию присваиваем Xначала значение Хконца yn=yk; // после того как нарисовали линию присваиваем Yначала значение Yконца xk++; // смещаем Xконца на единицу }
Запускаем и ……..
Да что за фигня. Диаграмма рисуется, зато теперь текст сам себя закрашивает. Тупик - маска дауна на лицо.
Честно говоря, я долго искал решение этой проблемы. Пытался даже написать программу которая бы рисовала ломанную линию в циклично заливающемся окне. Коду было много. А потом пришла в голову мысль, что я делаю лишние телодвижения – все равно, что суперклей языком намазывать – можно но сложно. Нам, по сути, нужно заливать только определенную область. А значит можно добавить прямоугольник, который будет рисоваться поверх предыдущего кадра и иметь цвет фона, тем самым затирать наш предыдущий текст. Попробуем:
int xn=0; // переменная координаты X начала int yn=0; // переменная координаты Y начала int xk=0; // переменная координаты X конца int yk=0; // переменная координаты Y конца void setup(){ size (500, 200); // устанавливаем размер окна background(0); // цвет заливки черный } void draw(){ yk=mouseY; // пишем в переменную ук значение положения курсора мыши по оси Y textSize(32); // размер текста fill(0); // заливка для объекта прямоугольник noStroke();//рисовать прямоугольник без абриса rect (5,5,200,40); //рисует прямоугольник перекрывающий наш текст fill(255); // заливка для текста text("Y= "+yk, 10, 30); // пишем Y= и подставляем полученное значение stroke(255); // цвет будущей линии белый line (xn, yn, xk, yk); // рисуем линию xn=xk; // после того как нарисовали линию присваиваем Xначала значение Хконца yn=yk; // после того как нарисовали линию присваиваем Yначала значение Yконца xk++; // смещаем Xконца на единицу }
Запускаем и радуемся – все работает.
Обратите внимание что прямоугольник нарисован до того как будет выведен текст. Иначе выведенный текст будет тут же закрашен. И еще команды fill(); stroke() и тому подобные. Они устанавливают параметры заливки объекта, и наличие и цвет абриса. Если вы хотя бы одному объекту присвоили эти значения, то вам придется указать эти параметры и для других объектов, так как иначе та команда, которая расположена выше по коду, будет распространяться на все последующие.
На этом пожалуй стоит закончить, вам же я рекомендую поэкспериментировать с последовательностями расположения команд и функций в коде – для лучшего понимания работы Processing.
Удачи и до новых встреч.
В следующем примере я буду стирать нарисованную диаграмму и прикручивать ардуинку к этому примеру.
Респект! Ждём продолжения! Я тоже в процессинге сделал, что-то вроде погодной станции)...вот только графики никак не могу прикрутить. Будет интересно послушать
Ну для погодной станции график можно прикрутить скажем с ценой деления в 1 сутки, и соответственно будет отражено скажем графиком температура за месяц. Но в дальнейшем соответственно задача усложнится. Нужно будет прикрутить масштабирование от 1 суток до 1 года. Что пока для меня сложно - но можно. Если не забуду то в следующем примере я немного изменю вид диаграммы в которой как раз можно регистрировать максимумы температур более наглядно.
Еще бы кто нибудь подсказал формулу как из пяти чисел скажем выявить максимальное.
Из трёх так int Hmax = max (55, 56, 67);
либо так из скольки хочешь http://www.processing.org/reference/max_.html
int[] values = { 9, -4, 362, 21, 57, 567 };
int d = max(values);
Блин тока что догнал, не надо 5 чисел. Можно тупо сравнивать с переменной и если число (входные данные) больше переменной, то записываем его в эту переменную, затем по кругу
Да точно спасибо, так даже короче выходит
У меня остались сомнение насчет перерисовки чисел с помощью закрашивания прямоугольником в цвет фона. Это все-таки хак или идеалогия такая? Просто на однотонном фоне это просто, а если фон сложный, а если это график, который нужно стоить. Я так понял гуглением, что как-то можно добиться слоев с помощью PGraphics или вспомогательных библиотек.
Выше по тексту, я писал что пытался писать программу которая бы рисовала мне график (диаграмму) путем создания сложной ломаной. Это все можно. Но поцессинг очень гибкий и изящный инструмент, позволяющий простыми методами решить какую то задачу, не углубляясь в программирование как таковое. В этих примерах я хочу показать как можно просто и без особых усилий что либо сделать, опираясь на особенности использования Процессинга.
Если вас не затруднит - киньте ссылку на тот материал который вы нашли. Думаю об этом можно будет сделать несколько примеров.
Мне вначале попалась ветка на форуме
http://forum.processing.org/topic/creating-layers-in-processing
там говорилось о PGraphics object
Zapek@n
Озадачили вы меня, всю ночь сидел разбирался))) Отличная, кстати сказать, эта ваша "заливная рыба". Думаю сделать отдельный пример использования слоев в P. Но простота всего лишь кажущаяся, скорее удобство. То о чем я писал так же присутствует и в использовании слоев, в частности это background (0);.
Так что пока буду допиливать метод и постараюсь сделать пример.
похожей проблемой с затиранием текста маялся на LCD зацепленном по SPI, и при этом нужна была динамика на выходе, а заливка прямоугольника это куча лишних пикслей уже имеющих цвет фона. Победил проблему алгоритмом 1. напечатать текст, 2. получить в буфер новый текст, 3. напечатать старый текст фоновым цветом, 4. напечатать новый текст из буфера. И т.д. с пункта 2. Как частный случай кому то может пригодится.
Спасибо за проделанную работу!
До утра сидел и пытался данные с сенсора в график представить, но кривой линии не получалось, только точка.
Ошибку увидел посмторев на пример ваш.
void draw() {
background(100, 150, 255);
в draw, когда нужно получить след перемещаемого объекта нельзя указывать background.
Ковырялся и нервно курил, потом решил посмотреть пример и всё получилось.
похожей проблемой с затиранием текста маялся на LCD зацепленном по SPI, и при этом нужна была динамика на выходе, а заливка прямоугольника это куча лишних пикслей уже имеющих цвет фона. Победил проблему алгоритмом 1. напечатать текст, 2. получить в буфер новый текст, 3. напечатать старый текст фоновым цветом, 4. напечатать новый текст из буфера. И т.д. с пункта 2. Как частный случай кому то может пригодится.
Все зависит от организации видеопамяти, принципа и скорости доступа к ней. Обычно в монохромных LCD дисплеях доступ к изображению осуществляется побайтно, а в байте - 8 пикселей. Т.е. оптимизировать нужно не пиксельные операции, а байтовые. Кроме того, можно записать индивидуальный байт по определенному адресу, а можно - несколько последовательных байт, начиная с некоторого адреса. Причем, во втором случае запись одного байта происходит в 3-4 раза быстрее.
Обычно оптимальный (а заодно самый простой для пользователя) алгоритм состоит в том, чтобы задать режим вывода текста с непрозрачным фоном. В любой грамотно написанной библиотеке такой режим должен присутствовать, хотя не обязательно стоять по умолчанию (в Windows он именно по умолчанию). Если такого режима в библиотеке нет, это является признаком низкой квалификации автора библиотеки - такой библиотекой лучше вообще не пользоваться.
valA нигде не меняется, ему нужно присваивать изменяющееся значение. А это значение из порта Вы не считываете, потому и выводится только 0.
Привет всем!
На официальном сайте Arduino на страничке Arduino and Processing рекомендуют следующие библиотеки:
Download
Library for Processing v2.0: processing2-arduino.zip (Updated 6 Nov. 2013)
(properties file here: processing2-arduino.txt)
Library for Processing v1.5: processing-arduino.zip (Updated 11 Nov. 2011)
(properties file here: processing-arduino.txt)
У меня стоит Processing 3.02 и такое ощущение, что он не работает с предложенными старыми библиотеками.
Уже около часа пляшу с бубнами, но связь не получается. Ни один приложенный скетч не работает.
Запускается без ошибок, порт несколько раз определял и переопределял штатным Диспетчером устройств (win10/32). Результат отрицательный :(((
Вариант import processing.serial.*; настраивается и работает без проблем.
Кто-нибудь пробовал ТЕ библиотеки с Processing 3.02 и работает ли оно вааще?
Советую перейти на C# в среде Visual Studio. Возможностей больше и главное удобнее.
Спасибо за совет, уважаемый Spa-sam.
Мне как-то нужнее среда под Андроид.
Многие примеры там работают, но пока карячусь с передачей данных по Bluetooth или иным способом из Ардуины.
На С# в Visual Studio можно писать и под андроид. Пакет назвается Xamarin. Раньше он был платным, но теперь эту контору выкупила microsoft и включила в Visual Studio бесплатно.
На С# в Visual Studio можно писать и под андроид. Пакет назвается Xamarin. Раньше он был платным, но теперь эту контору выкупила microsoft и включила в Visual Studio бесплатно.
Спасибо за инфу.
Буду смотреть в ту сторону.
На С# в Visual Studio можно писать и под андроид. Пакет назвается Xamarin. Раньше он был платным, но теперь эту контору выкупила microsoft и включила в Visual Studio бесплатно.
Есть Уроки по Xamarin + Arduino ? не могу найти в поиске
Чтобы такой режим задать, нужно Буфер Кадра иметь или как минимум Буфер Команд Рисования, а в Ардуине нет памяти даже на Битовую маску толком (булевую), не точто Буфер кадра полноценный
Советую перейти на C# в среде Visual Studio. Возможностей больше и главное удобнее.
Как там под Ардуину писать для PC ?
https://processing.org/
https://ru.wikipedia.org/wiki/Processing
https://processing.org/
https://ru.wikipedia.org/wiki/Processing
это ты кому и к чему? в статье есть эти ссылки
Из всего, что я нашёл толкового http://metanit.com/sharp/xamarin/1.1.php
Но этого далеко недостаточно! Видеоуроков пока толковых нет, но что-то уже появляется.
Пока пользую сторонние mqtt проекты на android...в частности https://play.google.com/store/apps/details?id=net.routix.mqttdash
А свой развиваю на C# в winforms. Думаю перевести совй проект на WPF.
Из всего, что я нашёл толкового http://metanit.com/sharp/xamarin/1.1.php
Но этого далеко недостаточно! Видеоуроков пока толковых нет, но что-то уже появляется.
Пока пользую сторонние mqtt проекты на android...в частности https://play.google.com/store/apps/details?id=net.routix.mqttdash
А свой развиваю на C# в winforms. Думаю перевести совй проект на WPF.
Xamarin же вроде для телефонов и тп а не для ПК
Зачем WPF? я как понял в winforms программы проще получаются в связке с Ардуиной, даже в примерах МДСН форума так написано
Xamarin, да, это для телефонов, но программируется на C#.(хочется не ограничиваться только ПК, а получать телеметрию и на телефоне в удобной для меня форме) Winforms гораздо проще, но WPF с точки зрения оформления интереснее, более гибкий.
Вот с серийным поротом в WPF что-то не задалось, написал код вроде всё верно, а выскакивает ошибка, при тех же условиях, что и в Winforms, где работает всё отлично. Вот думаю не заморачиваться больше с серийным портом, а всё перевести на mqtt (вторая часть телеметрии так и работает и в wpf тоже)
Xamarin, да, это для телефонов, но программируется на C#.(хочется не ограничиваться только ПК, а получать телеметрию и на телефоне в удобной для меня форме)
вопрос главный вот в чем: Может ли один и тот же проект на С# работать и на ПК и на Телефоне? (ну естественно что нужно дописать для телефона интерфейс как Xamarin предполагает)
Winforms гораздо проще, но WPF с точки зрения оформления интереснее, более гибкий.
в чем гибкость заключается ? там и там окошки кнопочки положение на экране размеры элемента
Вот с серийным поротом в WPF что-то не задалось, написал код вроде всё верно, а выскакивает ошибка, при тех же условиях, что и в Winforms, где работает всё отлично. Вот думаю не заморачиваться больше с серийным портом, а всё перевести на mqtt (вторая часть телеметрии так и работает и в wpf тоже)
дело наверно не в самом WPF как таковом а в Самом Проекте WPF в среде (чтото по другому сделано) и не работает
А что такое mqtt? Имею ввиду через что физически обаться? также через USB? Или Ethernet? если 2ое, то это уже совсем другая песня и неоправдана при малой удалённости от ПК (нужен модуль Ethernet а там вроде своих проблем хватает)
Так, чтобы взять и просто перенести код на телефон не получится, основная часть останется, но то что касается оформления нужно полностью переделать.
WPF работает быстрее, так как в нем обработка с помощью directx. По оформлению, можешь посмотреть на том же youtube и увидешь в чём разница. (тут удобство настраивания под разный размер экрана, разметка, оформление окна и начинки, всё вертеть можно как хочешь и т.д.)
По серийному порту ещё буду разбираться.
mqtt очень классная вещь по обмену сообщениями с помощью различных сетевых интерфейсов. Опять же в инете полно инфы, повторяться не буду.
https://processing.org/
https://ru.wikipedia.org/wiki/Processing
это ты кому и к чему? в статье есть эти ссылки
Ардуина то тут причем?
Так, чтобы взять и просто перенести код на телефон не получится, основная часть останется, но то что касается оформления нужно полностью переделать.
это я понял, сам Xamarin так устроен, но хотелось бы увидеть пример такого проекта, который и для ПК и для Телефона, чтобы понимать как это делается
По серийному порту ещё буду разбираться.
сегодня/завтра попробую С#+Arduino заодно наверно и с твоим WPF ом попробую
mqtt очень классная вещь по обмену сообщениями с помощью различных сетевых интерфейсов
ключевая фраза "сетевых интерфейсов", не нужно смешивать стационарную связь с ПК и удалённую - совсем разные условия и подходы, гдето одно не оправдано гдето другое
https://processing.org/
https://ru.wikipedia.org/wiki/Processing
это ты кому и к чему? в статье есть эти ссылки
Ардуина то тут причем?
при том что я с ней общаться хочу )) как предлагается через прогу C#
https://processing.org/tutorials/electronics/
Тогда я не понял, тема про Processing. При чем тут C#.
Я думаю, что у каждого есть wi-fi, lan, поэтому это не совсем удаленно получается)) Дабы не захламлять тему, лучше сделать отдельную ветку с тематикой С#
Я думаю, что у каждого есть wi-fi, lan, поэтому это не совсем удаленно получается)) Дабы не захламлять тему, лучше сделать отдельную ветку с тематикой С#
да ктоб взялся ))
Если есть специалист Отзовись! ))
https://processing.org/tutorials/electronics/
Тогда я не понял, тема про Processing. При чем тут C#.
а я не понял почему ты мне написал "Ардуина то тут причем?", я подумал что это относится к моей переписке про С#
https://processing.org/tutorials/electronics/
Тогда я не понял, тема про Processing. При чем тут C#.
а я не понял почему ты мне написал "Ардуина то тут причем?", я подумал что это относится к моей переписке про С#
Тогда при чем тут Processing?
Processing - java подобное для НЕ Ардуины. Ты же решил использовать Сишарп вместо Processing. Вот я и спрашиваю, нафига в теме про Processing спрашивать про Сишарп и про Ардуину? Так понятней?
https://processing.org/tutorials/electronics/
Тогда я не понял, тема про Processing. При чем тут C#.
а я не понял почему ты мне написал "Ардуина то тут причем?", я подумал что это относится к моей переписке про С#
я спрашивал у конкретного человека, который предложил C# использовать