[Arduino] - 피버시노가 연결된 포트 자동 탐색기능 추가 (피버시노 v.1.1.3)

USB 포트가 바뀌어도 프로그램이 피버시노를 자동으로 찾을 수 있도록 해보자.

Bluno Link와 Bluno Beetle은 아두이노 IDE 보드 정보에서 시리얼 넘버가 출력되지 않는다.
그래도 무언가 나오지 않을까 해서 파이썬으로 시리얼 넘버를 읽어보았다.
  • 다음은 현재 컴퓨터에 연결된 모든 COM 포트 리스트를 출력해준다.
import serial.tools.list_ports  # For listing available serial ports
dev = serial.tools.list_ports.comports()
ports=[]
for d in dev:
    ports.append((d.device, d.serial_number))
print('\nDetected serial ports:')
for d in ports:
    print("Port:" + str(d[0]) + "\tSerial Number:" + str(d[1]))
cs

포트 넘버와 시리얼 넘버가 중요하기 때문에 이 둘 만 출력하도록 했다.
결과는 다음과 같다. 

여기서 내가 찾아 할 디바이스는 COM27에 있다.
결과과 딸랑 '6'만 나왔다. 과연 이게 시리얼 넘버인가?
"장치 관리자"에서도 시리얼 넘버를 알 수 있는지 확인해보았다.

지난번에도 말했지만 디바이스의 시리얼 넘버는
장치관리자 > 포트(COM & LPT) > 장치속성 > 이벤트 탭 에서 볼 수 있다.

COM4 로 연결된 이 디바이스의 정체는 아두이노 우노다.


USB\VID_2341&PID_0043\757353037313519091C0
여기서 VID & PID 다음에 오는 "757353037313519091C0"가 이 디바이스의 시리얼 넘버다.

Bluno Link가 연결된 COM27 은 다음과 같이 나온다.


USB\VID_2341&PID_0043\6&21d02812&0&3
'6'이 있다. 그럼 뒤에 &로 연결된 애들은 뭐지?
  • findTo(serial_number)는 입력된 시리얼 넘버와 일치하는 디바이스를 찾아준다.
import serial.tools.list_ports
def findTo(serial_number):
    for arduino in serial.tools.list_ports.comports():
        if arduino.serial_number == serial_number:
            return (arduino.device)
    raise IOError("There was no such thing.")
        
sn = findTo('6')
print("The device you are looking for " + str(sn))
cs

'6'만으로도 디바이스를 찾을 수 있었다.
당연하면서도 조금 이상하지만 저 '6'이 시리얼 넘버같다. 

그런데 이 대로 사용하게 되면 문제가 발생한다.

보통 아두이노 우노처럼 대부분의 USB 디바이스들은 고유의 시리얼 넘버를 가지고 있다. 덕분에 USB 포트를 바꾸거나 컴퓨터를 바꿔도 시리얼 넘버가 바뀌지 않고, 컴퓨터도 알아서 같은 포트 넘버를 제공해준다.


하지만 Bluno Link는 USB 포트를 바꾸거나 컴퓨터를 바꾸면 6&21d02812&0&3, 6&21d02812&0&2, 5&10394ca8&0&1, 5&356b5377&0&4 이런식으로 바뀌고 위사진처럼 USB 포트 자리가 바뀌면 계속해서 새로운 디바이스로 인식한다.

왜 이런일이 발생하는 걸까?

msdn의 한 포스트에 따르면 시리얼 넘버는 USB 디바이스에서 선택사항이라고 한다.
따라서 이 상황은 시리얼 넘버가 없거나 부족하면 발생하는 문제로 보인다.
실제로 시리얼 넘버가 충분한 다른 USB 디바이스들은 포트 넘버가 바뀌지 않았다.

일단은 다른 컴퓨터에 연결해도 '5'아니면 '6'으로 연결되기 때문에
시리얼 넘버, PID, VID 3가지가 모두 일치하는 디바이스를 조건으로 달았다.

import serial.tools.list_ports
def findTo(vid, pid, serial_number):
    for arduino in serial.tools.list_ports.comports():
        if arduino.vid == vid and arduino.pid == pid and arduino.serial_number == serial_number:
            return (arduino.device)
    #raise IOError("There was no such thing.")
        
if findTo(9025,67,'6'):
    sn = findTo(9025,67,'6')
    print("The device you are looking for " + str(sn))
else:
    sn = findTo(9025,67,'5')
    print("The device you are looking for " + str(sn))
cs

확실하진 않지만 아두이노는 보드 종류마다 PID, VID가 다른 것으로 보고, 설치되는 드라이버도 다른것 같다. (가지고 있는 보드 종류가 4가지인데 모두 다르다.)
아두이노 우노는 VID_2341 & PID_0043를 사용하고, 상당히 긴 시리얼 넘버를 가지고 있다.
반면 Bluno Link와 Bluno Beetle은 VID와 PID는 우노와 같지만 시리얼 넘버가 없다.
  • 피버시노 수정된 부분
serialDic={'5':'5','6':'6'}
def waitForSerialInit():
    #print("\n=Currently available Arduino Uno devices=")
    while True:
        for arduino in serial.tools.list_ports.comports():
            if arduino.vid == 9025 and arduino.pid == 67# Arduino Uno vid & pid
                sn = arduino.serial_number
                
                #print("*S/N : [" + sn + "]" )
                if sn in serialDic:
                    print("\nConnected to serial number [" + sn + "]" )
                    arduDev = arduino.device
                else:
                    arduDev = "anywhere"
        com_Port = [str(arduDev)]
        for device_Port in com_Port:
            try:
                serialFromArduino = initSerial(device_Port)
                print("device found on " + device_Port)
                return serialFromArduino
            except Exception:
                print("Failed to device on " + device_Port)
        time.sleep(5)
cs

수정된 부분을 간단하게 설명하자면 
"야 waitForSerialInit() 아두이노 우노 보드 중에 시리얼 넘버가 '5'나 '6'인 애 대리고 와바, 그리고 찾을때 까지 못 쉰다." 라고 할 수 있다.
디바이스가 제거되면 다시 찾기 시작한다.
주석 처리 된 부분을 활성화하면 현재 연결된 아두이노 우노들의 시리얼 넘버를 모두 보여준다.


  • 업데이트 버전
=====================================================





PivotIno 소스코드 (제 깃허브로 연결됩니다. :7)

Comments

Popular posts from this blog

[POE] - 패스 오브 엑자일 획득키 F 의 사용법 (Path of Exile)

[Arduino] - HC-06를 이용해 PC 와 Arduino 블루투스 연결

[XBOX] - 엑스박스원s 패드 and 블루투스 자동연결 for PC

[Raspberry Pi] - rc카 만들기 #2 Servo Motor