정보나눔

오픈소스하드웨어 프로젝트에 대한 다양한 정보를 나누는 공간입니다.

프로세싱에서 아두이노로 여러가지 값을 보낼 때 어떻게 해야하나요??
로봇팔만들기 | 2019-01-11

1. 프로젝트 사용한 보드 종류

  (EX : 오렌지보드, 오렌지 BLE보드, 아두이노 UNO 등)

 아두이노 UNO

 

2. 사용한 개발 프로그램명

  (EX : 아두이노 IDE, 스크래치, mBlock 등)

 아두이노 IDE, 프로세싱

 

3. 사용한 센서 모델명

  (센서 모델명을 자세하게 적어 주실 경우 더 정확하게 확인할 수 있습니다.)

 

 

4. 연결한 회로 설명 (또는 이미지)

 

 

5. 소스코드 (주석 필수)

  (원하는 기능의 코드를 전부 작성해 드리긴 어렵습니다. 기초부터 차근차근 공부해보면서 코드를 만들어 보세요.)

 

프로세싱 코딩:

 

import de.voidplus.leapmotion.*; //Step1. We are realizing about showing Coordinates(x , y , z)

import processing.serial.*;

 

Serial Port;

LeapMotion leap;

 

 

int angleX;

int angleY;

int anlgeZ;

 

/*

int lx;

int ly;

int lz;

*/

void setup()

{

  size(1000, 500);

  

  leap = new LeapMotion(this);

  Port = new Serial(this, "COM8" , 9600);

}

 

void draw()

{

    

    background(255);

    

    

  for (Hand hand : leap.getHands()) 

  {

 

      {

        

    PVector handPosition = hand.getPosition();

   

   fill(100,0,0);

   textSize(30);

    text("x: ",70 , 100);

    text("y: ",70 , 150);

    

   //text("z: ",70 , 200);

    

    

    

    text(handPosition.x, 100, 100);

    text(handPosition.y, 100, 150);

    //text(lz, 100, 200);

 

//ellipse(handPosition.x, handPosition.y, 10, 10);

 

    if ( handPosition.x > 720)

    {

      angleX = 180;

    }

    else if( handPosition.x < 0)

    {

      angleX = 0;

    }

    else

    {

      angleX = int((handPosition.x)/4);

    }

    /*

    if (handPosition.y >720)

    {

      angleY= 180;

    }

    else if(handPosition.y <0)

    {

      angleY = 0;

    }

    else

    {

      angleY = int((handPosition.y)/4);

    }

    */  

    //lx = (int)map(hand.getPosition().x,0,700,0,180);

    //ly = (int)map(hand.getPosition().y,0,700,0,180);

    //lz = (int)map(hand.getPosition().z,0,700,0,180);

 

    

    print("x:");

    println(handPosition.x);

    println("y:");

    println(handPosition.y);

    //println("z:");

    //println(lz);

    Port.write('x');

    Port.write(angleX);

 

   // Port.write(angleY);

  }

  }

}

 

 아두이노 코딩:
 
#define robotSerial Serial
#include <Servo.h>
 
Servo myservo;
 
String robotString = "";
 
static float AngleX;
static float AnlgeY;
 
void serialRobot(); // 시리얼 통신 함수선언
 
void setup()
{
  robotSerial.begin(9600);
  myservo.attach(9);
}
 
void loop()
{
  serialRobot();
}
 
void serialRobot()
{
  if(robotSerial.available() <=0)
  {
  return;
  }
  char a = robotSerial.read();
 
  robotString += a;
 
  if(a == 'x')
  {
    if(robotString.length()>0)
    {
      int startCMD = 0;
      String serArray[10];
      int tmpcnt = 0;
      int idx;
 
      String tmpString = robotString;
 
      tmpString.trim();
 
      while(tmpString.length()>0)
      {
        idx = tmpString.indexOf(",");
        if(idx == -1)
        {
          serArray[tmpcnt] = tmpString;
          serArray[tmpcnt].trim();
          tmpcnt++;
          break;
        }
 
        serArray[tmpcnt] = tmpString.substring(0,idx);
        tmpString = tmpString.substring(idx+1);
        tmpString.trim();
        serArray[tmpcnt].trim();
 
        tmpcnt++;
      }
 
      if(serArray[0] == "x")
      {
        AngleX = serArray[1].toInt();
 
        myservo.write(AngleX);
      }
    }
    robotString = "";
  }
}

6. 문제점 및 에러 내용

  (소스코드 문제일 경우 에러 내용도 같이 올려주세요.)

 

이번에 립모션을 이용해서 모션에 따라 동작하는 로봇팔을 제작하려 합니다.

 

그래서 프로세싱을 이용하여 아두이노에 값을 전달하고 이 값을 토대로 서보모터가 동작하는 로봇팔을

 

만드는 중입니다.

 

여러가지 모터를 동작시킬 경우에는 통신 프로토콜을 이용하여 데이터 파싱을 통해 각각의 모터를 제어해야 하는 것으로 알고 있습니다.

 

그래서 우선 프로세싱으로 X라는 변수를 보내고 컴마, 를 보낸 후 angleX라는 변수로 각도값을 보내고 있습니다. 

 

그래서 아두이노로 문자 X뒤에 나오는 angleX라는 값을 읽어들여 그 값을 토대로 서보모터를 제어하려 하니 동작을 하지 않습니다.

 

혹시 제가 올린 코딩을 보고 조언을 해주시면 정말 감사드리겠습니다 ..ㅠㅠㅠㅠㅠ

프로필사진

kocoafab 2019-01-14 13:45:34

안녕하세요.

 

아두이노에서는 Serial 통신을 하게 되면 한번에 문자 1개(char값 1개)가 전달이 됩니다.

 

위 아두이노 코드를 보면 Serial명령어를 통해서 한번에 문자 1개를 받게 되는데 이 문자 1개 데이터를 이용해서 String 값을 분류하다보니 제대로 된 결과값이 나오지 않게 됩니다.

 

프로세싱에서 데이터 1줄 보낼때 끝에 구분자를 넣고 보낸 후, 아두이노에서 Serial 데이터를 받을 때 해당 구문자가 나올때 까지 계속 데이터를 받은 다음 구분자가 나오면 거기까지 받은 데이터를 기준으로 string함수들을 이용해서 문자를 구분하고 나누는게 좋을 것 같습니다.

 

ex:

 

String longData = "";

 

if(Serial.available() > 0){

  char data = Serial.read();

  longData += data;

  if(data == '%'){

    String(longData)값 분리

  }

}

 

위 예제는 임시로 작성한 코드이니 맞게 수정하여 넣어주시면 되겠습니다.

 

이상입니다.

프로필사진

로봇팔만들기 2019-01-16 00:13:54

말씀하신대로 구문자 ','를 사용하여 코딩을 해봤는데도

똑같이 동작이 되지 않습니다 ㅠㅠㅠ

코드를 새로 짜봤는데 혹시 봐주실 수 있으신가요?

 

프로세싱 코드:


import de.voidplus.leapmotion.*; //Step1. We are realizing about showing Coordinates(x , y , z)
import processing.serial.*;

Serial Port;
LeapMotion leap;


int angleX;
int angleY;
int angleZ;

/*
int lx;
int ly;
int lz;
*/
void setup()
{
  size(1000, 500);
  
  leap = new LeapMotion(this);
  Port = new Serial(this, "COM8" , 9600);
}

void draw()
{
    
    background(255);
    
    
  for (Hand hand : leap.getHands()) 
  {

      {
        
    PVector handPosition = hand.getPosition();
   
   fill(100,0,0);
   textSize(30);
    text("x: ",70 , 100);
    text("y: ",70 , 150);
    text("z: ",70 , 200);
    
    
    
    text(handPosition.x, 100, 100);
    text(handPosition.y, 100, 150);
    text(handPosition.z, 100, 200);
 
//ellipse(handPosition.x, handPosition.y, 10, 10);

    if ( handPosition.x > 720)
    {
      angleX = 180;
    }
    else if( handPosition.x < 0)
    {
      angleX = 0;
    }
    else
    {
      angleX = int((handPosition.x)/4);
    }
    
    if (handPosition.y >720)
    {
      angleY= 180;
    }
    else if(handPosition.y <0)
    {
      angleY = 0;
    }
    else
    {
      angleY = int((handPosition.y)/4);
    }
     /*
    if( handPosition.z > 130)
    {
      angleZ = 180;
    }
    else if(handPosition.z < -50)
    {
      angleZ = 0;
    }
    else
    {
      angleZ = int((handPosition.z)/1.5);
      }
      */
    //lx = (int)map(hand.getPosition().x,0,700,0,180);
    //ly = (int)map(hand.getPosition().y,0,700,0,180);
    //lz = (int)map(hand.getPosition().z,0,700,0,180);

    
    println("x:");
    println(handPosition.x);
    println("y:");
    println(handPosition.y);
    println("z:");
    println(handPosition.z);
    //println("z:");
    //println(lz);
    Port.write(angleX);
    Port.write(',');
    Port.write(angleY);
   // Port.write(angleZ);
  }
  }
}

 

아두이노 코드:

#define robotSerial Serial
#include <Servo.h>
 
Servo myservo1;
Servo myservo2;
Servo myservo3;
void setup()
{
  robotSerial.begin(9600);
  myservo1.attach(9);
  myservo2.attach(10);
  myservo3.attach(11);
}
 
void loop()
{
  int AngleX = getAngleX();
  myservo1.write(AngleX);
  int AngleY = getAngleY();
  myservo2.write(AngleY);
}

String getAngle()
{
  String outputValueOfAngle = "";

  while(robotSerial.available())
  {
   
  
    char incomingAngle = robotSerial.read();
    outputValueOfAngle += incomingAngle;
  
  }
  return outputValueOfAngle;
}

double getAngleX()
{
  String outputValueOfAngle = getAngle();

  int firstComma = outputValueOfAngle.indexOf(',');

  String AngleXST = outputValueOfAngle.substring(1, firstComma);
  double AngleX = AngleXST.toInt();

  return AngleX;
}

double getAngleY()
{
  String outputValueOfAngle = getAngle();

  int firstComma = outputValueOfAngle.indexOf(',');
  //int secondComma = outputValueOfAngle.indexOf('E', firstComma+1);

  String AngleYST = outputValueOfAngle.substring(firstComma+1, outputValueOfAngle.length() - 1);
  double AngleY = AngleYST.toInt();

  return AngleY;
}

 

아두이노 코드에서는 함수를 사용하여 각 축의 값을 받도록 새로 설정했습니다!

혹시 이상한 점이 있나 한번 봐주시면 정말 감사하겠습니다 ㅠㅠㅠ

이전글   |    talkie와 minim의 차이점 2019-01-06
다음글   |    아두이노 블루투스와 블루투스 이어폰 2019-01-14