logo
+7 (495) 997-37-74
Москва, ул.Международная, 15

Processing и Ардуино. Работа по Serial

Этой статьёй мы продолжаем цикл материалов о языке программирования Processing и сегодня мы рассмотрим как связь (родство) самих систем программирования Processing и Arduino, так и связь между программами и приложениями, работающими в этих системах. В частности, мы рассмотрим управление работой программ по последовательному интерфейсу (Serial).

Processing и Arduino

Processing и Arduino являются родственными системами с похожей идеологией и реализацией. Можно сказать, что Ардуино «выросла» из Процессинга. Ардуино использует похожий (хотя и несколько урезанный по сравнению с Processing) синтаксис, только ориентированный на работу с микроконтроллерами. Официально язык программирования Ардуино называется Wiring.

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

Связь между Processing и Arduino

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

Вообще, связать микроконтроллер под управлением Wiring и компьютерную программу под управлением Processing можно множеством способов, среди них:

  • по Serial
  • при помощи специализированного протокола Firmata
  • по Ethernet сети
  • различными беспроводными способами
  • и т. д.

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

Управление «Processing to Arduino»

Сначала мы рассмотрим вариант управления Ардуино-контроллером из скетча на Processing. Этот вариант может понадобиться вам для управления (по последовательному интерфейсу) контроллером с вашего компьютера.

Поскольку взаимодействие происходит между двумя системами, то мы приведём здесь два скетча, которые должны будут работать одновременно — один на контроллере, другой — на компьютере. В качестве Ардуино контроллера мы будем использовать Arduino Nano.

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

Первый скетч для Ардуино контроллера:

/*
  Serial Processing to Arduino
*/

#define LED_PIN 13

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  if (Serial.available() > 0) {
    int i = Serial.read();
    if      (i == 'H') {digitalWrite(LED_PIN, HIGH);}
    else if (i == 'L') {digitalWrite(LED_PIN, LOW);}
  }
}

Здесь мы определяем пин к которому присоединён светодиод (на плате Arduino Nano).

#define LED_PIN 13

Затем запускаем работу Serial интерфейса на скорости 115200.

  Serial.begin(115200);

И переключаем пин светодиода на «выход».

  pinMode(LED_PIN, OUTPUT);

Далее следует цикл loop().

void loop() {
  if (Serial.available() > 0) {
    int i = Serial.read();
    if      (i == 'H') {digitalWrite(LED_PIN, HIGH);}
    else if (i == 'L') {digitalWrite(LED_PIN, LOW);}
  }
}

В котором мы «ловим» приходящие данные по Serial интерфейсу (от нашего компьютера и скетча на Processing) и присваиваем их переменной i.

  if (Serial.available() > 0) {
    int i = Serial.read();

А далее просто включаем или выключаем светодиод в зависимости от приходящих байтов (символов).

    if      (i == 'H') {digitalWrite(LED_PIN, HIGH);}
    else if (i == 'L') {digitalWrite(LED_PIN, LOW);}

Теперь рассмотрим «ответный» скетч на Processing:

/*
  Serial Processing to Arduino
*/

import processing.serial.*;
 
int boxX;
int boxY;
int boxSize = 20;

Serial port;
 
void setup()  {
  port = new Serial(this, "COM41", 115200);
  
  size(200, 200);
  
  boxX = width  / 2;
  boxY = height / 2;
  rectMode(RADIUS);
}
 
void draw() {
  background(0);
 
  if (mouseX > boxX - boxSize && mouseX < boxX + boxSize &&
      mouseY > boxY - boxSize && mouseY < boxY + boxSize) {
    fill(220, 0, 0);
    port.write('H');      
  } else {
    fill(127);
    port.write('L');      
  }
 
  rect(boxX, boxY, boxSize, boxSize);
}

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

import processing.serial.*;

Затем определяем параметры графического элемента.

int boxX;
int boxY;
int boxSize = 20;

Определяем объект.

Serial port;

И затем создаём его. Обратите внимание: вместо "COM41" вы должны указать номер COM порта, к которому у вас подключён микроконтроллер Arduino.

  port = new Serial(this, "COM41", 115200);

Далее задаём размер графического окна на котором будем выводить графику, в данном случае это окно размером 200 на 200 пикселей.

  size(200, 200);

Определяем центр графического окна.

  boxX = width  / 2;
  boxY = height / 2;

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

  rectMode(RADIUS);

Затем в циклической функции draw() рисуем серый или красный квадрат в зависимости от положения указателя мыши и посылаем соответствующие управляющие символы в Serial порт (на контроллер Ардуино).

void draw() {
  background(0);
 
  if (mouseX > boxX - boxSize && mouseX < boxX + boxSize &&
      mouseY > boxY - boxSize && mouseY < boxY + boxSize) {
    fill(220, 0, 0);
    port.write('H');      
  } else {
    fill(127);
    port.write('L');      
  }
 
  rect(boxX, boxY, boxSize, boxSize);
}

Подробнее: очищаем графическое окно.

  background(0);

Определяем положение указателя мыши (над квадратом или нет).

  if (mouseX > boxX - boxSize && mouseX < boxX + boxSize &&
      mouseY > boxY - boxSize && mouseY < boxY + boxSize) {

Определяем цвет и посылаем управляющие символы.

    fill(220, 0, 0);
    port.write('H');      
  } else {
    fill(127);
    port.write('L');      
  }

Рисуем квадрат.

  rect(boxX, boxY, boxSize, boxSize);

В результате когда указатель мыши находится не над квадратом, квадрат выводится серым цветом, на контроллер отправляется символ «L» и на контроллере не горит светодиод.

Как только курсор мыши появляется над квадратом, квадрат становится красным, на контроллер посылается символ «H» и на нём загорается встроенный светодиод.

Таким образом при помощи движения мыши мы можем управлять включением и выключением светодиода на контроллере Ардуино. Понятно, что это только пример управления контроллером с компьютера при помощи скетча на Processing — по этому принципу вы можете создать любые другие варианты управления контроллеров в соответствии с вашими задачами и содержанием вашего проекта.

Управление «Arduino to Processing»

Теперь рассмотрим противоположный вариант — управление (или передачу данных) компьютером (скетчем на Processing) с Ардуино контроллера. Это тоже очень востребованный паттерн работы системы, которому можно найти множество практических применений.

Итак, скетч для Ардуино контроллера, реализующий свою часть работы системы:

/*
  Serial Arduino to Processing
*/

#define ANALOG_PIN A0

void setup() {
  Serial.begin(115200);
}

void loop() {
  int i = analogRead(ANALOG_PIN);
  i = map(i, 0, 1023, 0, 255);
  Serial.println(i);
  delay(1000);
  
  Serial.println(0);
  delay(1000);
}

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

#define ANALOG_PIN A0

В цикле получаем данные и преобразуем их.

  int i = analogRead(ANALOG_PIN);
  i = map(i, 0, 1023, 0, 255);

Отправляем их на компьютер и делаем задержку в 1 секунду.

  Serial.println(i);
  delay(1000);

Далее посылаем нулевое значение и снова делаем задержку.

  Serial.println(0);
  delay(1000);

В общем, наш скетч делает одну простую вещь — раз в секунду посылает либо данные с аналогового порта A0, либо нулевое значение в Serial.

Теперь «ответный» скетч на Processing:

/*
  Serial Arduino to Processing
*/

import processing.serial.*;

Serial port;

float bright = 0;

void setup() {
  size(300, 300);
  port = new Serial(this, "COM41", 115200);
  port.bufferUntil('\n');
}

void draw(){
  background(bright);
}

void serialEvent(Serial port) {
 bright = float(port.readStringUntil('\n'));
}

Здесь: создаём переменную для хранения значения яркости и присваиваем ей нулевое значение:

float bright = 0;

Проводим стандартные операции, описанные выше.

  size(300, 300);
  port = new Serial(this, "COM41", 115200);

Очищаем буфер последовательного порта.

  port.bufferUntil('\n');

И далее в цикле устанавливаем яркость фона графического окна.

void draw(){
  background(bright);
}

Всю работу по получению данных от микроконтроллера Ардуино выполняет функция serialEvent(), которая автоматически вызывается всякий раз, когда появляются новые данные в порту.

void serialEvent(Serial port) {
 bright = float(port.readStringUntil('\n'));
}

Таким образом, наш контроллер на Ардуино передаёт управляющие байты (взятые им из аналогового порта), а скетч на Processing использует эти значения для установки яркости фона графического окна (серый):

А затем предаёт нулевой байт и скетч на Processing соответствующим образом меняет цвет фона графического окна (чёрный):

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

Заключение

В этой статье мы рассмотрели варианты управления «Processing to Arduino» и «Arduino to Processing» и используя их или их сочетание вы сможете добавить новый и очень интересный функционал в ваши проекты.

Ссылки по теме

Система программирования Processing

Processing и Ардуино. Работа по Serial

Сетевые возможности Processing

Работа Processing в браузере и на сайте