Semua Tentang Belajar Teknologi Digital Dalam Kehidupan Sehari - Hari

  • IC Timer 555 yang Multifungsi

    IC timer 555 adalah sirkuit terpadu (chip) yang digunakan dalam berbagai pembangkit timer, pulsa dan aplikasi osilator. Komponen ini digunakan secara luas, berkat kemudahan dalam penggunaan, harga rendah dan stabilitas yang baik

  • Ayo Migrasi TV Digital

    Kami bantu anda untuk memahami lebih jelas mengenai migrasi tv digital, apa sebabnya dan bagaimana efek terhadap kehidupan. Jasa teknisi juga tersedia dan siap membantu instalasi - setting perangkat - pengaturan antena dan distribusi televisi digital ke kamar kos / hotel

  • Bermain DOT Matrix - LOVEHURT

    Project Sederhana dengan Dot Matrix dan Attiny2313. Bisa menjadi hadiah buat teman atau pacarmu yang ulang tahun dengan tulisan dan animasi yang dapat dibuat sendiri.

  • JAM DIGITAL 6 DIGIT TANPA MICRO FULL CMOS

    Jika anda pencinta IC TTL datau CMOS maka project jam digital ini akan menunjukkan bahwa tidak ada salahnya balik kembali ke dasar elektronika digital , sebab semuanya BISA dibuat dengan teknologi jadul

  • Node Red - Kontrol Industri 4.0

    Teknologi kontrol sudah melampaui ekspektasi semua orang dan dengan kemajuan dunia elektronika, kini semakin leluasa berkreasi melalui Node Red

Tampilkan postingan dengan label antares. Tampilkan semua postingan
Tampilkan postingan dengan label antares. Tampilkan semua postingan

Sabtu, 15 Juni 2024

IOT - GPS dengan bantuan apps smartphone netGPS

 


Kalau kita kembali belajar IOT di awal-awal maka akan dikenalkan dengan yang namanya piramida IOT. Bagian paling ujung dari piramida ini adalah pelaporan ke orang yang akan membutuhkan informasi melalui IOT. Salah satu contoh pelaporan adalah GIS (Geographic Information System) dimana data yang diambil oleh sensor dan dikirimkan secara IOT akan ditampilkan pada peta. Tentunya cuap-cuap saya diawal ini akan terasa omong kosong kalau alat GPS nya seperti yang pernah saya bahas disini, susah di koneksikan...ala mak jang !

Sadar atau tidak sadar, pada kenyataannya, smartphone yang kita pakai mesti ada penerima GPS lho mas broo ! nah..benda yang selalu kita pegang tiap saat ini seharusnya dan pastinya dapat memberikan koordinat bujur dan lintang selama berada pada lokasi terbuka. Masalahnya bagaimana cara membagi pembacaan hardware GPS pada smartphone android ke perangkat IOT? 



Aplikasi android yang saya gunakan adalah netGPS yang akan mengirimkan data GPS secara TCP (berfungsi sebagai TCP server) dan mengirimkan sebagai teks log dari berbagai macam standar data GPS yang digunakan oleh smartphone android. Aplikasi ini cukup jadul jadi jika ingin menginstallnya harap gunakan cara selain google play jika ternyata HP kamu ditolak.




Contoh standar pembacaan teks NMEA (National Marine Electronics Association)  yang saya gunakan sederhana saja cukup sebaris ( karena saya butuhnya hanya koordinat saja) dan saya pilihkan standar $GPRMC. Saya butuh membayar 15ribu rupiah ke aplikasi ini untuk dapat memilih secara custom pesannya seperti pada gambar diatas. Dari sebuah website saya dapatkan standar pesannya adalah sebagai berikut:


$GPRMC

Recommended minimum specific GPS/Transit data

eg1. $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
eg2. $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68

225446 Time of fix 22:54:46 UTC A Navigation receiver warning A = OK, V = warning 4916.45,N Latitude 49 deg. 16.45 min North 12311.12,W Longitude 123 deg. 11.12 min West 000.5 Speed over ground, Knots 054.7 Course Made Good, True 191194 Date of fix 19 November 1994 020.3,E Magnetic variation 20.3 deg East *68 mandatory checksum

Dan kemudian saya parsing data dari teks $GPRMC, namun karena saya tukang koding abal-abal, butuh bantuan chatGPT dan hasilnya saya diberikan script yang sangat jitu !


#include <ESP8266WiFi.h>

const char* ssid = "YourHotspotSSID";
const char* password = "YourHotspotPassword";

// Example NMEA GPRMC string
String nmeaString = "$GPRMC,043652,A,0713.64753,S,11243.78,E,,,290524,000.7,E,A*33";

void setup() {
  Serial.begin(115200);
  parseNMEA(nmeaString);
}

void loop() {
  // No code needed here for this example
}

double convertNMEACoordinate(String nmeaCoord, bool isLongitude) {
  // Determine the length of degrees part (3 for longitude, 2 for latitude)
  int degreesLength = isLongitude ? 3 : 2;
  // Extract the degrees part
  double degrees = nmeaCoord.substring(0, degreesLength).toInt();
  // Extract the minutes part and convert to decimal
  double minutes = nmeaCoord.substring(degreesLength).toFloat();
  degrees += minutes / 60.0;
  return degrees;
}

void parseNMEA(String nmea) {
  // Check if the string starts with "$GPRMC"
  if (nmea.startsWith("$GPRMC")) {
    // Buffer for each field in the NMEA string
    char buf[75];
    nmea.toCharArray(buf, 75);

    // Tokenize the NMEA string by comma
    char* token = strtok(buf, ",");
    
    // Index to track the position in the NMEA string
    int index = 0;
    
    // Variables to hold parsed data
    String time, status, latitude, latitudeDirection;
    String longitude, longitudeDirection, date;

    while (token != NULL) {
      switch (index) {
        case 1: time = String(token); break;
        case 2: status = String(token); break;
        case 3: latitude = String(token); break;
        case 4: latitudeDirection = String(token); break;
        case 5: longitude = String(token); break;
        case 6: longitudeDirection = String(token); break;
        case 9: date = String(token); break;
      }
      token = strtok(NULL, ",");
      index++;
    }

    // Convert latitude and longitude
    double latitudeDegrees = convertNMEACoordinate(latitude, false);
    if (latitudeDirection == "S") {
      latitudeDegrees = -latitudeDegrees;
    }

    double longitudeDegrees = convertNMEACoordinate(longitude, true);
    if (longitudeDirection == "W") {
      longitudeDegrees = -longitudeDegrees;
    }

    // Prepare buffer for formatted longitude
    char longitudeStr[20];
    dtostrf(longitudeDegrees, 1, 7, longitudeStr);

    // Prepare buffer for the final concatenated string
    char resultStr[40];  // Adjust size based on expected combined length
    strcpy(resultStr, "latitude ");
    strcat(resultStr, longitudeStr);

    // Print the parsed data
    Serial.println("Time: " + time);
    Serial.println("Status: " + status);
    Serial.print("Latitude: ");
    Serial.println(latitudeDegrees, 7);
    Serial.print("Longitude: ");
    Serial.println(longitudeDegrees, 7);
    Serial.print("Concatenated String: ");
    Serial.println(resultStr);  // Print concatenated string
    Serial.println("Date: " + date);

    // Convert and print additional data if necessary
    // Convert time to HH:MM:SS format
    String hours = time.substring(0, 2);
    String minutes = time.substring(2, 4);
    String seconds = time.substring(4, 6);
    Serial.println("Formatted Time: " + hours + ":" + minutes + ":" + seconds);

    // Convert date to DD/MM/YY format
    String day = date.substring(0, 2);
    String month = date.substring(2, 4);
    String year = date.substring(4, 6);
    Serial.println("Formatted Date: " + day + "/" + month + "/" + year);
  } else {
    Serial.println("Invalid NMEA string");
  }
}

Penjelasan:

1. Function konversi NMEA  (convertNMEACoordinate): 

  • Mengonversi koordinat NMEA ke format derajat desimal.


2. Function Penguraian (parseNMEA):

  • Memberi token pada string NMEA dan mengekstrak bidang yang relevan.
  • Mengonversi lintang dan bujur menjadi derajat desimal.
  • Menyesuaikan tanda berdasarkan arah (N/S untuk garis lintang, E/W untuk garis bujur).

3. Memformat Bujur/Lintang:

  • Fungsi dtostrf memformat garis bujur/lintang menjadi string dengan 7 tempat desimal.

4. Concatenate string:

  • Buffer resultStr disiapkan untuk menampung hasil gabungan.
  • Fungsi strcpy menginisialisasi resultStr dengan label "latitude".
  • Fungsi strcat menambahkan string garis bujur yang diformat ke resultStr.

5. Print / output :

  • String gabungan dicetak ke Serial Monitor.

Kode ini mem-parsing string NMEA GPRMC, mengubah garis lintang dan garis bujur menjadi derajat desimal, memformat garis bujur menjadi string dengan 7 tempat desimal, dan menggabungkannya dengan label longitude dan latitude. String gabungan kemudian dicetak pada serial monitor.




Untuk menerima pesan $GPRMC dari smartphone, saya akan membuat ESP8266-wemos saya sebagai client dan terhubung dengan hotpsot dari Smartphone yang saya gunakan. Hal ini akan memudahkan saya karena Smartphone saya fungsikan sebagai TCP server di IP Gatewaynya ( 192.168.43.1) pada port yg saya pilih 8088. IP ini adalah IP umum yang digunakan oleh hotspot smartphone android, namun sudah saya akali pada script agar TCP server yang di-bind-kan adalah IP gatewaynya, selanjutnya menunggu data GPS berupa teks $GPRMC.


/* GPS SMARTPHONE (netGPS Android) to ESP8266
Hardware : DHT 11 & OLED SSD1306 128x64
This script is incomplete, you should add data sending 
via IOT protocol, MQTT, HTTP  or Lora
www.aisi555.com 
*/


#include <ESP8266WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"


#define SCREEN_WIDTH 128 // display display width, in pixels
#define SCREEN_HEIGHT 64 // display display height, in pixels

#define DHT_PIN D4   // pin sensor DS18B20


#define display_RESET     -1 // Reset pin 
#define SCREEN_ADDRESS 0x3C ///address i2c oled 
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, display_RESET);



#define DHTTYPE DHT11  //Sensor DHT11
DHT dht(DHT_PIN, DHTTYPE); 


const char* ssid = "myHotspot";
const char* password = "99999999";

// Server details
IPAddress serverIP;  // Define server IP address (gateway IP)
const uint16_t serverPort = 8088;

WiFiClient client;

bool gpsOK = false;
char longitudeStr[20];
char latitudeStr[20];

void setup() {
  Serial.begin(9600);
   Serial.println("");
  Serial.println(F(" ...www.aisi555.com GPS From Smartphone ...."));

    // initialize display display with address 0x3C for 128x64
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }

  delay(2000);         // wait for initializing
  display.clearDisplay(); // clear display

  
  display.setTextSize(1);          // text size
  display.setTextColor(WHITE);     // text color
  
  displayDisplayCenter("www.aisi555.com", 4);
  displayDisplayCenter("Connecting to wifi.. ",56);

  
    // Connect to Wi-Fi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  delay(1000);



  display.clearDisplay(); // clear display
  displayDisplayCenter("www.aisi555.com", 4);
  displayDisplayCenter("Connecting to Aps..",56);
  
  IPAddress gatewayIP = WiFi.gatewayIP();
  serverIP = gatewayIP;  // Use the gateway IP as server IP

  // Attempt to connect to the server
  if (!client.connect(serverIP, serverPort)) {
    Serial.println("Connection to server failed");
  } else {
    Serial.println("Connected to server");
  }


  dht.begin();

  
}


void writeTempHumid(){ //kirim data pengukuran DHT
   
 
    float h = dht.readHumidity();
    float t = dht.readTemperature();

    if (isnan(h) || isnan(t)) {
      Serial.println("Failed to read from DHT sensor!");
    }
    
    Serial.print("Humidity: "); 
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: "); 
    Serial.print(t);
    Serial.println(" °C ");
  
    String tempString;
  
    tempString  = String(t, 1); // 
    tempString += (char)247;
    tempString += "C | ";
    tempString += String(h, 0);;
    tempString += " %";
  
    //biar ketumpuk hitam dulu biar bersih

    display.fillRect(0,17,128,48,BLACK);
    
  //lanjut tulis warna putih
   display.setTextColor(WHITE);
   
   String latString;
   latString  = "Lat: ";
   latString += String(latitudeStr);
   displayDisplayCenter(latString,20);

   String lonString;
   lonString  = "Lon: ";
   lonString += String(longitudeStr);
   displayDisplayCenter(lonString,30);
   displayDisplayCenter(tempString,42);

   if(gpsOK)displayDisplayCenter("GPS is Connected",56);
   else displayDisplayCenter("GPS disconnected !",56);


   /* ADD YOUR IOT DATA SENDING SCRIPT BELOW  */
   
  }


void loop() {

  if (runEvery(5000)) {
    writeTempHumid();
  }
  
  if (client.connected()) {
    // Check if data is available to read
    
    gpsOK=true;
    
    while (client.available()) {
      String receivedData = client.readStringUntil('\n');  // Read data until newline
      Serial.print("Received data: ");
      Serial.println(receivedData);

      // Process the received data
      // Add your data processing logic here

      parseNMEA(receivedData);
    }
  } else {
    // Reconnect if connection is lost
    if (!client.connect(serverIP, serverPort)) {
      Serial.println("Reconnection to server failed");
      gpsOK=false;
      delay(1000);  // Wait before retrying
    } else {
      Serial.println("Reconnected to server");
    }
  }
}

//function agar tulisan rata tengah (center)

void displayDisplayCenter(String text, int posisi) {
  int16_t x1;
  int16_t y1;
  uint16_t width;
  uint16_t height;

  display.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);

  display.setCursor((SCREEN_WIDTH - width) / 2, posisi);
  display.println(text); // text to display
  display.display();
}



double convertNMEACoordinate(String nmeaCoord, bool isLongitude) {
  // Determine the length of degrees part (3 for longitude, 2 for latitude)
  int degreesLength = isLongitude ? 3 : 2;
  // Extract the degrees part
  double degrees = nmeaCoord.substring(0, degreesLength).toInt();
  // Extract the minutes part and convert to decimal
  double minutes = nmeaCoord.substring(degreesLength).toFloat();
  degrees += minutes / 60.0;
  return degrees;
}

void parseNMEA(String nmea) {
  // Check if the string starts with "$GPRMC"
  if (nmea.startsWith("$GPRMC")) {
    // Buffer for each field in the NMEA string
    char buf[75];
    nmea.toCharArray(buf, 75);

    // Tokenize the NMEA string by comma
    char* token = strtok(buf, ",");
    
    // Index to track the position in the NMEA string
    int index = 0;
    
    // Variables to hold parsed data
    String time, status, latitude, latitudeDirection;
    String longitude, longitudeDirection,date;

    while (token != NULL) {
      switch (index) {
        case 1: time = String(token); break;
        case 2: status = String(token); break;
        case 3: latitude = String(token); break;
        case 4: latitudeDirection = String(token); break;
        case 5: longitude = String(token); break;
        case 6: longitudeDirection = String(token); break;
        case 9: date = String(token); break;
      }
      token = strtok(NULL, ",");
      index++;
    }

    // Convert latitude and longitude
    double latitudeDegrees = convertNMEACoordinate(latitude, false);
    if (latitudeDirection == "S") {
      latitudeDegrees = -latitudeDegrees;
    }

    double longitudeDegrees = convertNMEACoordinate(longitude, true);
    if (longitudeDirection == "W") {
      longitudeDegrees = -longitudeDegrees;
    }

    //kirim ke display 
    dtostrf(longitudeDegrees, 1, 7, longitudeStr);
    dtostrf(latitudeDegrees, 1, 7, latitudeStr);
    

    // Print the parsed data
    Serial.println("Time: " + time);
    Serial.println("Status: " + status);
    Serial.print("Latitude: ");
    Serial.println(latitudeDegrees, 7);
    Serial.print("Longitude: ");
    Serial.println(longitudeDegrees, 7);
    Serial.println("Date: " + date);

    // Convert and print additional data if necessary
    // Convert time to HH:MM:SS format
    String hours = time.substring(0, 2);
    String minutes = time.substring(2, 4);
    String seconds = time.substring(4, 6);
    Serial.println("Formatted Time: " + hours + ":" + minutes + ":" + seconds);

    // Convert date to DD/MM/YY format
    String day = date.substring(0, 2);
    String month = date.substring(2, 4);
    String year = date.substring(4, 6);
    Serial.println("Formatted Date: " + day + "/" + month + "/" + year);
  } else {
    Serial.println("Invalid NMEA string");
  }
}

//timer
boolean runEvery(unsigned long interval)
{
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    return true;
  }
  return false;
}

Dan jika script kamu benar dapat mengirimkan data GPS menggunakan lorawan seperti berikut :
 


Dan kemudian pengolahan data GIS nya kita dapat manfaatkan google maps atau yang secara online yaitu kepler.gl (lihat gambar paling atas). Keberhasilan pengaplikasian trik saya ini sangat bergantung pada sensitifitas GPS receiver pada smartphone, sehingga syarat mutlak adalah HP kamu berada pada lokasi yg open space / langit terbuka.

SELAMAT MENCOBA
Share:

Senin, 27 Mei 2024

LoRaWan Antares - Menampilkan Grafik di Aplikasi Android IOT MQTT PANEL

 



Kesulitan mendasar kembali ditemukan saat menggunakan LoRaWan telkom ber platform Antares, padahal ini merupakan ujung "raja terakhir" dari setiap kali bermain IOT. Bagian ini adalah membuat tampilan menarik dari hanya sekedar teks uplink dari console antares, namun beberapa kali saya menemukan anak-anak mahasiswa kesulitan juga dibagian awal. Jadi library yang saya gunakan mungkin satu-satunya solusi yang berhasil mengirimkan LoRaWan ke antares (Guaya puoooll). Heheheh... baca dulu deh disini ya...



Lalu ada lagi sambungan setelah mereka (pembaca blog) saya ajari kirim-kiriman, ehhh pengolahan datanya menjadi grafik belum bisa, jadi nanggung banget ! Kalau dilihat dari fasilitas chart di antares pada menu widget...yakkk ampunnn..coba deh lihat..



Belum dapat dinamakan grafik kalau seperti ini, karena data lorawan yang masuk belum sama sekali diparsing. Kesusahan kali ya membuat json parser data seperti ini di php ? Ingat dulu pembahasan saya disini ? baca dulu deh.. 

Akses data antares yang di subscribe via MQTT selalu ada pada 1 topic :  /oneM2M/resp/antares-cse/access:key/json  

Uplink perangkat LoRaWan akan menghasilkan output mqtt seperti berikut ini :


{
   "m2m:rsp" : {
      "rsc" : 2001,
      "rqi" : "123456",
      "pc" : {
         "m2m:cin" : {
            "rn" : "cin_tuYp3j-bTIy5fUm4",
            "ty" : 4,
            "ri" : "/antares-cse/cin-tuYp3j-bTIy5fUm4",
            "pi" : "/antares-cse/cnt-661860573",
            "ct" : "20240527T095651",
            "lt" : "20240527T095651",
            "st" : 0,
            "cnf" : "message",
            "cs" : 296,
            "con" : "{\"type\": \"uplink\",\"port\": 1,\"data\": { \"suhu\": 27.81,\"humi\": 75},\"counter\": 2,\"devEui\": \"4fd4a31429711655\",\"radio\": {\"gps_time\": 1400813829,\"hardware\": {\"snr\": -17.6,\"rssi\": -116},\"datarate\": 0,\"modulation\": {\"bandwidth\": 125000,\"spreading\": 12},\"delay\": 0.060113125618098,\"freq\": 922,\"size\": 40}}"
         }
      },
      "to" : "",
      "fr" : "/antares-cse"
   }
}

Data yang berguna ada di "con" sehingga harus parsing json dulu ...nah dari pada bingung, kita belajar dulu menerima data yg masuk dari LoRaWan menggunakan python sebagai penerima MQTT nya. Jangan lupa untuk menginstall library Paho-Mqtt, dimana kalau menggunakan google colab bisa install versi 1.6.0 saja yang lebih sederhana. Script ini secara realtime akan menerima data masuk jika LoRaWan menerima uplink dari device.


!pip install paho-mqtt==1.6.0



from paho.mqtt import client as mqtt_client
import time
from time import sleep
from random import randrange


# Inisialisasi broker antares
broker_address="mqtt.antares.id"
broker_port=1883

#sesuaikan dengan acces key antares kamu
antareskey= "access:key"
antaresdevice = "aplikasi/device"

#topik subscribe hanya 1 saja untuk tiap akun
topicsubantares = f'/oneM2M/resp/antares-cse/{antareskey}/json'


def connect_mqtt() -> mqtt_client:
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)

    client= mqtt.Client(f'aisi555-client-{randrange(0,1000)}') 
    client.on_connect = on_connect
    client.connect(broker_address, broker_port)
    return client


def subscribe(client: mqtt_client):
    def on_message(client, userdata, msg):
        print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")

    client.subscribe(topicsubantares)
    client.on_message = on_message


def run():
    client = connect_mqtt()
    subscribe(client)
    client.loop_forever()


if __name__ == '__main__':
    run()


Hasil dari script diatas akan menampilkan semua data yang masuk, memang ini kekurangan oneM2M dimana tidak melayani sub mqtt per device. Hasilnya kita harus parsing per device di "pi:" lalu di bandingkan dengan device yang sedang kita olah datanya.



Sekalian saja saya kemudian akan parsing "con" dan mengambil beberapa data seperti suhu, humi, snr dan rssi. Scriptnya seperti ini :


from paho.mqtt import client as mqtt_client
import time
from time import sleep
from random import randrange
import json


# Inisialisasi broker
broker_address="mqtt.antares.id"
broker_port=1883

antareskey= "access:key"
antaresdevice = "/antares-cse/device-uri" 

topicsubantares = f'/oneM2M/resp/antares-cse/{antareskey}/json'


def connect_mqtt() -> mqtt_client:
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)

    client= mqtt.Client(f'aisi555-client-{randrange(0,1000)}') 
    client.on_connect = on_connect
    client.connect(broker_address, broker_port)
    return client


def subscribe(client: mqtt_client):
    def on_message(client, userdata, msg):
        #print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
        olah_data(msg.payload.decode())
    client.subscribe(topicsubantares)
    client.on_message = on_message

def olah_data(datanya):
  # Parsing json
  data = json.loads(datanya)
  penerima = data["m2m:rsp"]["pc"]["m2m:cin"]["pi"] 
  # ambil con untuk data
  con_json_str = data["m2m:rsp"]["pc"]["m2m:cin"]["con"]  
  # Parse the JSON string inside "con"
  con_data = json.loads(con_json_str)
  
  print(f"Terima dari device : {penerima}")
  print("Suhu:", con_data["data"]["suhu"], " Celcius")
  print("kelembaban:", con_data["data"]["humi"], " %")
  print("Radio SNR:", con_data["radio"]["hardware"]["snr"])
  print("Radio RSSI:", con_data["radio"]["hardware"]["rssi"]) 


def run():
    client = connect_mqtt()
    subscribe(client)
    client.loop_forever()


if __name__ == '__main__':
    run()
	


Tapi masih belum juga bisa menampilkan grafik ke IOT MQTT PANEL seperti yang sering saya bahas setiap membuat proyek IOT disini.  Untuk itu saya membuat bridge untuk menjembatani MQTT diantara antares dan aplikasi melalui broker mqtt gratisan HIVEMQ. Wahh benar-benar script python saya berfungsu jadi bridge ini, dimana saya melakukan koneksi ke 2 buah broker, antares saya sub dan hivemq saya pub.  Saya kutipkan beberapa  potongan penting:




def olah_data(datanya):
  # Parsing json
  data = json.loads(datanya)
  penerima = data["m2m:rsp"]["pc"]["m2m:cin"]["pi"] 
  # ambil con untuk data
  con_json_str = data["m2m:rsp"]["pc"]["m2m:cin"]["con"]  
  # Parse the JSON string inside "con"
  con_data = json.loads(con_json_str)
  
 
  if(penerima == antaresdevice):
    print(f"Terima dari device : {penerima}")
    print("Suhu:", con_data["data"]["suhu"], " Celcius")
    print("Kelembaban:", con_data["data"]["humi"], " %")
    print("Radio SNR:", con_data["radio"]["hardware"]["snr"])
    print("Radio RSSI:", con_data["radio"]["hardware"]["snr"]) 
    print("Kirim ke HiveMQ !")
    hivemq.publish("/aisi555/suhu", con_data["data"]["suhu"])
    hivemq.publish("/aisi555/humi", con_data["data"]["humi"])
    hivemq.publish("/aisi555/snr", con_data["radio"]["hardware"]["snr"])
    hivemq.publish("/aisi555/rssi", con_data["radio"]["hardware"]["snr"])


def run():
    #konek ke antares
    client = connect_mqtt()
    #konek ke Hivemq
	global hivemq
    hivemq = connect_hivemq()
    #subscribe ke antares
	subscribe(client)
    client.loop_forever()


Hasilnya seperti ini, langsung bisa dari Sensor ==> LoRaWan Antares ==> google colab ==> grafik apk IOT MQTT PANEL (gambar paling atas) secara real time. Script saya potong dan seperti biasa kontak saya jika berminat belajar lebih dalam lagi. 








Share:

Minggu, 19 Mei 2024

LoRaWan TTGO - ESP32 - Telkom Antares

 



Breaking news: Telkom akan melakukan migrasi LoRaWan ke Telkomiot.id, Silahkan baca disini


Setelah beberapa tahun yang lalu blog ini berhasil mengoprek "LoRaWan" milik Telkom-Antares, ternyata nasib library loraid atau lorawan antares kelihatannya tidak di maintenance lagi. Walaupun tahun 2023 ada update di website nya antares tapi ini khusus untuk hardware yang di desain dan bekerjasama dengan antares langsung. Saya menjadi sedikit khawatir satu hari sinyal lorawan di telkom antares menghilang atau berpindah pemilik seperti terkejutnya saya melihat platform iot telkomiot (telkomiot.id) yang tiba-tiba hadir kembali namun masih gagal konek.

Beberapa mahasiswa masih rajin menghubungi saya untuk bertanya hal library ini, namun tetap saya sarankan mengikuti teknik saya menggunakan library yang walau belum lengkap (menurut penyusunnya) namun terbukti bisa mengirim data, seperti yang dilihat pada tulisan saya sebelumnya disini.



Mikrokontroler yang saya gunakan dulu adalah arduino, dan sudah berhasil mengirim data secara benar secara radio LoRaWan lanjut masuk ke platform antares. Masalahnya ada pembaca yang gagal kirim ketika menggunakan mikrokontroller modern ESP32 semacam TTGO yang sekarang makin terjangkau. "LoRa Init Failed" begitu katanya ! Yahh kalau ini pasti ada hubugannya dengan error di koneksi SPI.




Kebetulan saja saya ada project yang menggunakan TTGO dan benar saja koding saya terdahulu tidak jalan di TTGO, analisa saya karena ESP32 memiliki 2 buah port SPI, sehingga untuk SPI.begin() nya harus dilakukan penulisan port MISO, MOSI, SCK dan CS. Dan langsung saja saya kreasikan beserta display Oled nya TTGO yang walau kurang berguna (karena boros daya) namun untuk sekelas proyekan atu tugas kampus bisa memperindah tampilan.

Modul TTGO LoRa adalah perangkat yang dirancang untuk memfasilitasi pengembangan aplikasi IoT dengan kemampuan komunikasi jarak jauh yang andal dan konsumsi daya rendah. Berikut ini adalah fasilitas utama yang ditawarkan oleh modul TTGO LoRa serta informasi mengenai frekuensi kerjanya.


Fasilitas Modul TTGO LoRa

  • Mikrokontroler ESP32: Modul ini dilengkapi dengan mikrokontroler ESP32 yang memiliki dual-core CPU, Wi-Fi, dan Bluetooth. ESP32 adalah salah satu mikrokontroler yang paling populer di kalangan pengembang karena kemampuannya yang serbaguna dan efisiensi daya.
  • Chip LoRa SX1276/78: Chip LoRa ini memungkinkan komunikasi jarak jauh dengan konsumsi daya yang rendah. Chip ini terkenal karena kinerjanya yang stabil dan jangkauan yang luas.
  • Antena LoRa: Modul ini dilengkapi dengan antena LoRa eksternal yang meningkatkan kualitas sinyal dan jangkauan komunikasi.
  • Layar OLED: Banyak varian TTGO LoRa dilengkapi dengan layar OLED kecil (biasanya 0.96 inci) yang dapat digunakan untuk menampilkan informasi seperti status koneksi, data sensor, atau informasi lainnya.
  • Port USB: Modul ini memiliki port USB untuk kemudahan pemrograman dan daya, memungkinkan pengembang untuk dengan mudah mengunggah kode dan menguji perangkat mereka.
  • Slot Kartu SD: Beberapa varian TTGO LoRa memiliki slot kartu SD untuk penyimpanan data tambahan, memudahkan penyimpanan log data dalam aplikasi yang memerlukan pencatatan jangka panjang.
  • GPIO dan Pin I/O Analog: Modul ini menyediakan beberapa General Purpose Input/Output (GPIO) dan pin input/output analog yang dapat digunakan untuk menghubungkan berbagai sensor dan aktuator.
  • Dukungan Perangkat Lunak: TTGO LoRa kompatibel dengan Arduino IDE, PlatformIO, dan berbagai alat pengembangan lainnya. Hal ini memudahkan pengembang untuk memulai dan membuat prototipe proyek IoT mereka.


Frekuensi Kerja Modul TTGO LoRa


Modul TTGO LoRa bekerja pada beberapa frekuensi yang disesuaikan dengan peraturan komunikasi di berbagai wilayah. Frekuensi utama yang digunakan adalah:


  • 433 MHz: Frekuensi ini sering digunakan di wilayah Eropa dan Asia.
  • 868 MHz: Digunakan terutama di Eropa, frekuensi ini sesuai dengan regulasi ISM (Industrial, Scientific, and Medical).
  • 915 MHz: Frekuensi ini umum digunakan di Amerika Utara dan Australia.
  • 923 MHZ : Indonesia menggunakand Band Plan AS_923_2

Pemilihan frekuensi yang tepat tergantung pada wilayah penggunaan dan regulasi lokal. Modul TTGO LoRa yang berbeda dapat disesuaikan dengan frekuensi yang sesuai dengan kebutuhan proyek dan kepatuhan regulasi.


Konfigurasi PIN seperti berikut :


#define SCK 5

#define MISO 19

#define MOSI 27

#define SS 18

#define RST 14

#define DIO0 26


//OLED pins

#define OLED_SDA 4

#define OLED_SCL 15 

#define OLED_RST 16

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels


Hasilnya ketika saya mendekati BTS lorawan, maklum di depan rumah sejak setahun lalu ada bangunan tinggi yang menghalangi pengiriman, seperti berikut ini :



Saya bagi script sederhana untuk pengiriman LoRaWan pada TTGO-ESP32 yang bisa membantu kamu belajar. Sebaiknya baca-baca dulu pembahasan LoRaWan sebelumnya agar bisa paham library yang saya pake.



/*

LoRaWan - Antares - ESP32(TTGO)
by www.aisi555.com
2024 


*/

//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>
#include <LoRaWanPacket.h>

//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//Gunakan pin ini untuk TTGO, sesuaikan jika berbeda
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26

//OLED pins
#define OLED_SDA 4
#define OLED_SCL 15 
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);



//Sesuaikan dev address dan key device LoRa
const char *devAddr = "aaaaaaaa";
const char *nwkSKey = "bbbbbbbbbbbbbbbb0000000000000000";
const char *appSKey = "0000000000000000cccccccccccccccc";


struct LoRa_config
{
  long Frequency;
  int SpreadingFactor;
  long SignalBandwidth;
  int CodingRate4;
  bool enableCrc;
  bool invertIQ;
  int SyncWord;
  int PreambleLength;
};


//Scanning frekuensi satu persatu di BAND AS_923_2

long LoRa_frek_INA_923_start = 921200000 ;
long LoRa_frek_INA_923_end   = 922600000 ;
long LoRa_frek_step = 200000;
long LoRa_frek_INA_923 = LoRa_frek_INA_923_start;
                                     
static LoRa_config txLoRa = {LoRa_frek_INA_923, 12, 125000, 5, true, false, 0x34, 8};


void LoRa_setConfig(struct LoRa_config config)
{
  LoRa.setFrequency(LoRa_frek_INA_923);
  LoRa.setSpreadingFactor(config.SpreadingFactor);
  LoRa.setSignalBandwidth(config.SignalBandwidth);
  LoRa.setCodingRate4(config.CodingRate4);
  if (config.enableCrc)
    LoRa.enableCrc();
  else
    LoRa.disableCrc();
  if (config.invertIQ)
    LoRa.enableInvertIQ();
  else
    LoRa.disableInvertIQ();
  LoRa.setSyncWord(config.SyncWord);
  LoRa.setPreambleLength(config.PreambleLength);
  LoRa.setTxPower(20); //max power ubah jika ingin irit

}

void LoRa_TxMode()
{
  LoRa_setConfig(txLoRa);
  LoRa.idle();
}


void setup() {
   //initialize Serial Monitor
  Serial.begin(9600);
  
  //reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, HIGH);
  
  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("LORAWAN AISI555");
  display.display();

  Serial.println("LoRaWan Antares Test");

  LoRaWanPacket.personalize(devAddr, nwkSKey, appSKey);

  //SPI LoRa pins
  SPI.begin(SCK, MISO, MOSI, SS);
  //setup LoRa transceiver module
  LoRa.setPins(SS, RST, DIO0);
  
  if (!LoRa.begin(txLoRa.Frequency)) {
    Serial.println("LoRa Gagal. Cek perkabelan kamu...");
    while (true);
  }

  Serial.println("LoRa init berhasil.");
  Serial.println();
  display.setCursor(0,10);
  display.println("LoRa Initializing OK!");
  display.display(); 

}

void loop() {
  if (runEvery(5000)) { // ganti interval kirim lorawan

    Serial.print("Send Message! frek = ");
    Serial.println(LoRa_frek_INA_923);
    
    
    LoRa_sendMessage();

    display.clearDisplay();
    display.setCursor(0,0);
    display.print("KIRIM LORAWAN AIS555");
    display.setCursor(0,20);
    display.print("frekuensi: ");
    
    float freku = LoRa_frek_INA_923/1000000.0;
    display.print(freku , 1);  
    display.print(" MHz ");
    display.display();



  if( LoRa_frek_INA_923 >= LoRa_frek_INA_923_end ) LoRa_frek_INA_923 = LoRa_frek_INA_923_start;
  else LoRa_frek_INA_923 += LoRa_frek_step;
  }

}


void LoRa_sendMessage()
{
  LoRa_TxMode();
  LoRaWanPacket.clear();
  LoRaWanPacket.print("coba kirim frek : ");
  LoRaWanPacket.print(String(LoRa_frek_INA_923));
  
  
  if (LoRaWanPacket.encode()) 
  {
    LoRa.beginPacket();
    LoRa.write(LoRaWanPacket.buffer(), LoRaWanPacket.length());
    LoRa.endPacket();
  }

  
}

boolean runEvery(unsigned long interval)
{
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    return true;
  }
  return false;
}
   
Share:

Senin, 18 Desember 2023

Antares Webhooks - Solusi Pengolahan Data Realtime Memanfaatkan Google Sheets

 



Tulisan ini merupakan kelanjutan dari pembahasan pengolahan data REALTIME antares menggunakan MQTT (dapat dibaca disini ). Lalu bagaimana jika pengolahan datanya dilakukan oleh script yang tidak mengenal event based seperti API ? Tenang saja ternyata tombol SUBSCRIBE pada console device antares merupakan fasilitas pengolahan data bernama WEBHOOK. Apa itu ? Mari kita tanya chatGPT.


Breaking news: Telkom akan melakukan migrasi LoRaWan ke Telkomiot.id, Silahkan baca disini


API (Application Programming Interface):


API (Application Programming Interface) adalah kumpulan aturan yang memungkinkan satu aplikasi perangkat lunak berinteraksi dengan aplikasi lainnya. API menyediakan cara bagi sistem perangkat lunak yang berbeda untuk berkomunikasi satu sama lain dengan mendefinisikan metode dan format data yang dapat digunakan aplikasi untuk meminta dan bertukar informasi. API bisa digunakan untuk mengambil data, melakukan tindakan, atau mengintegrasikan fungsionalitas dari satu sistem ke sistem lainnya. Biasanya melibatkan mekanisme permintaan-respons, di mana aplikasi mengirim permintaan data atau aksi ke API, dan API mengembalikan respons.


Webhook:

Webhook, di sisi lain, adalah mekanisme bagi aplikasi web untuk memberikan informasi secara real-time kepada aplikasi atau sistem lainnya. Berbeda dengan API yang bergantung pada aplikasi untuk melakukan permintaan informasi, webhook mengirim data secara otomatis dari satu aplikasi ke aplikasi lainnya ketika terjadi peristiwa atau pemicu tertentu. Webhook adalah cara bagi aplikasi untuk memberi tahu satu sama lain tentang peristiwa atau pembaruan tanpa memerlukan polling terus-menerus untuk informasi. Ketika peristiwa yang telah ditentukan terjadi, aplikasi yang meng-host webhook akan mengirim permintaan HTTP POST ke URL tertentu, biasanya berisi data yang relevan dengan peristiwa tersebut.


Perbedaan:

Perbedaan kunci antara API dan webhook terletak pada arah komunikasi dan mekanisme pemicu:

  • API umumnya melibatkan model permintaan-respons di mana aplikasi secara aktif meminta data atau aksi dari titik akhir yang telah ditentukan aplikasi lain.
  • Webhook beroperasi dalam model push, di mana data secara otomatis dikirim dari satu aplikasi ke aplikasi lain berdasarkan peristiwa atau pemicu tertentu tanpa perlu permintaan yang berkelanjutan.

Jadi, API digunakan untuk permintaan dan respons sesuai kebutuhan, sementara webhook digunakan untuk notifikasi peristiwa real-time dan berbagi data antar aplikasi.


Untuk mencobanya (pertama kali bagi saya) mari kita lanjutkan praktek simulasi data IOT - python dari google colab (tulisan saya sebelumnya) menuju kke antares, dan kemudian kita gunakan layanan testing webhookd bernama REQUESTCATCHER.


1. Buat alamat endpoint webhooks anda secara gratis di website requestcatcher.com



2. Masukkan endpoint webhooks di tombol subscribe pada console device antares. Dan masukkan seperti contoh pada gambar alamatnya https://ahocool.requestcatcher.com/test


 


3. Jalankan script simulasi pengiriman data suhu dan kelembaban pada google colab dan perhatikan data yang masuk pada console antares akan muncul juga pada alamat requestcatcher secara realtime.




Lalu bagaimana pengolahan datanya agar lebih berguna , secara endpoint nya memerlukan server dan pengolahanya pun di servercloud ? Tenang ! Ternyata google sheets memiliki fasilitas ekstensi / addons yang beranama "webhooks for sheets". Banyak video membahas cara registrasi dan setingnya, pada intinya ikuti langkah-langkah pada google sheets terutama pada bagian pengaktifkan scripts pada akun google anda.


1. Lakukan setting webhook paga google sheets kamu sampai muncul gambar astronot seperti dibawah ini. Link yang ada dibawahnya merupakan ENDPOINT dari webhooknya.


2. Lakukan subscribe pada antares dan masukkan endpoint webhooks dari google sheets.



3. Jika subscribe berhasil akan muncul tampilan testing seperti berikut :




4. Jalankan script simulasi data IOT pada google colab dan data akan masuk ke google sheets. Kita kemudian ambil data pada kolom yang berguna dan lalu kita masukkan ke sheets2 untuk diolah grafiknya.


5. Perlu parsing teks serta pengolahan jenis data yang tepat sehingga data yang masuk bisa menjadi NUMBER sebagai syarat agar bisa dimasukkan ke CHART / GRAFIK.





6. Hasilnya grafik realtime dapat di nikmati oleh yang memerlukan data.




Share:

Jumat, 15 Desember 2023

Membedah keruwetan Pub-Sub MQTT pada antares


Satu kata yang dapat menjabarkan MQTT pada platform IOT milik telkom antares adalah keruwetannya, namun saya sudah terlebih dahulu mengalami pusing saat membedahnya 3 tahun yang lalu pada tulisan saya disini:  https://www.aisi555.com/2020/06/solved-bug-fatal-pada-mqtt-subscription.html, dan saya sudah "khatam" dengan ini. Buat anda sepertinya harus paham prinsisp M2M IOT yg dipakai oleh antares yaitu :

  • Proses PUB antares spesifik dikirimkan ke project/device namun berbeda dengan SUB pada Antares yang menggunakan 1 topik yg sama untuk kemudian lebih tepatnya dinamakan proses RESPONSE. Jadi ketika data MQTT realtime diterima antares (pada akun yang sama), maka semua data dari semua device yg PUB akan diberikan/relay kepada client yang SUB (secara realtime juga), jadi butuh parsing data  payload dengan metode tertentu baru data yg di inginkan muncul. Bisa dibaca disini  ,  disini , dan disini 
  • Python Paho-mqtt sebagai library paling umum untuk menerima dan mengolah protokol mqtt sehingga dapat dilanjutkan ke proses advance seperti menyimpan database, membuat grafik atau mengirim ke bot telegram. Bisa dibaca dulu agar mengerti disini dan disini.

Untuk kali ini saya memanfaatkan google colab untuk melakukan PUBLISH data random ke antares melaui script python, dan dapat dicoba GRATIS dengan script dibawah ini : jangan lupa  install paho-mqtt dulu di colab!



import paho.mqtt.client as mqtt
from time import sleep
from random import randrange

# Inisialisasi broker
broker_address="mqtt.antares.id"
broker_port=1883
antareskey= "aaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbb" #sesuaikan key antares anda
antaresdevice ="Project/DHT11" #sesuaikan project/device anda

topicpubantares = f'/oneM2M/req/{antareskey}/antares-cse/json'

def on_publish(client,userdata,result):                  
    print("data terkirim ke broker")
    pass


def antares_pub(datae):
    print(datae)
    data_raw = ("{"
      "\"m2m:rqp\": {"
      f'\"fr\": {{antareskey}},'
      f'\"to\": \"/antares-cse/antares-id/{antaresdevice}\",'
      "\"op\": 1,"    
      "\"rqi\": 123456,"
      "\"pc\": {"
          "\"m2m:cin\": {"
            "\"cnf\": \"message\","
            f'\"con\": \"{datae}\"'
          "}"
        "},"
      "\"ty\": 4"
      " }"
      "}")
    ret=client.publish(topicpubantares,data_raw)


client= mqtt.Client(f'unesa-client-{randrange(0,1000)}')  #clientnya harus random
client.on_publish = on_publish                           #assign function to callback
client.connect(broker_address,broker_port)               #establish connection


while 1:                                                  #loop terus sambil kirim data
    suhu = float( randrange(250,350,2) / 10)              #random suhu dan kelembaban
    humi = randrange(80,95,2)
    datanya = {"suhu": suhu, "humi": humi}
    antares_pub(datanya)
    sleep(5)



Jadi ubah dulu parameter akun dan device sesuai yang anda buat di antares. Selajutnya gunakan MQTT explorer untuk membuat demo proses SUB nya.


1. Masuk ke MQTT EXPLORER dengan parameter MQTT Servernya di : mqtt.antares.id port 1883. Username dan password jangan diisi, namun pada bagian advance anda perlu subscribe pada topik yang ada input User:Key antares anda.





TOPIK  SUBSCRIBE :
  /oneM2M/resp/antares-cse/access:key/json


2. Masuk/konek ke mqtt explorer lalu running script python pada google colab,
dan jika benar akan muncul hasil seperti ini






Videonya dapat di lihat disini







Share:

Kamis, 02 Juni 2022

LoRaWan - Antares - Kini tidak GRATIS lagi ! Trik buat yang ingin belajar

 


Terkejutnya saya saat membaca email yang datang dari antares di akhir mei 2022, yang menyatakan platform IOT antares akan meng "upgrade" layanannya ke versi premium berbayar. Padahal bulan mei yang lalu saya sedang getol-getolnya meng "oprek" gateway LoRaWan milik telkom yang jangkauannya nyampe jauh ke berbagai pelosok kota Surabaya. Dan benar saja ketika saya membuat video dibawah ini pada tanggal 1 juni 2022 siang hari, tiba-tiba saja console web antares saya ter-logout sendiri ditengah-tengah rekaman. Panik lah saya dan videonya jadi sedikit terbata-bata di akhir rekaman dan terpaksa saya edit karena isinya banyak misuh-misuh "JA#%%##^@" ...


Breaking news: Telkom akan melakukan migrasi LoRaWan ke Telkomiot.id, Silahkan baca disini



Hal yang serupa terjadi dengan keponakan teman yang sedang skripsi bertopik LoRa di Telkom University Bandung, katanya harga platformya Antares sih terjangkau namun untuk Conectivity nya yang menggunakan LoRa sangatlah mencengangkan, karena walau harga 1 koneksi ke device di antares cuman 56.200 per tahun, namun seharinya dibatasi 10 kali UPLINK saja. Ala mak jang !!!

Awalnya saya bingung juga masalah harga yang keluar di hari libur kelahiran pancasila 1 juni itu, namun setelah dilihat lebih seksama ada 2 jenis pembayaran prepaid yang harus dipahami :



Device yang dimaksud adalah device pada web consolenya antares, dimana selama sebulan dengan merogoh kocek Rp 53.250, kita bebas menggunakan 25 device IOT dengan jalur komunikasi melalui Internet. Jadi para pengguna IOT via wifi dengan modul ESP8266 atau arduino dengan modul GSM SIM800 dapat mengirimkan dan menerima data secara unlimited. Murah dan terjangkau kalau ini menurut saya. Namun kejanggalan terlihat pada Conectivity LoRa yang ditawarkan oleh Antares dengan LoRaWan gatewaynya yang tersedia di hampir semua STO Telkom ( kota besar ) se-NKRI ...


10 UPLINK / hari ???


Langsung saja saya kontak mahasiswa yang sedang bimbingan skripsi ke saya mengenai topik LoRa, awalnya tidak paham..namun...ujungnya lemas tak berdaya, walau saya jelaskan kalau trialnya masih 3 bulan kok untuk pengguna lama maupun baru. Cuman 10 uplink perhari nya ini menyebabkan skripsinya jadi terancam ! Walau dengan trik membuat akun baru yang banyak, namun ini akan merepotkan. Lalu bagaimana solusi buat yang sering melakukan coding Trial- Error ?  Begini beberapa kesimpulan yang saya dapat ambil hikmahnya dari kegaduhan ini:


1. Perbaiki kebiasaan coding dengan cek-ricek script dan baru upload ke Arduino setelah yakin benar


Ini sih menertawakan style coding saya, dimana kebiasaan trial-error, copy paste, upload , ulang lagi dst berkali-kali. Ini akan fatal kalau quota LoRaWan saya habis dengan prematur. Jadi buat anda yg memulai  belajar, perhatikan style coding anda.


2. Bagi yg ber "uang", lakukan prototyping dengan LoRaWan Gateway sendiri



Kalau model yang satu ini sebaiknya dilakukan secara Gotong Royong atau minta bantuan sponsor dari kampus untuk membelikan Gateway LoRaWan dan dipakai belajar bersama-sama. Jadi ketika sudah sukses dengan LoRaWan di Lab sendiri, baru deh meng-upload versi LoRaWan-Antares.


3. Gunakan UPLINK  dengan menunggu perintah input dari serial/tombol, jangan lakukan TX-timer based



Karena memang investasi BTS LoRaWan itu mahal, maka sudah saatnya Telkom memberikan "meteran berbayar" bagi pengguna gatewaynya. Seperti yang kita ketahui LoRaWan adalah protokol yang sharing resource, sehingga node LoRa diharapkan Transmit TX / Uplink nya jarang-jarang apalagi RX / Downlink / penerimaan data pada nodes nya.  Sehingga buat yang baru tahap belajar, haram hukumnya untuk mengirimkan TX Uplink secara timer based. Solusinya yang saya sarankan adalah dengan mengirimkan data dengan menunggu perintah yang dikirimkan melalui Serial Monitor di sketch. Perhatikan contoh komunikasi serial berikut : 


String a;

void setup() {
  // Inisialisasi serial
  Serial.begin(9600);
  Serial.println("tessss");

}

void loop() {

 // cek ada data masuk dari serial monitor 
   
  while(Serial.available()) 
    {
      a= Serial.readString();
        Serial.println(a);
      if (a == "aho ganteng")
           Serial.println("aho memang ganteng kok !!");
    }
  
}



Maksud dari script diatas adalah membandingkan inputan serial berupa kalimat " aho ganteng " dan kemudian jika benar maka akan dikirimkan jawaban " aho memang ganteng kok !! " . Jangan lupa di gambar diatas ada petunjuk nomer 1 dimana pilih no line ending agar tidak mengirmkan enter atau baris baru pada serial ke arduinonya.

Lalu bagaimana dengan script untuk mengirim data suhu dan kelembaban DHT11 ke antares seperti contoh sebelumnya (dapat dibaca disini ) ? Begini scriptnya kira-kira.


#include <SPI.h>
#include <LoRa.h>
#include "DHT.h"
#include <LoRaWanPacket.h>

//Sesuaikan PIN CS, Reset, DIO0

const int csPin = 10;
const int resetPin = 9;
const int irqPin = 2;

const int dhtPin = 3; //Sesuaikan pin DHT

String input; // variabel menyimpan input

//Sesuaikan dev address dan key device LoRa
const char *devAddr = "xxxxxxx";
const char *nwkSKey = "11111111111111110000000000000000";
const char *appSKey = "00000000000000002222222222222222";

#define DHTTYPE DHT22  //Sensor DHT22 sesuaikan
DHT dht(dhtPin, DHTTYPE); 

struct LoRa_config
{
  long Frequency;
  int SpreadingFactor;
  long SignalBandwidth;
  int CodingRate4;
  bool enableCrc;
  bool invertIQ;
  int SyncWord;
  int PreambleLength;
};

//Frekuensi Telkom LoRawan 922MHZ, sesuaikan dengan BTS GW terdekat

static LoRa_config txLoRa = {922000000, 10, 125000, 5, true, false, 0x34, 8};

void LoRa_setConfig(struct LoRa_config config)
{
  LoRa.setFrequency(config.Frequency);
  LoRa.setSpreadingFactor(config.SpreadingFactor);
  LoRa.setSignalBandwidth(config.SignalBandwidth);
  LoRa.setCodingRate4(config.CodingRate4);
  if (config.enableCrc)
    LoRa.enableCrc();
  else
    LoRa.disableCrc();
  if (config.invertIQ)
    LoRa.enableInvertIQ();
  else
    LoRa.disableInvertIQ();
  LoRa.setSyncWord(config.SyncWord);
  LoRa.setPreambleLength(config.PreambleLength);
}

void LoRa_TxMode()
{
  LoRa_setConfig(txLoRa);
  LoRa.idle();
}

void setup()
{
  Serial.begin(9600);
  while (!Serial);

  LoRaWanPacket.personalize(devAddr, nwkSKey, appSKey);

  LoRa.setPins(csPin, resetPin, irqPin);

  if (!LoRa.begin(txLoRa.Frequency)) {
    Serial.println("LoRa init failed. Check your connections.");
    while (true);
  }

  Serial.println("LoRa init succeeded.");
  Serial.println();
  dht.begin();

}


String SendTempHumid(){ //kirim data pengukuran DHT
   
 
    float h = dht.readHumidity();
    float t = dht.readTemperature();

    if (isnan(h) || isnan(t)) {
      Serial.println("Failed to read from DHT sensor!");
    }
    
    Serial.print("Humidity: "); 
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: "); 
    Serial.print(t);
    Serial.println(" °C ");
  //yang dikirim data berupa string JSON
  
  return( "{\"suhu\":" + String(t) + ",\"humi\":" + String(h) +"}"); 
  }


void loop() {

while(Serial.available())  // jika ada serial input masuk
    {
      input = Serial.readString();
      Serial.println(input);
    
      if( input == "Kirim"){  // jika perintah yg dikirim berupa "kirim"
        LoRa_sendMessage();   //kirim ke LoraWan 
        Serial.println("Ngirit Kirim data Ke LoRaWan Antares !");
    }
  }
}

void LoRa_sendMessage()
{
  LoRa_TxMode();
  LoRaWanPacket.clear();
  //Serial.println(SendTempHumid());
  LoRaWanPacket.print(SendTempHumid());
  if (LoRaWanPacket.encode()) 
  {
    LoRa.beginPacket();
    LoRa.write(LoRaWanPacket.buffer(), LoRaWanPacket.length());
    LoRa.endPacket();
  }
}




Dapat dilihat dari hasil pada gambar diatas, data akan terkirim ke Gateway LoRaWan Antares lebih terkontrol hanya ketika diketikkan kata " Kirim" lalu pencet SEND pada serial monitor. Semoga dapat membantu kalian yang mengalami kegalauan akibat berbayarnya LoRaWan Antares. 
Share:

Jumat, 27 Mei 2022

Tutorial LoRaWan Antares - Menentukan frekuensi terbaik dengan python

 



Operasi sistem IoT di pita spektrum ISM yang tidak berlisensi di satu sisi menguntungkan karena rendahnya biaya lisensi, namun di sisi lain  penggunaan spektrum secara bersama menyebabkan peningkatan kebisingan / noise pada latar (background noise) yang tak terhindarkan, karena banyaknya perangkat baru yg hadir belakangan ini. Masalah gangguan yang meningkat ini juga disadari oleh pihak regulator, di mana dilakukan pengukuran spektrum pita lebar (untuk kisaran 200–3000 MHz) dilakukan di lingkungan perkotaan pada tahun 2016. Dari hasil penelitian ditunjukkan bahwa dibandingkan dengan penelitian data analog yang dikumpulkan pada tahun 2004 rata-rata hunian spektral meningkat secara signifikan yang menunjukkan munculnya sejumlah besar sumber radiasi baru (sehingga lebih padat) yang telah muncul selama periode tersebut. 




Ini dicirikan oleh ketidakpastian yang tinggi dan varians yang cukup besar baik dalam time domain maupun dalam amplitudo yang tidak memungkinkan kualifikasi mereka disebut sebagai white Gaussian noise. Kontributor utama dari radiasi yang baru ini, tentu saja telah diidentifikasi sebagai sistem seluler (GSM, UMTS, dan LTE) dan DVB-T. Namun, ada juga kejadian tak terduga dengan karakteristik acak, yang hampir tidak dapat dijelaskan dengan model statistik, seperti kendaraan yang lewat yang memancarkan gelombang EM dari komunikasi pada ECM dan sinyal yang dipancarkan dari remote control untuk membuka pintu dan gerbang dan dari sistem otomasi rumah. Radiasi dalam ruangan dapat berasal dari peralatan komputer (terutama ruang server), WLAN, atau periferal komputer yang berkomunikasi melalui Bluetooth. Kebisingan latar belakang yang meningkat di dalam gedung ini dapat menjadi sangat berbahaya bagi sistem IoT, yang menurut definisi didedikasikan untuk memperoleh data dari lokasi dalam ruangan dan mengirimkannya melalui modem yang terletak langsung pada meter dan sensor.





Untuk menjaga data tetap terkirim ke server dan gateway IOT, saya telah mengkreasikan script baik di arduino maupun python untuk dapat mengumpulkan data statistik masing-masing frekuensi LoRa yang telah disepakati di Indonesia yaitu frekuensi 921.2 - 922.6 Mhz, dengan jarak tiap channel 200Khz. Tanpa berpanjang lebar saya akan share sciptnya, asalkan pembaca telah mengerti pada pembahasan Hello world dan pengolahan data antares yang bisa dibaca disini dan disini.  

#include <SPI.h>
#include <LoRa.h>

#include <LoRaWanPacket.h>


const int csPin = 10;
const int resetPin = 9;
const int irqPin = 2;

const char *devAddr = "aabbccdd";
const char *nwkSKey = "11111111111111110000000000000000";
const char *appSKey = "00000000000000002222222222222222";


struct LoRa_config
{
  long Frequency;
  int SpreadingFactor;
  long SignalBandwidth;
  int CodingRate4;
  bool enableCrc;
  bool invertIQ;
  int SyncWord;
  int PreambleLength;
};


long LoRa_frek_INA_923_start = 921200000 ;
long LoRa_frek_INA_923_end   = 922600000 ;
long LoRa_frek_step = 200000;
long LoRa_frek_INA_923 = LoRa_frek_INA_923_start;
                                     
static LoRa_config txLoRa = {LoRa_frek_INA_923, 10, 125000, 5, true, false, 0x34, 8};

void LoRa_setConfig(struct LoRa_config config)
{
  LoRa.setFrequency(LoRa_frek_INA_923);
  LoRa.setSpreadingFactor(config.SpreadingFactor);
  LoRa.setSignalBandwidth(config.SignalBandwidth);
  LoRa.setCodingRate4(config.CodingRate4);
  if (config.enableCrc)
    LoRa.enableCrc();
  else
    LoRa.disableCrc();
  if (config.invertIQ)
    LoRa.enableInvertIQ();
  else
    LoRa.disableInvertIQ();
  LoRa.setSyncWord(config.SyncWord);
  LoRa.setPreambleLength(config.PreambleLength);
}

void LoRa_TxMode()
{

  LoRa_setConfig(txLoRa);
  LoRa.idle();

  

}


void setup()
{
  Serial.begin(9600);
  while (!Serial);

  LoRaWanPacket.personalize(devAddr, nwkSKey, appSKey);

  LoRa.setPins(csPin, resetPin, irqPin);

  if (!LoRa.begin(txLoRa.Frequency)) {
    Serial.println("LoRa init failed. Check your connections.");
    while (true);
  }

  Serial.println("LoRa init succeeded.");
  Serial.println();
 
}

void loop() {
  if (runEvery(5000)) {

    Serial.print("Send Message! frekuensi =  ");
    Serial.println(LoRa_frek_INA_923);
    
    LoRa_sendMessage();

  }
}

void LoRa_sendMessage()
{
  LoRa_TxMode();
  LoRaWanPacket.clear();
  LoRaWanPacket.print("coba kirim frek: ");
  LoRaWanPacket.print(String(LoRa_frek_INA_923));
  if (LoRaWanPacket.encode()) 
  {
    LoRa.beginPacket();
    LoRa.write(LoRaWanPacket.buffer(), LoRaWanPacket.length());
    LoRa.endPacket();
  }

  if( LoRa_frek_INA_923 >= LoRa_frek_INA_923_end ) LoRa_frek_INA_923 = LoRa_frek_INA_923_start;
  else LoRa_frek_INA_923 += LoRa_frek_step;
}

boolean runEvery(unsigned long interval)
{
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    return true;
  }
  return false;
}

Hasilnya akan bisa mengirim data frekuensi ke antares





Untuk script python nya sehingga dapat menampilkan grafik di excel, silahkan rekues ke saya melalui email: ahocool@gmail.com atau whatsapp 08155737755. Hasilnya luar biasa masbroo...saya mendapatkan kesimpulan yaitu frekuensi terbaik di lokasi saya ada pada 2 channel yaitu 921.2 Mhz dan 922 Mhz.








Share:

Kontak Penulis



12179018.png (60×60)
+628155737755

Mail : ahocool@gmail.com

Site View

Categories

555 (8) 7 segmen (3) adc (4) amplifier (2) analog (19) android (14) antares (11) arduino (28) artikel (11) attiny (3) attiny2313 (19) audio (5) baterai (5) blog (1) bluetooth (1) chatgpt (2) cmos (2) crypto (2) dasar (46) digital (11) dimmer (5) display (3) esp8266 (26) euro2020 (13) gcc (1) gsm (1) iklan (1) infrared (2) Input Output (3) iot (76) jam (7) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (17) komputer (3) komunikasi (1) kontrol (8) lain-lain (8) lcd (2) led (14) led matrix (6) line tracer (1) lm35 (1) lora (11) lorawan (2) MATV (1) memory (1) metal detector (4) microcontroller (70) micropython (6) mikrokontroler (2) mikrokontroller (14) mikrotik (5) modbus (9) mqtt (3) ninmedia (5) ntp (1) paket belajar (19) palang pintu otomatis (1) parabola (88) pcb (2) power (1) praktek (2) project (33) proyek (1) python (8) radio (28) raspberry pi (9) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (2) sharing (3) signage (1) sinyal (1) sms (6) software (18) solar (1) solusi (1) tachometer (2) technology (1) teknologi (2) telegram (2) telepon (9) televisi (167) television (28) telkomiot (5) transistor (2) troubleshoot (3) tulisan (94) tutorial (108) tv digital (6) tvri (2) vu meter (2) vumeter (2) wav player (3) wayang (1) wifi (3) yolo (7)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika