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

Rabu, 08 Mei 2024

[AI] Kirim Data Suhu LM35 Lewat Radio Amatir / HT


 
Disclaimer : " Penggunaan frekuensi radio amatir merupakan domain dari Kemkominfo, ORARI dan RAPI. Jangan sekali-kali menggunakan frekuensi amatir untuk tujuan lain daripada Amatir Radio yang tunduk pada aturan-aturan baku yang mengikat. Jika perangkat kamu akan memancarkan pembacaan data, silahkan berkomunikasi lanjut dengan pengelola lokal orari setempat agar tidak terjadi masalah dikemudian hari. Tulisan ini hanya sebagai pembuktian teknologi radio untuk pelaporan data jaman sekarang"

Suatu hari ketika saya scanning frekuensi maritim (150Mhz-170Mhz) menggunakan RTL-SDR yang beberapa bulan ini sedang saya gandrungi, terdengar sayup-sayup suara operator yang membacakan laporan cuaca di wilayah syahbandar pelabuhan tanjung perak Surabaya. Suaranya begitu "kurang bersemangat", mungkin karena dia sadar data cuaca untuk kapal shiping line, sudah lengkap dan mudah didapatkan melalui internet atau radar mereka, jadi operator ini hanya menjalankan tugas rutinitas yang harus dia lakukan sesuai perintah instansi. 

Tahukah kamu, di belahan bumi Amerika utara terdapat stasiun radio amateur WWV yang bekerja pada 2,5Mhz, 5Mhz, 10 Mhz, 15 Mhz dan 20Mhz, dimana secara berkala akan memberikan informasi waktu yang akurat berdasarkan jam atom. Yang berbicara di radio adalah suara mesin/komputer. Sempat juga saya melihat youtuber asal kanada yg scanning radio di dekat pelabuhan, laporan cuaca nya dibacakan juga oleh komputer, seperti halnya suara google map ketika kita berkendara dan menggunakan panduan arah.

Lalu teringat lah saya pada suatu kejadian letusan gunung merapi dan gunung agung beberapa tahun yg lalu, dimana laporan kegempaan seismik ditautkan pada sebuah frekuensi radio amatir VHF dengan tone yang berayun jika ada guncangan / letusan di puncak. Dan di wilayah rural seperti pegunungan, radio amatir / HT menjadi sarana komunikasi handalan. Jadi penggunaan radio HT untuk pengiriman data serta warning lumayan masih diperlukan.

Lalu bagaiman sih caranya menggantikan operator manusia menjadi suara text to speech (TTS) layaknya suara google ? Ayo saya share caranya... Pertama-tama tentunya kamu butuh memiliki sepasang radio HT / Walkie Talkie untuk melakukan experimen ini. Dan saya pilihkan merek baofeng yang sedang laris manis digunakan satpam dimana-mana.



Saya akan menggunakan mikrocontroller ESP8266 - Wemos yang berfungsi sebagai :

  1. Pembaca Sensor Suhu LM35
  2. Penerjemah pembacaan suhu menjadi urutan file mp3
  3. Pemutar audio mp3
  4. Pemutus - sambung transmit PTT (Push To Talk) sesuai kebutuhan


Dengan komponen beserta rangkaian secara lengkap seperti ini :



Lalu pertanyaannya apakah ESP8266 dapat memutar file audio langsung tanpa memerlukan player lainnya semacan DF player ? Ooooo itu sudah lama saya tau, dengan memanfaatkan I2S dari generasi ESP8266 atau ESP32 maka memutar file audio sangatlah mudah. Silahkan meluncur ke : https://github.com/earlephilhower/ESP8266Audio untuk belajar bagaimana cara memutar beberapa jenis file audio secara langsung, tanpa atau dengan DAC.

Untuk melakukan generate audio robot, maka gunakan layanan TTS (text to speech) yang versi bahasa Indonesia secara gratis dapat di googling seperti BOTIKA. Kalau punya teman atau saudara yg suaranya renyah dapat juga direkam beberapa file pembacaan angka "satu", "dua", "sebelas" dan lainnya. Seperti contoh yang saya buat dan letakkan di folder /data dibawah directory project arduino saya.



Untuk melakukan upload file suara mp3 ke ESP8266 maka diperlukan library SPIFFS yang memungkinkan ESP memiliki penyimpanan file tersendiri. Langkah pengaturan dan cara upload nya bisa dibaca disini : https://randomnerdtutorials.com/install-esp8266-filesystem-uploader-arduino-ide/.


Sedangkan script lengkap yang bisa kalian coba, saya bagikan secara FREE alias GRATEEESS 


/* Pengubah pembacaan Suhu LM35 ke suara dan dikirim via HT Baofeng  
   www.aisi555.com  08155737755 nyoman yudi kurniawan 2024
   
   Pada IDE gunakan mode clock ESP8266 160MHz, serta mode SPIFFS sebesar 1MB atau lebih
   Pelajari cara "Tools->ESP8266/ESP32 Sketch Data Upload" untuk menyimpan MP3 di SPIFFS
   Baca disini : https://randomnerdtutorials.com/install-esp8266-filesystem-uploader-arduino-ide/
   File mp3 simpan di folder /data pada direktori sketch arduino, dengan nama file berikut
   rekam sendiri di HP/PC atau gunakan layanan text to speech untuk membuat tiap file

   0.mp3  
   1.mp3
   2.mp3
   3.mp3
   4.mp3
   5.mp3
   6.mp3
   7.mp3
   8.mp3
   9.mp3
   10.mp3 ==> sepuluh
   11.mp3 ==> sebelas
   1_1.mp3 ==> belas
   p.mp3  ==> puluh
   d.mp3  ==> derajat
   k.mp3  ==> koma
   s.mp3  ==> ucapan pertama /salam
  
  
  Selanjutnya bisa baca di www.aisi555.com
  Gunakan secara gratis dan bertanggung jawab
  semua aturan penggunaan frekuensi radio amatir mengacu pada ORARI/RAPI/KEMKOMINFO/BALMON
*/

#include <Arduino.h>
#include <ESP8266WiFi.h>

#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"

//sesuaikan pin PTT 
#define ptt 5
#define lm35 A0

int16_t suhu = 337;
uint8_t proses = 0;


AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioOutputI2SNoDAC *out;



void setup()
{
  pinMode(ptt, OUTPUT);
  digitalWrite(ptt, LOW);
  WiFi.mode(WIFI_OFF); 
  Serial.begin(115200);
  delay(1000);
  SPIFFS.begin();
  Serial.println("======= www.aisi555.com ========");
  Serial.println("  kirim Suhu LM 35 ke HT yukkkkk");
  Serial.println("================================");
  
  audioLogger = &Serial;

  //baca suhu LM35 di A0, Vin = 3.3 volt

    int16_t analogValue = analogRead(lm35);
    
    suhu = analogValue  * (3300/1024);
    Serial.println(analogValue);
    Serial.print("Suhu : ");
    Serial.println(suhu);
  

  //awal mulai pertama
  proses=1;
  //kirim PTT dan kirim suara ke HT
  digitalWrite(ptt, HIGH);
  delay(500);
  
  file = new AudioFileSourceSPIFFS("/s.mp3");
  out = new AudioOutputI2SNoDAC();  
  mp3 = new AudioGeneratorMP3();
  mp3->begin(file, out);
}


void tts(int16_t angka) //disini proses memilih angka jadi file mp3
{   
    uint8_t pilih;
    if (proses == 2) {
       pilih = angka/100;

      if ( angka <200 && angka >=120 ) pilih = (angka /10) % 10;
      else if (angka <120 && angka >=110) pilih =11; 
      else if (angka <110 && angka >=100) pilih =10;
      else if (angka <100 && angka >=0) pilih = angka /10;
    
    }
    else if (proses == 4){  
      pilih = (angka /10) % 10;
      if (pilih == 0) return;
      if (angka <200 && angka >=0) return;  
    
    }
    else if (proses == 6) pilih = angka % 10;

   switch (pilih) {
     case 0 : file = new AudioFileSourceSPIFFS("/0.mp3");
        break;
     case 1 : file = new AudioFileSourceSPIFFS("/1.mp3");
        break;
     case 2 : file = new AudioFileSourceSPIFFS("/2.mp3");
        break;
     case 3 : file = new AudioFileSourceSPIFFS("/3.mp3");
        break;   
     case 4 : file = new AudioFileSourceSPIFFS("/4.mp3");
        break;
     case 5 : file = new AudioFileSourceSPIFFS("/5.mp3");
        break;
     case 6 : file = new AudioFileSourceSPIFFS("/6.mp3");
        break;
     case 7 : file = new AudioFileSourceSPIFFS("/7.mp3");
        break;
     case 8 : file = new AudioFileSourceSPIFFS("/8.mp3");
        break;
     case 9 : file = new AudioFileSourceSPIFFS("/9.mp3");
        break; 
     case 10 : file = new AudioFileSourceSPIFFS("/10.mp3");
        break;        
     case 11 : file = new AudioFileSourceSPIFFS("/11.mp3");
        break;
   }

  out = new AudioOutputI2SNoDAC();  
  mp3 = new AudioGeneratorMP3();
  mp3->begin(file, out);
   
}




void loop()
{
  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    
    if(proses == 7){
      
    proses =1;
    Serial.printf("MP3 play selesai\n");
    //matikan PTT
    digitalWrite(ptt, LOW);


    
    delay(5000);
    //ulang reset ESP agar fresh terus 
    ESP.reset();
 
    }

   else if ( proses == 1){ //puluhan
    proses=2;
    tts(suhu);
   }
   else if ( proses == 2){ //puluh, belas atau lewat
    proses=3;
     
     if( suhu <200 && suhu >=120 ) file = new AudioFileSourceSPIFFS("/1_1.mp3");
     else if( suhu <120 && suhu >=0 ) file = new AudioFileSourceSPIFFS(NULL);
     else file = new AudioFileSourceSPIFFS("/p.mp3");
    
     out = new AudioOutputI2SNoDAC();  
     mp3 = new AudioGeneratorMP3();
     mp3->begin(file, out);
   }   
   else if ( proses == 3){ //satuan
    proses=4;
    tts(suhu);
   }    
   else if ( proses == 4){ // koma
     proses=5;
     file = new AudioFileSourceSPIFFS("/k.mp3"); 
     out = new AudioOutputI2SNoDAC();  
     mp3 = new AudioGeneratorMP3();
     mp3->begin(file, out);
   }  
   else if ( proses == 5){ //desimal
    proses=6;
    tts(suhu);
   } 

   else if ( proses == 6){ //derajat
     proses=7;
     file = new AudioFileSourceSPIFFS("/d.mp3");
     out = new AudioOutputI2SNoDAC();  
     mp3 = new AudioGeneratorMP3();
     mp3->begin(file, out);
   }
     
  }
}

Dan jika kalian sukses dan beruntung (karena setiap kali compile hasilnya bisa error mulu, jadi kesabaran adalah kunci), akan kira-kira seperti video dibawah 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:

ESP8266 - @Telegram_Bot - Part 3 : Python Matplotlib Graph DHT11

 



Python sebagai bahasa pemrograman yang dikhususkan buat pecinta data science memiliki berbagai fasilitas dan module untuk visualisasi data. Saking banyaknya sampai tiap coder memiliki stylenya masing-masing tergantung yg disukainya. Namun yg paling umum dipakai adalah Matplotlib.


Matplotlib adalah library python yang cukup lengkap untuk membuat visualisasi statis, animasi, dan interaktif . Matplotlib membuat hal-hal mudah menjadi mudah dan hal-hal sulit menjadi mungkin. seperti :


Membuat

  • Kembangkan plot kualitas bagus hanya dengan beberapa baris kode
  • Gunakan figur interaktif yang dapat memperbesar, menggeser, memperbarui...


Sesuaikan

  • Kendalikan penuh gaya garis, properti font, properti sumbu...
  • Ekspor dan sematkan ke sejumlah format file dan lingkungan interaktif


Extended

  • Jelajahi fungsionalitas yang disesuaikan yang disediakan oleh paket pihak ketiga
  • Pelajari lebih lanjut tentang Matplotlib melalui banyak sumber belajar eksternal 

Tanpa berpanjang lebar lagi, saya akan lanjutkan pembahasan sebelumnya yaitu menulis data DHT11 - MQTT ke database SQLite ( disini ) , dan selanjutnya melalui matplotlib akan di ubah menjadi visualisasi grafis yang menarik. Script lengkapnya sebagai berikut :


import sqlite3
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser
from matplotlib import style


def graph_data():
# Connect to database
sqlite_file = 'humitemp.db' #sesuaikan nama db
conn = sqlite3.connect(sqlite_file)
c = conn.cursor()
style.use('seaborn-bright')

c.execute('SELECT * FROM dht11 ORDER BY date DESC LIMIT 50')
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("Data Lingkungan Kamar")

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

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

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

# 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.show()
c.close()
conn.close()

if __name__ == '__main__':
graph_data()



Penjelasannya seperti berikut , modul python yg digunakan  :


import sqlite3
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser
from matplotlib import style


Untuk koneksi ke database, pastikan data sudah tersedia  dari praktek sebelumnya dan saya menggunakan 50 data terakhir pada database.


def graph_data():
# Connect to database
sqlite_file = 'humitemp.db' #sesuaikan nama db
conn = sqlite3.connect(sqlite_file)
c = conn.cursor()
style.use('seaborn-bright')

c.execute('SELECT * FROM dht11 ORDER BY date DESC LIMIT 50')
data = c.fetchall()


Setelah itu data dari database saya buatkan list, kemudian saya masukkan satu persatu dan tambahkan Xaxis berupa data waktu. 


    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("Data Lingkungan Kamar")


Berikut ini plotingnya berdasarkan time series, dan saya tambahkan Yaxis kedua (twinx) agar grafiknya lebih simple.


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

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

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


Dan kemudian saya tampilkan grafiknya beserta legenda dan label-labelnya.


    # 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.show()
c.close()
conn.close()



Hasilnya seperti berikut :



Pada tulisan berikutnya akan saya kasi tahu cara menggabungkan kesemuanya, sehingga bot telegram dapat menampilkan data berupa grafik secara real time.
Share:

ESP8266 - @Telegram_Bot - Part 2 : Database

 



Perlu dipahami dan disadari bagi para pembaca sekalian, ESP8266 adalah microcontroller yang sangat terbatas resource nya, baik dalam ukuran ram/rom serta kemampuan untuk penggunaanya dalam komputasi lebih lanjut. Salah satunya adalah ketika penulis mencoba memanfaatkan micropython pada esp8266 apakah mampu langsung berkomunikasi dengan bot telegram? Ternyata limitasinya terjadi pada memori ram, yg kurang bersahabat saat menggunakan jalur SSL certificate. Apalagi ketika berbicara tentang database, mungkin bisa, namun sangat disarankan untuk menggunakan jembatan lainnya berupa komputer yang berbasis 32/64 bit seperti raspberry pi atau PC sekalipun.

Sebenarnya tujuan menulis di part 2 ini adalah jembatan untuk praktek akhir menampilkan grafik suhu dan kelembaban yang akan ditampilkan pada telegram bot. Untuk itu akan dibahas terlebih dahulu cara menyimpan data pembacaan sensor DHT11 pada database. Secara singkat jalan ceritanya seperti berikut:  pembacaan sensor DHT11 akan dikirimkan oleh wemos/esp8266 secara MQTT PUB ke broker, sedangkan PC saya yg terinstal SQL Lite dan  python sebagai bahasa pemrogramannya yg akan satu persatu menyisipkan data ke tabel dbase saat ada pesan SUB dari broker MQTT.


Langkah pertama adalah dengan melakukan instalasi SQLite pada website : https://www.sqlite.org/download.html , pilih yg sesuai dengan environtmet pc yg kamu gunakan lalu buatlah tabel dengan nama dht11 seperti gambar dibawah ini :



Jadi kita akan menyimpan pembacaan suhu dan kelembaban, ditambahkan juga kolom date yg merupakan waktu dari data sensor diterima. Pengiriman data ini dilakukan melalui MQTT, jadi sebelumnya harap dipahami praktek sebelumya disini : https://www.aisi555.com/2021/08/wemos-esp-8266-part-5-mqtt-ke-aplikasi.html , namun data yang kita kirim disini berupa  JSON teks dengan format seperti berikut :


'{"suhu":"30.00" , "humi":"89.0"}'


Untuk script Arduino-Esp8266-MQTT Publish data ke broker hivemq seperti berikut ini :


#include <ESP8266WiFi.h>
#include <PubSubClient.h> //library pubsub by o'leary
#include "DHT.h"


const char *ssid =  "Nama wifi";   // Gunakan sesuai wifi kamu
const char *pass =  "password";   //

//inisialisasi broker
const char *mqtt_server = "broker.hivemq.com"; //BROKER GRATIS
const int mqtt_port = 1883;
const char *mqtt_user = "";
const char *mqtt_pass = "";
const char *mqtt_client_name = "namamu123456"; // Client connections random dan gak boleh sama

// Daftar Topik disingkat, karena biasanya panjang-panjang namanya
#define TOPIC "/aisi555/dht"


//IO pin
const int dhtPin = 13; //pin DHT di wemos

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

//Timer
unsigned long previousMillis = 0;
const long interval = 5000;   // interval pengambilan dht 11

WiFiClient wclient;            //wifi client terhubung lib pubsub
PubSubClient client(wclient);

void setup() {
  //Inisialisasi broker & Callback sub message
  client.setServer(mqtt_server, mqtt_port);
  Serial.begin(9600);
  delay(10);
  Serial.println();
  Serial.println();
  setupwifi();
  dht.begin();
}

void setupwifi()
{
   if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Terhubung Ke Wifi:  ");
    Serial.print(ssid);
    Serial.println("...");
    WiFi.begin(ssid, pass);

    if (WiFi.waitForConnectResult() != WL_CONNECTED)
      return;
    Serial.println("WiFi Terhubung");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }
}

void reconnectmqtt() //function mengatur koneksi ke broker 
{
   
    
      Serial.println("Connecting to MQTT server..");
     
      if (client.connect(mqtt_client_name,mqtt_user, mqtt_pass)) {
        Serial.println("Connected to MQTT server");
      } else {
        Serial.println("Could not connect to MQTT server");   
      }
   
  
}



// Non-Blocking delay agar gak ganggu proses utama
void SendTempHumid(){
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis >= interval) {
    // cek interval  
    previousMillis = currentMillis;   
 
    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 jsondht="{\"suhu\" : \""+String(t)+"\" , \"humi\" : \""+String(h)+" \" } ";

    //yg dibawah ini metode pengiriman PUB ke TOPIC
    //dikirim perbyte message + header nya
    //sudah dimudahkan oleh library pubsub

    Serial.println("publish to topic: " );
    Serial.print(TOPIC);
    Serial.print(" : ");
    Serial.println(jsondht);
    char message_buff[jsondht.length() + 1];
    jsondht.toCharArray(message_buff, jsondht.length() + 1);
    client.publish(TOPIC,message_buff );

   

  }

}





void loop() {
 
  if (!client.connected()) 
   {
    reconnectmqtt();
   }
   else client.loop(); //cek terus kalau ada data masuk
  
  
  SendTempHumid();
  
}

 

Script diatas sudah sering saya bahas, jadi bila belum paham agar membaca dulu disini. Selanjutnya script untuk memasukkan nilai suhu (desimal) dan kelembaban (integer) ke dalam sqlite seperti dibawah ini, dan pastikan tabel database kamu type datanya sudah sesuai. 


from paho.mqtt import client as mqtt_client
import random, json, sqlite3, datetime, time

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

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


def sql_insert(s,h):
db = sqlite3.connect("blog_aisi555.db") #sesuaikan nama DB
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()

# koneksi
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 mqtt broker
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
if (msg.topic == topicdht):
data= json.loads(msg.payload.decode())
suhu = float(data["suhu"])
humi = float(data["humi"])
sql_insert(suhu,humi)
# daftar pada topic
client.subscribe(topicdht)
client.on_message = on_message

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


if __name__ == '__main__':
run()


Penjelasannya seperti berikut :



Library yang dipakai bermacam, mulai dari mqtt sampai json .

from paho.mqtt import client as mqtt_client
import random, json, sqlite3, datetime, time


Inisialisasi MQTT broker :


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

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


Koneksi ke broker dimulai pada routine berikut :



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


Sedangkan yang ini proses subscribe dari topik dan kemudian menungu pesan masuk :


def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
if (msg.topic == topicdht):
data= json.loads(msg.payload.decode())
suhu = float(data["suhu"])
humi = float(data["humi"])
sql_insert(suhu,humi)
# daftar pada topic
client.subscribe(topicdht)
client.on_message = on_message



Script diatas ada yg khusus berupa parsing data suhu dan kelembaban menggunakan json :



            data= json.loads(msg.payload.decode())
suhu = float(data["suhu"])
humi = float(data["humi"])
sql_insert(suhu,humi)



Kemudian Routine sql_insert( t, h) akan memasukkan data suhu dan kelembaban menuju tabel database. Sebelumnya data waktu akan ikut dimasukkan juga :

 
def sql_insert(s,h):
db = sqlite3.connect("blog_aisi555.db")
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()


Dan hasilnya seperti berikut ini.




Untuk selanjutnya di tulisan berikutnya akan kita masukkan data suhu dan kelembaban pada database diatas kedalam grafik python MATPLOTLIB.
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 (12) antares (11) arduino (26) 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) iklan (1) infrared (2) Input Output (3) iot (72) 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 (1) 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 (3) transistor (2) troubleshoot (3) tulisan (93) 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