Pendahuluan

NB-IoT merupakan teknologi telekomunikasi terbaru yang dirancang secara khusus agar komunikasi antar mesin yang semakin masif dengan coverage jaringan telekomunikasi yang semakin luas dapat dilakukan secara efisien, serta penggunaan daya pada perangkat pengguna semakin hemat. Teknologi radio akses NB-IoT, yang merupakan salah satu jenis teknologi jaringan Low Power Wide Area (LPWA), memungkinkan perangkat beroperasi hingga bertahun-tahun tanpa pengisian daya ulang baterai sehingga sangat menghemat biaya. Teknologi ini juga mampu menghasilkan kapasitas koneksi yang masif untuk solusi dan aplikasi berbasis IoT.

Gambar NB-IOT Shield SIM7000C


Menghubungkan ke ANTARES

NB-IOT Shield menggunakan komunikasi serial untuk mengirim dan menerima data dari cloud melalui jaringan telekomunikasi, sehingga kita menggunakan AT-Command sebagai perintah untuk menghubungkan device dengan jaringan telekomunikasi dari suatu provider yang sudah support NB-IOT. Berikut ini source code untuk menghubungkan NB-IOT Shield ke ANTARES menggunakan Arduino IDE dan AT-Command.

A. Arduino IDE
#include "Wire.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"
#include "SoftwareSerial.h"

#define PIN_TX     7
#define PIN_RX     8
#define PWRKEY    12
SoftwareSerial     SIM7000(PIN_RX,PIN_TX);
Adafruit_BME280 bme; // I2C

char bufferRX[200];
int indexBufferRX;
bool statusKoneksi = false;
String accessKey = "YOUR-ACCESS-KEY";
float temperature,humidity,pressure;

void getSensor() {
    temperature = bme.readTemperature();
    pressure = bme.readPressure() / 100.0F;
    humidity = bme.readHumidity();

    Serial.print("Temperature = ");
    Serial.print((String)temperature);
    Serial.println(" *C");
    Serial.print("Humidity = ");
    Serial.print((String)humidity);
    Serial.println(" %");

    Serial.println();
}
void setup() {
    Serial.begin(9600);
    bool status = bme.begin(0x76);
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
    }
    initSIM7000();
}

void sendCommand(String AtCommand)
{
  SIM7000.print(AtCommand+ "\r\n");
  delay(500);
  SIM7000.listen();
  indexBufferRX =0;
  while(SIM7000.available()){
    bufferRX[indexBufferRX] = SIM7000.read();
    indexBufferRX++;
  }
  SIM7000.flush();
}

void cleanBuffer(char *buffer,int count)
{
    for(int i=0; i < count; i++){
        buffer[i] = '\0';
    }
}

int readBuffer(char *buffer, int count, unsigned int timeout=0, unsigned int chartimeout=0)
{
    int i = 0;
    unsigned long timerStart, prevChar;
    timerStart = millis();
    prevChar = 0;
    while(1){
        while(SIM7000.available()){
            buffer[i++] = SIM7000.read();
            prevChar = millis();
            if(i >= count)
                return i;
        }
        if(timeout){
            if((unsigned long) (millis() - timerStart) > timeout*1000){
                break;
            }
        }
        if(((unsigned long) (millis() - prevChar) > chartimeout*10) && (prevChar != 0)){
            break;
        }
    }
    SIM7000.flush();
    return i;
}

bool sendCommand(const char* cmd, const char* resp)
{
    char SIMbuffer[100];
    cleanBuffer(SIMbuffer,100);
    SIM7000.write(cmd);
    readBuffer(SIMbuffer,100,1,1);
    Serial.println("====> " + (String)cmd);
//    Serial.println("Response Want : " + (String)resp);
    Serial.println("<====" + (String)SIMbuffer);
    if(NULL != strstr(SIMbuffer,resp)){
//        Serial.println("Masuk");
        return  true;
    }else{
        return  false;
    }
}

void loop() {
   checkStatusConnection();
   delay(5000);
   getSensor();
   if (statusKoneksi)
   {
    sendToAntares("\\\"t\\\":\\\""+(String)temperature+"\\\",\\\"h\\\":\\\""+(String)humidity+"\\\"");//,\\\"p\\\":\\\""+(String)pressure+"\\\"");
   }
}

void turnONSim7000()
{
  digitalWrite(PWRKEY, HIGH);
  delay(2000);
  digitalWrite(PWRKEY, LOW);
}

boolean checkSIM7000()
{
  if (sendCommand("AT\r\n","OK")) Serial.println("SIM7000 Sudah ON");
  else
  {
    turnONSim7000();
    Serial.println("Tunggu 5 Detik");
    for (int i=0;i<5;i++)
    {
      delay(1000);
      if (sendCommand("AT\r\n","OK"))
      {
        sendCommand("ATE0\r\n","OK");
        Serial.println("SIM7000 Berhasil ON");
        i=10;
      }
    }
  }

}

void setNBIOT()
{
  if (sendCommand("AT+CNMP=38\r\n","OK")) Serial.println("Setting LTE OK!");
  delay(500);
  if (sendCommand("AT+CMNB=2\r\n","OK")) Serial.println("Setting NBIOT OK!");
}

void setGSM()
{
  if (sendCommand("AT+CNMP=13\r\n","OK")) Serial.println("Setting GSM OK!");
  delay(500);
  if (sendCommand("AT+CMNB=3\r\n","OK")) Serial.println("Setting GPRS OK!");
}

void checkStatusConnection()
{
    char SIMbuffer[100];
    cleanBuffer(SIMbuffer,100);
    SIM7000.write("AT+CIPSTATUS\r\n");
    readBuffer(SIMbuffer,100,1,1);
//    Serial.println("Response : " + (String)SIMbuffer);
    if(NULL != strstr(SIMbuffer,"PDP DEACT")) SIM7000.write("AT+CIPSHUT\r\n");
    if(NULL != strstr(SIMbuffer,"IP START")) SIM7000.write("AT+CIICR\r\n");
    if(NULL != strstr(SIMbuffer,"IP INITIAL")) SIM7000.write("AT+CSTT=\"nb1internet\"\r\n");
    if(NULL != strstr(SIMbuffer,"IP GPRSACT")) SIM7000.write("AT+CIFSR\r\n");
    if(NULL != strstr(SIMbuffer,"TCP CLOSED")) SIM7000.write("AT+CIPSHUT\r\n");
    if(NULL != strstr(SIMbuffer,"IP STATUS")) SIM7000.write("AT+CIPSTART=\"TCP\",\"platform-iot.unnes.ac.id\",\r\n")
    if(NULL != strstr(SIMbuffer,"CONNECT OK"))
    {
      statusKoneksi=true;
      Serial.println("CONNECT OK!!");//SIM7000.write("AT+CIPSEND\r\n");
    }

}

void sendToAntares(String dataSend)
{
  //180.250.117.125
    String dataXSend = "{\"m2m:cin\": {\"con\": \"{"+dataSend+"}\"}}";
//    Serial.println(dataXSend);
    delay(1000);
    SIM7000.write("AT+CIPSEND\r\n");
    delay(1000);
    SIM7000.print("POST /~/antares-cse/cnt-569059221 HTTP/1.1\r\nHost: platform-iot.unnes.ac.id \r\n");
    SIM7000.print("Accept: application/json\r\nContent-Length: "+(String)dataXSend.length()+"\r\n");
    SIM7000.print("Content-Type: application/json;ty=4\r\n");
    SIM7000.print("X-M2M-Origin: "+accessKey+"\r\n\r\n");
    SIM7000.print(dataXSend);
    delay(100);
    SIM7000.write(0x1A);
    Serial.println("Send OK");
}

void startConnection()
{
  if (sendCommand("AT+CSTT=\"nb1internet\"\r\n","OK")) Serial.println("Setting APN OK!");
}

void initSIM7000 ()
{
  SIM7000.begin(9600);
  pinMode(PWRKEY,OUTPUT);
  SIM7000.write(0x1A);
  checkSIM7000();
  setGSM();
  delay(500);
  if (sendCommand("AT+CGDCONT=1,\"IP\",\"nb1internet\"","OK")) Serial.println("CGD OK!");
  delay(1000);
}
B. AT-Command POST Data
AT+CNMP=38<CR><LF>
AT+CMNB=2<CR><LF>
AT+CPSI?<CR><LF>
AT+CGDCONT=1,"IP","nb1internet"<CR><LF>
AT+CSTT="nb1internet"<CR><LF>
AT+CIICR<CR><LF>
AT+CIFSR<CR><LF>
AT+CIPSTART="TCP","platform-iot.unnes.ac.id"
AT+CIPSEND

POST /~/antares-cse/antares-id/YOUR-APPLICATION-NAME/YOUR-DEVICE-NAME HTTP/1.1<CR><LF>
Host: platform-iot.unnes.ac.id<CR><LF>
Accept: application/json<CR><LF>
Content-Length: 36<CR><LF>
Content-Type: application/json;ty=4<CR><LF>
X-M2M-Origin: YOUR-ACCESS-KEY<CR><LF><CR><LF>
{"m2m:cin": {"con": "{\"test\":1}"}}<SUB> 
C. AT-Command GET Data
AT+CNMP=38<CR><LF>
AT+CMNB=2<CR><LF>
AT+CPSI?<CR><LF>
AT+CGDCONT=1,"IP","nb1internet"<CR><LF>
AT+CSTT="nb1internet"<CR><LF>
AT+CIICR<CR><LF>
AT+CIFSR<CR><LF>
AT+CIPSTART="TCP","platform-iot.unnes.ac.id",<CR><LF>
AT+CIPSEND<CR><LF>

GET /~/antares-cse/antares-id/YOUR-APPLICATION-NAME/YOUR-DEVICE-NAME/la HTTP/1.1<CR><LF>
Host: 180.250.117.125<CR><LF>
Accept: application/json<CR><LF>
Content-Type: application/json;ty=4<CR><LF>
X-M2M-Origin: YOUR-ACCESS-KEY<CR><LF><CR><LF><SUB>