본문 바로가기

👩‍💻 도비는 공부중/💼 하계연구연수생(2023)

[Binary Protocol]

Binary protocol

 

bit stream = 데이터 구조를 중심으로 다르게 구성

숫자 2020은 단일 데이터 유형 (2 byte)로 표시 ( uint16 )

 

- more compact, saves bandwidth, more performant

- 네트워크에서 데이터 교환 시 바이트 순서 (endianness) 고려

- message carry only data, but without information what that data means. Semantic is implicit and stay in a program used to decode/encode. So it requires separate program to decode.

- binary protocols are typically proprietary, it's less likely to be an open standard like XML or JSON

- 이전 버전과의 호환성 유지 어려워

- data structure consists of fixed and variable length fields, and always specifies length of the variable segments. It's easy to detect END boundary between packets/messages.

 

=> UDP 프로토콜과 같이 패킷 크기에 제한, 메시지 크기가 제한적일때 사용: 성능/대영폭 소비가 중요한 경우 사용한다

 

더보기

Text protocol

 

bit stream = 일련의 문자 or text 문자열 (ex. 유니코드 or ASCII)

두 컴퓨터는 문자 메시지 교환, 숫자 2020은 5개의 문자로 표현된다(5 byte)

 

- JSON, XML 을 준수하는 플랫폼 및 런타임 간의 interoperability

- 더 큰 크기의 메시지 생성

- can be easily, inspected, read, debugged

- self-explanatory, data is associated with names, that tell what that data means. Message captures semantics.

- can be extended in a backward-compatible way

- can be parsed and decoded by any 3rd party software. Does not need some proprietary program to decode.

- when multiple messages are sent, it's hard to detect the boundary between individual messages. Usually some sort of text delimiters are used (=====, newlines, etc).

 

 


Project

 

ADS1299-DK protocol

SOP(4bytes) + SequenceNo.(4bytes) + EMGdata_Ch(4bytes) * 2 channel  : 16 bytes
_EMG_Packet_Data_type = np.dtype([
                    ('SequenceNo', 'u4'),           # 32-bit unsigned integer
                    ('EMGdata_Ch0', 'i4'),          # 32-bit signed integer
                    ('EMGdata_Ch1', 'i4')])         # 16-bit unsigned integer

 

checksum_verify

- 패킷을 받았을 때 checksum_index

- index에 해당하는 checksum 값

- cal_checksum = -sum(packet[: checksum_index]) & 0xff

 

checksum 값과 계산한 checksum 값이 일치한다면 True 

 

 

find_SOP

pSOP_code = [0xFF, 0xFF, 0xFF, 0xFF]
check_code = [0x00, 0x00, 0x00, 0x00]

serial_obj 받아 SOP_code와 check_code가 동일하지 않은 경우:

left shif 수행(np.roll)

 

read_data = serial_obj.read(1)

check_code[3] = read_data[0]

 

 

더보기

list_port_info

USB 디바이스 리스트와 정보들을 찾아 반환

try:
    from serial.tools.list_ports import comports
except ImportError:
    return None
if comports:
    com_ports = list(comports())
    port_info = []
    for port in com_ports:
        port_info.append(port[0]) # port name
        port_info.append(port[1]) # Identifier
        port_info.append(port[2]) # VID/PID
    if port_info:
       return port_info

 

 
 

serial_reading_Thread

 

global objSerial 에 대해 stop_thread_flag 가 아닌 경우

정의한 ADS1299 프로토콜 (16byte) 에 의해 .read(16)

unpack_data = struct.unpack("< I 2i", read_data[0:12])

( read_data[12:16] == b'\xff\xff\xff\xff'인 경우 SOP )

 

 

read_data를 가지고 원하는 데이터 처리 

 

-- 해당 프로젝트의 경우, 읽은 데이터를 녹화해 .bin 파일과 .csv 파일로 저장한다

-- 디지털 필터링을 위한 array 저장

 

==== thread: lock.acquire()

 

original_signal = np.roll( -1)

filtering_signal

vEMG

 

==== thread: lock.release()