"Kembali Ke Dasar Elektronika Digital ... "

  • 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

  • Animasi LED Dengan IC 4017

    IC 4017 adalah IC 16-pin CMOS dekade counter dari seri IC CMOS 4000. Sangat berguna jika ingin membuat animasi lampu atau LED secara sederhana seperti led berjalan, tulisan berjalan , counter/timer dan masih banyak kegunaan lainnya

  • 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

  • BIKIN PCB SEDERHANA TAPI GA MURAHAN

    Bikin PCB itu ga susah kok..dengan software EAGLE CAD dan teknik sterika kamu dapat membuat PCB untuk berbagai project elektronika mu ...

Jumat, 29 Mei 2020

[Praktek] Love Hurt 2020 - Remake pake Arduino




Lama banget gak utak-atik LED MATRIX padahal barang satu ini favorit saya sejak kuliah 20 tahun yang lalu. Kekaguman saya pada benda ini berawal saat tahun 90an saya sering diminta teman membuat LED susun menjadi tulisan tertentu dan kemudian digabung dengan IC 4017 agar menjadi efek gerak kedip kanan kiri, sayangnya karakter yg dibentuk gak bisa diubah. Dan saat saya kuliah ketemu dot matrix yang gak lain led disusun yang bisa diubah ubah tampilannya sesuai keinginan. Bahkan ingatan saya masih clink pada tahun 1998 di atas atap kampus Elektro ITS terpampang text berjalan dari Bohlam yg disusun menjadi seperti LED matrix berukuran super besar. 


Tuh saya masih inget bikin generator susunan led ke bit / hex yang nantinya dimasukkan ke script atmel studio. Dulu saya pake IC legendaris ATTINY 2313 dan banyak yang belajar dari modul pembelajaran (yang saya jual paketan) dimana praktek terakhirnya bikin teks berjalan pada satu marix yang bisa dibaca disini. Kini sudah tahun 2020 saya ingin membagi ilmu nya kembali dengan format lebih jaman now menggunakan Arduino. Lanjut kumpulin bahan-bahannya yuk...


Bahan-bahan dapat disesuaikan dengan yang ada dirumah aja jangan kaku sampe harus beli (walau murah tinggal klik olshop). Rangkaian nya sangat simple karena akan menggunakan pin I/O nomer 2-8 sebagai BARIS dan pin 9-13 sebagai KOLOM dari led matrix. Sebaiknya jika bingung prinsip penyalaan LED MATRIX bisa dibaca dulu dasarnya disini.



Karena Arduino Pro Mini yg saya gunakan memakai header cowok maka sangat simple menyambungkannya  ke Led Matrix dengan menggunakan kabel jumper cewek ke cewek. Tinggal colok seperti gambar dibawah. Kalau pake arduino jenis lain tinggal sesuaikan saja.


Mari kita bahas scriptnya secara mendalam..jangan sampe pusing ya ! Pegangan kalau kepala sudah muncul bintang nya..hehehe


- Penyusunan Karakter di Memori

const byte love1[5] =
{
0b0011110,
0b0100001,
0b1000010,
0b0100001,
0b0011110

};

const byte love2[5] =
{
0b0001100,
0b0010010,
0b0100100,
0b0010010,
0b0001100

};

Untuk menyusun karakter diatas anda butuh mengunduh software TextToBit yang saya kerasikan disini. Jadi saya ingin membuat animasi jantung berdenyut dengan 2 frame karakter yang dinyalakan bergantian (kalau mau banyak ya lebih keren juga). Jadi prinsipnya menyusun BIT sedemikian rupa agar karakter terwakili pada led dengan kombinasi 7 output BARIS (HIGH) vs 5 output KOLOM (LOW). Perhatikan gambar berikut ya ...


Dari gambar dapat dibayangkan bahwa BIT biner pada array (BARIS)  diatas menunjukkan  nilai 1 berarti LED NYALA dan sebaliknya. Selanjutnya akan di scanning KOLOM nya satu persatu secara cepat dan mata melihat sebagai satu gambar utuh. Karena Matrix yg kita gunakan 7x5 maka cukup menggunakan 7 bit saja per baris. 

- Inisialisasi PIN I/O

#define BARIS1 2
#define BARIS2 3
#define BARIS3 4
#define BARIS4 5
#define BARIS5 6
#define BARIS6 7
#define BARIS7 8
#define KOLOM1 9
#define KOLOM2 10
#define KOLOM3 11
#define KOLOM4 12
#define KOLOM5 13


byte kolomnya[5]= {KOLOM1,KOLOM2,KOLOM3,KOLOM4,KOLOM5} ;
byte barisnya[7] = {BARIS1,BARIS2,BARIS3,BARIS4,BARIS5,BARIS6,BARIS7} ;

void setup() {
   //BARIS
   pinMode(BARIS1, OUTPUT);
   pinMode(BARIS2, OUTPUT);
   pinMode(BARIS3, OUTPUT);
   pinMode(BARIS4, OUTPUT);
   pinMode(BARIS5, OUTPUT);
   pinMode(BARIS6, OUTPUT);
   pinMode(BARIS7, OUTPUT); 

   //KOLOM
   pinMode(KOLOM1, OUTPUT);
   pinMode(KOLOM2, OUTPUT);
   pinMode(KOLOM3, OUTPUT);
   pinMode(KOLOM4, OUTPUT);
   pinMode(KOLOM5, OUTPUT);

}


Tujuan membuat array yang isinya PIN I/O untuk kolom dan baris adalah memudahkan proses geser BIT saat scanning dan penyalaan LED. Ini karena arduino menggunakan penamaan PIN sebagai Port I/O tersendiri bukan seperti Attiny dan microcontroler AVR lainnya yg PORT disesuaikan dengan register portnya masing-masing selebar 8 bit sehingga mudah melakukan operasi geser bit. Ini bedanya tukang solder yg pernah belajar microcontroller menggunakan bahasa assembly dengan yang langsung lompat menggunakan arduino. Kalau anda langsung menggunakan Arduino mungkin akan kebingungan memahaminya.


- Function Untuk Menulis Karakter


void tulis(int lama, byte *dot)
{

for(int a=0 ; a<lama ; a++)
{
 for(int b=0 ; b<5 ; b++)         
  {

   for( int c=0;c<5 ; c++){
       if( c == b) digitalWrite(kolomnya[c],LOW );
       else digitalWrite(kolomnya[c],HIGH );
        }
   

   for(int d=0;d<7;d++) {
         digitalWrite(barisnya[d], ((1<<d) & dot[b]) >> d );       
         }
   delay(2);
   blank();
   delay(1);    
  }
 }
}

Kita akan bahas baris per baris fungsi diatas agar gampang memahaminya.


void tulis(int lama, byte *dot)

Lama = waktu lama for loop dijalankan agar menunjukan lama tampilnya sebuah karakter.
*dot   = Pointer ke array yang akan melewatkan 7 bit baris karakter

Terdapat 4 buah FOR LOOP yaitu :

a = Loop lama tampil sebuah karakter 
b = Scanning KOLOM
c = Geser kolom (LOW)
d = Geser baris (HIGH)

Kita akan breakdown for loop C dan D :

for( int c=0;c<5 ; c++){
       if( c == b) digitalWrite(kolomnya[c],LOW );
       else digitalWrite(kolomnya[c],HIGH );
        }

Ketika scanning kolom satu persatu maka yg bergerak adalah memberikan pin i/o sebagai  LOW / 0, jadi kalau diberikan perintah secara manual akan menjadi  :

if ( b == 0 ) { 
                        digitalWrite(KOLOM1, LOW);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                    }

else if ( b == 1 ) { 
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, LOW);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                    }

else if ( b == 2 ) { 
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, LOW);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                    }

else if ( b == 3 ) { 
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, LOW);
                        digitalWrite(KOLOM1, HIGH);
                    }

else if ( b == 4 ) { 
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, HIGH);
                        digitalWrite(KOLOM1, LOW);
                    }


Terlalu panjang, namun mudah dimengerti dan merupakan terjemahan isi dari FOR LOOP C yang hanya 4 baris saja.


for(int d=0;d<7;d++) {
         digitalWrite(barisnya[d], ((1<<d) & dot[b]) >> d );       
         }

For Loop D memiliki keunggulan geser bit dengan hanya sebaris script, tapi untuk memahaminya butuh penjabaran yaitu :

GESER BIT  1 :  (1<<d) & dot[b] 
GESER BIT  2 :   >> d 

Semisal nih..7 BIT baris yg akan dinyalakan adalah 0b0001100 , dimana 0 = mati , 1 = nyala. Sehingga kita perlu mengetahui bit yg sesuai dengan PIN i/o yg bersesuaian juga. Inilah hubungan kita membuat ARRAY yg berisikan nomer PIN. 

Jadi dengan 7 kali loop maka kita akan tau PIN BARIS ke X  itu mati atau nyala. Penejelasannya seperti berikut :

saat d=0 , maka angka 1 geser kiri sebanyak 0 kali = 0000001 , lanjut di AND dengan isi semuanya  0001100 hasilnya = 00000000, kemudian geser kanan semuanya sebanyak 0 kali hasilnya PIN BARIS1 = 0 /MATI

saat d=1 , maka angka 1 geser kiri sebanyak 1 kali = 0000010 , lanjut di AND dengan isi semuanya  0001100 hasilnya = 00000000, kemudian geser kanan semuanya sebanyak 1 kali hasilnya PIN BARIS2 = 0 /MATI

saat d=2 , maka angka 1 geser kiri sebanyak 2 kali = 0000100 , lanjut di AND dengan isi semuanya  0001100 hasilnya = 00000100, kemudian geser kanan semuanya sebanyak 2 kali hasilnya PIN BARIS3 = 1 /NYALA


saat d=3 , maka angka 1 geser kiri sebanyak 3 kali = 0001000 , lanjut di AND dengan isi semuanya  0001100 hasilnya = 00001000, kemudian geser kanan semuanya sebanyak 3 kali hasilnya PIN BARIS4 = 1 /NYALA

saat d=4 , maka angka 1 geser kiri sebanyak 4 kali = 0010000 , lanjut di AND dengan isi semuanya  0001100 hasilnya = 00000000, kemudian geser kanan semuanya sebanyak 4 kali hasilnya PIN BARIS5 = 0 /MATI

saat d=5 , maka angka 1 geser kiri sebanyak 5 kali = 0100000 , lanjut di AND dengan isi semuanya  0001100 hasilnya = 00000000, kemudian geser kanan semuanya sebanyak 5 kali hasilnya PIN BARIS6 = 0 /MATI

saat d=6 , maka angka 1 geser kiri sebanyak 6 kali = 1000000 , lanjut di AND dengan isi semuanya  0001100 hasilnya = 00000000, kemudian geser kanan semuanya sebanyak 6 kali hasilnya PIN BARIS7 = 0 /MATI


Seperti itulah proses geser BIT sehingga tiap LED dapat ditentukan mati dan nyalanya .

   delay(2);
   blank();
   delay(1);    


Fungsi blank mengatasi kelembaman mata yg menyebabkan efek LED berbayang (saking cepetnya ) dengan cara mematikan semua LED saat akan pindah  7 bit Baris selanjutnya 


 void blank ()
 {
   digitalWrite(BARIS1,LOW);
   digitalWrite(BARIS2,LOW);
   digitalWrite(BARIS3,LOW);
   digitalWrite(BARIS4,LOW);
   digitalWrite(BARIS5,LOW);
   digitalWrite(BARIS6,LOW);
   digitalWrite(BARIS7,LOW);
   
 }


- Sedangkan untuk LOOP utama cukup singkat aja 

void loop() {


 tulis(10,love1);
 tulis(10,love2);

 }


- Hasilnya :





Selanjutnya ada fasilitas text geser kanan dan naik



Tinggal mengolah sedikit script pada tulisan sebelumnya di 2011.

Bagaimana ? SELAMAT MENCOBA !
Share:

Selasa, 26 Mei 2020

Praktek {IOT} : Bermain dengan alat GPS receiver jadul - Part 2 - MQTT vs GIS



Sebelum melanjutkan membaca lebih kebawah, ada baiknya prolog nya dibaca terlebih dahulu agar tidak kehilangan arah ya! Ini urutan membacanya :


  1. Raspbery Pi Sebagai MQTT Broker Publik
  2. Geopy Library Python Untuk GIS
  3. Bermain GPS Jadul - Part 1
Titik kulminasi dari beberapa tulisan saya setelah gatel meng"oprek" raspi zero w yg di berikan seorang teman, saya curahkan  pada tulisan ini. Jadi dapat dibilang lengkap end to end yang sangat bermanfaat bagi pembaca yg kemungkinan sedang mencari judul tugas atau skripsi. Memang saya sarankan jangan di jiplak langsung karena dapat membunuh kreatifitas, tapi cobalah baca skema paling atas ! Modifikasi di bagian sensor dan output dengan apapun yg kamu inginkan maka ratusan ide judul skripsi dapat kamu kreasikan. 





kalau kita ingat pada 2 tulisan sebelumnya, dapat dilihat keterkaitan kedua gambar yaitu informasi koordinat GPS bisa diberikan oleh arduino ke Raspberry dan kemudian python akan melakukan  Reverse Geopy untuk mendapatkan nama titik koordinat tadi. Ujungnya informasi nama titik yg sudah didapatkan dikembalikan oleh python menuju ke arduino dan ditampilkan pada LCD. Bingung ? Begini kalau dijabarkan secara sederhana.

  • GPS receiver menerima data dari satelit berupa koordinat berformat "Lattitude , Longitude" dan dikirimkan melalui serial/UART ke arduino
  • Arduino mengirimkan informasi (PUBLISH) ke topic "Lattitude , Longitude" ke broker MQTT melalui Wifi
  • Karena alat akan mobile/bergerak maka butuh Smartphone sebagai Hotspot yg akan ikut dibawa berkeliling selain juga berfungsi sebagai internet gateway melalui 3G/4G
  • Raspberry Pi dirumah berfungsi sebagai broker MQTT (Mosquitto) yang terhubungkan ke modem WAN/Internet.
  • Script python pada Raspi melakukan SUBSCRIBE pada topic mqtt dan menunggu informasi koordinat , setelah data tersedia  akan melakukan Geopy Reverse Nominatim untuk mendapatkan nama titik GPS yg dimaksud.
  • Python juga akan melakukan pengiriman data nama titik tadi secara PUBLISH ke topic mqtt sekaligus melakukan penyimpanan data log dalam format csv.
  • Arduino menunggu kiriman data secara SUB pada topik yg sama dengan yg di PUB oleh python dan selanjutnya ditampilkan di LCD 4 x 20.


Selanjutnya saya akan berbaik hati membahas satu per satu bagian dari script nya, akan saya bahas berselingan antara script arduino dan python agar seperti cerita bersambung.


- Insialisasi Arduino 

#include <TinyGPS++.h> // library parsing data gps
#include <LiquidCrystal.h> // library LCD
#include <SoftwareSerial.h> // library serial port tambahan
#include <ESP8266WiFi.h> // library wifi 
#include <PubSubClient.h> // library MQTT dari knoleary
#include "DHT.h" // Librasi sensor DHT

static const int RXPin = 0, TXPin = 15; //pake RX aja hanya baca data !
static const uint32_t GPSBaud = 4800; // kecepatan serial GPS

#define DHTPIN 2 // pin sensor DHT
#define DHTTYPE DHT11 // Saya pake DHT11

//inisialisasi DHT
DHT dht(DHTPIN, DHTTYPE); 
// The TinyGPS++ object
TinyGPSPlus gps;
// Koneksi serial GPS
SoftwareSerial ss(RXPin, TXPin);
//PIN LCD 
LiquidCrystal lcd(16, 5, 4, 14, 12, 13);
//milis agar timer lebih jitu
unsigned long previousMillis = 0;
 //interval pembacaan dht 11 
const long interval = 5000;

const char *ssid =  "Nama wifi mu";   
const char *pass =  "Passwordnya"; 

//inisialisasi client dan server MQTT
WiFiClient wclient;
PubSubClient client(wclient);

const char *mqtt_server = "sesuaikan_nama_server.hopto.org";
const int mqtt_port = 1883;
const char *mqtt_user = "nama user";
const char *mqtt_pass = "password mqtt";
const char *mqtt_client_name = "ahocool123";

String latlong = "invalid"; // variabel koordinat


- Inisialisasi Python  (raspberry pi)


import paho.mqtt.client as mqtt #import modul mqtt client
from geopy.geocoders import Nominatim #import nominatim sebagai geocoder
from datetime import datetime #waktu

humitemp=[""] #list global suhu kelembaban

#inisialisasi geolocator nominatim gratisan

geolocator = Nominatim(user_agent="my-application") 



- Setup Arduino

void setup()
  Serial.begin(9600); // monitor serial
  ss.begin(GPSBaud); // hidupkan software serial u/ gps
  lcd.begin(20, 4); //hidupkan LCD 4 x 20
  dht.begin(); //hidupkan sensor dht 11
  lcd.setCursor(0,0); // awal lcd
  lcd.print("--Network Startup--");
  //Setup MQTT server
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(mqtt_callback);
  delay(10);
  Serial.println();
  Serial.println();
  //konek ke wifi
   if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Connecting to Wifi:  ");
    Serial.print(ssid);
    Serial.println("...");
    WiFi.begin(ssid, pass);
    //tunggu sampe terkoneksi dengan wifi..
    if (WiFi.waitForConnectResult() != WL_CONNECTED)
      return;
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  
   }
}

- Setup Python (Raspberry Pi)

broker_address="localhost" #lokal aja di raspi
broker_port=1883
broker_user="username"
broker_pass="password"
print("creating new instance")
client = mqtt.Client("P1") #create new instance
client.on_message=on_message #attach function to callback
client.username_pw_set(broker_user,broker_pass)
print("connecting to broker")
client.connect(broker_address,broker_port) #connect to broker
 #start the loop
print("Subscribing to topic...")
client.subscribe("/gps") #subscribe ke topik /gps
client.subscribe("/dht") #subscribe ke topik /dht
client.loop_forever()
 #muter terusss


- Function pada Arduino

Function berikut ini memiliki tujuan untuk menunggu koneksi ke broker mqtt, jika sukses terhubung lanjut subscribe pada topik "/lokasi". 

void reconnectmqtt()
{
   
    
    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");   
      }
   

    if (client.connected()){
      Serial.println("subscribe to topic: ");
      client.subscribe("/lokasi"); //subscribe ke topic lokasi point
    }
  
}

Yang dibawah ini merupakan rutin untuk mengambil data GPS dan kemudian menuliskannya ke LCD. Sudah pernah dibahas pada tulisan sebelumnya. Selain outputnya dapat dilihat pada LCD, juga di output monitor melalui serial port/console.

void displayInfo()
{
  Serial.print(F("Location: ")); //kirim ke console serial
  if (gps.location.isValid()) // jika data GPS lengkap dan valid
  {
    Serial.print(gps.location.lat(), 6); //nulis ke serial
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
    lcd.setCursor(0,0);
    lcd.print(F("LAT : "));
    lcd.print(gps.location.lat(), 6); //nulis ke LCD
    lcd.print(F("     "));
    lcd.setCursor(0,1);
    lcd.print(F("LONG: "));
    lcd.print(gps.location.lng(), 6);    
    //jangan lupa informasi koordinat disimpan dalam variabel
    latlong = String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6) ;
  }
  else //jika GPS nya error
  {
    Serial.print(F("INVALID"));
    lcd.setCursor(0,0);
    lcd.print(" ---GPS SEARCHING---");
    
    latlong = "invalid";
  }
// yang dibawah ini untuk menulis tanggal dan jam
  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());
    
    lcd.setCursor(0,2);
    lcd.print(gps.date.month());
    lcd.print(F("/"));
    lcd.print(gps.date.day());
    lcd.print(F("/"));
    lcd.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
    lcd.setCursor(0,2);
    lcd.print(F("Date Err"));
  }

  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());

    lcd.setCursor(10,2);
    if (gps.time.hour() < 10) lcd.print(F("0"));
    lcd.print(gps.time.hour());
    lcd.print(F(":"));
    if (gps.time.minute() < 10) lcd.print(F("0"));
    lcd.print(gps.time.minute());
    lcd.print(F(":"));
    if (gps.time.second() < 10) lcd.print(F("0"));
    lcd.print(gps.time.second());
    
  }
  else //jam error
  {
    Serial.print(F("INVALID"));
    lcd.setCursor(10,2);
    lcd.print(F("Time Err"));
  }

  Serial.println();
  
} 


Yang selanjutnya adalah function untuk pengolahan data sensor DHT11 sekaligus sebagai timer untuk pengiriman data MQTT secara PUBLISH

void baca_dht(){
//timer milis digunakan agar tidak mengganggu proses subscribe mqtt
 unsigned long currentMillis = millis();
   if(currentMillis - previousMillis >= interval) {
    //baca sensor dan simpan waktu terakhir membaca

    previousMillis = currentMillis;   
    float h = dht.readHumidity();
    float t = dht.readTemperature();
   
   // jika sensor ngaco
    if (isnan(h) || isnan(t)) {
      lcd.setCursor(0,3);
      lcd.print(F("..DHT Sensor Err...."));
      return; //This will ensure that data is always sent
    }
    else{ //jika bener nulis LCD
    lcd.setCursor(0,3);  
    lcd.print(F("H="));
    lcd.print(h);
    lcd.print(F(" % "));
    lcd.setCursor(10,3);
    lcd.print(F("T="));
    lcd.print(t);
    lcd.print(F(" C "));
    
    //publish data suhu kelembaban ke topik /dht
    String pubString = String(t)+ "," + String(h);
    Serial.println("publish to topic: /dht : " );
    Serial.println(pubString);
    //serialisasi data mqtt
    char message_buff[pubString.length() + 1];
    pubString.toCharArray(message_buff, pubString.length() + 1);
    client.publish("/dht",message_buff );
    
    //sekalian barengan ngirim data GPS jika ada ke topik /gps
    if(latlong != "invalid")
     {
     Serial.println("publish to topic: /gps : " );
     Serial.println(latlong);
     char message_buffgps[latlong.length() + 1];
     latlong.toCharArray(message_buffgps, latlong.length() + 1);
     client.publish("/gps",message_buffgps );
     }
    }
  }
}

Lanjut nih kita mau bikin function untuk callback / menunggu pesan yg telah di SUBSCRIBE yaitu pada topik "/lokasi". Jika data lokasi telah diterima maka lanjut ditulis ke LCD.

void mqtt_callback(char* topic, byte* payload, unsigned int length) {
  //jika data masuk
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
  Serial.print("Message:");
  //Tulis di serial console
  String message;
  for (int i = 0; i < length; i++) {
    message = message + (char)payload[i];  //Convert *byte to String
  }
   Serial.print(message);
      //biar ringkas saya bikin function baru
   tulis_lokasi(message);
   
}

//function khusus menulis ke LCD hasil reply nama lokasi dari MQTT
void tulis_lokasi(String lokasi)
{

//sedikit tricky untuk membaagi nama yg panjang ke LCD 4x20
//yg ini menentukan berapa bagian baris yg akan ditampilkan 
//trick nya jika dibagi 20 gak genap baris tambahkan 1
int bagian = lokasi.length() / 20;
   if( (lokasi.length() % 20) != 0 ) bagian+=1;
//yg ini menentukan berapa kali layar full akan ditampilkan 
//trick nya jika dibagi 4 gak genap layar tambah 1 lagi
int layar = bagian / 4;
   if( (bagian % 4) != 0  ) layar+=1;

String tulisan[bagian]; //array yg berisikan bagian (20 karakter)

  //loop untuk mengepaskan tampilan LCD sesuai panjang tulisan
  for(int a =0 ; a< bagian ; a++)
   {
    tulisan[a]= lokasi.substring(a*20,(a*20)+20);
    
   }
 // ini ketemu by trial dan error..jangan mumet ya...
  int ujung =0;
  for(int a = 0 ; a < layar ;a++)
    { lcd.clear();
      
      for( int b = 0 ; b < 4 ; b++)
        { 
          ujung++;
          lcd.setCursor(0,b);  
          if(ujung <= bagian) lcd.print( tulisan[ (a*4) + b]);       
        }
      delay(5000); 
   }
   lcd.clear();
   unsigned long currentMillis = millis();
   previousMillis = currentMillis; //biar 5 detiknya dht lancar
}

Untuk loop utama seperti ini :

void loop()
{
  // Jika ada koordinat GPS yg selesai di parsing
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();
 // Jika parsing salah mulu
  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("GPS Mu Matek Bozz..."));
    while(true);
  }
 // Yang ini loop untuk ngecek MQTT nyambung apa tidak
   if (!client.connected()) 
   {
    reconnectmqtt(); // Jika mqtt putus sambungkan lagi
   }
   else client.loop(); //cek terus jaga2 kalau ada data masuk

   baca_dht(); // baca sensor suhu dan kirim2 data
}

##CATATAN##
Ubah panjang maksimum teks dari library MQTT pada file PubSubClient.h

// MQTT_MAX_PACKET_SIZE : Maximum packet size

#ifndef MQTT_MAX_PACKET_SIZE

#define MQTT_MAX_PACKET_SIZE 256

#endif



- Function pada script Python  (raspberry pi)

Function yg dibawah ini bertujuan untuk me Reverse GeoLocator dari koordinat menjadi nama titik atau alamat yg diwakilkan. Data API yang digunakan adalah Nominatim dari OpenStreetMap yang bersifat gratisan, jadi tidak seakurat Google Map API yg berbayar.

def on_message(client, userdata, message): #routine pesan mqtt masuk
    print("message received " ,str(message.payload.decode("utf-8")))
    print("message topic=",message.topic)
    
    if (message.topic == '/gps'): #jika topik /gps
       outF = open("log.csv", "a")
       dateTimeObj = datetime.now()
       kor=str(message.payload.decode("utf-8"))
       location = geolocator.reverse(kor)
       loc = (location.address).split(',')  #ambil nama geo
       lokasi = ''.join(loc) 
       print(lokasi)
       client.publish("/lokasi",lokasi) #kirim ke topik /lokasi
      # dibawah ini untuk menulis log.csv
       outF.write(str(dateTimeObj))
       outF.write(",")
       outF.write(humitemp[0])
       outF.write(",")
       outF.write(kor)
       outF.write(",")
       outF.write(lokasi)
       outF.write("\n")
       outF.close()
    elif (message.topic == '/dht'): #jika topik /dht
       humitemp[0]=str(message.payload.decode("utf-8")) #simpan di var

That's it...telah saya tulis satu persatu dan semoga penjelasannya dirasa cukup jelas. Oh iya untuk menjalankan Script tanpa membuka layar terminal terus menerus, gunakan cara NOHUP seperti dibawah ini :

pi@raspberry:~ $ nohup python3 coba_geopy.py &

Dan selanjutnya biarkan raspberry pi nya menyala sedangkan alat akan kita bawa berkeliling mencari Landmark / Titik terkenal diseputaran rumah. Mau tahu hasil yang saya dapatkan ? Maaf kalau gambarnya kurang jelas tapi berusahalah membaca (pakai kaca pembesar kalau bisa ! wkwkwkw)







Dan script python saya juga memiliki fasilitas untuk menyimpan ke log.csv, jadi bikin dulu header kolomnya dengan notepad seperti halnya membikin file csv pada umumnya. hasil keliling saya seperi ini nih.



Untuk lebih kerennya, file CSV ini dapat juga diolah menjadi informasi GIS pada software Google EARTH ataupun yg paling gampang dengan meng import CSV nya ke google "MY MAPS". Ini fasilitas GRATIS baru dari google dan sangat menarik untuk dicoba.



Jika mau melihat kemana saja kemarin saya jalan-jalan (walau PSBB) saat lebaran hari ke-2 bisa meng klik LINK DISINI.



SELAMAT MENCOBA
Share:

Kontak Penulis



12179018.png (60×60)
+628155737755

HP: 081331339072
Mail : ahocool@gmail.com

Site View

Categories

555 (6) 7 segmen (3) adc (3) amplifier (1) analog (9) android (11) arduino (8) attiny (1) attiny2313 (17) blog (1) bluetooth (1) cmos (2) crypto (2) dasar (35) display (3) gcc (1) iklan (1) infrared (2) Input Output (3) iot (8) jam (6) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (12) komputer (3) komunikasi (1) kontrol (2) lain-lain (8) lcd (2) led (9) led matrix (6) line tracer (1) lm35 (1) memory (1) metal detector (4) microcontroller (50) mikrokontroller (2) mikrotik (5) ninmedia (1) paket belajar (19) palang pintu otomatis (1) parabola (28) pcb (2) project (33) proyek (1) radio (3) raspberry pi (3) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (1) sharing (2) signage (1) sms (6) software (18) tachometer (2) telepon (7) televisi (53) television (1) transistor (1) troubleshoot (3) tulisan (50) tutorial (76) tvri (1) vu meter (1) vumeter (1) wav player (3) wayang (1) wifi (1)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika