Передача чисел из processing на arduino через COM

space.andy
Offline
Зарегистрирован: 04.05.2016

Срочно понадобилось прикрутить к программе на arduino простенький графический интерфейс. Выбрал Processing, но самостоятельно сходу разобраться не получилось, поэтому прошу помощи знающих людей.

Нужно, чтобы пользователь вводил числа в графическом интерфейсе Processing'а, Processing сохранял эти значения передавал на arduino через COM-порт. Путем изучения примеров с первым и вторым пунктом справился, остался третий, а именно передача чисем по ком-порту. Для теста написал скетч, слушающий ком-порт и зажигающий диод на 13-м пине, когда приходит 1, потом отсылал единицу через форму Processing'а. Ничего не получалось. Другого способа проверить, как общаются Processing с Arduino я не придумал - монитор порта у второго не открывается, когда первый запущен.

Поэтому прошу помощи с этим. Да, и, может есть более простой способ в Processing'е считывать с клавиатуры символы и сохранять в переменную. В меня в скетче читает символы getStringValue(), которая потом конвертируется в int. Жуть конечно, но не нашел, как по другому это реализовать. Есть еще флоатовая getValue(), но с ней почему-то не работает.

Вот скетч на Processing'а,

import processing.serial.*;
import controlP5.*;

ControlP5 cp5;
Serial myPort;

String textFreq, textDC;
int i_textFreq, i_textDC;

void setup() {
  size(400, 600);
  
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);

  cp5 = new ControlP5(this);

  cp5.addTextfield("frequency")
                   .setPosition(10, 20)
                   .setSize(100, 20)
                   .setFocus(true)
                   .setColor(color(255, 255, 255))
                   ;
  cp5.addTextfield("duty cycle")
                   .setPosition(10, 60)
                   .setSize(100, 20)
                   .setFocus(false)
                   ;     
}

void controlEvent(ControlEvent theEvent) 
{
    if(theEvent.getName() == "frequency") 
    {
      textFreq = theEvent.getStringValue();
      i_textFreq = int(textFreq);
    } else if(theEvent.getName() == "duty cycle") {
        textDC = theEvent.getStringValue();
        i_textDC = int(textDC);
      }  
}

void draw() {
  
  background(58, 143, 176);
  fill(255);
  text("Vibro", 1, 10);
  
  
  if(i_textFreq > 0) {
  myPort.write(i_textFreq);
      println(i_textFreq);} //чтобы контроллировать, что числа считываются
  if(i_textDC > 0) {
  myPort.write(i_textDC);
        println(i_textDC); }
}
Олег М.
Олег М. аватар
Offline
Зарегистрирован: 22.11.2015

space.andy пишет:

Срочно понадобилось прикрутить к программе на arduino простенький графический интерфейс. Выбрал Processing, но самостоятельно сходу разобраться не получилось, поэтому прошу помощи знающих людей.

Нужно, чтобы пользователь вводил числа в графическом интерфейсе Processing'а, Processing сохранял эти значения передавал на arduino через COM-порт. Путем изучения примеров с первым и вторым пунктом справился, остался третий, а именно передача чисем по ком-порту. Для теста написал скетч, слушающий ком-порт и зажигающий диод на 13-м пине, когда приходит 1, потом отсылал единицу через форму Processing'а. Ничего не получалось. Другого способа проверить, как общаются Processing с Arduino я не придумал - монитор порта у второго не открывается, когда первый запущен.

Поэтому прошу помощи с этим. Да, и, может есть более простой способ в Processing'е считывать с клавиатуры символы и сохранять в переменную. В меня в скетче читает символы getStringValue(), которая потом конвертируется в int. Жуть конечно, но не нашел, как по другому это реализовать. Есть еще флоатовая getValue(), но с ней почему-то не работает.

Вот скетч на Processing'а,

Не очень разобрался с твоим скетчем, но как я понял, библиотека processing.serial.* работает только с байтами.
Гемор еще тот.
Еще тщательно следи за скоростью портов Processing и Arduino.
Хотя в своих задачках я установил скорость 57600, все равно приходится давать delay(20-50), поскольку без этого данные куда-то пропадают.
Самому придумывать интерфейс страх как не хочется. Да и не умею я это. Пока.

Олег М.
Олег М. аватар
Offline
Зарегистрирован: 22.11.2015

Вот кусочек из Processing:
 

Serial myPort;                                              // Create object from Serial class
int val = 0;                                                // Data received from the serial port


/*****************   V O I D    D R A W   *********-*******/
void draw() {

  thread("readData");
  
  myStopWatch.display() ;
  myWatch.display() ;
  myPlotter.display(val) ;
  myMaximeter.display(val) ;
  myMeter.display(val) ;
}
.......................................

void readData() {                                           // Нить чтения данных
  if ( myPort.available() > 0) {                            // If data is available, 
    val = myPort.read() ;                                   // read it and store it in val    
  }
}

И ответная часть в Arduino:


int val = 0 ;                                             // значение, полученное из  АЦП
....................
void setup() {
  Serial.begin(57600);                                      // Запуск последовательного порта
  pinMode(LED_BUILTIN, OUTPUT);
  val = analogRead(FORCE) ;                          // начальное чтение
................

void loop() {
  val = analogRead(FORCE) ;   
  Serial.write( val / 4 );                                    // Отправка переменной в порт в формате BYTE
  delay(50);                                                 // Задержка 50 мс. Если меньше - перестает принимать

Надеюсь, поможет.

Nosferatu
Offline
Зарегистрирован: 04.11.2012

По-моему надо перед пересылкой преобразовывать переменную в byte.

myPort.write(byte(i_textFreq));

А после вывода данных обнулять переменные.

import processing.serial.*;
import controlP5.*;

ControlP5 cp5;
Serial myPort;

String textFreq, textDC;
int i_textFreq, i_textDC;

void setup() {
  size(400, 600);

  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);

  cp5 = new ControlP5(this);

  cp5.addTextfield("frequency")
    .setPosition(10, 20)
    .setSize(100, 20)
    .setFocus(true)
    .setColor(color(255, 255, 255))
    ;
  cp5.addTextfield("duty cycle")
    .setPosition(10, 60)
    .setSize(100, 20)
    .setFocus(false)
    ;
}

void controlEvent(ControlEvent theEvent) 
{
  if (theEvent.getName() == "frequency") 
  {
    textFreq = theEvent.getStringValue();
    i_textFreq = int(textFreq);
  } else if (theEvent.getName() == "duty cycle") {
    textDC = theEvent.getStringValue();
    i_textDC = int(textDC);
  }
}

void draw() {

  background(58, 143, 176);
  fill(255);
  text("Vibro", 1, 10);

  if (i_textFreq > 0) {
    myPort.write(byte(i_textFreq));
    println(i_textFreq);
    i_textFreq = 0;           //чтобы контроллировать, что числа считываются
  } 
  
  if (i_textDC > 0) {
    myPort.write(byte(i_textDC));
    println(i_textDC);
    i_textDC = 0;
  }
}

 

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

Nosferatu пишет:

По-моему надо перед пересылкой преобразовывать переменную в byte.

myPort.write(byte(i_textFreq));

А после вывода данных обнулять переменные.

import processing.serial.*;
import controlP5.*;

ControlP5 cp5;
Serial myPort;

String textFreq, textDC;
int i_textFreq, i_textDC;

void setup() {
  size(400, 600);

  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);

  cp5 = new ControlP5(this);

  cp5.addTextfield("frequency")
    .setPosition(10, 20)
    .setSize(100, 20)
    .setFocus(true)
    .setColor(color(255, 255, 255))
    ;
  cp5.addTextfield("duty cycle")
    .setPosition(10, 60)
    .setSize(100, 20)
    .setFocus(false)
    ;
}

void controlEvent(ControlEvent theEvent) 
{
  if (theEvent.getName() == "frequency") 
  {
    textFreq = theEvent.getStringValue();
    i_textFreq = int(textFreq);
  } else if (theEvent.getName() == "duty cycle") {
    textDC = theEvent.getStringValue();
    i_textDC = int(textDC);
  }
}

void draw() {

  background(58, 143, 176);
  fill(255);
  text("Vibro", 1, 10);

  if (i_textFreq > 0) {
    myPort.write(byte(i_textFreq));
    println(i_textFreq);
    i_textFreq = 0;           //чтобы контроллировать, что числа считываются
  } 
  
  if (i_textDC > 0) {
    myPort.write(byte(i_textDC));
    println(i_textDC);
    i_textDC = 0;
  }
}

 

 

скетч простой как 2х2

переведи все в числа, измени скорость порта, никаких delay там ненадо.

в byte конечно хорошо - но можно и не писать в порт а печатать 

print или println и т.п., ардуина сожрет и не подавится.