본문 바로가기

Software/Python

Python을 통한 간편 시리얼 통신법

사실 Python에 대한 관심은 많았습니다. 뭐 그러나 역시나 어쩔수없이 항상...ㅠㅠ 필요하지 않으면 진도가 잘 안나가나 봅니다.^^. 그래서 Python 설치법에 대해서 간단히 익힌다음[바로가기] 또 고이 접어두고 있었지요. 그러다가 Python이 살짝 필요해서 또 다루었습니다. 언제나 그렇듯 별거 아닙니다. 그저 간단히 인터넷 서치만으로 다 할 수 있는건데요. 전 그냥 그걸 또 정리합니다.^^. 오늘은 Python으로 시리얼 통신을 하는 걸 알려드릴려구요^^.

먼저 Python에서 Serial 통신을 하기 위해서는 

pywin32 : Python for windows extensions

pySerial : Python Serial Port extenstion

이 두가지가 먼저 설치되어야 합니다. pywin32는 MS 윈도우에서 동작시키기 위한 여러 지원 라이브러리를 포함한다고 하는데요. 저는 윈도우에서 Python을 테스트 중이라 필요합니다. 그리고 pySerial은 Python에서 시리얼 통신을 위한 라이브러리들을 가지고 있으니 당연히 설치해야하구요.

먼저 위 sourceforge에서 pywin32를 다운받습니다. [바로가기] 그리고나서

자신에 맞는 아이로 다운받아 설치하시면 됩니다. 이때, 이미 설치된 python 버젼과 맞아야하고, 윈도우 레지스트리에서 정보를 받아 이미 설치된 python 경로를 찾습니다. 그러니 그냥 '다음'만 눌러주시면 됩니다.^^ 또, 다음으로

pySerial을 다운받으면 되는데요.[바로가기]

압축을 풀면 저렇게 나옵니다. setup 파일이 응용프로그램이 아니에요^^ py 파일입니다. 그래서 설치하실려면

명령 프롬프트에서 python 설치 경로로 이동하신 다음, 

C:경로> python setup.py install

라고 명령을 주면

이런 과정을 거쳐서 인스톨이 됩니다. 전 Python이 3.3버젼과 2.7버젼을 동시에 깔아서 위의 경로가 약간 이상하실 수도 있지만, 그건 캡쳐하다가 나타난 저의 오류이고 실제로는 2.7버젼을 기준으로 설명합니다.

이제, Python Shell 에서

import serial

이라고 명령을 줘서 에러가 없으면 일단 정상 설치라고 보시면 됩니다.

test = serial.Serial(5, 115200)

이라고 입력하시면 됩니다. 숫자 '5'는 Comport 6을 열겠다는 뜻입니다. Python에서는 포트번호가 0번부터 시작하기 때문에, 열려는 포트넘버보다 하나를 낮춰서 입력해야합니다. 그리고, 뒤의 115200은 baudrate입니다. 나머지는 기본적인 디폴트 설정이 들어갑니다. 만약 설정을 알고싶으시면 그냥 test 변수를 호출하면 됩니다.

test 변수를 불러보면, 위의 그림에 나타난 것 처럼 되죠. 그리고, 5라는 숫자가 COM6을 의미하는 것도 알 수 있지요. 이제 아~주 기본적인 명령을 통해 확인해보겠습니다. 먼저 간단히 뭐 소스랄것도 없는 소스코드를 보겠습니다.

import serial

test = serial.Serial(5, 115200)

test.writelines("<CAO>")

result = test.readline()

print result

test.close()

아주 간단하죠?^^ 위 코드에서 1번, 3번행은 위에서 이미 언급했구요. 지금 제가 대상으로 하는 것은 얼마전 MATLAB에서 시리얼통신하는 법[바로가기]을 이야기했 듯이, 제가 입사하고서 처음 작품활동을 했던 ARS라는 각도 측정 모듈[바로가기]을 시리얼 통신 예제로 삼을려고 합니다. 하드웨어적인 결선은 MATLAB으로 시리얼 통신하는 예제에서 이야기했으니 넘어가구요, 이 ARS라는 아이에게 시리얼통신으로 <CAO>라고 명령을 주면 각도가 출력이 됩니다. 그러니, 5번행에서처럼 <CAO>라고 통신으로 날려줘야겠네요. 그 명령이 writelines()입니다. 하나의 문자가 아니라 여러 문자로 이루어진 string의 경우 사용하는 명령입니다.

그리고나면 ARS에서는 각도값을 다시 돌려주는데요. 그걸 잘 받아야죠^^. 그게 7번행의 readline()입니다. 역시 날라오는 게 한문자라면 그냥 read()로 받으면 되는데, 문자열이 날라오기 때문에 readline()으로 편하게 받은겁니다. 만약 read()로 받는다면, 문장을 끝을 알리는 문자가 올때까지 반복문으로 계속 받으면 됩니다. 

위 그림에 나타난 결과가 바로 간편한 코드를 실행한거에요. <-15, 4, -3, 41> 이렇게 받았네요^^

그런데, 문제가 하나 있습니다. MATLAB으로 시리얼통신을 하는 예제[바로가기]를 보여드릴때도 이야기했지만, 어떤 이유에서 ARS는 라디안 단위의 각도이긴 하지만, 거기에 1000을 곱해서 보내거든요. 또 어차피 받은 아이가 문자이기도 하구요. read()함수로 한 문자씩 받는다면 약간 다르게 하겠지만, 어차피 readline()으로 홀라당 받았으니,  MATLAB으로 시리얼통신을 하는 예제[바로가기 ]에서 처럼 각도로 환산하기로 해 보겠습니다. 한가지 주의해 주셔야할 건, 여전히 전 Python 초보이니, 프로그램 소스가 python 스럽지 않습니다. 뭐 그건 좀 더 짬밥을 먹어야겠죠^^. 그래서 MATLAB의 이전 코드를 그냥 단순히 변환하는 정도가 되었습니다. 창피스럽습니다만..ㅠㅠ. 일단 코드부터 보시죵

import serial

test = serial.Serial(5, 115200)

test.writelines("<CAO>")

out = test.readline()

tmpCounter = 1
tmpResult = 0
tmp1 = 1

for tmp in out:
    if tmp == '-':
        tmp1 = -1
        
    if tmp == ',' or tmp == '>':
        result = tmpResult*tmp1
        
        if tmpCounter == 1:
            rollAngle = result
            
        elif tmpCounter == 2:
            pitchAngle = result
            
        else:
            break
        
        tmpCounter = tmpCounter + 1
        tmp1 = 1
        tmpResult = 0
        
    if '0' <= tmp <= '9':
        tmpResult = tmpResult*10 + int(tmp)

rollAngleDegree = rollAngle*0.001*180/3.141592
pitchAngleDegree = pitchAngle*0.001*180/3.141592

print('Roll Angle is ' + str(rollAngleDegree) + ' degree.')
print('Pitch Angle is ' + str(pitchAngleDegree) + ' degree.')

test.close()

7번행까지는 동일하구요. MATLAB때의 예제를 단순 컨버젼했으니, 부호를 판정하는 부분과, 두개의 각도 및 두개의 각속도 중에서 roll과 pitch각만 받도록 했습니다. 이렇게 하다보니, Python에는 뭔가 재미난 문법들이 있더군요. for나 if 문의 끝에서 콜론(:)을 사용하는 것과, 들여쓰기로 for, if문의 끝을 인식하는 것이 신기했구요. 또, 33번 행에 보이듯이, 2중 조건문의 형식이 자연적이어서 또 신기했습니다.^^.

그리고, for 문에서 13번 행처럼 주어진 배열(혹은 수열)에서 그 값 자체를 사용하는 것도 또 신기했지요^^ 아무튼 이래저래 Python에 적응도 할겸 시리얼 통신 예제를 올려봤습니다. 다음에는 좀 더 Python 스러운 문법으로 접근할 수 있지 않을까해요. 이건 그냥 Python에서 단지 돌려볼 수 있는 것일뿐이니까요. 그냥 시리얼 통신 예제라고 생각해주세용^^ 아 그리고, 제가 Python 첫 글의 내용중에 이클립스(Eclipse)와의 연동을 했지요.

이렇게 이클립스와 연동하면 아래의 콘술창에서 결과를 바로 볼 수 있지요. 왼쪽에 생성된 프로젝트가 HelloPy 밖에 없는것도 얼마나 Python 공부를 안한게 티가 나는지... ㅎㅎ 하여간 공부는 평생해야 하나 봅니다. 화이팅~~~^^

반응형