Пример № 1.2. Визуализация входящих данных. Обмен данными между Arduino & Processing.

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

 

«Вата»

 Урок рассчитан на пользователей, ознакомленных с языком программирования Processing, если его можно так назвать. Для тех же, кто еще не в курсе, что это такое, милости просим на http://processing.org/.  Будем так же надеяться что на http://arduino.ru появится раздел с переводом как для Arduino IDE.

 «Виртуальная нормальность»

Здравствуйте мои дорогие читатели. Продолжаю свою серию бредней о том, как же использовать Processing для наших проектов. Сегодня я приведу простой пример того, как можно реализовать двусторонний обмен данными между Arduino и Processing. Простой он, потому что мы не будем изобретать велосипед и воспользуемся уже написанным протоколом Firmata, с уже готовым скетчем для наших целей.  Конечно этот «метод» не самый красивый, но и недооценивать его не стоит.

 «Вкратце»

Простыми словами протокол Firmata, позволяет перенести программное пространство с железяки,  по имени Arduino, в программное пространство Processing. Таким образом, залив скетч в Arduino один раз, больше вы туда ни чего заливать не будете, и все программные решения будут производиться именно в Processing.

«О боже!! Зовите меня просто P»

Итак, приступим.

Для работы нам понадобится Arduino, резистор на 10 кОм и светодиод. Подключаем все это дело по следующей схеме:

 

Думаю с этим проблем возникнуть не должно.

Далее, подключаем Arduino к компу. Запускаем Arduino IDE. Заходим во вкладку File, там выбираем выпадающий список «Examples». Затем, в списке библиотек, находим библиотеку «Firmata». У вас выпадет список готовых скетчей-примеров. Нас интересует “StandardFirmata”.Запускаем его, и ни чего не меняя, грузим его в нашу Arduino.

Все. Про Arduino IDE можно забыть. Переходим к Processing. Для работы вам потребуется скачать библиотеку для Processing-а и распаковать её в папку libraries/arduino в каталоге для скетчей Processing (при необходимости, каталоги нужно создать); http://www.arduino.cc/playground/uploads/Interfacing/processing-arduino-0017.zip

Все скачали, все залили, проверили, что Arduino подключен к компу. И вот что я предлагаю сделать. Давайте реализуем по средствам Processing управление яркостью светодиода (ШИМ), а управление будем осуществлять перемещением мышки в области окна проекта. Для этого светодиод должен быть подключен к порту PWM на Arduino, в нашем случае это пин 3. Поехали:

import processing.serial.*;
import cc.arduino.*;
Arduino arduino;

int pin = 3;
void setup() {
  size(255, 200);
  println(Arduino.list());
  arduino = new Arduino(this, Arduino.list()[0], 57600);
  arduino.pinMode(pin, Arduino.OUTPUT);
}

void draw() {
  background(0);
  int value = mouseX;
  arduino.analogWrite(pin, value);
  text (value, 10, 10);
 }

 

Что здесь происходит. Я специально не стал делать комментарии в коде, дабы разобрать код в дальнейшем.

Итак, первые две строки как вы наверно догадались – импорт библиотек. Третьей строкой задаем имя нашему объекту Arduino (это я так понимаю, можете поправить, если я ошибаюсь). Затем в функции setup() происходит создание объекта Arduino, через вызов его конструктора: arduino = new Arduino(this, Arduino.list()[0], 57600);.

 Далее цитирую: «Первым аргументом в списке идет this - так уж принято. Далее указывается порт, к которому подключен Arduino. Для его получения существует функция Arduino.list() - статическая (можно использовать без привязки к экземпляру объекта), возвращающая список плат. Подключение будет выполнено к первой из этого списка (элемент с номером 0).  Последним идет скорость порта, для этой версии Firmata она фиксирована и составляет 57600.»

 В этих строках я ни чего не меняю, практически, никогда.

И вот теперь мы намешиваем команды Processinga и Arduino IDE в кучу. Если вам нужно зажечь светодиод, то вы пишите команду digitalWrite (pin, HIGH); c одним только НО – перед командой нужно указать название объекта – arduino.digitalWrite (pin, Arduino.HIGH); (прим. – работает и так arduino.digitalWrite (pin, HIGH);). В нашем же примере мы работаем с ШИМ, а значит, прописываем команду arduino.analogWrite(pin, value);. Да, да, так же как и в Arduino IDE, только, в начале, ставим arduino. Вы уже догадались, что команды считывания digitalRead(); и analogRead(); так же ни куда не делись. По сути, вам, они, только, и понадобятся.

 «Очень приятно, Царь!»

 Немного познакомились, теперь давайте усложним процесс и добавим в схему переменный резистор, который будет регулировать яркость светодиода (все тот же ШИМ). 

Многие проделывали такое с Arduino, заливая в него подобный код:


Int value=0; // назначаем переменную куда будем писать значения с аналогового входа
Int Apin=0; // определяем номер аналогового входа
Int Dpin=3; // определяем номер порта к которому подключен светодиод
void setup(){
pinMode(Dpin, OUTPUT); // установка порта на выход
}
void loop(){
value = analogRead(Apin); // записываем значения с аналогового входа
digitalWrite(Dpin, value/4); // зажигаем светодиод, analogRead возвращает значения от 0 до 1023, analogWrite должно быть в диапозоне от 0 до 255
}

 

Все мы, с вами, проходили через это, но сейчас мы все сделаем «по-другому». Почему в кавычках? Потому что, в принципе, мы сделаем то же самое, только на стороне Processing. Вдобавок все будет нагляднее. Поехали:

import processing.serial.*; // Подключаем библиотеку serial
import cc.arduino.*;  // Подключаем библиотеку arduino
Arduino arduino; // определяем имя объекта ардуино

int pin=3; // пин на котором весит светодиод
int val=0; // переменная куда будем записывать значение яркости от положения ручки резистора
int Apin; // пин резистора
void setup(){
size(255, 200); 
  println(Arduino.list());// размер окна
  arduino = new Arduino(this, Arduino.list()[0], 57600); // создаем объект Arduino
  arduino.pinMode(pin, Arduino.OUTPUT); // устанавливаем пин для светодиода как выход
 }

void draw (){
background(100); // цвет покадровой заливки фона
val=arduino.analogRead(Apin)/4; //считываем значения с аналогового входа и записываем в переменную val
arduino.analogWrite(pin, val); // отправляем записанные значения в ШИМ выход
fill(255); // цвет текста
text("Dimmer",10, 15); // надпись Dimmer
stroke(255);  // цвет линии
line (0, 20, 255, 20);  // линия для разлиновки
for (int i = 0; i < 255; i = i+10) { // создаем риски через промежуток 10 пикс.
  stroke(255); // цвет рисок
  line(i, 20, i, 23); // рисуем риски
}
fill(250); // цвет ползунка
noStroke();  // без абриса
rect(0, 25, val, 10); // рисуем прямоугольник (ползунок), изменяет свою длину в зависимости от полученных значений
fill(val); // заливка эллипса, цвет изменяется в зависимости от полученных значений
ellipse (125, 100, 55, 55); // рисуем эллипс с радиусами 55 пикс
}

 

Разъяснять тут, особо, нечего. Не вооруженным взглядом видно, что присутствует код из Arduino IDE, перекрещенный с Processing. Запустив код вы увидите такую картинку:

Теперь покрутите ручку переменного резистора, и вы увидите как изменяется цвет круга и перемещается прямоугольничек. Примерно так:

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

 «Зад – на перёд»

 Перед следующим примером, хочу отметить, что все, что я тут тараторю, не есть идеальный метод. Каждый из вас может найти для себя путь более изящный и более производительный, чем я. Я же, хочу поделиться с вами своими «чайниковскими» наработками.

Один из участников форума натолкнул меня на факт, что Processing позволяет работать со слоями, по средствам PGraphics объектов. И вы знаете … отличная штука. И я думаю, что в следующих примерах, мы потыкаем этот сочный помидор, дабы выжать из него все соки)))

До новых встреч, Друзья!!

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Вопрос, а как заставить приложение коннектится к порту ардуины?

println(Arduino.list());
    arduino = new Arduino(this, Arduino.list()[], 57600);

Как узнать сколько в массиве данных?

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

knack, я немного не понял вопрос.

при таком раскладе программа просмотрит все порты и зацепится к тому на котором висит ардуино. В случае если у вас несколько подобных устройств то подключение будет к первому из списка № 0. Если же нужно подключиться ко второму из двух то там просто нужно проставить номер например № 1, или же если нужно к первому то № 0 (так будет корректно).

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

Одна висела на com2 другая на com3. если запустить arduino = new Arduino(this, Arduino.list()[], 57600);то приконектится к первому com2 (но это не корректно), правильно канечно прописать new Arduino(this, Arduino.list()[0], 57600), и соответственно если нужно приконектиться к com3 то пишем Arduino(this, Arduino.list()[1], 57600).

Надеюсь понятно объяснил.

bababababa
Offline
Зарегистрирован: 28.10.2011

Удобный и правильный метод работы.

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

В чем может быть проблемма? Библиотеки он вроде распознает.

Пишу  new Arduino(this, "COM3", 57600) - таким образом исключаю ошибку с портом, не помагает.

Единственное, я запускаю из Processing 1.5 потому что новый с 64 виндой не хочет работать

 

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

Создайте тему на форуме в этой ветке, попробуем разобраться. У меня примерно подобная проблема была когда я старую библиотеку Firmata заливал, она вроде меньше но работает не оч корректно. 

ourlive
Offline
Зарегистрирован: 26.05.2012

неправду говорите, 2.0b отлично работает под 64х битной виндой (у меня win8-64), а вот при компилировании создаётся только application.windows32, соответственно скомпилированное отлично работает. А сообщение об ошибке говорит только о несоздании application.windows64 (в разработке).

А по поводу коннекта, есть реальная необходимость рулить портами именно с компа через специальную библиотеку? А напрямую через Serial данные идут? Самое простое, что может быть, это "порт занят другим приложением". Processing на занятость порта ошибку не выдаёт, в лист портов исправно добавляет все комы.

bababababa
Offline
Зарегистрирован: 28.10.2011
knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

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

Теперь представим компьютер на котором не стоит процессинг,  я хочу подключить к нему некое устройство на базе ардуины,  в массив считалось некое количество данных,  внимание вопрос,  как сделать меню с выбором портов? т.е. мы имеем массив с .непостоянным mass[x] нужно сделать меню с x позициями,  как узнать сколько в массиве данных???

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

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

Теперь представим компьютер на котором не стоит процессинг,  я хочу подключить к нему некое устройство на базе ардуины,  в массив считалось некое количество данных,  внимание вопрос,  как сделать меню с выбором портов? т.е. мы имеем массив с .непостоянным mass[x] нужно сделать меню с x позициями,  как узнать сколько в массиве данных???

Russk1j
Offline
Зарегистрирован: 03.05.2012

Добрый вечер. Не могу понять в чем причина ошибки. Делаю все по инструкции. Библиотеку в процессинг залил. Прошил МК стандартным примером.

При запуске программы в процессинге ругается на строчку:

И комментарий к ошибке:

  arduino = new Arduino(this, Arduino.list()[0], 57600);
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
[0] "COM6"
 
ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Russk1j пишет:

Добрый вечер. Не могу понять в чем причина ошибки. Делаю все по инструкции. Библиотеку в процессинг залил. Прошил МК стандартным примером.

При запуске программы в процессинге ругается на строчку:

И комментарий к ошибке:

  arduino = new Arduino(this, Arduino.list()[0], 57600);
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
[0] "COM6"
 

 

Была аналогичная ошибка...... но (дай Бог памяти) не могу вспомнить ка решил.... вспомню, напишу.

Russk1j
Offline
Зарегистрирован: 03.05.2012

ingener.solovyev пишет:

Russk1j пишет:

Добрый вечер. Не могу понять в чем причина ошибки. Делаю все по инструкции. Библиотеку в процессинг залил. Прошил МК стандартным примером.

При запуске программы в процессинге ругается на строчку:

И комментарий к ошибке:

  arduino = new Arduino(this, Arduino.list()[0], 57600);
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
[0] "COM6"
 

 

Была аналогичная ошибка...... но (дай Бог памяти) не могу вспомнить ка решил.... вспомню, напишу.

Да вот уже все перепробывал. Вот на форуме решение, сделал все так, но не помогло. Та же ошибка. Думаю найти 32битную винду и на ней попробовать. У меня 64.

http://forum.processing.org/topic/how-do-i-install-rxtx-2-2pre1-jar-on-windows-7
 

manaraga
Offline
Зарегистрирован: 11.09.2012

Russk1j пишет:

Добрый вечер. Не могу понять в чем причина ошибки. Делаю все по инструкции. Библиотеку в процессинг залил. Прошил МК стандартным примером.

При запуске программы в процессинге ругается на строчку:

И комментарий к ошибке:



  arduino = new Arduino(this, Arduino.list()[0], 57600);
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
[0] "COM6"
 

Такая же байда :( причем приложение с обещанными кавадратами не запускается. Другие (стандартные) примеры работают" на ура". Кто сталкивался - подскажите, как исправить???!!!!

manaraga
Offline
Зарегистрирован: 11.09.2012

Заработало. Была проблема в неправильно распложенной библиотеке. До этого я пытался разместить примеры дуиновских скетчей и библиотеки в соответствующие папки процессинга. А нужно было всего лишь деиствовать строго по инструкции. СОздать папку "libraries" в папке со скетчами, скопировать туда папку "arduino"  и выставить одинаковую скорость на ком-порту со стороны скетча, заливаемого в ардуино и скетча процессинга. Опробовано на разных скростях: 4800, 9600, 115200 - работают. Есть ньюанс: После запуска скетча в процессинге и появления синего окошка с квадратами необходимо резетнуть ардуину на плате(кнопка РЕСЕТ), иначе светодиод на нажатие первого слева квадрата не риагирует, хотя диод "Rx" сигналит о нажатии той самой кнопки. У меня ардуино - МЕГА 2560. 

Russk1j
Offline
Зарегистрирован: 03.05.2012

manaraga пишет:

Заработало. Была проблема в неправильно распложенной библиотеке. До этого я пытался разместить примеры дуиновских скетчей и библиотеки в соответствующие папки процессинга. А нужно было всего лишь деиствовать строго по инструкции. СОздать папку "libraries" в папке со скетчами, скопировать туда папку "arduino"  и выставить одинаковую скорость на ком-порту со стороны скетча, заливаемого в ардуино и скетча процессинга. Опробовано на разных скростях: 4800, 9600, 115200 - работают. Есть ньюанс: После запуска скетча в процессинге и появления синего окошка с квадратами необходимо резетнуть ардуину на плате(кнопка РЕСЕТ), иначе светодиод на нажатие первого слева квадрата не риагирует, хотя диод "Rx" сигналит о нажатии той самой кнопки. У меня ардуино - МЕГА 2560. 

Да, аналогично делал. Спасибо!

Но теперь немного другая ошибка. 

Фото: http://rghost.ru/50100772
Я так понимаю выставлять скорость нужно в стандартном примере Arduino IDE Firmata:

  Firmata.begin(57600);

И прямо в программе Processing:

  arduino = new Arduino(this, Arduino.list()[0], 57600);

Или еще нужно в настройках где-то?

Скорость разную ставил в Processing в программе. Но одна и та же ошибка.

Все сделал по инструкции. Правда пока сам диод к дуине не подключал. Как запустится и откроется окно, так все и подключить.

У тебя Windows 7 x64? 

Я уже думаю, может папки с программами лежать где-то конкретно должны? У меня на рабочем столе и processing и Arduino IDE. Версия последняя с сайта processing-2.1-windows64. А Arduino IDE старенькая относительно arduino-1.0.1-windows. Но не думаю что из-за этого.

manaraga
Offline
Зарегистрирован: 11.09.2012

У меня win7/ 32 бит. Возможно проблема в этом, хотя, ошибка такая вроде тоже мелькала, но это когда с библиотекой игрался - складывал файлы в разные папки процессинга. Где-то читал что процессинг работает с первыми 4 сом- портами. попробуй COM 6 переправь на один из первых. Кстати скорость там тоже желательно установить такую же как в фирмата и процессинге. Диод на плате уже подключен к 13 ноге, и его включает первый слева квадрат в тестовом скетче, так что отдельно ничего подключать не нужно. 

У меня все лежит в папке в корне на диске где установена винда седьмая (диск D), есть еще ХР на С. Ардуино версии 1.0.4, процессинг 2.0.3. и папка  библиотекой для ардуино MEGA 2560 R3 (плата не оригинал, китай). Пока других идей решения проблемы не вижу. Удачи.

Russk1j
Offline
Зарегистрирован: 03.05.2012

Благодарю за информацию!
Попробовал поменять пока COM порт на первый. Аналогичная ошибка. Попробую на 32 винде. 

Al
Offline
Зарегистрирован: 29.11.2013

Долго экспериментировал с разными ОС (7, XP, Ubuntu). Потом пробовал разные версии процессинга. В итоге заработало на Win 7 c processing-1.5.1-windows. Ура. Хочу добавить, что для того чтобы правильно указать расположение библиотеки в процессинге, нужно воспользоваться меню File->Preferences.

Dgg-01
Offline
Зарегистрирован: 28.08.2018

Доброго времени суток.
Подскажите кто знает при работе ардуинки и processing изложенным тут способом. Кто что вычисляет? И как выбирать крайнего(ардуино или процессинг) которы будет вычислять кусок кода?