ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CZ-ME310G1모뎀 AGPS 꼭 쓰세요~!! 첫번째 이야기
    Asset tracking 2026. 6. 26. 20:55

     
    CZ-ME310G1모뎀은 AGPS를 지원합니다. 
     

     

    GNSS 속도의 한계를 깨는 키, A-GPS

    GNSS 모듈이 맨 처음 켜졌을 때(Cold Boot) 하늘에 떠 있는 위성 신호를 직접 다 잡아 위치를 계산하려면 보통 수분이 걸립니다. 하지만 A-GPS를 사용하면 이야기가 달라집니다.

    • 동작 원리: LTE 기지국 네트워크를 통해 위성 좌표 데이터를 서버에서 초고속으로 다운로드하여 참조합니다.
    • 성능 향상:
      • 콜드 부트(Cold Boot): 최초 위치 확보(TTFF) 속도를 극적으로 단축합니다.
      • 웜 부트(Warm Boot): 칩이 깨어나는 즉시 신속하게 현재 위치를 타겟팅합니다.

    💡 검증된 퀄컴(Qualcomm) 인프라 활용 A-GPS의 성능은 데이터를 뿌려주는 서버의 상태에 좌우됩니다. CZ-ME310G1모뎀은 업계 표준인 퀄컴의 글로벌 위치 서비스 서버를 기본 제공하므로, 상용 제품 수준의 독보적인 신뢰성과 빠른 속도를 안정적으로 누릴 수 있습니다.

     
    얼마나 빨리 접속하는지는 뒤에서 테스트코드와 데모영상으로 보여 드리겠습니다. 
    CZ-ME310G1모뎀은 AT커맨드 몇 줄로 간단하게 AGPS를 사용하실 수 있습니다. 
     
    일단 TransparentBridge example을 올려서 AT커맨드로 바로 사용해 보겠습니다. 

     
    부팅 후 모뎀을 사용할 수 있는 준비가 되면 아래와 같이 Bridge Communication Enabled 메시지가 출력됩니다. 

     
    이제 Serial Monitor를 Carriage Return, 115200baud로 설정합니다. 

     
    Serial Monitor 아래 입력창에 AT 입력 후  Enter키를 눌렀을 때 OK라고 나오면 이제 시작하겠습니다.

     
    순서대로 살펴보겠습니다.
     

    1. AGPS 준비과정 : AGPS 설정 후 REBOOT 해야 AGPS를 사용할 수 있음
    1)  AGPS 설정되어 있는가?
    AT$AGNSS?
    $AGNSS: 0,0,0
    OK
    --> 반환값이 $AGNSS: 0,0,0 이면 AGPS 설정이 안 되어 있는 상태
     
    2)  AGNSS 설정
    AT$AGNSS=0,1
    OK
     
    3) Qualcomm XTRA 데이터 자동 다운로드 설정
    아래 내용을 참고해서 설정 합니다. 

    • 1일 치 파일: 12.993 KB
    • 3일 치 파일 (기본값): 17.827 KB
    • 7일 치 파일: 27.489 KB

    XTRA 데이터는 세 번째 값이 0이면 24시간에 1, 1이면 72시간 1(기본값), 2면 168시간 1
    AT$AGNSSCFG=0,0,0
    OK
     
    4) 셋팅값 확인 
    AT$AGNSS?
    $AGNSS: 0,0,1   현재는 0이고 재부팅 후에는 1이 될 거야.
    OK
     
    5) REBOOTAT OK 반환될 때까지될때까지 대기 후 진행
    AT#REBOOT
    OK

     

    2. AGPS 사용
    1)  AGPS 설정되어 있는가? è 반환값이 $AGNSS: 0,1,1 이면 AGPS 설정 완료되어 있는 상태
    AT$AGNSS?
    $AGNSS: 0,1,1
    OK
     
    2) 망에 연결되었는지 체크, 연결되면 다음으로 진행
    AT+CEREG?
    +CEREG: 0,5
    OK
     
    3) 기지국에서 IP 획득
    AT#SGACT=1,1
    #SGACT: 10.87.179.130
    OK
     
    4) NTP 설정 준비
    AT#NTPCFG=1,0
    OK
     
    5) NTP 서버를 통해 RTC설정  
    AT#NTP="216.239.35.0",123,1,5,36
    #NTP: 26/06/24,21:26:56+36
    OK
     
    3. MQTT 통신으로 위도, 경도 좌표 전달

    연결 끊김 없이 LTE와 GPS를 번갈아 쓰는 비법

    IoT 단말을 개발하다 보면 MQTT 데이터 전송과 GPS 위치 수신을 번갈아 해야 할 때가 많습니다. 다행히 매번 서버 접속을 끊고 다시 연결(Re-connect)하는 수고를 겪을 필요가 없습니다. 서버와 한 번 연결된 상태만 잘 이용하면 끊김 없는 연속 통신이 가능합니다.

    비밀은 모뎀 내부의 '아비터(Arbiter)' 블록에 있습니다.
    • 일시 중지(Suspend) 마법: 모뎀 내부의 중재자인 아비터는 GNSS 위치를 잡아야 할 때, 기존에 서버와 접속 중이던 LTE 통신 블록을 잠시 '일시 중지(Suspend)' 상태로 만듭니다.
    • 타임아웃의 활용: 연결이 완전히 끊긴 것이 아닙니다! 설정해 둔 타임아웃(예: MQTT Keep-Alive 120초) 이내에 GPS 수신을 끝내고 다시 LTE 모드로 복귀하기만 하면 기존 접속이 그대로 유지됩니다.
    이 원리는 순수 소켓(Socket) 통신에서도 똑같이 통합니다. 지정된 Socket Timeout 시간 내에만 LTE 상태로 돌아온다면 서버는 단말이 계속 연결되어 있다고 판단하므로, 빠르고 전력 효율적인 디바이스를 설계할 수 있습니다.

     
    이 개념을 염두에 두고 아래 AT커맨드 동작흐름을 살펴보겠습니다. 

     
    AT#MQEN=1,1
    OK
     
    AT#MQCFG=1,"broker.emqx.io",1883,1,0
    OK 
     
    AT#MQCFG2=1,120,0 //Keep-Alive 120초 설정
    OK 
     
    //MQTT 서버 연결  
    AT#MQCONN=1,"myIoTDevice","",""
    OK
     
    AT$GPSCFG=3,0  //RF우선순위를 GPS로 변경, 서버는 연결된 상태로 120초간 유지됨.모드 변경에 3초 소요
    OK 
     
    AT$GPSP=1 //GPS를 켜준다. AGPS로 동작시작.
    OK 
     
    AT$GNSSACP           //8번째 매개변수가 2 이상이 되면 AGPS가 위치를 잡은 상태임. 그때부터 위도, 경도값 사용
    $GNSSACP: ,,,,,,,1,,,,,,,  //8번째 매개변수 값이 2 : 2D Fix, 3 : 3D Fix
    OK 
     
    AT$GNSSACP
    $GNSSACP: ,,,,,,,1,,,,,,,
    OK 
     
    AT$GNSSACP           //8번째 매개변수 3 : 3D Fix, 13번째 매개변수 07: 현재 연결된 위성갯수 7, 좌표획득!!
    $GNSSACP: 123602.000,240626,3730.3641N,12704.7538E,22.9,1.4,1.0,3,0.0,0.0,0.0,AANNNN,07,22.41,36.25
    OK
     
    AT$GPSCFG=3,1 //RF우선순위를 LTE로 변경, 모드 변경에 3초 소요
    OK
     
    AT#MQPUBS=1,"czme310/topic/put",0,0,"3730.3730N,12704.7397E"    //위도, 경도 좌표 Publish
    OK
     
    AT$GPSCFG=3,0 //RF우선순위를 GPS로 변경, 모드 변경에 3초 소요
    OK
     
    AT$GNSSACP
    $GNSSACP: 123930.000,240626,3730.3645N,12704.7478E,40.,0.9,0.8,3,0.0,0.0,0.0,AANNNN,11,5.62,9.34
    OK
     
    AT$GPSCFG=3,1 //RF우선순위를 LTE로 변경, 모드 변경에 3초 소요
    OK 
     
    AT#MQPUBS=1,"czme310/topic/put",0,0,"3730.3645N,12704.7478E"    //위도, 경도 좌표 Publish
    OK
     
    //MQTT 서버 DisConnect 
    AT#MQDISC=1
    OK
     
    //MQTT Disable 
    AT#MQEN=1,0
    OK
     
    //기지국 해제
    AT#SGACT=1,0
    OK
     
    마지막으로 GNSSACP 프로토콜 스펙입니다. 

    $GNSSACP: 111417.000,240626,3730.3331N,12704.7752E,43.9,1.0,0.9,3,00,0.0,0.0,AANNNN,10,10.00,7.92
     
    1. 측정된 UTC 시간 : 111417.000 (<UTC>) (11시 14분 17.000초).
    2. 측정된 날짜 : 240626 (<date>) (2024년 6월 26일, ddmmyy 형식).
    3. 위도 데이터 : 3730.3331N (<latitude>) (북위 37도 30.3331분).
    4. 경도 데이터 : 12704.7752E (<longitude>) (동경 127도 04.7752분).
    5. 고도 : 43.9 (<altitude>) 해수면을 기준으로 한 해발 고도(미터) (43.9m).
    6. 수평 위치 정밀도 저하율 : 1.0 (<hdop>) (낮을수록 정밀함).
    7. 수직 위치 정밀도 저하율 : 0.9 (<vdop>).
    8. 위치 고정(Fix) 상태 : 3 (<fix>) 3은 고도까지 정확하게 잡아낸 완벽한 3D Fix 상태를 의미. (0, 1invalid fix)
    9. 진행 방향(Course over Ground)을 진북을 기준으로 나타낸 도(degrees) 값 : 00 (<cog>).
    10. 지면 이동 속도 : 0.0 (<spkm>) (0.0 km/h).
    11. 지면 이동 속도 노트 단위 : 0.0 (<spkn>) (0.0 knots).
    12. AANNNN (<mode>): 6개의 위성 시스템(GPS, GLONASS, Galileo, BDS, QZSS, NavIC) 동작 모드를 차례대로 나타냄. A 단독(Autonomous) 모드로 성공적으로 위치를 잡고 있음, N은 사용되지 않음(No fix)을 의미.
    즉, 첫 번째와 두 번째 시스템인 GPS와 GLONASS 두 개의 위성망을 사용 중.
    13. 10 (<nsat>): 현재 위치 획득에 실제로 사용 중인 위성의 총 개수

     
    이제 AGPS를 사용해서 ColdBoot, WarmBoot에서 GNSS 위치를 잡는데 얼마나 빨라지는지 아래 간단한 테스트 코드로 확인해 보겠습니다. 

    #include <Arduino.h>
    #include <ME310.h>

    #define ON_OFF 2 /*Select the GPIO to control ON_OFF*/

    // 모듈과 연결된 시리얼 포트 (ESP32나 Mega 등 하드웨어 시리얼 사용 시 Serial1 추천)
    #define MODEM_SERIAL Serial1
    #define DEBUG_SERIAL Serial

    using namespace me310;

    ME310 myME310;
    ME310::return_t rc;  // Enum of return value  methods

    unsigned long startTime = 0;

    int lv = 0;

    // 함수 선언
    String sendATCommand(String command, const int timeout);
    String extractParameter(String payload, int index);
    double nmeaToDecimalDegrees(String nmeaString);

    void setup() {
      DEBUG_SERIAL.begin(115200);
      MODEM_SERIAL.begin(115200);
      delay(100);
      myME310.debugMode(true);
      myME310.powerOn(ON_OFF);

      DEBUG_SERIAL.println("=== ME310G1 AGPS & 좌표 변환 Test Started ===");

      // 1. 망 접속 확인 (AT+CEREG?)
      DEBUG_SERIAL.println("\n1. Network Registration Check...");
      while (true) {
        String response = sendATCommand("AT+CEREG?", 2000);
        if (response.indexOf("0,5") != -1 || response.indexOf("0,1") != -1) {
          DEBUG_SERIAL.println("-> Network Registered!");
          break;
        }
        DEBUG_SERIAL.println("-> Not registered yet. Retrying in 2 seconds...");
        delay(2000);
      }

      // 2. PDP 컨텍스트 활성화
      DEBUG_SERIAL.println("\n2. Activating PDP Context...");
      sendATCommand("AT#SGACT=1,1", 5000);

      // 3. NTP 설정
      DEBUG_SERIAL.println("\n3. Configuring NTP...");
      sendATCommand("AT#NTPCFG=1,0", 2000);

      // 4. NTP 동기화 (한국 시간)
      DEBUG_SERIAL.println("\n4. Synchronizing Time with NTP...");
      sendATCommand("AT#NTP=\"216.239.35.0\",123,1,5,36", 10000);

      // 5. 런타임 우선순위 GNSS로 변경
      DEBUG_SERIAL.println("\n5. Setting GNSS Runtime Priority...");
      sendATCommand("AT$GPSCFG=3,0", 2000);

      // 6. GNSS 엔진 가동!
      DEBUG_SERIAL.println("\n6. Powering up GNSS Engine...");
      sendATCommand("AT$GPSP=1", 2000);

      startTime = millis();
      DEBUG_SERIAL.println("\n*** Timer Started! Waiting for GPS Fix... ***\n");
    }

    void loop() {
      String response;

      if (lv == 0) {
        // 7. 위치 정보 확인 (AT$GNSSACP 실행)
        response = sendATCommand("AT$GNSSACP", 1500);

        if (response.indexOf("$GNSSACP:") != -1) {
          // "$GNSSACP: " 이후의 실제 데이터 문자열만 분리
          int payloadStart = response.indexOf(':') + 1;
          String payload = response.substring(payloadStart);
          payload.trim();  // 양쪽 공백 제거

          // 8번째 매개변수(<fix> 상태) 추출 -> 인덱스 번호는 7 (0부터 시작)
          String fixStr = extractParameter(payload, 7);
          int fixVal = fixStr.toInt();

          if (fixVal == 0 || fixVal == 1) {
            DEBUG_SERIAL.println("Connecting...");
          } else if (fixVal >= 2) {
            // 🌟 2D 또는 3D Fix 성공! 🌟
            unsigned long elapsedTime = millis() - startTime;

            // 위도(3번째 매개변수, 인덱스 2)와 경도(4번째 매개변수, 인덱스 3) 추출
            String raw_lat = extractParameter(payload, 2);
            String raw_lon = extractParameter(payload, 3);

            // NMEA 포맷을 Decimal Degrees(십진수) 포맷으로 변환
            double dd_lat = nmeaToDecimalDegrees(raw_lat);
            double dd_lon = nmeaToDecimalDegrees(raw_lon);

            // 결과 출력
            DEBUG_SERIAL.print("\n====================================\n");
            DEBUG_SERIAL.print("🌟 AGPS 연결 성공! 🌟\n");
            DEBUG_SERIAL.print("소요 시간(TTFF): ");
            DEBUG_SERIAL.print(elapsedTime / 1000.0);
            DEBUG_SERIAL.println(" 초");
            DEBUG_SERIAL.println("전체 응답값: " + response);
            DEBUG_SERIAL.println("------------------------------------");
            DEBUG_SERIAL.println("[좌표 변환 결과]");
            DEBUG_SERIAL.print("원본 위도 (NMEA): ");
            DEBUG_SERIAL.println(raw_lat);
            DEBUG_SERIAL.print("변환된 위도 (DD): ");
            DEBUG_SERIAL.println(dd_lat, 6);
            DEBUG_SERIAL.print("원본 경도 (NMEA): ");
            DEBUG_SERIAL.println(raw_lon);
            DEBUG_SERIAL.print("변환된 경도 (DD): ");
            DEBUG_SERIAL.println(dd_lon, 6);
            DEBUG_SERIAL.print("====================================\n");

            DEBUG_SERIAL.println("\nPowering off GNSS Engine...");
            sendATCommand("AT$GPSP=0", 2000);

            delay(3000);

            DEBUG_SERIAL.println("\nPowering on GNSS Engine...");
            sendATCommand("AT$GPSP=1", 2000);

            startTime = millis();
            DEBUG_SERIAL.println("\n*** Timer ReStarted! Waiting for GPS Fix... ***\n");

            lv++;
          }
        }
      }
      else {
          // 7. 위치 정보 확인 (AT$GNSSACP 실행)
          response = sendATCommand("AT$GNSSACP", 1500);

          if (response.indexOf("$GNSSACP:") != -1) {
            // "$GNSSACP: " 이후의 실제 데이터 문자열만 분리
            int payloadStart = response.indexOf(':') + 1;
            String payload = response.substring(payloadStart);
            payload.trim();  // 양쪽 공백 제거

            // 8번째 매개변수(<fix> 상태) 추출 -> 인덱스 번호는 7 (0부터 시작)
            String fixStr = extractParameter(payload, 7);
            int fixVal = fixStr.toInt();

            if (fixVal == 0 || fixVal == 1) {
              DEBUG_SERIAL.println("Connecting...");
            } else if (fixVal >= 2) {
              // 🌟 2D 또는 3D Fix 성공! 🌟
              unsigned long elapsedTime = millis() - startTime;

              // 위도(3번째 매개변수, 인덱스 2)와 경도(4번째 매개변수, 인덱스 3) 추출
              String raw_lat = extractParameter(payload, 2);
              String raw_lon = extractParameter(payload, 3);

              // NMEA 포맷을 Decimal Degrees(십진수) 포맷으로 변환
              double dd_lat = nmeaToDecimalDegrees(raw_lat);
              double dd_lon = nmeaToDecimalDegrees(raw_lon);

              // 최종 결과 출력
              DEBUG_SERIAL.print("\n====================================\n");
              DEBUG_SERIAL.print("🌟 AGPS 연결 성공! 🌟\n");
              DEBUG_SERIAL.print("소요 시간(TTFF): ");
              DEBUG_SERIAL.print(elapsedTime / 1000.0);
              DEBUG_SERIAL.println(" 초");
              DEBUG_SERIAL.println("전체 응답값: " + response);
              DEBUG_SERIAL.println("------------------------------------");
              DEBUG_SERIAL.println("[좌표 변환 결과]");
              DEBUG_SERIAL.print("원본 위도 (NMEA): ");
              DEBUG_SERIAL.println(raw_lat);
              DEBUG_SERIAL.print("변환된 위도 (DD): ");
              DEBUG_SERIAL.println(dd_lat, 6);
              DEBUG_SERIAL.print("원본 경도 (NMEA): ");
              DEBUG_SERIAL.println(raw_lon);
              DEBUG_SERIAL.print("변환된 경도 (DD): ");
              DEBUG_SERIAL.println(dd_lon, 6);
              DEBUG_SERIAL.print("====================================\n");

              DEBUG_SERIAL.println("\nPowering off GNSS Engine...");
              sendATCommand("AT$GPSP=0", 2000);
              // 테스트 종료 (무한 대기)
              while (true) {
                delay(10000);
              }
            }
          }
        }
        delay(1000);  // 1초 간격으로 반복 조회
      }

      // ---------------------------------------------------------
      // [헬퍼 함수] AT 커맨드 전송 및 응답 수신
      // ---------------------------------------------------------
      String sendATCommand(String command, const int timeout) {
        String response = "";
        MODEM_SERIAL.println(command);
        long int time = millis();

        while ((time + timeout) > millis()) {
          while (MODEM_SERIAL.available()) {
            char c = MODEM_SERIAL.read();
            response += c;
          }
        }
        return response;
      }

      // ---------------------------------------------------------
      // [헬퍼 함수] 콤마(,)로 구분된 데이터에서 특정 인덱스의 값 추출
      // ---------------------------------------------------------
      String extractParameter(String payload, int index) {
        int start = 0;
        for (int i = 0; i < index; i++) {
          start = payload.indexOf(',', start) + 1;
          if (start == 0) return "";  // 콤마가 모자라면 빈 문자열 반환
        }
        int end = payload.indexOf(',', start);
        if (end == -1) end = payload.length();  // 마지막 파라미터인 경우

        return payload.substring(start, end);
      }

      // ---------------------------------------------------------
      // [헬퍼 함수] NMEA 포맷을 Decimal Degrees로 변환하는 함수
      // ---------------------------------------------------------
      double nmeaToDecimalDegrees(String nmeaString) {
        int dotIndex = nmeaString.indexOf('.');
        if (dotIndex == -1) return 0.0;  // 잘못된 데이터 처리

        // '분(Minute)'은 항상 소수점 앞 2자리부터 시작합니다.
        int minIndex = dotIndex - 2;

        // '도(Degree)'와 '분(Minute)' 문자열 분리
        String degStr = nmeaString.substring(0, minIndex);
        String minStr = nmeaString.substring(minIndex);

        // 숫자로 변환 (이때 뒤에 붙은 N, E 등의 문자는 자동으로 제외됨)
        int degrees = degStr.toInt();
        double minutes = minStr.toFloat();

        // 공식: 도 + (분 / 60)
        double decimalDegrees = degrees + (minutes / 60.0);

        // (Pro-Tip) 남반구(S)나 서반구(W)일 경우 음수로 변환하는 방어 로직 추가
        if (nmeaString.endsWith("S") || nmeaString.endsWith("W")) {
          decimalDegrees *= -1.0;
        }

        return decimalDegrees;
      }

     
    결과가 콜드부트 연결 시 16.5초, 웜부트 연결시 5초 정도 소요 되었습니다. 
    16.5초는 기록이 상당히 좋게 나왔는데 일반적으로 19초에서 30초 정도 콜드부트 GNSS 연결시간이 소요됩니다.
    AGPS를 사용하지 않고 연결 시 1분에서 1분 30초 정도 걸리던 시간에서 상당히 단축되었습니다.(!!!)
     
    콜드부트상태에서 최초 위치를 잡은 후 GNSS만 ON/OFF 하면서 사용하는데 다시 연결할 때는 2.5초에서 5초 정도로 상당히 빠른 속도로 위치를 잡습니다. 

    AT
    AT
    AT
    AT$GPSP=1
    AT$GPSP=0
    === ME310G1 AGPS & 좌표 변환 Test Started ===

    1. Network Registration Check...
    -> Not registered yet. Retrying in 2 seconds...
    -> Network Registered!

    2. Activating PDP Context...

    3. Configuring NTP...

    4. Synchronizing Time with NTP...

    5. Setting GNSS Runtime Priority...

    6. Powering up GNSS Engine...

    *** Timer Started! Waiting for GPS Fix... ***

    Connecting...
    Connecting...
    Connecting...
    Connecting...
    Connecting...
    Connecting...

    ====================================
    🌟 AGPS 연결 성공! 🌟
    소요 시간(TTFF): 16.50 초
    전체 응답값: AT$GNSSACP

    $GNSSACP: 133922.100,150726,3730.3769N,12704.7314E,-1.9,1.3,0.9,3,0.0,1.5,0.8,ANNNNN,06,35.41,41.95

    OK

    ------------------------------------
    [좌표 변환 결과]
    원본 위도 (NMEA): 3730.3769N
    변환된 위도 (DD): 37.506282
    원본 경도 (NMEA): 12704.7314E
    변환된 경도 (DD): 127.078857
    ====================================

    Powering off GNSS Engine...

    Powering on GNSS Engine...

    *** Timer ReStarted! Waiting for GPS Fix... ***

    Connecting...

    ====================================
    🌟 AGPS 연결 성공! 🌟
    소요 시간(TTFF): 5.00 초
    전체 응답값: AT$GNSSACP

    $GNSSACP: 133935.000,150726,3730.3607N,12704.7456E,11.2,1.1,0.8,3,0.0,0.0,0.0,AANNNN,09,17.55,21.68

    OK

    ------------------------------------
    [좌표 변환 결과]
    원본 위도 (NMEA): 3730.3607N
    변환된 위도 (DD): 37.506012
    원본 경도 (NMEA): 12704.7456E
    변환된 경도 (DD): 127.079093
    ====================================

    Powering off GNSS Engine...

     
    영상(Youtube)
    https://youtu.be/FYK6WQKIjdQ

     

    위도, 경도를 구글맵에 표시한 지도는 아래와 같습니다.
    상당히 정확하게 위치를 잡았습니다. 

     
    LTE-CATM1 내장형 모뎀 대량 구매 상담, 외주 개발, 협업 문의, vodafone IoT유심 문의
    (주)코드주
    장병남 대표 010-8965-1323 rooney.jang@codezoo.co.kr  

    코드주 LTE-CatM1 내장형 모뎀 CZ-ME310G1 / GNSS(GPS) 지원 / 외장 LTE 안테나 포함 / Zephyr 및 Arduino 지원

    메카솔루션 공식 쇼핑몰

    www.mechasolution.com

    iot유심 : codezoo

    [codezoo] IoT Global SIM, IoT Connectivity, IoT Device

    smartstore.naver.com

    LTE + GNSS Cabinet 안테나 : codezoo

    [codezoo] IoT Global SIM, IoT Connectivity, IoT Device

    smartstore.naver.com

    CodeZoo LTE-CatM1 전용 아두이노 브레이크아웃 쉴드

    메카솔루션 공식 쇼핑몰

    mechasolution.com

     
     

Designed by Tistory.