블로그 이미지
래머
오늘도 열심히 개발하는 개발자입니다.

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2015. 5. 3. 22:26 아두이노

간단하게 텍스트 형식으로 데이터 전달이 필요할때 심플하게 이용할 수 있는 파서이다.


#define MAX_DATA_BUFFER 100 //파서 임시 버퍼 사이즈, 자신의 환경에 맞게 적절히 길이를 조정

#define MAX_WORD_LENGTH 50  //한단어의 최대길이, 자신의 환경에 맞게 적절히 길이를 조정

#define SEPARATOR_MARK ';' //각 단어사이를 구분하는 구분자


/*

세미콜론 기호를 구분자로 전송된 데이터를 파싱하는 클래스


데이터 전송측에서 


data;1.5;3.5;ffffffffffffff;


등과 같이 각 데이터 사이를 세미콜론으로 구분하여 전송하는 경우, 수신된 순서되로 데이터를 분리해낼 수 있다.


위 데이터 전송예시의 경우


GetBlock()함수의 매 호출마다 얻어지는 결과는


data

1.5

3.5

ffffffffffffff

등과 같다.


*/


class CSimpleParser

{

char m_cArrLastWord[MAX_WORD_LENGTH];

char m_cArray[MAX_DATA_BUFFER]; //시리얼로부터 수신받은 데이터를 저장하는 버퍼

int m_iPos; //다음 저장할 위치


public:


CSimpleParser()

{

m_iPos = 0;

m_cArray[0] = 0;

}



//시리얼로부터 수신받은 데이터에서 수신이 완료된 한단어 블록을 가져옴

//수신받은 명령이 없으면 null을 리턴

char* GetBlock()

{


int tagpos = FindSeparator();


if (tagpos < 0)


return NULL;


if (tagpos != 0)

{

memcpy(m_cArrLastWord, m_cArray, tagpos);

m_cArrLastWord[tagpos] = 0;

}


if ((tagpos + 1) < m_iPos)

CopyData(0, tagpos + 1, m_iPos - tagpos - 1);


m_iPos -= tagpos + 1;  


if (tagpos != 0)

return m_cArrLastWord;


return NULL;

}


//수신된 정수 값을 얻음, 수신된 데이터가 없는경우나 올바르지 않은 포맷인경우에도 0을 리턴하므로 주의가 필요함

int GetInt()

{

char* pValue = GetBlock();


if (pValue != NULL)

return atoi(pValue);


return 0;

}


//수신된 실수 값을 얻음, 수신된 데이터가 없는경우나 올바르지 않은 포맷인경우에도 0을 리턴하므로 주의가 필요함

float GetFloat()

{

char* pValue = GetBlock();


if (pValue != NULL)

return (float)atof(pValue);


return 0.0f;

}


//시리얼로부터 데이터를 수신하여 버퍼에 쌓는다.

void ProcessSerial()

{

int receivedbytes = Serial.available();


if (receivedbytes > 0)

{


for (int i = 0;i < receivedbytes; ++i)

{

PushData(Serial.read());

}

}

}


protected:



//프로토콜에서 정의한 명령의 끝을 찾는다. 즉 버퍼에서 ;의 위치를 찾음

int FindSeparator()

{

for (int i =0;i < m_iPos; ++i)

{

if (m_cArray[i] == SEPARATOR_MARK)

return i;

}


return -1;

}


//한 바이트를 버퍼에 삽입

void PushData(int data)

{

if (m_iPos < MAX_DATA_BUFFER)

m_cArray[m_iPos++] = (unsigned char)data;

}



//srcindex위치에서 datasize바이트 만큼 destindex위치에 복사한다.

void CopyData(int destindex, int srcindex, int datasize)

{

for (int i = 0;i < datasize; ++i)

{

m_cArray[destindex + i] = m_cArray[srcindex + i];

}

}

};


CSimpleParser g_Parser;


void setup()

{

  Serial.begin(9600);

}



void loop()

{

//시리얼에서 데이터 수신을 처리한다.

  g_Parser.ProcessSerial();



  //주신완료된 단어가 있으면 가져와서 시리얼에 다시 전송한다.

  char* pWord = g_Parser.GetBlock();


  if (pWord == NULL)

    return;

   


    Serial.print("received word : ");


    Serial.println(pWord);


}



'아두이노' 카테고리의 다른 글

ET-DCM 모터드라이버  (0) 2015.05.06
아두이노 L298N 모터드라이버 제어하기  (0) 2015.05.05
아두이노 delay() 함수  (0) 2015.05.02
아두이노 millis() 함수  (0) 2015.05.02
SPI library  (0) 2015.02.23
posted by 래머