Semua Akan Digital Pada Akhirnya... Dari Audio, Video, TV, Kontrol, Keuangan, Kesehatan dan Sebagainya. Blog Ini Ditujukan Buat Kamu Yang Ingin Belajar Dasar Digital Dan Yang selalu Bertanya, Kenapa Bisa Begini Dan Harus Begitu ?

  • 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

  • Kontrol Perangkat Rumah Dari Internet

    Internet Of Things sudah menjadi istilah yang semakin dikenal orang. Mau tahu bagaimana konsep, cara pembuatan dan pemanfaatannya ?

  • 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

Jumat, 17 September 2021

Penjelasan Proses Input Output Dan Register I/O Pada Microcontroller AVR

 



Proses Input dan Output pada sebuah microcontroller dapat dipastikan melibatkan perubahan dan akses pembacaan dari REGISTER I/O . Ini tentu saja bertujuan untuk memudahkan pengaksesan dari semua Port atau Pin I/O pada microcontroller,  dengan cara menautkannya secara hardware pada sebuah alamat memory tertentu. Inilah memory khusus yang dinamakan Register I/O. Perhatikan datasheet dari IC kesayangan saya dibawah ini ATTiny 2313 dimana saya mencuplik Register I/O untuk Port B.




  • PORTB (0x18) : Merupakan Register untuk merubah nilai dari port B ketika berfungsi sebagai output
  • DDRB (0x17) : Merupakan Register untuk merubah arah data tiap Pin pada Port B apakah akan menjadi input atau output
  • PINB (0x19) : Merupakan Register untuk membaca (walau menulis bisa namun jarang) data yg didapatkan pada tiap tiap Pin B apakah bernilai 1 (5Volt) atau 0


Jadi ke 8 buah kaki yang diberi nama PORTB pada microcontroller ATTiny 2313 secara hardware terkoneksi pada 3 buah Register input output seperti gambar diatas. Perhatikan gambar rangkaian berikut ini dimana saya akan menempatkan sebuah LED pada Port B#0 dan sebuah Switch / Tombol (kalau beli di online namanya Tactile Switch)  pada  Port B#1







Penjelasan Rangkaian : 

  1. Vcc terhubung ke tegangan catuan 5 Volt, untuk ATTiny 2313 bisa menggunakan catuan baterai 3 volt atau menggunakan tegangan 5volt yg didapatkan dari downloader USB ASP.
  2. R1 mutlak diperlukan sebagai pengaman LED, nilai berkisar 100 s/d 470 ohm.
  3. Switch diberikan Resistor Pull Down 10Kohm agar mendapatkan default tegangan 0 volt atau Logic LOW saat tidak ada penekanan tombol, dan ketika terjadi penekanan tombol maka PIN microcontroller yg terhubung akan tersambung dengan VCC (5 volt) dan berarti mendapatkan logic HIGH.
  4. AVRISP merupakan header standar menuju programmer ISP seperti yg saya jelaskan sebelumnya disini : https://www.aisi555.com/2021/08/usb-asp-isp-programmer-untuk-avr.html


Bagaimana Flow Chart untuk menghidupkan dan mematikan ( Led Kedip)  LED di PortB#0 ?


Catatan :

Delay merupakan fungsi / routine khusus yg pada compiler atau IDE programming microcontroller yg sudah tersedia dan siap pakai. Pada intinya delay merupakan timer yg BLOCKING yang artinya menghentikan semua proses dan menunggu sampai counternya selesai sesuai nilai waktu yg diberikan. Jadi ingat delay ini sangat tidak disarankan untuk proses yang kompleks karena akan mengehentikan semua proses pada microcontroller.


Scriptnya seperti ini : 


#define F_CPU 1000000UL // frekuensi clock internal 1Mhz
#include <avr/io.h> // definisi library standar IO port
#include <util/delay.h> // definisi include untuk delay


int main(void)

{



	DDRB=0b00000001 ; // Inisialisasi bahwa port B#0 Output
    


	while(1)

	{

		PORTB=0b1; //port B#0 = 1 atau nyala

		_delay_ms(1000); //delay 1 detik
			

		PORTB=0b0; //port B#0 = 0 atau mati

		_delay_ms(1000); //delay 1 detik


	}
	
}

Penjelasan :

  • Langkah pertama adalah menentukan arah data dari PORT B#0 menjadi output dengan perintah DDRB=0b00000001. Ini oleh compiler GCC akan diterjemahkan menjadi menuliskan ke alamat memory Register 0x17 dengan nilai berupa 0b00000001
  • Untuk menyalakan LED di PORT B#0 maka dilakukan penulisan di alamat register PORTB (0x16)  dengan nilai 0b00000001. Agar lebih menyingkat dan lebih bergaya bahasa C yg benar dapat ditulis sebagai :  PORTB = 0x1.
  • Untuk mematikan LED cukup memberikan nilai 0 pada PORTB .


Lalu bagaimana jika Output LED saya tempatkan pada port 5 dan 6 ? Sebaiknya harus membaca penjelasan operasi geser byte disini : https://www.aisi555.com/2012/06/operasi-geser-byte-pada-win-avr-gcc.html. Jadi untuk melakukan blink atau kedip bergantian pada 2 buah LED secara simplenya scriptnya seperti berikut:



#define F_CPU 1000000UL // frekuensi clock internal 1Mhz
#include <avr/io.h> // definisi library standar IO port
#include <util/delay.h> // definisi include untuk delay


int main(void)

{

        // Inisialisasi bahwa port B#5, B#6 Output
DDRB |= (1<<PB5) | (1<<PB6) ; while(1) { PORTB |=(1 << PB5) ; //port B#5 nyala                 PORTB &=~(1 << PB6); //Port B#6 Mati         _delay_ms(1000); //delay 1 detik
		PORTB |=(1 << PB6) ; //port B#6 nyala
                PORTB &=~(1 << PB5); //Port B#5 Mati
        	_delay_ms(1000); //delay 1 detik
} }


Penjelasan :

  • Untuk melakukan SET BIT pada bit tertentu pada sebuat BYTE, maka bisa melakukan operasi geser Byte seperti contoh diatas   DDRB |= (1<<PB5) | (1<<PB6) dimana nilai yg dirubah pada bit ke 5 dan ke 6 saja dengan nilai bit = 1.
  • Jika susah untuk memahami, cukup dengan mengikuti polanya saja, dimana ketika ingin meng "CLEAR" ataui memberikan nilai 0 pada bit tertentu bisa menggunakan pola penulisan        PORTB &= ~(1<<PB5) & ~(1<<PB6) , dimana artinya Port B#5 dan Port B#6 diberikan nilai 0 pada masing-masing bit, tanpa merubah nilai bit disebelahnya yang tidak ikut dalam proses.


 
Bagaimana Flow Chart untuk menerima input pada PIN B#1 dan berinteraksi dengan LED di PORT B#0 ?




Scriptnya sederhana saja seperti berikut :


#define F_CPU 1000000UL // frekuensi clock internal 1Mhz
#include <avr/io.h> // definisi library standar IO port
#include <util/delay.h> // definisi include untuk delay


int main(void)

{
        DDRB |= (1<<PB0) ;   //Port B#0 Output
        DDRB &= ~(1<<PB1) ;  //Pin B#1 Input
while(1)      { if (PINB & (1 << PINB1)) PORTB |=(1 << PB0); // PB#0 Nyala else PORTB &= ~(1 << PB0); //Port B#0 Mati     }  
             }


Penjelasan :

  • if (PINB & (1 << PINB1))  , script ini berarti melihat apakah PIN pada microcontroller diberikan nilai 1 atau SETBIT. Ini merupakan macro standar pada basa GCC - Winavr, yang kemudian disempurnakan lagi menjadi  :  bit_is_set(PINB, PINB1) untuk nilai logic 1 dan bit_is_clear(PINB, PINB1) untuk nilai logic 0. 
  • Kita tidak perlu dipusingkan dengan proses pembacaan pada Register dengan alamat 0x16, ini sudah dipermudah dengan bahasa GCC-Winavr yg sudah menterjemahkan semua nama Mnemonic menjadi alamat registernya.
  • Ingat pada bahasa GCC WINAVR , istilah PORT untuk output, sedangkan PIN untuk input 


Untuk berikutnya silahkan dicoba menjalankan script berikut dan perhatikan apa yg terjadi :



#define F_CPU 1000000UL // frekuensi clock internal
#include <avr/io.h> // definisi standar io port
#include <util/delay.h> // definisi include untuk delay


int main(void)

{


	DDRB |= (1<<PB0) ;   //Port B#0 Output
	DDRB &= ~(1<<PB1) ;  //Pin B#1 Input
	
 bool pencet =false;

	while(1)

	{


		if (bit_is_set(PINB,PINB1) ) {
			
			 if(pencet == false) pencet = true;
			 else pencet = false;
	   		 
			_delay_ms(200);
		}

       if(pencet == true) PORTB |= (1<<PB0);
	   else  PORTB &= ~(1<<PB0);
	


	}
	
}


Script diatas menggunakan variabel boolean   bool pencet =false;  merupakan jenis variabel yg bernilai 1 atau TRUE dan 0 atau FALSE.  Silahkan cari di google atau di blog ini pun sudah dibahas bagaimana cara men - "toogle" atau merubah kondisi dari state BIT sebelumnya dengan teknik yg lebih cepat.  


Selamat Mencoba !
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

HP: 081331339072
Mail : ahocool@gmail.com

Site View

Categories

555 (8) 7 segmen (3) adc (4) amplifier (2) analog (15) android (12) antares (3) arduino (21) artikel (11) attiny (3) attiny2313 (19) blog (1) bluetooth (1) cmos (2) crypto (2) dasar (45) digital (1) display (3) esp8266 (25) euro2020 (13) gcc (1) iklan (1) infrared (2) Input Output (3) iot (44) jam (7) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (16) komputer (3) komunikasi (1) kontrol (7) lain-lain (8) lcd (2) led (14) led matrix (6) line tracer (1) lm35 (1) MATV (1) memory (1) metal detector (4) microcontroller (70) micropython (6) mikrokontroller (12) mikrotik (5) mqtt (2) ninmedia (3) ntp (1) paket belajar (19) palang pintu otomatis (1) parabola (78) pcb (2) power (1) praktek (2) project (33) proyek (1) python (4) radio (15) raspberry pi (4) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (1) 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 (145) television (28) transistor (2) troubleshoot (3) tulisan (83) tutorial (80) tvri (2) vu meter (2) vumeter (2) wav player (3) wayang (1) wifi (3)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika