# Mengirim Data Sederhana ke Antares

Pada project ini Anda akan diarahkan untuk mengirim data sederhana dari board **NB-LYNX-95** ke **Antares IoT Platform** menggunakan serangkaian AT Command dari modul BG95-M3.&#x20;

## Prasyarat

Material yang dibutuhkan mengikuti **Prasyarat Umum** pada laman sebelumnya. Jika Anda belum menyiapkan kebutuhan pada laman tersebut, maka Anda dapat mengunjungi laman berikut.

{% content-ref url="/pages/06cSsRDaM6t4BfBjxejL" %}
[Prasyarat Umum NB-Lynx-95](/contoh-kode-dan-library/nb-iot/nb-lynx-95/prasyarat-umum-nb-lynx-95.md)
{% endcontent-ref %}

## Langkah Kerja

### 1. Setup Peralatan

Hal yang perlu Anda lakukan pertama kali adalah melakukan setup peralatan dengan cara menghubungkan board **NB-LYNX-95** ke perangkat laptop/komputer Anda menggunakan kabel USB-C.&#x20;

{% hint style="info" %}
Pastikan Anda telah memasang antena pada port antena GSM sebelum menghubungkan board **NB-LYNX-95** ke laptop/komputer.
{% endhint %}

Berikut adalah board NB-LYNX-95 yang sudah dihubungkan ke laptop/komputer.

<figure><img src="/files/caSurJ1dKK4B1b6ppG15" alt=""><figcaption><p>Board NB-LYNX-95</p></figcaption></figure>

### 2. Jalankan Aplikasi Arduino IDE

### 3. Menginputkan Kode Program

Untuk mengirim data ke Antares, Anda perlu menginputkan kode program di bawah pada Arduino IDE.&#x20;

{% code lineNumbers="true" fullWidth="false" %}

````arduino
#include <Arduino.h>

// Configurable macros
#define APN "nb1internet"
#define APPNAME "YOUR-APP-NAME"
#define DEVNAME "YOUR-DEVICE-NAME"
#define ACCESSKEY "0000000000000000:0000000000000000"
#define PAYLOAD "{\\\"t\\\":\\\"25.5\\\",\\\"h\\\":\\\"60.35\\\"}"
#define BG96_POWER_KEY 27

const uint32_t interval = 10000; // 10 s interval to send message
uint32_t previousMillis = 0;     // will store last time message sent
uint32_t counter = 0;            // message counter

String sendCommand(String command, uint32_t timeout, char delimiter)
{
  while (Serial2.available())
    Serial2.read();

  uint32_t T = millis();
  String res = "";
  Serial.print("[SYS CMD] ");
  Serial.print(command);
  Serial.println("=========");
  Serial2.print(command);
  while ((millis() - T) < timeout)
  {
    while (Serial2.available())
    {
      res = Serial2.readStringUntil(delimiter);
      res.trim();
      if (res.length() > 0)
      {
        Serial.print("[SYS RES] ");
        Serial.println(res);
        return res;
      }
    }
  }
  return "TIMEOUT";
}

String receiveAddCommand(int32_t timeout)
{
  String res = "";
  uint32_t T = millis();
  while ((millis() - T) < timeout)
  {
    while (Serial2.available())
    {
      res = Serial2.readStringUntil('\0');
      res.trim();
      if (res.length() > 0)
      {
        Serial.print("[SYS RES] ");
        Serial.println(res);
        return res;
      }
    }
  }
  return res;
}

bool checkResponse(String response, String expected_response)
{
  if (response.indexOf(expected_response) != -1)
    return true;
  else
    return false;
}

bool bg96_L1()
{
  for (uint8_t i = 0; i < 2; i++)
  {
    if (checkResponse(sendCommand("AT\r\n", 300, '\0'), "OK"))
    {
      sendCommand("ATE0\r\n", 300, '\n');
      return true;
    }

    delay(1000);
  }
  
  pinMode(BG96_POWER_KEY, OUTPUT);
  delay(100);
  digitalWrite(BG96_POWER_KEY, HIGH);
  delay(700);
  digitalWrite(BG96_POWER_KEY, LOW);
  delay(5000);
  for (uint8_t i = 0; i < 5; i++)
  {
    if (checkResponse(sendCommand("AT\r\n", 300, '\0'), "OK"))
    {
      sendCommand("ATE0\r\n", 300, '\n');
      return true;
    }

    delay(1000);
  }
  return false;
}

bool bg96_L2()
{
  if (!checkResponse(sendCommand("AT+QCFG=\"nwscanseq\",03,1\r\n", 300, '\0'), "OK"))
    return false;
  if (!checkResponse(sendCommand("AT+QCFG=\"nwscanmode\",3,1\r\n", 300, '\0'), "OK"))
    return false;
  if (!checkResponse(sendCommand("AT+QCFG=\"iotopmode\",1,1\r\n", 300, '\0'), "OK"))
    return false;
  if (!checkResponse(sendCommand("AT+QCFG=\"band\",3,80,80,1\r\n", 300, '\0'), "OK"))
    return false;
  if (!checkResponse(sendCommand("AT+QCFG=\"servicedomain\",1,1\r\n", 300, '\0'), "OK"))
    return false;

  return true;
}

bool bg96_L3(uint8_t stage)
{
  switch (stage)
  {
  case 0:
    if (!checkResponse(sendCommand("AT+QIDEACT=1\r\n", 40000, '\n'), "OK"))
      return false;

  case 1:
    if (!checkResponse(sendCommand("AT+QICSGP=1,1,\"" + String(APN) + "\",\"\",\"\",0\r\n", 300, '\n'), "OK"))
      return false;

  default:
    if (!checkResponse(sendCommand("AT+QIACT=1\r\n", 60000, '\n'), "OK"))
      return false;
  }

  return true;
}

bool bg96_L3_check()
{
  String response = sendCommand("AT+QIACT?\r\n", 300, '\0');
  if (checkResponse(response, "OK"))
  {
    response.replace("+QIACT:","");
    int firstCommaIndex = response.indexOf(",");
    int secondCommaIndex = response.indexOf(",", firstCommaIndex+1);
    String ctx_id = response.substring(0, firstCommaIndex);
    String ctx_state = response.substring(firstCommaIndex + 1, secondCommaIndex);

    if (checkResponse(ctx_state, "0"))
      return bg96_L3(0);
    else
      return true;
  }
  else
    return bg96_L3(0);
}

void bg96_send()
{
  String httpBody = "{\"m2m:cin\": {\"con\": \"%1\"}}";
  httpBody.replace("%1", PAYLOAD);

  String response = sendCommand("AT+QIOPEN=1,0,\"TCP\",\"platform.antares.id\",8080\r\n", 300, '\n');
  Serial.println("Response : " + response);
  if (checkResponse(response, "OK"))
  {
    response = receiveAddCommand(60000);
    Serial.println("Response1 : " + response);
    if (checkResponse(response, "QIOPEN"))
    {
      response.replace("+QIOPEN: ","");
      response.trim();
      Serial.println("Response2 : " + response);
      String socketResult = response.substring(response.indexOf(",") + 1, response.length());
      Serial.println("socketResult : " + socketResult);
      if (socketResult.toInt() > 0)
      {
        sendCommand("AT+QICLOSE=0\r\n", 10000, '\n');
        return;
      }
    }
    else
    {
      sendCommand("AT+QICLOSE=0\r\n", 10000, '\n');
      return;
    }

    Serial.print("POST /~/antares-cse/antares-id/" + String(APPNAME) + "/" + String(DEVNAME) + " HTTP/1.1\r\n");
    Serial.print("Host: platform.antares.id:8080\r\n");
    Serial.print("Accept: application/json\r\n");
    Serial.print("Content-Type: application/json;ty=4\r\n");
    Serial.print("X-M2M-Origin: " + String(ACCESSKEY) + "\r\n");
    Serial.print("Content-Length: " + String(httpBody.length()) + "\r\n\r\n");
    Serial.println(httpBody);

    sendCommand("AT+QISEND=0\r\n", 300, '\0');
    Serial2.print("POST /~/antares-cse/antares-id/" + String(APPNAME) + "/" + String(DEVNAME) + " HTTP/1.1\r\n");
    Serial2.print("Host: platform.antares.id:8080\r\n");
    Serial2.print("Accept: application/json\r\n");
    Serial2.print("Content-Type: application/json;ty=4\r\n");
    Serial2.print("X-M2M-Origin: " + String(ACCESSKEY) + "\r\n");
    Serial2.print("Content-Length: " + String(httpBody.length()) + "\r\n\r\n");
    Serial2.print(httpBody);
    Serial2.write(0x1A);

    String response2 = receiveAddCommand(60000);
    Serial.print("Response2 : ");
    Serial.println(response2);
    
  }
  
  sendCommand("AT+QICLOSE=0\r\n", 10000, '\n');
}

bool nbSetup()
{
  Serial2.begin(115200);
  Serial.println("[BG96] Turning ON...");
  if (bg96_L1())
    Serial.println("Success");
  else
  {
    Serial.println("Failed");
    return false;
  }

  Serial.println("[BG96] Set NB Mode... ");
  if (bg96_L2())
    Serial.println("Success");
  else
  {
    Serial.println("Failed");
    return false;
  }

  Serial.println("[BG96] Start IP Connection...");
  bg96_L3(0);

  return true;
}

void setup()
{
  Serial.begin(115200);
  if (!nbSetup())
  {
    while (1)
      delay(1000);
  }
}

void loop()
{
  // Check interval overflow
  if (millis() - previousMillis > interval)
  {
    previousMillis = millis();

    if (bg96_L3_check())
    {
      char message[50];
      sprintf(message, "Sending frame : %d", counter);
      Serial.println(message);
      bg96_send();
      counter++;
    }
  }
}

```
````

{% endcode %}

{% hint style="info" %}
Jangan lupa untuk menggganti **APPNAME** dengan nama aplikasi yang Anda buat di platform Antares, **DEVNAME** dengan nama device yang dibuat pada platform Antares, dan **ACCESSKEY** dengan access-key akun Anda.
{% endhint %}

Setelah menginputkan kode program, jangan lupa untuk menyimpan kode program tersebut dengan memilih **File > Save As**. Berikut adalah tampilan pada Arduino IDE ketika Anda sudah menginputkan kodenya.

<figure><img src="/files/O2hkKsAKVybgZBhuFD5V" alt=""><figcaption><p>Tampilan pada Arduino IDE ketika Program Sudah Diinput</p></figcaption></figure>

### 4. Penjelasan Kode Program

Supaya board **NB-LYNX-95** dapat berkomunikasi dengan platform Antares, digunakan modul **BG95-M3**. BG95-M3 merupakan modul komunikasi seluler yang dikembangkan oleh Quectel. Modul ini menerapkan beberapa protokol yang memungkinkan perangkat untuk terhubung ke jaringan internet menggunakan **AT command**. Berikut dijelaskan beberapa AT command yang digunakan pada kode program.

```
AT<CR><LF>
```

Pada kode program terdapat command "AT\r\n" yang dikirimkan sebagai starting point atau tahap inisialisasi modul SIM7000. \r merupakan carriage return , sedangkan \n merupakan line feed. Command ini dikirimkan untuk mendapatkan respons “OK”.

```
ATE0<CR><LF>
```

Pada kode program terdapat command "ATE0\r\n" yang dikirimkan setelah mendapatkan respons “OK”. Command ini digunakan untuk menonaktifkan echo mode yang menandakan bahwa inisialisasi telah berhasil.

```
AT+QCFG="nwscanseq”[,<scanseq>[,effect]]<CR><LF>
```

Pada kode program terdapat command “AT+QCFG="nwscanseq",03,1\r\n” yang dikirimkan untuk mengatur urutan pencarian RAT (Radio Access Technology). Pada command tersebut tedapat parameter “03” yang merupakan \<scanseq> sebagai urutan pencarian untuk NB-IoT, sedangkan parameter “1” merupakan \<effect> supaya konfigurasi segera berlaku.&#x20;

{% hint style="info" %}
Berikut parameter \<scanseq> lain yang dapat digunakan

* 00 = Otomatis (eMTC --> NB-IoT --> GSM)
* 01 = GSM
* 02 = eMTC
* 03 = NB-IoT
  {% endhint %}

{% hint style="info" %}
Berikut parameter \<effect> lain yang dapat digunakan

* 0 = Konfigurasi berlaku ketika UE (user equipment) di-restart
* 1 = Konfigurasi akan segera berlaku
  {% endhint %}

```
AT+QCFG="nwscanmode”[,<scanmode>[,effect]]<CR><LF>
```

Pada kode program terdapat command “AT+QCFG="nwscanmode",3,1\r\n” yang dikirimkan untuk menentukan RAT yang boleh dicari. Parameter “3” merupakan \<scanmode> untuk melakukan pencarian pada LTE saja, sedangkan parameter “1” merupakan supaya konfigurasi segera berlaku.&#x20;

{% hint style="info" %}
Berikut parameter lengkap \<scanmode> yang dapat digunakan

* 0 = Otomatis
* 1 = GSM saja
* 3 = LTE saja
  {% endhint %}

```
AT+QCFG="iotopmode”[,<mode>[,effect]]<CR><LF>
```

Pada kode program terdapat command “AT+QCFG="iotopmode",1,1\r\n” yang dikirimkan untuk menentukan kategori jaringan yang akan dicari di bawah LTE RAT. Parameter “1” merupakan untuk mencari kategori jaringan berupa NB-IoT, sedangkan parameter “1” berikutnya merupakan \<effect> supaya konfigurasi segera berlaku.

{% hint style="info" %}
Berikut parameter lengkap \<mode> yang dapat digunakan

* 0 = eMTC
* 1 = NB-IoT
* 2 = eMTC dan NB-IoT
  {% endhint %}

```
AT+QCFG="band”[,<gsmbandval>,<emtcbandval>,<nbiotbandval>[,effect]]<CR><LF>
```

Pada kode program terdapat command “AT+QCFG="band",3,80,80,1\r\n” yang dikirimkan untuk menentukan pita frekuensi yang diperbolehkan untuk dicari. Parameter “3” merupakan \<gsmbandval> untuk mengatur frekuensi GSM di Indonesia yang berada pada 900 MHz dan 1800 MHz, parameter “80” merupakan \<emtcbandval> untuk mengatur frekuensi pada LTE B8, sedangkan parameter “80” berikutnya merupakan \<nbiotbandval> untuk mengatur frekuensi NB-IoT pada LTE B8, kemudian parameter “1” merupakan \<effect> supaya konfigurasi segera berlaku.

```
AT+QCFG="servicedomain”[,<service>[,effect]]<CR><LF>
```

Pada kode program terdapat command “AT+QCFG="servicedomain",1,1\r\n” yang dikirimkan untuk menentukan domain service yang terdaftar. Parameter “1” merupakan \<service> untuk menentukan domain service sebagai PS (Packet Swithced) saja, sedangkan parameter “1” berikutnya merupakan \<effect> supaya konfigurasi segera berlaku.

{% hint style="info" %}
Berikut parameter lengkap \<service> yang dapat digunakan

* 1 = PS (Packet Swithced ) saja
* 2 = CS (Circuit Switched) dan PS (Packet Swithced)
  {% endhint %}

```
AT+QIDEACT=<contextID><CR><LF>
```

Pada kode program terdapat command “AT+QIDEACT=1\r\n” yang dikirimkan untuk menonaktifkan PDP context, dalam hal ini diatur pada parameter \<contextID> dengan nilai “1”, dan menutup semua koneksi TCP/IP.

```
AT+QICSGP=<contextID>[,<context_type>,<APN>,[,<username>,<password>[,<authentication>]]]<CR><LF>
```

Pada kode program terdapat command “AT+QICSGP=1,1,"" + String(APN) + "","","",0\r\n” untuk mengatur parameter TCP/IP context \<APN>, \<username>, \<password>, dan \<authentication>. Parameter “1” menunjukkan nilai \<contextID>, sedangkan parameter “1” berikutnya menunjukkan nilai \<context\_type> untuk mengatur protokol yang digunakan berupa IPv4.

Pada command tersebut parameter \<APN> yang diatur dengan String(APN) sesuai dengan yang sudah didefinisikan pada awal program dengan value "nb1internet". Untuk parameter lain seperti \<username> dan \<password> dibiarkan kosong pada command ini, sedangkan untuk parameter \<authentication> diatur sebagai “0” yang menandakan tidak ada metode autentikasi yang digunakan

{% hint style="info" %}
Berikut parameter lengkap \<context\_type> yang dapat digunakan

* 1 = IPv4
* 2 = IPv6
* 3 = IPv4v6
  {% endhint %}

{% hint style="info" %}
Berikut parameter lengkap \<authentication> yang dapat digunakan

* 0 = Tidak ada autentikasi
* 1 = PAP
* 2 = CHAP
* 3 = PAP atau CHAP
  {% endhint %}

```
AT+QIACT=<contextID><CR><LF>
```

Pada kode program terdapat command “AT+QIACT=1\r\n” yang dikirimkan untuk mengaktifkan PDP context dengan nilai \<contextID> adalah “1”.

```
AT+QIACT?<CR><LF>
```

Pada kode program terdapat command “AT+QIACT?\r\n” yang dikirimkan untuk menampilkan PDP context yang aktif beserta dengan IP address.

```
AT+QIOPEN=<contextID>,<connectID>,<service_type>,<IP_address>/<domain_name>,<remote_port><CR><LF>
```

Pada kode program terdapat command “AT+QIOPEN=1,0,"TCP","platform.antares.id",8080\r\n” yang dikirimkan untuk membuka socket service, dalam hal ini adalah Antares IoT Platform. Parameter “1” merupakan \<contextID>, sedangkan parameter “0” merupakan \<connectID>. Selanjutnya didefinisikan juga parameter “TCP” sebagai \<service\_type>, “platform.antares.id” sebagai \<domain\_name> dari Antares IoT Platform, sedangkan parameter “8080” sebagai \<remote\_port> dari remote server.

```
AT+QISEND=<connectID><CR><LF>
```

Pada kode program terdapat command “AT+QISEND=0\r\n” yang dikirimkan untuk mengirimkan data pada socket service yang telah diatur sebelumnya. Parameter “0” merupakan nilai dari \<connectID>.

```
AT+QICLOSE=<connectID><CR><LF>
```

Pada kode program terdapat command “AT+QICLOSE=0\r\n” yang dikirimkan untuk menutup socket service yang sedang berjalan. Parameter “0” merupakan nilai dari \<connectID>.

### 5. Upload Program ke Board NB-LYNX-7000

Pertama. Anda harus mengatur board yang digunakan dengan memilih **ESP32 Dev Module** pada bagian **Tools > Board > esp32**.

<figure><img src="/files/y0V3K1UUpuC80RQhoCsa" alt=""><figcaption><p>Setup Board di Arduino IDE</p></figcaption></figure>

Setelah itu, Anda perlu mengatur port yang digunakan dengan membuka **Tools > Port >** **COM(X)**. Nilai X menyesuaikan dengan nomor port yang digunakan oleh board NB-LYNX-7000.

<figure><img src="/files/kLDCeYY0dEH8t2Y1rryw" alt=""><figcaption><p>Pemilihan Port di Arduino IDE</p></figcaption></figure>

Setelah Anda mempersiapkan kode program, selanjutnya Anda dapat meng-upload kode program tersebut dengan menekan tombol upload seperti ditunjukkan pada gambar di bawah.

<figure><img src="/files/VwWWpLoCY4qjliFwzRHm" alt="" width="375"><figcaption><p>Upload Kode Program</p></figcaption></figure>

Jika kode program sudah berhasil di-upload, Anda dapat membuka Serial Monitor dengan menekan icon seperti ditunjukkan pada gambar di bawah. Icon tersebut dapat Anda temukan pada bagian atas sebelah kanan.

<figure><img src="/files/zZ0O4bmnLawx7ZjEb4h9" alt="" width="197"><figcaption><p>Ikon Serial Monitor</p></figcaption></figure>

Anda perlu mengatur baud rate Serial Monitor menjadi 115200 supaya output-nya dapat terbaca.

<figure><img src="/files/aTWLpLXnxED8zmgqwQyK" alt=""><figcaption><p>Baud Rate</p></figcaption></figure>

Tampilan Serial Monitor akan menjadi seperti pada gambar di bawah yang menandakan proses inisiasi modul BG95-M3.

<figure><img src="/files/bkKbEg6QN8VedxmB0twW" alt=""><figcaption><p>Output Serial Monitor ketika Proses Inisiasi Modul BG95-M3</p></figcaption></figure>

Selanjutnya proses yang akan terjadi pada serial monitor adalah pengaturan mode menjadi NB-IoT dengan jaringan LTE. Berikut tampilan yang muncul pada serial monitor.

<figure><img src="/files/6RmSuMgzEHWZcXdAHEWL" alt=""><figcaption><p>Output Serial Monitor yang Menunjukkan Proses Pengaturan Mode NB-IoT</p></figcaption></figure>

Setelah berhasil, proses yang bekerja adalah pengaturan konektivitas jaringan dengan memulai koneksi IP. Berikut adalah tampilan yang muncul pada serial monitor.

<figure><img src="/files/Ed2rJDHkrVnP3i7ncujw" alt=""><figcaption><p>Output Serial Monitor yang Menunjukkan Proses Pengaturan Koneksi IP</p></figcaption></figure>

Setelah IP berhasil didapatkan, modul NB-LYNX-95 telah siap untuk mengirimkan data ke Antares IoT Platform. Proses pengiriman data ditandai dengan tulisan "Sending frame" yang dimulai dari frame 0. Kemudian modul tersebut akan mengakses server Antares dengan koneksi TCP untuk mengirimkan data. Berikut adalah tampilan pada serial monitor.

<figure><img src="/files/QqPOGoYuuXpJb0RAwcMb" alt=""><figcaption><p>Output Serial Monitor ketika Mengirimkan Data Pertama ke Antares IoT Platform</p></figcaption></figure>

Pada gambar di atas, modul NB-LYNX-95 telah berhasil mengirimkan satu data pada Antares IoT Platform. Kode program dirancang untuk terus menerus mengirimkan data ke Antares IoT Platform yang ditandai dengan hitungan frame. Berikut adalah tampilan pada serial monitor ketika mengirimkan data berikutnya.

<figure><img src="/files/0a5anH5mlo4d77LKqyda" alt=""><figcaption><p>Output Serial Monitor ketika Mengirimkan Data Berikutnya</p></figcaption></figure>

### 6. Periksa Data pada Antares IoT Platform

Untuk memastikan bahwa data telah terkirim dengan benar dari modul NB-LYNX-95 ke Antares IoT Platform, Anda dapat membuka URL device Anda. Gambar berikut menunjukkan tampilan pada Antares IoT Platform yang sudah menerima data dari NB-LYNX-7000.

<figure><img src="/files/iqypeRJwuwpkh7wGs0Vq" alt=""><figcaption><p>Tampilan pada Antares IoT Platform yang Telah Menerima Data dari board NB-LYNX-7000</p></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.antares.id/contoh-kode-dan-library/nb-iot/nb-lynx-95/mengirim-data-sederhana-ke-antares.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
