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 python. Tampilkan semua postingan
Tampilkan postingan dengan label python. Tampilkan semua postingan

Minggu, 14 Juli 2024

[raspi - yolo] Memanfaatkan Komputer Lain Untuk Membantu Raspi Zero W Mengolah Gambar

 


Judulnya sedikit membuat ambigu, ngapain sih pake raspberry segala kalau juga digunakan PC lain untuk mengolah yolo ? Eiittsss ..saya pingin mensimulasikan raspberry pi zero w saya sebagai pengambil gambar melalui camera raspi ov5647, lalu alat saya ini akan dipasang pada banyak titik untuk medeteksi jumlah orang di bawah lampu jalan. Jadi harga raspi zero w yg cukup murah ditambah camera yg terjangkau menjadi pilihan yang cukup bagus dibanding meng-upgrade ke versi raspi 4 yang jauh harganya walau dapat mengolah gambar dengan lebih bagus (akan di bahas belakangan). Cukup 1 komputer yang processor kelas i5 sudah bisa menjadi server pengolah gambar.




Kali ini saya akan membahas membuat "server" pengolah gambar pada pc saya yang terhubung dengan wifi yang sama dengan raspi zero w yang saya gunakan sebagai simulator pengambil gambar. Untuk itu sebaiknya baca penjelasan sebelumnya untuk memahami yolo-python untuk mendeteksi objek disini:

  • Yolo dan python untuk deteksi objek :  Videonya dilihat disini
  • Deteksi object pada cctv menggunakan python pada node-red : Klik disini

Yang kita gunakan sebagai server lokal adalah flask yang merupakan pilihan favorit untuk mengetest sistem server berbasis python.  Flask adalah sebuah mikroframework web untuk Python yang dikembangkan oleh Armin Ronacher sebagai bagian dari proyek Pocoo. Flask sangat populer karena kesederhanaannya dan fleksibilitasnya, sehingga memungkinkan pengembang untuk membuat aplikasi web dengan cepat dan efisien.

Fitur Utama Flask

  • Ringan dan Fleksibel: Flask tidak memiliki lapisan abstraksi database atau validasi form bawaan, tetapi memungkinkan integrasi dengan banyak pustaka pihak ketiga.
  • WSGI: Flask berbasis pada Werkzeug WSGI toolkit dan Jinja2 templating engine.
  • Routing: Flask menyediakan sistem routing yang mudah digunakan untuk mengarahkan URL ke fungsi Python.
  • Templating: Dengan menggunakan Jinja2, Flask memungkinkan penggunaan template untuk memisahkan logika aplikasi dari tampilan.
  • Blueprints: Flask mendukung modularisasi aplikasi melalui blueprints, yang memungkinkan pengembangan aplikasi besar menjadi lebih terstruktur.
  • Ekstensi: Banyak ekstensi yang tersedia untuk Flask, seperti Flask-SQLAlchemy untuk ORM, Flask-WTF untuk validasi form, dan Flask-Login untuk otentikasi pengguna.

Contoh Aplikasi Sederhana dengan Flask

Berikut adalah contoh dasar aplikasi Flask:
from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

@app.route('/')
def home():
    return 'Hello, Flask!'

@app.route('/hello/<name>')
def hello(name):
    return f'Hello, {name}!'

@app.route('/form', methods=['GET', 'POST'])
def form():
    if request.method == 'POST':
        name = request.form['name']
        return redirect(url_for('hello', name=name))
    return render_template('form.html')

if __name__ == '__main__':
    app.run(debug=True)

Kalau kita test pada python, hasilnya seperti ini pada browser :



Penjelasan Contoh:

  • Importing Flask: Mengimpor Flask dan modul terkait lainnya.
  • Inisialisasi Aplikasi: app = Flask(__name__) menginisialisasi aplikasi Flask.
  • Route and View Functions: @app.route('/') mendefinisikan route untuk halaman utama. Fungsi home akan mengembalikan string "Hello, Flask!".
  • Dynamic Route: @app.route('/hello/<name>') mendefinisikan route dinamis yang menerima parameter name.
  • Form Handling: Route /form menerima metode GET dan POST. Jika metode POST, data dari form akan diambil dan pengguna akan diarahkan ke halaman hello.

Kelebihan Flask

  • Kesederhanaan: Mudah dipelajari dan digunakan, cocok untuk pemula maupun pengembang berpengalaman.
  • Fleksibilitas: Dapat dengan mudah disesuaikan sesuai kebutuhan aplikasi.
  • Komunitas: Komunitas yang besar dan aktif, menyediakan banyak tutorial dan dukungan.

Kelemahan Flask

  • Kurangnya Fitur Bawaan: Tidak memiliki banyak fitur bawaan seperti framework web lain yang lebih besar (misalnya, Django).
  • Pengaturan Manual: Banyak fitur yang harus diatur dan diintegrasikan secara manual.

Flask sangat cocok untuk aplikasi web kecil hingga menengah, API, dan proyek yang membutuhkan fleksibilitas tinggi.


Selanjutnya pada raspi zero w akan saya buat script python untuk mengirimkan gambar ke server saya :

import sys
import requests
import cv2
import time

def send_image(image_path, server_url):
    # Read image from file
    image = cv2.imread(image_path)
    if image is None:
        print(f"Failed to load image {image_path}")
        return

    # Encode image as JPEG
    _, img_encoded = cv2.imencode('.jpg', image)

    # Measure the start time for the network request
    start_time = time.time()

    # Send the image to the Flask server
    response = requests.post(f"{server_url}/detect", files={"image": img_encoded.tobytes()})

    # Measure the end time for the network request
    end_time = time.time()

    # Calculate network time
    network_time = end_time - start_time

    # Check and parse the response
    response_data = response.json()
    server_processing_time_str = response_data.get('processing_time', None)

    if server_processing_time_str is not None:
        try:
            server_processing_time = float(server_processing_time_str)
            print(f"Server processing time: {server_processing_time:.2f} seconds")
        except ValueError:
            print("Error: Server processing time is not a valid float.")
            server_processing_time = None
    else:
        print("Server processing time not found in response.")
        server_processing_time = None

    print(response_data)
    print(f"Network time: {network_time:.2f} seconds")

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: python myscript.py <image_path> <server_url>")
    else:
        image_path = sys.argv[1]
        server_url = sys.argv[2]
        send_image(image_path, server_url)

Script diatas akan menggunakan cara panggil : 

python flask.py <nama_gambar.jpg> <ip_server_flask:port>


Sedangkan pada sisi server, seperti yang sudah saya bahas pada cara pengolahan yolo sebelumnya  disini, maka script yang saya buat sebagai berikut :


from flask import Flask, request, jsonify
import cv2
import numpy as np
import time


app = Flask(__name__)


yolo = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
classes = []

with open("coco.names", "r") as file:
    classes = [line.strip() for line in file.readlines()]


layer_names = yolo.getLayerNames()
output_layers = [layer_names[i - 1] for i in yolo.getUnconnectedOutLayers()]

colorRed = (0,0,255)
colorGreen = (0,255,0)

# #Loading Images
def detect_objects(img):
    starting_time = time.time()
    height, width, channels = img.shape

    # # Detecting objects
    blob = cv2.dnn.blobFromImage(img, 0.00392, (255, 255), (0, 0, 0), True, crop=False)

    yolo.setInput(blob)
    outputs = yolo.forward(output_layers)

    class_ids = []
    confidences = []
    boxes = []
    for output in outputs:
        for detection in output:
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            if confidence > 0.4 and ( class_id == 0 or class_id == 2 or class_id == 3 ): # 0 = orang, 2 = motor , 3 = mobil 
                center_x = int(detection[0] * width)
                center_y = int(detection[1] * height)
                w = int(detection[2] * width)
                h = int(detection[3] * height)

                x = int(center_x - w / 2)
                y = int(center_y - h / 2)

                boxes.append([x, y, w, h])
                confidences.append(float(confidence))
                class_ids.append(class_id)


    indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
    org = 0
    mob = 0
    mot = 0

    for i in range(len(boxes)):
        if i in indexes:
            if class_ids[i] == 0:
                org = org + 1
                label = 'orang : ' + repr(org)
            elif class_ids[i] == 2:
                mob = mob + 1
                label = 'mobil : ' + repr(mob)
            elif class_ids[i] == 3:
                mot = mot + 1
                label = 'motor : ' + repr(mot)
            x, y, w, h = boxes[i]
            #label = str(classes[class_ids[i]]) + ', x=' +repr(x) + ',y=' +repr(y)
            #label = str(classes[class_ids[i]]) + '- no: ' + repr(i+1)
            cv2.rectangle(img, (x, y), (x + w, y + h), colorGreen, 3)
            cv2.putText(img, label, (x, y -5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255) )




    print("{")
    print(f"\"Jumlah Orang\": {org},")
    print(f"\"Jumlah Mobil\": {mob},")
    print(f"\"Jumlah Motor\": {mot},")

    elapsed_time = time.time() - starting_time
    print("\"processing time\":" + repr(elapsed_time)  )
    print("}")
    cv2.imwrite("output.jpg",img) 
    return {"Orang": org, "Mobil": mob, "Motor": mot, "time": elapsed_time }
    

@app.route("/detect", methods=["POST"])
def detect():
    file = request.files["image"]
    npimg = np.fromfile(file, np.uint8)
    image = cv2.imdecode(npimg, cv2.IMREAD_COLOR)
    result = detect_objects(image)
    return jsonify(result)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

Dan hasilnya sebagai berikut :



Nah...bisa dan cepat bukan ? Jadi file gambar yang saya tampilkan output.jpg diatas merupakan hasil pengolahan gambar pada pc saya sebagai sever dan kemudian dikembalikan ke raspberry pi zero w sebagai json hasil perhitungan jumlah orang. Jadi cukup 1 server bisa melayani banyak alat pengambil gambar yang sama menggunakan raspberry pi zero w yang harganya lumayan murah.

Bagaimana jika PC nya tidak tersedia dan hanya ada jaringan wifi dilokasi ? Kita kan bahas selanjutnya memanfaatkan komputasi cloud dari google lanjut disini.
Share:

Jumat, 12 Januari 2024

[Node Red] Deteksi Object Pada CCTV Menggunakan Yolo

 


Tutorial yang akan saya tuliskan pada blog kali ini merupakan penggabungan dari beberapa tulisan maupun video kuliah saya sebelumnya, sehingga untuk kelancaran tutorial harap menyimak pembahasan sebelumnya yaitu :


  • Yolo dan python untuk deteksi objek :  Videonya dilihat disini
  • Menjalankan python pada node-red : Klik disini

Untuk sumber dari gambar capture dari  CCTV bisa mengambil dari berbagai lokasi cctv publik yang ada di internet, dan yang saya pakai pada praktek kali ini adalah CCTV di wilayah jogja yang berbasis wowza sehingga source streamingnya dapat dilihat (melalui cara tertentu). Alamat untuk masuk ke koleksi CCTV kota jogja (paling menarik seputaran malioboro) dapat dilihat di alamat : https://cctv.jogjakota.go.id/. 




Lokasi diatas adalah monumen nol kilometer di ujung malioboro dengan alamat cctv nya : https://cctvjss.jogjakota.go.id/malioboro/NolKm_Timur.stream/chunklist_w221624478.m3u8 . Jadi jika url streaming diatas mati atau berubah, silahkan cari sendiri ya !


Script - Yolo - Python :

import cv2
import numpy as np
import time
import sys

#penghitung waktu proses
starting_time = time.time()

#cmd windows pake spasi biar bisa dieksekusi pada node-red
if len(sys.argv) != 2:
    print("Cara Pakai: python<spasi>script.py<spasi>alamat/stream_url")
    sys.exit(1)

# ambil cmd pada bagian sumber streaming sesuai usage
stream_url = sys.argv[1]

# Open the video stream
cap = cv2.VideoCapture(stream_url)

# ambil 1 frame terakhir aja
ret, img = cap.read()

# alamat direktori yolo harus lengkap
yolo = cv2.dnn.readNet("G:\\IOT\\node_red\\yolov3.weights", "G:\\IOT\\node_red\\yolov3.cfg")
classes = []

with open("G:\\IOT\\node_red\\coco.names", "r") as file:
    classes = [line.strip() for line in file.readlines()]

#proses yolo
layer_names = yolo.getLayerNames()
output_layers = [layer_names[i - 1] for i in yolo.getUnconnectedOutLayers()]

colorRed = (0,0,255)
colorGreen = (0,255,0)

# #Loading Images
#img = cv2.imread(name)
height, width, channels = img.shape

# # Detecting objects
blob = cv2.dnn.blobFromImage(img, 0.00392, (255, 255), (0, 0, 0), True, crop=False)

yolo.setInput(blob)
outputs = yolo.forward(output_layers)

# deteksi 3 object orang (0), mobil(2) dan motor(3)
class_ids = []
confidences = []
boxes = []
for output in outputs:
    for detection in output:
        scores = detection[5:]
        class_id = np.argmax(scores)
        confidence = scores[class_id]
        if confidence > 0.5 and ( class_id == 0 or class_id == 2 or class_id == 3): # 3 objek
            center_x = int(detection[0] * width)
            center_y = int(detection[1] * height)
            w = int(detection[2] * width)
            h = int(detection[3] * height)

            x = int(center_x - w / 2)
            y = int(center_y - h / 2)
			#simpan koordinat dan nilai keyakinan
            boxes.append([x, y, w, h]) 
            confidences.append(float(confidence))
            class_ids.append(class_id)



#perhitungan indeks dan 3 object
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
org = 0
mob = 0
mot = 0

#kotak dan tulisan deteksi objek
for i in range(len(boxes)):
    if i in indexes:
        if class_ids[i] == 0:
            org = org + 1
            label = 'orang(' + repr(org)+ ')'
        elif class_ids[i] == 2:
            mob = mob + 1
            label = 'mobil(' + repr(mob)+ ')'
        elif class_ids[i] == 3:
            mot = mot + 1
            label = 'motor(' + repr(mot)+ ')'
        x, y, w, h = boxes[i]
        cv2.rectangle(img, (x, y), (x + w, y + h), colorGreen, 3)
        cv2.putText(img, label, (x, y -5), cv2.FONT_HERSHEY_DUPLEX, 2, (255,255,255) )


print("{")
print(f"\"Jumlah Orang\": {org},")
print(f"\"Jumlah Mobil\": {mob},")
print(f"\"Jumlah Motor\": {mot},")

elapsed_time = time.time() - starting_time
print("\"processing time\":" + repr(elapsed_time)  )
print("}")
## dibawah ini pilih mau simpan gambar atau tampilkan saja, sesuaikan kebutuhan
#cv2.imshow("Image", img)
cv2.imwrite("G:\\IOT\\node_red\\output.jpg",img) #
#cv2.waitKey(0)
#cv2.destroyAllWindows()


Hasil dari script diatas berupa string json yang nantinya berguna pada pengolahan data.




Node-Red Flow 


Untuk bagian ini cukup mengikuti pembahasan sebelumnya, dengan perbedaan inject yg digunakan berupa payload alamat stream dari CCTV.




Untuk menampilkan hasil pada flow, maka dibutuhkan pallete yang bernama : node-red-contrib-image-tools , dan untuk melakukan refresh agar tampilannya berubah setelah eksekusi script yolo selesai adalah dengan menggunakan function trigger.




Dengan konfigurasi diatas maka node image viewer akan menampilkan gambar bernama output.jpg setelah 250ms script yolo berhasil dieksekusi. Jika mau langsung import flow nya bisa copas json dibawah ini.


[
    {
        "id": "5e5b156e7f57b6cc",
        "type": "tab",
        "label": "aisi555 dot com",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "d4809067.5e61a",
        "type": "inject",
        "z": "5e5b156e7f57b6cc",
        "name": "nama stream",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "20",
        "topic": "",
        "payload": "https://cctvjss.jogjakota.go.id/atcs/ATCS_Lampu_Merah_SugengJeroni1.stream/chunklist_w758098670.m3u8",
        "payloadType": "str",
        "x": 190,
        "y": 40,
        "wires": [
            [
                "7a4e8130.b846f8"
            ]
        ]
    },
    {
        "id": "7a4e8130.b846f8",
        "type": "exec",
        "z": "5e5b156e7f57b6cc",
        "command": "python G:\\IOT\\node_red\\yolo_stream.py ",
        "addpay": "payload",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 520,
        "y": 40,
        "wires": [
            [
                "c95a2a0563597a2b",
                "50dcecd33a88080d"
            ],
            [],
            []
        ]
    },
    {
        "id": "c95a2a0563597a2b",
        "type": "debug",
        "z": "5e5b156e7f57b6cc",
        "name": "debug 6",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 920,
        "y": 20,
        "wires": []
    },
    {
        "id": "50dcecd33a88080d",
        "type": "trigger",
        "z": "5e5b156e7f57b6cc",
        "name": "",
        "op1": "",
        "op2": "G:/IOT/node_red/output.jpg",
        "op1type": "nul",
        "op2type": "str",
        "duration": "250",
        "extend": false,
        "overrideDelay": false,
        "units": "ms",
        "reset": "",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 920,
        "y": 80,
        "wires": [
            [
                "d6cf44e31cac223d"
            ]
        ]
    },
    {
        "id": "d6cf44e31cac223d",
        "type": "image viewer",
        "z": "5e5b156e7f57b6cc",
        "name": "",
        "width": "800",
        "data": "payload",
        "dataType": "msg",
        "active": true,
        "x": 190,
        "y": 120,
        "wires": [
            []
        ]
    }
]


Dengan kreativitas pembaca maka flows diatas dapat diatur otomatis eksekusi tiap selesai script yolo di eksekusi, mungkin juga berdasarkan waktu atau sebagainya. Mungkin jika komputer kamu super cepat dengan VGA sekelas gamers maka pengolahan gambarnya bisa di level video  (25fps minimal).


Beberapa faktor yang mempengaruhi keberhasilan deteksi object sebagai berikut :

  • Yolo v3 yang digunakan masih menggunakan weights bawaan dari yolo, sehingga tingkat keberhasilan pendeteksiannya hanya dibilang "cukup" karena object yg bisa dideteksi banyak dan umum.
  • Untuk pendeteksian objek yang spesifik dan lebih teliti bisa melakukan training pada object-object yang di kehendaki saja dan akan dibahas pada kesempatan lainnya
  • Tingkat kualitas kamera sangat menentukan deteksi object 

Share:

[Node Red] Script Python Pada Flow Node Red

 


Python sebagai bahasa pemrograman "serba bisa"  sekarang ini cenderung diakomodir untuk bekerjasama (atau pun terpaksa agar lebih up to date) dengan berbagai platform pemrograman visual jaman sekarang. Al hasil - Node Red - sebagai platform pemrograman otomasi "drag and drop" juga memiliki beberapa fasilitas untuk menjalankan script python, baik secara flow/pallete langsung atau memanfaatkan cara paling mudah menurut saya yaitu melalui node eksekusi shell / cmd / terminal  bernama "EXEC".



Sesuai yang kita sudah pahami, perintah shell bermacam-macam yah mungkin jika anda menggunakan CMD pada windows anda bisa menulisakan perintah "date" atau ping ke IP tertentu, semisal ip nya di masukkan ke manual trigger sebagai payload. Output dari node EXEC ada tiga berupa standard output, standar error dan return /exit code. 

Untuk memahami bagaimana cara menjalankan script python pada node red, saya anggap pemahaman python pembaca sudah level dasar, sehingga mudah memahami script dibawah ini untuk membaca inputan dary SYS.ARGV .



Sys.argv akan membaca inputan sebagai list/array dengan anggota yang dipisahkan oleh spasi. Sehingga script diatas jika dijalankan pada shell akan mendapatkan balasan sesuai input yang diberikan. Mari kita pindahkan script ini menjadi bergabung dengan node-red.



Gambar diatas menunjukkan flow node red dimana saya akan menginjekkan suatu nilai msg.payload ke node EXEC dan kemudian akan meng-eksekusi scipt python sederhana pada gambar sebelumnya. Saya akan melakukan append msg.payload dibagian belakang dari perintah shell pythonnya, dan harus diingat semua dependencies dari direktori shellnya harus ditulis dengan lengkap.



Hasilnya seperti pada gambar, ketika saya inject timestamp maka output akan keluar sesuai yang diharapkan dari script pythonnya. Bagaimana jika nilai yang diinject kosong?



Terlihat yang dioutput pada debug node sesuai yang diharapkan, dimana script python akan menjawab "kamu kirim kosong". Dan jika terjadi error semisal coding python saya salah maka debug juga akan memberikan output kesalahan yg dialami asalkan node debugnya diletakkan pada flow yang benar.



Pada tulisan selanjutnya saya akan mempraktekkan kemampuan node-red untuk bekerjasama dengan script python-yolo untuk pengenalan object.




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:

Selasa, 16 November 2021

MQTT Data Simulator Menggunakan Python - PahoMqtt

 



Kadang kalanya para penggiat IOT adalah mereka yang tidak berhubungan langsung dengan benda yg bernama mikrokontroler maupun sensor. Ya benar saja kenyataan ini terjadi akibat semakin melebarnya topik sensor 8 bit ke dunia koding yg semakin menjangkau mereka yg biasanya hanya terkoneksi dengan komputer PC saja. Akibatnya para "koder" yg jago ini menjadi kewalahan dalam memperoleh data pembacaan sensor kecuali bekerjasama dengan mereka yg sering bekerja dengan sensor dan mikrokontroler. Padahal kalau dilihat kemampuan orang yg mempunyai latar belakang koding informatika akan menghasilkan program yg lebih rapi pada umumnya. 


Lalu bagaimana menghasilkan data pembacaan sensor tanpa menggunakan mikrokontroller? Mudah saja sebenarnya karena kita dapat memanfaatkan bahasa pemrograman apapun untuk menciptakan data numerik random yang menyerupai data pembacaan sensor. Namun kendalanya adalah bahasa pemrograman paling mudah dan ready untuk komunikasi sensor secara IOT apa ya ? Jawabannya adalah python yg sering saya gunakan untuk mengolah data IOT menggunakan protokol MQTT, seperti pada pembahasan sebelumnya disini : https://www.aisi555.com/2020/07/tutorial-menggambar-grafik-data-arduino.html


Jadi untuk komunikasi berbasis MQTT sudah tersedia library /package siap pakai bernama paho MQTT.


pip install paho-mqtt


Diatas merupakan cara untuk menginstall packagenya pada console python anda. Sedangkan untuk membuat angka pembacaan sensor secara random bisa menggunakan script berikut:



from random import randrange

suhu = float( randrange(250,350,2) / 10)
humi = randrange(50,95,2)

Jadi dengan menggabungkan pahomqtt dan  randrange kita bisa memperoleh simulasi pembacaan sensor yg datanya dapat dicoba pada MQTT explorer atau IOT MQTT PANEL pada smartphone anda.



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

# Inisialisasi broker 
broker_address="broker.hivemq.com" 
broker_port=1883

def on_publish(client,userdata,result):                   #create function for callback
    print("data terkirim ke broker")
    pass

client1= mqtt.Client(f'unesa-client-{randrange(0,100)}')  #clientnya harus random
client1.on_publish = on_publish                           #assign function to callback
client1.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(50,95,2)
    ret= client1.publish("/testyuk/suhu",suhu)            #PUB suhu ke topik /testyuk/suhu
    sleep(3)
    ret= client1.publish("/testyuk/humi",humi)            #PUB Kelembaban ke topik /testyuk/humi
    sleep(3)         


Jangan lupa untuk membuat nama client     client1= mqtt.Client("unesa123")  yg unik agar tidak sama dengan nama client orang lain.  Hasilnya seperti berikut ini :








Share:

Senin, 13 September 2021

ESP8266 - @Telegram_Bot - Part 4 : Kirim Grafik Real Time ke Bot

 


Seperti yang sudah kita praktekkan sebelumnya, Modul ESP8266 sekelas Wemos D1 memiliki kemampuan untuk berkomunikasi dengan API Telegram BOT secara pooling. Namun dikarenakan limitasi dari resource dan syarat dari API yang menggunakan SSL terenkripsi maka akan menyebabkan lambatnya respon yg didapat. Untuk itu butuh perantara di mesin yg lebih cepat seperti raspberry pi atau komputasi cloud yg dapat melayani kebutuhan kapan saja. 

Setelah berhasil menyimpan data dan menggambarkan grafiknya, kita sampai pada pembahasan terakhir yaitu mengirimkan grafik realtime melalui bot telegram. Secara garis besar alur cerita dari logika yg saya buat seperti berikut :


  • ESP8266 membaca sensor DHT 11 dan mengirimkan secara PUB ke MQTT Broker.
  • MQTT broker meneruskan data ke pihak yg melakukan SUB, dalam hal ini PC+python di rumah saya.
  • Python melakukan penyimpanan data suhu dan kelembaban ke SQLite secara berkala setiap ada pesan MQTT yg sampai ke PC.
  • Python mengontrol komunikasi ke API telegram bot dan kemudian mengirimkan grafik jika diminta.


Library atau modul python yg digunakan untuk mengotrol telegram bot adalah python-telegram-bot, jangan lupa untuk meginstalnya di komputer kamu.


$ pip install python-telegram-bot 


Sedangkan module lainnya sudah dibahas pada praktek sebelumnya, tanpa berpanjang lebar lagi, berikut ini script python sebagai jembatan ESP8266 dengan telegram bot


from telegram import Bot, ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import Updater, MessageHandler, Filters
import random, json, sqlite3, datetime, time
from paho.mqtt import client as mqtt_client
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser
from matplotlib import style

# server/broker mqtt
broker = 'broker.hivemq.com'
port = 1883
topicdht= "/aisi555/dht" # sesuaikan topic di praktek sebelumnya


# client id random karena gak boleh sama antar client
client_id = f'python-mqtt-{random.randint(0, 100)}'
username = ''
password = ''

bot = Bot('XXXXXXXX:XXXXXXXXXXXXXXXXXX') #isi sesuai Token BOT anda


#Masukkan ke database dan tambahkan kolom date
def sql_insert(s,h):
db = sqlite3.connect("humitemp.db") #buat dulu databasenya
cursor = db.cursor()
now = int(time.time())
tgl = str(datetime.datetime.fromtimestamp(now).strftime('%Y-%m-%d %H:%M:%S'))
cursor.execute("insert into dht11(suhu, humi, date) values(?,?,?)",(s,h,tgl))
db.commit()
cursor.close()
db.close()

def graph_data(uid):
# Connect to database
sqlite_file = 'humitemp.db'
conn = sqlite3.connect(sqlite_file)
c = conn.cursor()
style.use('seaborn')
    #pilih 30 data terakhir
c.execute('SELECT * FROM dht11 ORDER BY date DESC LIMIT 30')
data = c.fetchall()

temperature = []
humidity = []
timenow = []

for row in data:
temperature.append(row[0])
humidity.append(row[1])
timenow.append(parser.parse(row[2]))

dates = [mdates.date2num(t) for t in timenow]

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_title("Kondisi Lingkungan")

# Configure x-ticks
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m %H:%M'))

# Plot temperature data on left Y axis
ax1.set_ylabel("Suhu [°C]")
ax1.plot_date(dates, temperature, '-', label="Suhu", color='r')

# Plot humidity data on right Y axis
ax2 = ax1.twinx()
ax2.set_ylabel("Kelembaban [% RH]")
ax2.plot(dates, humidity, '-', label="Kelembaban", color='g')

# Format the x-axis for dates (label formatting, rotation)
fig.autofmt_xdate(rotation=60)
fig.tight_layout()

# Show grids and legends
ax1.grid(True)
ax1.legend(loc='center left', framealpha=0.5)
ax2.legend(loc='center right', framealpha=0.5)

plt.savefig("figure.png") #simpan dalam file gambar

c.close()
conn.close()
bot.send_photo(uid, photo=open('figure.png', 'rb')) #kirim ke bot telegram berupa gambar

def reply(uid, teks, tombolList): #biar tampil tombol bot keren
if len(tombolList) == 0:
tombol = ReplyKeyboardRemove()
else:
tombol = ReplyKeyboardMarkup([tombolList], resize_keyboard=True)
bot.send_message(uid, parse_mode="HTML", text='<b>' + teks + '</b>', reply_markup=tombol)


def respond(data, update): #membaca dan membalas respon dari pengguna bot
message = data.message
teks = message.text
uid = message.chat.id # user id

if teks == 'suhu':
bot.send_message(uid, parse_mode="HTML", text="<b>Suhu</b> : " + str(suhu) + " °C")
elif teks == 'humi':
bot.send_message(uid, parse_mode="HTML", text="<b>Kelembaban</b> : " + str(humi) + " % rH")
elif teks == 'grafik':
graph_data(uid) #kirim grafik

if teks.find('suhu') != -1 or teks.find('humi') != -1 or teks.find('/start') != -1:
reply(uid, "ESP8266 ULO by Aisi555.com", ["suhu", "humi", "grafik"])
else:
reply(uid, "Silahkan Pilih Tombol", ["suhu", "humi", "grafik"])
return "ok"


# koneksi Mqtt
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.Client(client_id)
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client


# subscribe ke topik mqtt broker
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
global suhu, humi, indeks
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
if (msg.topic == topicdht):
data= json.loads(msg.payload.decode()) #parsing json
suhu = data["suhu"]
humi = data["humi"]
sql_insert(suhu,humi) #kirim ke SQLite
# daftar pada topic
client.subscribe(topicdht)
client.on_message = on_message


def run():
global klien
klien = connect_mqtt()
subscribe(klien)
klien.loop_forever()


if __name__ == '__main__':
updater = Updater(bot=bot)
dispatcher = updater.dispatcher

dispatcher.add_handler(MessageHandler(Filters.text, respond))

print("@" + bot.username + " siap.")
updater.start_polling()
run()
updater.idle()


Berikut ini penjelasan secara detail, dimulai dari Module Python yg digunakan :


from telegram import Bot, ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import Updater, MessageHandler, Filters
import random, json, sqlite3, datetime, time
from paho.mqtt import client as mqtt_client
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser
from matplotlib import style


Yang dibawah ini merupakan inilisalisasi broker MQTT dan token BOT Telegram.


# server/broker mqtt
broker = 'broker.hivemq.com'
port = 1883
topicdht= "/aisi555/dht" # sesuaikan topic di praktek sebelumnya


# client id random karena gak boleh sama antar client
client_id = f'python-mqtt-{random.randint(0, 100)}'
username = ''
password = ''

bot = Bot('XXXXXXXX:XXXXXXXXXXXXXXXXXX') #isi sesuai Token BOT anda


Selanjutnya routine / function untuk mengatur koneksi MQTT dan Subcribe topiknya. Setiap ada message yg masuk dari MQTT langsung disimpan pada database SQLite.


# koneksi Mqtt
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.Client(client_id)
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client


# subscribe ke topik mqtt broker
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
global suhu, humi, indeks
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
if (msg.topic == topicdht):
data= json.loads(msg.payload.decode()) #parsing json
suhu = data["suhu"]
humi = data["humi"]
sql_insert(suhu,humi) #kirim ke SQLite
# daftar pada topic
client.subscribe(topicdht)
client.on_message = on_message


Setelah data tersedia dari broker MQTT, maka dilakukan penyimpanan database oleh function berikut :


def sql_insert(s,h):
db = sqlite3.connect("humitemp.db") #buat dulu databasenya di SQLite
cursor = db.cursor()
now = int(time.time())
tgl = str(datetime.datetime.fromtimestamp(now).strftime('%Y-%m-%d %H:%M:%S'))
cursor.execute("insert into dht11(suhu, humi, date) values(?,?,?)",(s,h,tgl))
db.commit()
cursor.close()
db.close()


Respon dari Telegram Bot dilakukan di function berikut ini :


def respond(data, update): #membaca dan membalas respon dari pengguna bot
message = data.message
teks = message.text
uid = message.chat.id # user id

if teks == 'suhu':
bot.send_message(uid, parse_mode="HTML", text="<b>Suhu</b> : " + str(suhu) + " °C")
elif teks == 'humi':
bot.send_message(uid, parse_mode="HTML", text="<b>Kelembaban</b> : " + str(humi) + " % rH")
elif teks == 'grafik':
graph_data(uid) #kirim grafik

if teks.find('suhu') != -1 or teks.find('humi') != -1 or teks.find('/start') != -1:
reply(uid, "ESP8266 ULO by Aisi555.com", ["suhu", "humi", "grafik"])
else:
reply(uid, "Silahkan Pilih Tombol", ["suhu", "humi", "grafik"])
return "ok"


Biar tambah keren ditambahkan reply keyboard "markup" seperti berikut :


def reply(uid, teks, tombolList): #biar tampil tombol bot keren
if len(tombolList) == 0:
tombol = ReplyKeyboardRemove()
else:
tombol = ReplyKeyboardMarkup([tombolList], resize_keyboard=True)
bot.send_message(uid, parse_mode="HTML", text='<b>' + teks + '</b>', reply_markup=tombol)




Untuk menampilkan grafik digunakan module Matplotlib, persis dengan pembahasan sebelumnya.


def graph_data(uid):
# Connect to database
sqlite_file = 'humitemp.db'
conn = sqlite3.connect(sqlite_file)
c = conn.cursor()
style.use('seaborn')
    #pilih 30 data terakhir
c.execute('SELECT * FROM dht11 ORDER BY date DESC LIMIT 30')
data = c.fetchall()

temperature = []
humidity = []
timenow = []

for row in data:
temperature.append(row[0])
humidity.append(row[1])
timenow.append(parser.parse(row[2]))

dates = [mdates.date2num(t) for t in timenow]

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_title("Kondisi Lingkungan")

# Configure x-ticks
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m %H:%M'))

# Plot temperature data on left Y axis
ax1.set_ylabel("Suhu [°C]")
ax1.plot_date(dates, temperature, '-', label="Suhu", color='r')

# Plot humidity data on right Y axis
ax2 = ax1.twinx()
ax2.set_ylabel("Kelembaban [% RH]")
ax2.plot(dates, humidity, '-', label="Kelembaban", color='g')

# Format the x-axis for dates (label formatting, rotation)
fig.autofmt_xdate(rotation=60)
fig.tight_layout()

# Show grids and legends
ax1.grid(True)
ax1.legend(loc='center left', framealpha=0.5)
ax2.legend(loc='center right', framealpha=0.5)

plt.savefig("figure.png") #simpan dalam file gambar

c.close()
conn.close()
bot.send_photo(uid, photo=open('figure.png', 'rb')) #kirim ke bot telegram berupa gambar


Hasil pada BOT Telegram seperti berikut ini :




Grafik lebih jelasnya seperti pada gambar berikut :




Keren bukan ? Selamat mencoba ! 

Share:

Rabu, 07 Juli 2021

Atlet dan Wartawan di Olimpiade Tokyo Akan di Lacak Melalui GPS - Bikin Sendiri Yuk Dari Barang Bekas !

(bisnis.com) Penyelenggara Olimpiade Tokyo akan memantau pergerakan atlet menggunakan GPS seperti yang dilakukan kepada media asing. CEO Komite Penyelenggara Tokyo 2020, Toshiro Muto, mengatakan mengatakan sistem pemantauan akan digunakan tidak untuk melacak setiap gerakan peserta Olimpiade tetapi untuk melacak mereka secara retroaktif jika muncul masalah. 




Tokyo akan menjadi tuan rumah Olimpiade Musim Panas 2020 yang telah satu tahun ditunda dan akan dimulai 23 Juli, di tengah kekhawatiran bahwa acara global itu akan menambah beban sistem medis yang telah terbebani akibat pandemi virus corona. Penyelenggara Tokyo 2020, Selasa, mengatakan jurnalis luar negeri yang meliput Olimpiade Tokyo akan dilacak pergerakannya dengan GPS, dan terancam tidak dapat meliput jika melanggar aturan.




Setahun lalu saya ingat pernah belajar Coding Python yang berhubungan GeoPy ( baca dulu disini ) dan pengolahan data lokasi, dan saya bahas mengenai Hardware GPS receiver yg umum ada pasaran elektronika di olshop. Dan saya buka kotak perkakas di gudang dan teringat nostalgia kembali ke 15 tahun yang lalu ketika saya bekerja di salah satu vendor perangkat telekomunukasi CDMA. Jadi saat itu salah satu cara membedakan BTS CDMA dengan GSM adalah mencari antena berbentuk setengah bola atau kerucut yg diletakkan tidak terlalu tinggi dekat dengan shelter BTS.




Terbayang masa-masa proyek memasang antena GPS di atas tower, dimana saat itu pekerjaan ini dihargai tinggi,bisa untuk beli HP baru lho ! Belum lagi sisa kabel yang panjang, kualitas jerman yg laku keras di loak...ahhhh sudahlahh...namun kini, yang menjadi warisan di saya hanya sebuah receiver GPS USB yang dulunya digunakan  untuk referensi lokasi saat melakukan drive test sinyal. Dan saat saya colokkan port USB nya ke komputer  terdeteksi sebagai Usb to serial converter. Wahh ini dalemannya pasti masih berupa UART dan bisa  di interfacing ke arduino !




Jadi makin semangat nih buat menyambungkannya ke Arduino. Tapi sebelumnya ada baiknya mencari referensi tentang data yg dikirim oleh si receiver. Sial nya si pembuat modul telah bangkrut dan sedikit yg bisa saya dapatkan digoogle tapi cukuplah informasi yg di dapat bahwa receiver ini berbasis NMEA yg masih umum digunakan. Dengan terminal putty dan serial baudrate 4800 layar menangkap seperti ini :


Buset dah..banyak amat tuh tulisan yg harus diparsing, dan dari yg saya baca di standar NMEA receiver ini lumayan lengkap karena bisa membaca berbagai standar GPS , jadi ada $GPRSV dan $GPRSA untuk melihat informasi satelit dan $GPGGA dan $GPRMC untuk membaca koordiat, waktu, kecepatan, ketinggian dsb. Wah saya mumet ini kalau membaca parsingan segitu banyak, dan pilihan tertuju ke google dan saya cari ada gak software gratis untuk membaca parsingan NMEA seperti diatas...dan ternyata banyak loo..ayo kita coba dan bawa keruangan terbuka agar sinyal satelitnya lebih bagus.




Pilihan saya tertuju ke software yg pertama dimana terpampang jelas parsingan NMEA nya sehingga dari data serial yg didapat seperti ini :


$GPRMC,040503.246,A,0719.6784,S,11243.4344,E,0.00,0.00,220520,,*1B


Artinya kira-kira :

040503.246       =  Jam 04 , Menit 05, Detik 03.246 (UTC)
A                             = Data Benar ( V jika datanya salah )
0719.6784,S     = Latitude 7' 19.6784 " South
11243.4344,E   = Longitude 112' 43.4344 " East
220520        = Tanggal 22 Bulan 05 Tahun 20

Nah sudah siap nih...ayo kita siapkan bahan-bahan dan mulai menyolder modul receiver GPSnya agar bisa dihubungkan ke Arduino.



Skematik tidak akan saya bahas karena sangat gampang dicari apalagi cara koneksi LCD ke Arduino seperti apa pasti para pembaca sudah tahu, dan kalau belum ya tinggal googling aja bagaimana cara menyambungkan LCD ke arduino. Microcontroller yg pas ada disaya adalah wemos d1 r1  yang memiliki wifi berbasis ESP8266 dan nantinya akan saya proogram untuk membaca GPS secara serial dan DHT11 sebagai tambahan sensor agar sedikit berbau IOT. Tujuan akhir dari praktek ini adalah mengirimkan data sensor suhu/kelembaban beserta dengan data GPS dan nama lokasi pembacaan yg akan dikolaborasikan dengan Mqtt serta Geopy phyton. Pada part 1 ini akan difokuskan pembahasan mengenai pembacaan GPS ke LCD.


Pertanyaan besarnya adalah bagaimana cara parsing text serial secara efektif? Apakah manual saja? Secara tukang solder ini memiliki pengalaman buruk dengan parsing serial ! Teringat bahwa modul GPS receiver banyak dijual sebagai interfacing Arduino dan pastinya ada Library jadinya, dan benar saja beberapa library terpampang di sketch dan stelah mencoba beberapa kali akhirnya diputuskan untuk menggunakan library TinyGps++ . Kenapa? Karena dengan script examplenya (ada di folder lib nya) alat saya  sukses membaca data GPS dengan bagus. Mari kita berkreasi dengan cara copy paste ala tukang solder ini.



#include <TinyGPS++.h>
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>

static const int RXPin = 0, TXPin = 15; 
//pake RX aja hanya baca data !

static const uint32_t GPSBaud = 4800;



Seperti biasanya menggunakan board arduino versi kecil maka serial portnya harus dengan software serial. Baudrate disesuaikan yaitu 4800




// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

LiquidCrystal lcd(16, 5, 4, 14, 12, 13);



Inisialisai LCD seperti biasa simple aja dan harus diperhatikan Wemos D1 R1 memiliki GPIO yang agak loncat loncat, jadi sesuaikan penamaan portnya jangan sampe salah. Gunakan Google Search jika salah.



void setup()
  Serial.begin(9600);
  ss.begin(GPSBaud);
  lcd.begin(20, 4);

  Serial.println(F("Coba-Coba GPS"));
  Serial.println(F("Menggunakan  TinyGPS++ Dan GPS module"));
  Serial.print(F("Testing TinyGPS++ library v. ")); 
  Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by ahocool with respect to Lib creator  Mikal Hart"));
  Serial.println();
}


Function setup menyatakan bahwa serial dari wemos akan digunakan sebagai console juga untuk melihat hasil pembacaan GPS selain di LCD. keuntungan lainnya adalah memudahkan untuk debugging.


void displayInfo()
{
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
    lcd.setCursor(0,0);
    lcd.print(" ---- GPS VALID ----");
    lcd.setCursor(0,1);
    lcd.print("LAT :");
    lcd.print(gps.location.lat(), 6);
    lcd.setCursor(0,2);
    lcd.print("LONG:");
    lcd.print(gps.location.lng(), 6);    
  
  }
  else
  {
    Serial.print(F("INVALID"));
    lcd.setCursor(0,0);
    lcd.print(" ---GPS INVALID --- ");
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
  
}


Pada sript diatas berfungsi sebagai tampilan GPS ke Serial dan LCD, secara umumnya dapat dilihat class yg umum digunakan :


gps.location.isValid()
gps.location.lat()
gps.location.lng()
gps.date.isValid()
gps.time.hour()
gps.time.minute()
gps.time.second()
gps.time.second()


Untuk loop utama seperti dibawah ini :


void loop()
{
  // Data ditampilkan hanya setelah data selesai di olah 
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("GPSMU pedot brooo! cek kabelmu."));
    while(true);
  }


}


Hasilnya ketika saya jalankan diluar ruangan sangat akurat apalagi saat cuaca ternag dan LED dari GPS rceiver tidak berkedip yg artinya FULLY LOCKED TO 3 SATELLITES.






Tidak terlalu sulit jika kita sudah mengetahui langkah-langkah "googling" yang sesuai untuk meng "oprek" arduino. Untung saja saya punya receiver GPS jadul kalau tidak harus keluar duit 200rb an untuk membeli modul GPS Ublox Neo.

Untuk praktek keliling ke seputaran kompleks perumahan dan mengolah datanya ke database dapat dibaca disini :  https://www.aisi555.com/2020/05/praktek-iot-bermain-dengan-alat-gps.html
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 (27) 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 (75) 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