본문 바로가기

ESP32 Project

RockBLOCK 9603 이리듐 모뎀 위성 통신

반응형

RockBLOCK 9603은 이리듐(Iridium) 위성 네트워크를 사용하여 전 세계 어디서나(극지방 포함) 소량의 데이터(Short Burst Data, SBD)를 송수신할 수 있는 소형, 경량 위성 통신 모뎀입니다. WiFi나 셀룰러 신호가 없는 오지, 해상, 항공 등에서 시리얼(UART) 인터페이스를 통해 원격 모니터링, 추적, 제어 용도로 주로 사용됩니다. 

핵심 특징 및 설명
  • 글로벌 커버리지: 이리듐 위성망을 이용해 지구상 전 지역에서 동작.
  • 소형 SBD 모뎀: Iridium 9603N 트랜시버를 내장하여 작고 가벼우며, 기존 MK2 제품보다 작은 폼팩터를 제공.
  • 사용자 친화적 인터페이스: UART(시리얼) 인터페이스와 AT 명령어 세트를 지원하여 임베디드 보드(아두이노, 라즈베리 파이, PX4 오토파일럿 등)와 쉽게 연동.
  • 패치 안테나 내장: 안테나가 모듈에 통합되어 있어 구조가 단순하지만, 필요 시 SMA 커넥터를 통해 외부 안테나 연결 가능.
  • SIM-less 운영: 별도의 SIM 카드 없이 이리듐 네트워크에 접속.
  • 데이터 제한: 대용량 데이터 전송보다는 짧은 텍스트나 센서 데이터(약 50바이트당 1 크레딧) 송수신에 특화.
활용분야
  • 원격 기상 관측소 데이터 전송
  • 해양 부이(Buoy) 및 위치 추적
  • 오지 장비 모니터링 및 원격 제어
작동 방식 및 비용
  • 전송된 데이터는 RockBLOCK에서 제공하는 웹 서비스를 통해 이메일이나 API로 수신.
  • 사용을 위해서는 RockBLOCK 웹사이트에서 기기를 활성화해야 하며, 월간 회선 유지비와 데이터 송수신량에 따른 크레딧 비용이 발생.

 

자 이제 실제로 구현하는 방법을 설명합니다. 길지만 차근차근 하세요. 수 백 마리가 들어 있는 새 도감도 시작은 한 마리씩입니다. 

 

기본 통신 점검

 

RockBLOCK 모뎀은 시리얼 연결을 통해 전송되는 문자 메시지로 제어됩니다. RockBLOCK 모뎀을 가장 쉽게 시작하는 방법은 제공된 USB 시리얼 케이블을 사용하여 호스트 PC의 USB 포트에 연결하는 것입니다. 처음에는 이러한 방식으로 기본 설정이 제대로 작동하는지 테스트하는 것이 좋습니다. 나중에는 RockBLOCK 모델을 마이크로컨트롤러에 연결한 예제를 보여드리겠습니다.

 

 

이 케이블에는 FTDI FT232R 칩이 포함되어 있습니다. 드라이버를 설치해야 할 수도 있으며, 드라이버는 여기에서 다운로드할 수 있습니다.

 

RockBLOCK 9603은 실내에서 이리듐 위성과 통신할 수 없습니다. 따라서 위성 데이터 전송을 시도하려면 안테나가 하늘을 볼 수 있도록 해야 합니다. 저희는 열린 창턱에 안테나를 올려놓았더니 잘 작동했습니다. 노트북이 있다면 더 쉽게 할 수 있을 것입니다.

 

PC에 COM 포트가 표시되면 터미널 프로그램을 사용하여 연결하십시오. 시리얼 통신 매개변수는 다음과 같습니다.

  • Baud Rate = 19200
  • 데이터 비트 = 8
  • 패리티 = N
  • 정지 비트 = 1

여기 예시들은 리눅스 머신의 터미널에서 사용 방법을 보여줍니다.

 

AT 명령어

 

RockBLOCK 9603은 여기에 설명된 AT 명령어 세트를 사용합니다.

 

AT 커맨드 세트 참고자료입니다. 

 

9603 AT 명령어 세트.pdf
0.74MB

 

 

모든 명령어는 AT 로 시작하고 그 뒤에 특정 명령어가 오며, 마지막에는 캐리지 리턴( \r )으로 끝납니다. 명령어는 많지만 실제로 중요한 명령어는 몇 개 되지 않습니다. 중요한 명령어 몇 가지를 간략하게 정리해 보았습니다.

 

+SBDIX - 단거리 데이터 전송 세션을 시작합니다. 즉, 위성과 통신합니다. 메시지 데이터를 먼저 로드했는지 확인하십시오.

+SBDWT - 텍스트 메시지를 송신 버퍼에 기록합니다.

+SBDWB - 바이너리 데이터를 출력 버퍼에 기록

+SBDRT - 수신 버퍼에서 텍스트 메시지 읽기

+SBDRB - 입력 버퍼에서 바이너리 데이터를 읽어옵니다.

+SBDSX - 상태

 

예를 들어, 상태를 확인하려면 다음과 같이 보내면 됩니다.

 

AT+SBDSX\r

 

 

터미널 프로그램을 사용하는 경우, 일반적으로 엔터 키를 누르면 '\r' 문자 가 전송되므로 직접 입력할 필요는 없습니다. 하지만 시리얼 통신을 통해 직접 통신하는 사용자 정의 소프트웨어를 작성하는 경우에는 데이터 문자열에 ' \r'을 추가해야 합니다.

 

기본 정보

 

위성 데이터 전송을 시도하기 전에 기본 사항부터 확인해 보겠습니다. +CGMI 및 +CGMM 명령어를 사용하여 모델 정보를 얻습니다. 이 정보는 RockBLOCK 9603 모뎀에서 직접 제공되므로 위성 접속이 필요하지 않습니다.

 

 

screen사용 중인 터미널 프로그램을 실행하세요 . 전송 속도를 19200으로 설정하세요. screen이 값은 명령줄 매개변수입니다.

 

 

그다음 AT를 입력 하고 Enter 키를 누르세요. 실제로 \r을 입력할 필요는 없습니다.

 

"OK" 응답이 나오면 제대로 대화하고 있는 겁니다. 그다음 AT+CGMI 와 AT+CGMM을 입력해 보세요 . 그러면 아래 표시된 정보와 같은 내용이 나올 겁니다.

 

Hello World

 

좋아요, 재밌는 아르바이트네요. 메시지를 보내볼까요? 아직 RockBLOCK에 연결되어 있지 않다면 이전 섹션을 참조하세요. 또한 회선 임대료와 크레딧을 구매하여 서비스를 활성화해야 합니다.

 

이번 초기 테스트에서는 텍스트를 사용하겠습니다. 나중에는 바이너리 데이터를 사용할 예정인데, 이는 일반적으로 모든 통신이 이루어져야 하는 방식입니다. 텍스트는 단지 편의 기능일 뿐입니다.

 

 

연결이 완료되면 AT+SBDWT=Hello World를 입력 하고 Enter 키를 누르세요.

 

"OK"라는 응답을 받으실 겁니다 .

 



 

메시지를 보내려면 AT+SBDIX를 입력 하고 Enter 키를 누르십시오.

 

위성과 통신을 시도하고 일정 시간이 지난 후 +SBDIX: 32, 8, 2, 0, 0, 0 과 같은 상태를 반환합니다 .

 

첫 번째 숫자가 0이 아니면 메시지가 전송되지 않은 것이므로 다시 시도해야 합니다.

 

 

상태 반환 값의 첫 번째 숫자가 0이 될 때까지 AT+SBDIX 명령을 계속 입력하십시오 .

 

하늘이 얼마나 잘 보이는지, 위성이 어디에 있는지 등에 따라 여러 번 시도해야 할 수도 있습니다. 시도할 때마다 10초 정도 기다리세요. 위성 신호를 너무 자주 보내지 마세요.

 

 

계정에 로그인하여 메시지 탭에 접속하면, 메시지 내용에 "Hello World"가 포함된 수신 메시지를 확인할 수 있습니다.

 

 

 

주의: 실패한 시도에 대해서는 크레딧이 소모되지 않으므로 재시도 횟수에 대해 걱정하지 마세요. 실제로 크레딧이 차감되는 것은 마지막 한 번의 성공 시도뿐입니다.

 

주의: SBDIX 전송이 성공적으로 완료될 때마다 메시지 버퍼가 비어 있더라도 1크레딧이 소모됩니다.

 

저 상태 번호들은 무엇을 의미하나요?

 

AT+SBDIX 호출에서 반환되는 상태 값(6자리 숫자) 은 다음과 같습니다.

 

MO status, MOMSN, MT status, MTMSN, MT length, MT queued

 

  • MO 상태 = 송신 전송 상태
  • MOMSN = 발신 순번
  • MT 상태 = 수신 전송 상태
  • MTMSN = 수신 순번
  • MT 길이 = 수신된 바이트 수
  • MT 대기열 = 전달을 기다리는 메시지

 

첫 번째인 MO 상태는 전송 성공 여부를 판단하는 데 가장 중요합니다. 가능한 값과 그 의미에 대한 전체 목록은 AT 명령 참조 에서 확인할 수 있습니다 . 간단히 설명하면 다음과 같습니다.

 

  • 0 - 4 = 전송 성공
  • 32 = 네트워크 서비스 없음

 

그리고 참고로 말씀드리자면:

 

  • MO = 모바일 (Mobile )은 RockBLOCK에서 유래했습니다.
  • MT = 모바일 종단 , 즉 RockBLOCK 에 연결됨

 

메시지 송수신

 

 

 

 

모든 트래픽은 Ground Control 서버를 거쳐 전송됩니다 . 모뎀 에서 전송되는 메시지를 모바일 발신(MO) 메시지라고 하고, 모뎀 으로 전송되는 메시지를 모바일 수신(MT) 메시지라고 합니다 .

 

  • Mobile Originated(MO) - 모뎀에서 전송된 메시지
  • Mobile Terminated(MT) - 모뎀으로 전송되는 메시지

 

RockBLOCK 모뎀으로/부터 외부로 메시지를 송수신하는 옵션은 RockBLOCK 웹 서비스 사용자 가이드에 설명되어 있습니다.

 

하지만 선택지는 매우 제한적입니다.

 

RockBLOCK에서 MO 메시지를 수신하는 방법은 다음과 같습니다.

  • 애플리케이션에 HTTP POST 요청을 보내세요.
  • 이메일 전송

 

RockBLOCK 모뎀으로 MT 메시지를 전송하는 옵션은 다음과 같습니다.

  • RockBLOCK API로 HTTP POST 요청을 보냅니다.
  • Rock 7 CORE 웹 인터페이스

 

이 가이드는 MO 및 MT 메시지 모두에 대해 HTTP POST 메서드를 사용하는 예제를 제공합니다.

 

CircuitPython 예제

 

 

실제 응용 프로그램에서는 RockBLOCK을 제어하기 위해 마이크로컨트롤러를 사용하게 될 가능성이 높습니다. 저희는 CircuitPython 보드를 사용하여 이를 구현할 수 있도록 CircuitPython 라이브러리를 개발했습니다 .

 

이 예제에서는 Feather nRF52840 Sense를 사용하여 내장 센서에서 데이터를 전송합니다. RockBLOCK을 Feather에 연결하려면 액세서리 케이블 도 필요합니다 .

 

이는 모뎀에서 모바일 발신(MO) 메시지를 전송하는 예시입니다.

 

연결

 

다음은 배선도입니다. 액세서리 케이블을 사용하신다면 색상을 맞춰 연결하시면 됩니다. 하지만 RockBLOCK 본체의 실제 핀 위치를 확인하는 것이 가장 좋습니다.

 

 

* 이 예시에서는 Feather의 마이크로 USB 커넥터를 통해 모든 것에 전원을 공급합니다(배터리 없음).

 

CircuitPython 라이브러리

 

다음 CircuitPython 라이브러리가 설치되어 있어야 합니다. 모든 라이브러리가 CIRCUITPY/lib 폴더에 있는지 확인하십시오.

 

  • adafruit_apds9960
  • adafruit_bus_device
  • adafruit_register
  • adafruit_bmp280
  • adafruit_lis3mdl
  • adafruit_lsm6ds
  • adafruit_rockblock
  • adafruit_sht31d

 

 

Code

 

사용된 코드는 라이브러리의 예제로 포함되어 있습니다. 코드는 다음과 같습니다.

 

프로젝트 번들 다운로드

 

 

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import struct
import time

import adafruit_apds9960.apds9960
import adafruit_bmp280
import adafruit_lis3mdl
import adafruit_lsm6ds
import adafruit_sht31d
import board

import adafruit_rockblock

# RockBlock setup
uart = board.UART()
uart.baudrate = 19200
rb = adafruit_rockblock.RockBlock(uart)

i2c = board.I2C()  # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller

# all the sensors
accelo = adafruit_lsm6ds.LSM6DS33(i2c)
magno = adafruit_lis3mdl.LIS3MDL(i2c)
prox = adafruit_apds9960.apds9960.APDS9960(i2c)
sht = adafruit_sht31d.SHT31D(i2c)
bmp = adafruit_bmp280.Adafruit_BMP280_I2C(i2c)

# build data
# can decode on other end with struct.unpack("<6fB5f", data)
data = struct.pack("3f", *accelo.acceleration)
data += struct.pack("3f", *magno.magnetic)
data += struct.pack("B", prox.proximity())
data += struct.pack("2f", sht.relative_humidity, sht.temperature)
data += struct.pack("3f", bmp.pressure, bmp.altitude, bmp.temperature)

# send data
rb.data_out = data
print("Talking to satellite...")
retry = 0
status = rb.satellite_transfer()
while status[0] > 8:
    time.sleep(10)
    status = rb.satellite_transfer()
    print(retry, status)
    retry += 1
print("\nDONE.")

 

GitHub에서 보기

 

해당 코드를 code.py 라는 이름으로 CIRCUITPY 폴더 에 저장하세요 . 소프트 재부팅이 필요한 경우 REPL에서 -를 누르면 됩니다. 그러면 메시지 전송 시도 상태가 실행되고 표시됩니다.

 

 

출력 결과에는 시도 횟수와 상태(괄호 안의 숫자)가 표시됩니다. 앞서 수행한 간단한 테스트와 마찬가지로 첫 번째 숫자가 0이어야 성공합니다. 따라서 0이 될 때까지 계속 시도합니다.

 

 

성공적으로 완료되면 프로그램이 종료되고 작업이 끝납니다.

 

Rock Seven 서버의 계정에 로그인하여 메시지를 확인하면 다음과 같은 내용이 표시될 것입니다.

 

 

그렇다면 저 숫자와 문자들은 무엇을 의미할까요? 다음 섹션에서 간단히 설명드리겠습니다. 더 자세한 내용은 나중에 다루겠습니다.

 

데이터 압축 해제

 

파이썬의 struct 모듈 에 익숙한 사람이라면 다음과 같이 예제 데이터를 디코딩할 수 있습니다.

 

struct.unpack("<6fB5f", data)

 

여기서 data는 메시지에 포함된 원시 데이터의 바이트 또는 바이트 배열 입니다. 이를 생성하는 쉬운 방법은 bytes.fromhex()를 사용 하고 메시지에서 16진수 텍스트를 복사하여 붙여넣는 것입니다.

 

위 메시지를 예로 들면 다음과 같습니다.

 

>>> import struct
>>> data = bytes.fromhex("88984cbe90267bbe50b21d41f43754c2081dac3fb40c82c2009cd2bf4110aed74188277a44b4a2d342cc86d741")
>>> struct.unpack("<6fB5f", data)
(-0.19980061054229736, -0.24526429176330566, 9.856033325195312, -53.05464172363281, 1.3446359634399414, -65.02481079101562, 0, 23.97783660888672, 26.959991455078125, 1000.61767578125, 105.81777954101562, 26.940818786621094)

 

그리고 여기 데이터가 있습니다. 처음 세 개는 LSM6DS33에서 얻은 x/y/z 가속도이고, 다음 세 개는 LIS3MDL에서 얻은 x/y/z 자기장, 그 다음은 APDS9960에서 얻은 근접 거리, 그 다음은 SHT31D에서 얻은 습도와 온도, 그리고 마지막으로 BMP280에서 얻은 기압, 고도 및 온도입니다.

 

센서가 엄청 많네. 데이터가 엄청나다. 와!

 

라즈베리 파이 예시

 

RockBLOCK과 통신하기 위한 시리얼 포트가 있는 Raspberry Pi 또는 유사한 싱글보드 컴퓨터(SBC)도 사용할 수 있습니다. CircuitPython 라이브러리를 사용하려면 Blinka를 지원하는 SBC를 사용해야 합니다.

 

어떤 라즈베리 파이든 사용 가능합니다. 하지만 외딴 지역에는 와이파이가 없을 가능성이 높고 전력도 제한적일 수 있으므로 라즈베리 파이 제로가 좋은 선택입니다.

 

연결

 

다음은 배선도입니다. 액세서리 케이블을 사용하신다면 색상을 맞춰 연결하시면 됩니다. 하지만 RockBLOCK 본체의 실제 핀 위치를 확인하는 것이 가장 좋습니다.

 

 

* TX는 TX에, RX는 RX에 연결해야 합니다. RockBLOCK은 TX/RX 핀에 대해 역순 명칭을 사용합니다.

 

시리얼 활성화

 

라즈베리 파이의 GPIO 헤더에서 시리얼 통신을 활성화하려면 다음 단계를 따르세요. 일반적인 과정은 시리얼 하드웨어를 활성화하고, 시리얼 통신을 사용하는 기본 로그인 셸을 제거하는 것입니다.

 

이 모든 작업은 raspi-config를 통해 수행할 수 있습니다.

 

sudo raspi-config

 

 

인터페이스 옵션 5개를 선택하세요

 

 

P6 시리얼을 선택하세요

 

 

"직렬 연결을 통해 로그인 셸에 접근할 수 있도록 허용하시겠습니까?"라는 질문에 " 아니요 "라고 답하십시오 .

 

 

"직렬 포트 하드웨어를 활성화하시겠습니까?"라는 질문에 "예" 라고 답하십시오 .

 

 

확인을 선택하세요

종료 후 재부팅

 

CircuitPython 라이브러리를 설치하세요

 

Raspberry Pi에서 Python과 함께 CircuitPython 라이브러리를 사용할 수 있도록 Blinka를 설치하는 방법에 대한 정보는 여기를 참조하십시오.

 

그리고 Blinka 테스트를 통과했는지 확인하세요 .

 

다음으로, 다음 명령어를 사용하여 RockBLOCK 라이브러리를 설치하십시오.

 

pip3 install adafruit-circuitpython-rockblock

 

Simpletest 체크 실행

 

RockBLOCK에 제대로 연결되어 통신하는지 확인하기 위한 간단한 테스트로 라이브러리에서 제공하는 가장 간단한 예제를 사용해 보세요. 코드는 다음과 같습니다.

 

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

# CircuitPython / Blinka
import board

uart = board.UART()
uart.baudrate = 19200

# via USB cable
# import serial
# uart = serial.Serial("/dev/ttyUSB0", 19200)

from adafruit_rockblock import RockBlock

rb = RockBlock(uart)

print(rb.model)

 

 

먼저 몇 가지 변화를 주어야 합니다.

 

다음 줄들을 주석 처리하세요:

 

uart = board.UART()
uart.baudrate = 19200

 

그래서 이런 모습입니다:

 

# uart = board.UART()
# uart.baudrate = 19200

 

그리고 다음 새 줄들을 추가하세요:

 

import serial
uart = serial.Serial("/dev/serial0", 19200)

 

이제 UART가 라즈베리 파이의 GPIO 헤더를 통해 통신하고 있습니다.

 

예제를 실행해 보세요:

 

 

그러면 위 그림과 같이 모델 정보가 인쇄되어 있는 것을 확인할 수 있습니다.

 

추가 예시

 

다른 예제를 실행하기 위해 필요한 유일한 변경 사항은 UART 설정을 수정하는 것입니다. 이 작업을 완료하고 해당 UART를 CircuitPython RockBLOCK 라이브러리에 전달하면 나머지는 문제없이 작동할 것입니다.

 

라이브러리 저장소에 있는 다른 예제들도 확인해 보세요.

 

메시지 전달

 

네, 이제 RockBLOCK을 사용하여 지구 어디에 서든 메시지를 보내는 방법을 알아봤습니다 . 하지만 그 메시지를 최종 목적지까지 어떻게 전달할까요? 즉, Rock Server 서버에서 특정 최종 애플리케이션으로 메시지를 어떻게 포워딩할까요? 다음과 같이 하면 됩니다.

 

 

Rock Seven은 여기서 매우 기본적인 기능만 제공합니다. 메시지가 서버에 수신되면 사용자가 지정한 위치로 전달할 수 있습니다. 옵션은 두 가지뿐입니다.

 

이메일 - 입력하신 이메일 주소로 이메일이 발송됩니다.

HTTP - 제공된 URL로 HTTP POST 요청이 전송됩니다.

 

Rock Seven은 이와 관련한 문서를 여기에 게시했습니다.

 

HTTP API에 대한 문서는 여기에 있습니다.

 

배송 그룹

 

웹 기반 관리 시스템을 사용하여 메시지 전달을 구성합니다. 로그인 후 왼쪽 탐색 메뉴에서 '배달 그룹'을 클릭하십시오.

 

이 개념은 상당히 간단합니다. 각 배달 그룹은 하나 이상의 RockBLOCK 장치와 연결됩니다. 그런 다음 각 그룹에 대해 배달 주소 에 하나 이상의 배달 목적지를 지정할 수 있습니다. 이는 간단한 전달 방식입니다. 배달 그룹 에 속한 RockBLOCK 장치에서 수신된 모든 메시지는 배달 주소 에 지정된 목적지로 전달됩니다 .

 

다음은 모바일에서 발신된 메시지를 전달하기 위한 HTTP POST 예시입니다.

 

Adafruit IO

 

RockBLOCK 메시지를 Adafruit IO로 전송하는 방법이 있지만 몇 가지 제약 사항이 있습니다. Rock Seven은 발신 HTTP POST 메시지에 특별한 형식을 허용하지 않으므로 AIO API와 직접 연동할 수 없습니다. 하지만 AIO의 웹훅 기능을 사용하여 HTTP POST 데이터의 엔드포인트 대상을 제공할 수 있습니다.

 

먼저 이 가이드를 따라 AIO 피드용 웹훅을 생성하세요.

 

Adafruit IO에서 웹훅 URL을 생성할 때 웹훅 이벤트의 전체 내용을 전송하는 기능을 활성화하십시오 . 웹훅 생성 대화 상자에서 해당 옵션을 클릭하여 활성화할 수 있습니다.

 

 

그러면 해당 피드의 웹훅 URL을 얻게 됩니다.

 

URL 끝에 /raw가 포함되어 있는지 확인하세요.

 

이제 Rock Seven 계정에 로그인하고 배송 그룹으로 이동하세요. RockBLOCK에 새 배송 주소를 추가하세요.

 

  1. 주소 필드 에 AIO 피드의 웹훅 URL을 추가하세요 .
  2. 형식 드롭다운 메뉴에서 HTTP_JSON을 선택하세요 .

 

 

이제 RockBLOCK에서 메시지를 전송하면 JSON 데이터 형식으로 피드에 전달됩니다. 다음과 같은 형식으로 표시됩니다.

 

 

그다지 유용하지는 않습니다. 그냥 가공되지 않은 JSON 텍스트 덩어리만 얻을 수 있습니다. 추가적인 처리가 필요합니다. 하지만 실제 데이터는 이름 그대로 ' 데이터' 필드에 있습니다.

 

다음은 JSON 데이터를 가져와 CPython(데스크톱, 라즈베리 파이 등)에서 실제 값으로 처리한 다음, 해당 값을 관심 있는 AIO 피드로 다시 보내는 방법을 보여주는 예입니다. 사용된 데이터는 이 가이드의 CircuitPython 예제를 기반으로 합니다.

 

 

import struct
from Adafruit_IO import Client
from secrets import secrets

aio = Client(secrets['aio_username'], secrets['aio_key'])

# get the raw data
raw_feed = aio.feeds('test-feed')
raw_data = aio.receive(raw_feed.key).value

# the JSON blob is truncated, so just parse manually
print("Getting raw data...")
data = bytes.fromhex(raw_data.split(',')[2].split(':')[1].strip('"'))
values = struct.unpack("<6fB5f", data)
print(values)

# send parsed data back to specific feeds
print("Sending to AIO...")
aio.append(aio.feeds('rock-block.rb-humidity').key, values[7])
aio.append(aio.feeds('rock-block.rb-temperature1').key, values[8])
aio.append(aio.feeds('rock-block.rb-pressure').key, values[9])
aio.append(aio.feeds('rock-block.rb-temperature2').key, values[11])
print("DONE.")

 

 

모뎀으로 메시지 전송

 

다음 예제는 HTTP POST 옵션을 사용하여 RockBLOCK 모뎀으로 MT(Mobile Terminated) 메시지를 전송하는 방법을 보여줍니다. 자세한 내용은 RockBLOCK 웹 서비스 사용자 가이드를 참조하십시오 . 또한 CircuitPython 라이브러리를 사용하여 모뎀에서 해당 메시지를 수신하는 방법도 보여줍니다.

 

이는 모뎀으로 모바일 종료(MT) 메시지를 전송하는 예시입니다.

 

HTTP POST 요청을 생성하는 방법은 여러 가지가 있습니다.

  • 명령줄에서 curl을 사용하세요
  • 파이썬에서 requests 모듈을 사용하세요
  • Ruby, PHP, JavaScript 등에서도 유사한 옵션을 제공합니다.
  • 웹 브라우저에 URL을 입력하세요

 

기본 HTTP POST URL은 다음과 같습니다.

 

https://rockblock.rock7.com/rockblock/MT?imei=IMEI&username=USERNAME&password=PASSWORD&data=DATA

 

필수 매개변수 4 가지는 다음과 같습니다 .

  • IMEI = RockBLOCK 모뎀의 고유 IMEI입니다.
  • 사용자 이름 = Rock 7 Core 사용자 이름
  • 비밀번호 = Rock 7 Core 비밀번호
  • DATA = 메시지(16진수로 인코딩됨)

 

계정 사용자 이름과 비밀번호 정보는 URL에 반드시 포함되어야 합니다. 이러한 정보가 노출되지 않도록 주의하십시오.

 

IMEI 번호 찾기

 

RockBLOCK 모뎀의 IMEI 번호를 확인하려면 먼저 계정에 로그인하세요. 로그인 후 왼쪽 메뉴에서 '내 RockBLOCK' 탭을 선택합니다. 목록에 있는 각 RockBLOCK의 IMEI 번호가 표시됩니다.

 

 

16진수로 인코딩된 데이터

 

모뎀으로 전송되는 데이터는 각 바이트가 16진수 값으로 표현되는 원시 바이트 형식이어야 합니다. 예를 들어 "hello world"를 전송하려면 다음과 같은 형식은 작동하지 않습니다 .

 

data="hello world"

 

대신 텍스트를 변환해야 합니다. 파이썬에서는 binascii 모듈 의 hexlify() 명령어를 사용할 수 있습니다. hexlify()에 전달하기 전에 텍스트 문자열을 바이트로 변환해야 합니다. 이는 encode() 함수를 사용하거나, 바이트 원본을 나타내는 접두사 'b'를 사용하여 수행할 수 있습니다.

 

>>> import binascii
>>> DATA = binascii.hexlify(b'hello world')
>>> type(DATA)
<class 'bytes'>
>>> DATA
b'68656c6c6f20776f726c64'
>>>

 

 

따라서 URL의 최종 데이터 매개변수는 다음과 같습니다.

 

data=68656c6c6f20776f726c64

 

최종 URL 예시

 

기밀 정보를 공개하지 않고는 완전한 URL 예시를 보여드릴 수 없습니다. 하지만 RockBLOCK 모뎀으로 "hello world"를 전송하는 대표적인 URL은 다음과 같습니다.

 

https://rockblock.rock7.com/rockblock/MT?imei=123456789&username=foo&password=bar&data=68656c6c6f20776f726c64

 

 

RockBLOCK 온라인 API 참조 페이지에는 URL 생성에 도움이 되는 페이지가 있습니다. 또한 다양한 프로그래밍 언어에 대한 코드 스니펫도 제공합니다.

 

메시지 확인 중

 

HTTP POST 요청이 성공적으로 완료되면 메시지가 전송됩니다. 해당 메시지는 RockBLOCK 관리자 페이지의 메시지 탭에서 확인할 수 있습니다.

 

 

이 메시지를 보내는 데 1 크레딧이 소모되었습니다.

 

HTTP POST를 사용하여 RockBLOCK 모뎀에 메시지를 보내면 크레딧이 소모됩니다!

 

모뎀을 이용한 메시지 수신

 

메시지가 전송되면 RockBLOCK 모뎀을 통해 수신할 수 있습니다. CircuitPython 라이브러리의 텍스트 수신 예제를 사용할 수 있습니다.

 

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import time

# CircuitPython / Blinka
import board

uart = board.UART()
uart.baudrate = 19200

# via USB cable
# import serial
# uart = serial.Serial("/dev/ttyUSB0", 19200)

from adafruit_rockblock import RockBlock

rb = RockBlock(uart)

# try a satellite Short Burst Data transfer
print("Talking to satellite...")
status = rb.satellite_transfer()
# loop as needed
retry = 0
while status[0] > 8:
    time.sleep(10)
    status = rb.satellite_transfer()
    print(retry, status)
    retry += 1
print("\nDONE.")

# get the text
print(rb.text_in)

 

 

다음은 USB-시리얼 케이블을 통해 RockBLOCK 모뎀이 연결된 PC에서 위 예제를 실행했을 때의 출력 예시입니다.

 

$python3 rockblock_recv_text.py 
Talking to satellite...
0 (32, 14, 2, 0, 0, 0)
1 (32, 14, 2, 0, 0, 0)
2 (32, 14, 2, 0, 0, 0)
... deleted output ...
80 (32, 14, 2, 0, 0, 0)
81 (32, 14, 2, 0, 0, 0)
82 (0, 14, 1, 2, 11, 0)

DONE.
hello world

 

 

위성 연결에 성공하기까지 필요한 시도 횟수는 위치와 관측 가능한 하늘 영역에 따라 달라집니다. 위 테스트에서는 모뎀을 창가에 설치했는데, 창밖에는 나무가 여러 그루 있었습니다. 하늘이 잘 보이지는 않았지만, 결국 82번의 시도 끝에 연결에 성공했습니다.

 

데이터 전송에 대한 추가 정보

 

요약

 

RockBLOCK은 원시 데이터 바이트를 송수신합니다. 송신 및 수신 측 애플리케이션에서 해당 데이터를 원하는 방식으로 인코딩 및 디코딩하는 것은 사용자의 몫입니다.

 

전송당 최대 바이트 수 = 340

 

텍스트 vs. 바이너리

 

RockBLOCK은 기본적으로 1과 0만 주고받습니다. 그것들이 무엇인지, 무엇을 의미하는지는 전혀 신경 쓰지 않습니다. RockBLOCK은 이 1과 0을 8개씩 묶어서 전송하는데, 이것이 바로 1바이트입니다. 한 번의 위성 전송으로 최대 340바이트 까지 보낼 수 있습니다 .

 

Hello World 예제를 실행했을 때 간단한 텍스트 스타일 항목을 사용할 수 있었습니다.

 

AT+SBDWT=Hello World

 

일반적으로 각 문자에 대해 알려진 단일 바이트 표현이 있으므로 문제가 없습니다. 하지만 값을 보내고 싶다면 어떻게 해야 할까요? 예를 들어 센서에서 읽은 온도 값인 23.6245198을 보내고 싶다면 어떻게 해야 할까요?

 

AT+SBDWT=온도는 23.6245198 입니다 .

 

그렇게 할 수도 있고, 실제로도 가능하겠지만 몇 가지 문제가 있습니다.

 

우선, "온도는"이라는 문자를 보내는 것은 불필요합니다. 대부분의 경우 사용자는 자신이 다루는 데이터의 형식을 알고 있을 테니까요. 그렇다면 이것은 어떨까요?

 

AT+SBDWT=23.6245198

 

텍스트로 값을 전송하는 것도 가능하지만, 전송에 사용되는 바이트 수가 많아 비용이 많이 듭니다. 각 문자가 1바이트를 차지하므로 총 10바이트가 필요 합니다. 값을 실제 바이트 형태로 표현하는 것이 훨씬 효율적입니다. 값에 사용할 수 있는 바이트 표현 크기는 다양하지만, 예를 들어 일반적인 부동 소수점 값은 4바이트 (단정밀도 기준)에 저장할 수 있습니다. 따라서 동일한 온도 값을 텍스트로 전송할 때보다 절반 이하의 바이트로 전송할 수 있습니다.

 

좋습니다. 그런데 실제로 어떻게 하는 걸까요? 사용하는 프로그래밍 언어에 따라 다릅니다. 파이썬을 예로 들어 좀 더 자세히 살펴보겠습니다.

 

바이트를 전송할 때는 AT+SBDWT 명령 대신 AT+SBDWB 명령을 사용합니다.

 

파이썬에서 데이터 패킹하기

 

값을 원시 데이터 바이트로 변환하는 과정을 일반적으로 패킹(packing) 이라고 합니다 . 반대로 원시 데이터 바이트를 다시 값으로 변환하는 과정을 언 패킹(unpacking) 이라고 합니다 . 파이썬의 ` struct` 모듈은 이러한 작업에 필요한 기능을 제공합니다.

 

간단한 예를 들어 보겠습니다. 우리의 목표는 RockBLOCK 모뎀을 사용하여 이리듐 위성을 통해 지구상의 다른 곳으로 23.6245198이라는 값을 전송하는 것입니다. 바이트 단위로 크레딧이 소모되므로 최대한 효율적으로 전송해야 합니다.

 

먼저, 다음을 만들어 봅시다 value:

 

$ python3
Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> value = 23.6245198

 

 

만약 우리가 그것을 text로써 다음과 같이 보내고 싶다면:

 

>>> text = "{}".format(value).encode()
>>> text
b'23.6245198'
>>> len(text)
10

 

 

텍스트는 일반적으로 읽을 수 있습니다. 또한 10바이트를 차지한다는 점에 유의하십시오 .

 

자, 이제 struct를 사용하여 원시 바이트 데이터를 표현해 봅시다:

 

>>> import struct
>>> data = struct.pack("f", value)
>>> data
b'\x04\xff\xbcA'
>>> len(data)
4

 

 

서식 지정 문자 "f"의 의미는 여기를 참조하십시오.

 

내용이 더 이상 사람이 읽을 수 있는 형식이 아닙니다. 하지만 단 4바이트 만 필요합니다 .

 

그 가치가 여전히 유효하다는 것을 증명하기 위해 우리는 unpack다음과 같이 할 수 있습니다.

 

>>> struct.unpack( "f" , data)

( 23.62451934814453 ,)

 

4바이트의 데이터가 위성 시스템을 통과한 후 수신측에서 누군가가 할 일이 바로 그것입니다.

 

여기서 주목해야 할 핵심은 값의 텍스트 표현을 전송하는 데 10바이트가 소요되는 반면, 원시 바이트 표현은 4바이트만 필요하다는 점입니다.

 

정수 vs. 부동소수점

 

이전 예제에서 값을 풀어보면 추가 자릿수가 생겨 처음 값과 정확히 일치하지 않는 것을 볼 수 있습니다. 이는 부동 소수점 정밀도의 일반적인 문제입니다. 이 문제를 100% 해결할 방법은 없습니다. 거의 유일한 해결책은 더 많은 바이트를 사용하는 것입니다. 예를 들어 8바이트를 사용하는 배정밀도를 사용하면 더 나은 결과를 얻을 수 있습니다.

 

>>> value = 23.6245198
>>> data = struct.pack("d", value)
>>> len(data)
8
>>> struct.unpack("d", data)
(23.6245198,)

 

 

좋습니다만, 전송해야 할 바이트 수가 두 배로 늘어났습니다.

 

이 문제에 대한 더 나은 해결책은 모든 것을 정수로 처리하는 것입니다. 하지만 부동 소수점 숫자를 데이터 손실 없이 정수로 변환하는 방법은 무엇일까요? 일반적으로는 불가능합니다. 하지만 그럴 필요는 없습니다.

 

이 값들은 처음에는 대부분 정수였을 것입니다. 센서 레지스터에 1과 0의 연속으로 저장되어 있었기 때문입니다. 데이터시트에는 센서의 레이아웃에 대한 모든 정보가 나와 있으며, 이를 사용하여 관심 있는 실제 값을 계산할 수 있습니다. 센서 라이브러리를 사용하면 이러한 작업을 자동으로 수행해 주는 것이 주요 기능 중 하나입니다. 하지만 효율적인 위성 데이터 전송을 위해 레지스터를 읽고, 관심 있는 물리적 속성 값을 계산한 다음, 그 값을 전송하는 대신, 레지스터의 원시 값을 정수 형태로 그대로 전송하는 것이 좋습니다 .

 

정수 값은 레지스터의 모든 1과 0을 있는 그대로 저장할 수 있습니다. 이는 효율적이며 정보 손실이 없습니다. 또한 수신 측에서 이러한 값을 필요한 공학 단위로 변환하는 것은 매우 간단합니다.

 

위 기사의 출처는 이곳을 참고하였습니다.

반응형

캐어랩 고객 지원

취업, 창업의 막막함, 외주 관리, 제품 부재!

당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약, 아이디어는 있지만 구현할 기술이 없는 막막함.

우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.

이제 고민을 멈추고, 캐어랩을 만나세요!

코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.

제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!

귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.

지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.

카카오 채널 추가하기

카톡 채팅방에서 무엇이든 물어보세요

당신의 성공을 위해 캐어랩과 함께 하세요.

캐어랩 온라인 채널 바로가기

캐어랩