• MUHILHAM • Electronics Hobbyist and Maker
  • Shop
  • Sitemap
  • Portfolio
  • Jasa Custom Project





  • Home All posts
    Arduino Elektronika Robotic

    Wall Follower Robot dengan Kendali PID

    MUHAMMAD ILHAM 2 Comments



    Kali ini saya akan membagikan mengenai robot lagi nih, yah robot.. namun masih seperti robot-robot sebelumnya yang sudah pernah saya tulis di blog ini yaitu masih mobile robot atau robot yang masih menggunakan roda sebagai penggeraknya dan masih robot follower juga hehe... namun berbeda dengan yang sebelumnya untuk robot light follower bisa dibaca disini.

    Jadi robot yang akan dibahas kali ini adalah Wall Follower Robot atau robot pengikut dinding, artinya robot ini dapat berjalan dengan baik mengikuti dinding atau lintasan seperti labirin dan diharapkan tanpa menabrak tentunya. Cara kerja dari robot ini dengan membaca dan mendeteksi penghalang atau dinding terhadap robot dengan menggunakan sensor jarak, robot akan mengatur jaraknya terhadap dinding agar tetap konstan dengan cara robot akan bergerak jika terjadi perubahan jaraknya untuk kemudian menyesuaikan lagi secara terus menerus.

    Rancangan Mekanik Wall Follower Robot


    Rancangan Elektrikal

    Tampilan Hasil Rancangan Wall Follower Robot


    Wall Follower Dengan PID
    Untuk menghasilkan pergerakan robot yang responsif, robot ini menggunakan kendali PID, pada artikel ini saya tidak akan membahas apa itu PID atau pengertian dari kendali PID, untuk lebih jelas mengenai PID ini mungkin bisa dibaca melalui jurnal-jurnal yang berkaitan dengan sistem kendali PID karena disini hanya akan dibahas penerapan kendali PID tersebut pada robot wall follower.


    Pada robot ini digunakan 3 buah sensor jarak yang diletakkan pada robot, satu sensor diletakkan serong kiri, satu serong kanan dan satu sensor diletakkan menghadap depan. Jadi kendali pid nya bagaimana? oke.. jadi pada robot ini hanya satu sensor saja yang di pid kan yaitu bisa sensor kiri maupun kanan, artinya yang menjadi feedback untuk pengendalian pid ini didapat dari sensor jarak kiri ataupun kanan, jadi skenarionya gini.. sensor mana (kiri atau kanan) yang paling mendekati dinding maka jarak dari sensor tersebut yang digunakan untuk pengendalian pid, agar robot tidak menabrak depan maka itu fungsi dari sensor yang menghadap depan, untuk kondisi ini tidak masuk ke pengendalian pid.

    Diagram Blok Kendali PID Pada Wall Follower Robot


    Setpoint pada robot ini saya atur 10 cm yang artinya robot akan mempertahankan posisinya di 10 cm (kondisi ideal robot) dari dinding, caranya robot akan terus bergerak ke kiri maupun ke kanan jika kondisi tidak ideal dimana akan ada nilai error, pada kondisi error output PID akan mengeluarkan hasil kendalinya sesuai dengan besarnya nilai error yang terjadi dan kemudian akan di kalkulasikan denga nilai base PWM yang menjadi kecepatan PWM motor kiri maupun kanan, jika kondisi robot ideal atau jarak sesuai dengan setpoint maka robot akan bergerak lurus.

    Ilustrasi Kendali PID Pada Wall Follower Robot


    Dalam menentukan nilai parameter kendali PID bisa dilakukan dengan cara try and error atau dengan cara coba-coba namun dangan cara tersebut akan lebih sulit dan membutuhkan waktu yang lama untuk mendapatkan hasil kendali yang stabil, maka dari itu dalam menentukan nilai yang tepat untuk parameter aksi kontrol proporsional, integral dan derivative bisa dilakukan dengan melakukan tuning dengan metode Ziegler-Nichols sama seperti proses tuning yang di lakukan pada robot line follower, bisa di baca disini.

    Arduino Elektronika

    Desain Kendali Suhu Ruangan Berbasis Logika Fuzzy [Room Temperature Control Based on Fuzzy]

    MUHAMMAD ILHAM 19 Comments


    Kali ini mau berbagi lagi nih tentang proyek elektronika.. artikel yang akan dibagikan kali ini mengenai kendali fuzzy yang merupakan bagian dari sebuah kecerdasan buatan atau Artificial Intelligence, proyek ini merupakan proyek akhir semester mata kuliah kecerdasan buatan saya, adapun penerapan kendali fuzzy kali ini pada proyek sistem kendali suhu ruangan dengan inputan suhu dan banyaknya orang dimana outputnya adalah kecepatan kipas, proyek ini di implementasikan dalam bentuk prototype.

    Apa itu Logika Fuzzy?
    Akan dijelaskan sedikit pengertian mengenai logika fuzzy yang merupakan suatu cabang ilmu Artificial Intellegence atau kecerdasan buatan, yaitu suatu pengetahuan yang membuat komputer dapat meniru kecerdasan manusia sehingga diharapkan komputer dapat melakukan hal-hal yang apabila dikerjakan manusia memerlukan kecerdasan. Umumnya diterapkan pada masalah-masalah yang mengandung unsur ketidakpastian, ketidaktepatan, dan sebagainya (dikutip dari wikipedia).

    Perancangan Sistem Kendali Suhu Ruangan


    Sistem kendali suhu ruangan ini dirancang dalam bentuk prototype. Sistem dirancang agar dapat mengendalikan suhu pada suatu ruangan, adapun parameter sebagai pengendali adalah kondisi suhu pada ruangan dan banyaknya orang dalam ruangan tersebut, digunakan kipas angin sebagai pengendali suhu ruangan tersebut.

    Komponen yang dibutuhkan
    1x Arduino Uno
    1x Sensor Suhu (DHT11)
    2x Modul Sensor Infrared
    2x Kipas DC
    1x LCD + i2C
    1x Driver Motor DC
    Kabel Jumper Secukupnya

    Berikut ini rangkaian elektrikalnya

    Perancangan Sistem Fuzzy
    Proses pembuatan sistem fuzzy terdapat beberapa tahapan alur proses untuk mendapatkan keluaran fuzzy mulai dari fuzzifikasi hingga defuzzifikasi.

    Pada perancangan sistem kendali fuzzy ini terdapat beberapa bagian terpenting, yaitu sebagai berikut:

    Fuzzifikasi : Pada proses fuzzifikasi, inputan crisp akan dirubah menjadi variabel linguistic (variabel Fuzzy).
    Inferensi (Aturan Dasar) : Proses inferensi merupakan proses untuk mendapatkan keluaran dari rule set yang dibuat, ini merupakan inti dari proses fuzzy.
    Defuzzifikasi : Proses defuzzifikasi merupakan proses terakhir dalam sistem Fuzzy. Proses ini merupakan proses perubahan data input yang telah dimasukkan dalam himpunan-himpunan Fuzzy untuk mendapatkan kembali bentuk tegasnya (Crisp). 

    Baiklah.. selanjutnya masuk pada pembahasan utama, yaitu proses kendali fuzzy pada proyek kendali suhu ruangan ini, untuk tahapan akan dijelaskan adalah proses fuzzifikasi, proses inferensi dan proses defuzzifikasi, langsung saja untuk penjelasan tahap - tahap nya sebagai berikut :

    Proses Fuzzifikasi
    Pada proses ini dibuat beberapa fungsi keangotaan (membership function), yang digunakan sebagai input adalah membership fungsi suhu dan banyaknya orang dalam ruangan. Sedangkan output adalah persentase 0% - 100% pwm yang mengontrol kecepatan motor kipas.




    Jika proses fuzzifikasi diterapkan pada program sebagai berikut :
    Diatas merupakan program untuk proses fuzzifikasi pada mikrokontroler Arduino, pada fungsi hitung_member merupakan fungsi rumus perhitungan drajat keangotaan dengan menggunakan rumus kurva naik-turun. Pada fungsi fuzzifikasi merupakan proses fuzzifikasinya yaitu menghitung dan memasukkan nilai batas - batas untuk inputan suhu dan banyaknya orang dengan memanggil fungsi hitung_member.

    Proses Inferensi dan Defuzzifikasi

    Metode defuzzifikasi yang digunakan adalah centroid atau center of area (COA). Dimana nilai tegas outputnya diperoleh berdasarkan titik berat dari kurva hasil proses pengambilan keputusan. Dengan menggunakan persamaan sebagai berikut:
    Nilai Min didapat dengan mengambil nilai terendah dari masing - masing keanggotaan antara suhu dan banyak orang.
    Untuk mencari center of area (COA) dilakukan dengan menjumlahkan perkalian Nilai Minimum dengan bobot keanggotaan keluaran kecepatan kipas kemudian dibagi dengan jumlah Nilai Minimun. Jika diterapkan pada program sebagai berikut :

    Program tersebut merupakan program untuk proses inferensi dan defuzzifikasi. Proses ini untuk mendapatkan keluaran dari rule set yang dibuat, inferensi kali ini digunkan metode mamdani atau disebut dengan metode max – min, variable array fuzzy_set merupakan nilai bobot sesuai dengan rule yang dibuat.

    Digunakan fungsi max untuk mengambil nilai tertinggi dan min untuk mengambil nilai terkecilnya. Untuk proses fuzzifikasi digunakan metode Centre Of Area (COA) dan hasil dari fuzzifikasi ini merupakan keluaran untuk pwm kipas. 


    Pada Program looping merupakan program untuk menjalankan semua fungsi-fungsi yang buat. Pada gambar diatas terdapat fungsi pembacan sensor infrared dan pemcaan sensor suhu yang dilakukan update setiap 2 detik, fungsi fuzzifikasi,defuzzifikasi juga dilakukan pada program looping serta menghasilkan output 0 hingga 100 yang akan dilakukan mapping dari 0 hingga 255 untuk pwm kipas, setelah itu dilakukan pemanggilan fungsi untuk menggerakkan kipas.

    Program Arduino lengkapnya dapat di copy dibawah ini

    /********************************
      Room Temperature Control System
      Based On Fuzzy Logic
      www.muhilham.com
      2018
    *********************************/
    
    #include "liquidcrystal_i2c.h"
    LiquidCrystal_I2C lcd(0x3F, 16, 2);
    #include "DHT.h"
    
    DHT dht(4, DHT11);
    int sen_in, sen_out, offset_sen_in, offset_sen_out; // variabel sensor infrared
    boolean detect_in = false, detect_out = false;
    
    int count;
    float suhu,
          uMember,
          uDingin, uSejuk, uNormal, uPanas, uSangatPanas,
          uSangatSedikit, uSedikit, uSedang, uBanyak, uSangatBanyak,
          N_suhu[5], N_orang[5], kondisiSuhu, kondisiOrang, Min[25],
          Keluaran, Kecepatan;
    String OutputFuzzy;
    
    const int PWM_KIPAS   = 5,
              P1_KIPAS    = 6,
              P2_KIPAS    = 7,
              PWM_EXHAUST = 9,
              P1_EXHAUST  = 8,
              P2_EXHAUST  = 10;
    
    long lastTime_readSen = 0, lastTime_LCD = 0;
    int state_LCD = 1;
    
    void setup() {
      Serial.begin(9600);
      lcd.begin();
      dht.begin();
      for (int i = 0; i <= 1; i++) {
        pinMode(i, INPUT);
      }
      for (int i = 5; i <= 10; i++) {
        pinMode(i, OUTPUT);
      }
    
      sen_in = analogRead(A0);
      sen_out = analogRead(A1);
      offset_sen_in = sen_in - 70;   // sample sensor masuk
      offset_sen_out = sen_out - 70; // sample sensor keluar
      count = 0;
      temp()
    }
    
    void loop() {
      sensor_count();
    
      fuzzifikasi();
      defuzzifikasi();
      Output();
      Kecepatan = map(Keluaran, 0, 100, 0, 255);
      driveKipas_N_Exhaust(Kecepatan);
    }
    
    
    // -----------------------------------------------------------
    // Read DHT Function
    float temp() {
      float temp = dht.readTemperature();
      // Check if any reads failed and exit early (to try again).
      if (isnan(temp)) {
        Serial.println("Failed to read from DHT sensor!");
        return;
      }
    
      return temp;
    }
    // #END Read DHT Function -------------------------------------
    
    
    void sensor_count() {
      sen_in = analogRead(A0);
      sen_out = analogRead(A1);
    
      if (sen_in > offset_sen_in) {
        detect_in = false;
      }
      else if (sen_in < offset_sen_in && detect_in == false) {
        count++;
        detect_in = true;
        if (count >= 40)count = 40;
      }
    
      if (sen_out > offset_sen_out) {
        detect_out = false;
      }
      else if (sen_out < offset_sen_out && detect_out == false) {
        count--;
        detect_out = true;
        if (count < 0)count = 0;
      }
    }
    
    void driveKipas_N_Exhaust(float Kecepatan) {
      digitalWrite(P1_KIPAS, LOW);
      digitalWrite(P2_KIPAS, HIGH);
      analogWrite(PWM_KIPAS, Kecepatan);
      digitalWrite(P1_EXHAUST, LOW);
      digitalWrite(P2_EXHAUST, HIGH);
      analogWrite(PWM_EXHAUST, Kecepatan);
    }
    
    void hitung_member(int pilih, float Nilai, float A, float B, float C) {
      switch (pilih) {
        case 1:
          if ((Nilai >= A) && (Nilai <= B)) uMember = 1;
          if ((Nilai > B) && (Nilai < C)) uMember = (C - Nilai) / (C - B);
          if (Nilai >= C) uMember = 0;
          break;
        case 2:
          if ((Nilai <= A) || (Nilai >= C)) uMember = 0;
          if ((Nilai > A) && (Nilai < B)) uMember = (Nilai - A) / (B - A);
          if ((Nilai > B) && (Nilai < C)) uMember = (C - Nilai) / (C - B);
          if (Nilai == B) uMember = 1;
          break;
        case 3:
          if (Nilai <= A) uMember = 0;
          if ((Nilai > A) && (Nilai < B)) uMember = (Nilai - A) / (B - A);
          if (Nilai >= B) uMember = 1;
          break;
      }
    }
    
    void fuzzifikasi() {
      // Suhu
      uMember = 0;
      hitung_member(1, temp(), 0, 24, 26);
      uDingin = uMember;
      hitung_member(2, temp(), 24, 26, 29);
      uSejuk = uMember;
      hitung_member(2, temp(), 26, 29, 32);
      uNormal = uMember;
      hitung_member(2, temp(), 29, 32, 35);
      uPanas = uMember;
      hitung_member(3, temp(), 32, 35, 35);
      uSangatPanas = uMember;
    
      // Banyak Orang
      uMember = 0;
      hitung_member(1, count, 0, 5, 10);
      uSangatSedikit = uMember;
      hitung_member(2, count, 5, 10, 20);
      uSedikit = uMember;
      hitung_member(2, count, 10, 20, 30);
      uSedang = uMember;
      hitung_member(2, count, 20, 30, 40);
      uBanyak = uMember;
      hitung_member(3, count, 30, 40, 40);
      uSangatBanyak = uMember;
    }
    
    //int fuzzy_set[5][5] = {
    //  //Cold|Cool|Nor|Hot|Vhot
    //  {20, 20, 20, 60, 80},   //| Vlow
    //  {20, 40, 20, 60, 80},   //| Low
    //  {40, 40, 60, 80, 100},  //| Medium
    //  {40, 60, 80, 100, 100}, //| High
    //  {60, 80, 100, 100, 100} //| Very high
    //};
    
    //20 = Vslow, 40 = Slow, 60 = Med, 80 = Fast, 100 = Vfast
    int fuzzy_set[5][5] = {
      //|vLow|Low|Med|High|vHigh
      {20, 20, 40,  40,  60},  //| Cold
      {20, 40, 40,  60,  80},  //| Cool
      {40, 40, 60,  80,  100}, //| Normal
      {60, 60, 80,  100, 100}, //| Hot
      {80, 80, 100, 100, 100}  //| Very hot
    };
    
    void defuzzifikasi() {
      float pembil = 0, penyeb = 0, centre_of_area = 0;
      N_suhu[5] = {};
      N_orang[5] = {};
    
      for (int set = 0; set < 25;) {
        for (int i = 0; i < 5; i++) {
          for (int j = 0; j < 5; j++) {
            float data_uSuhu[5] = {uDingin, uSejuk, uNormal, uPanas, uSangatPanas};
            N_suhu[i] = data_uSuhu[i];
            float data_uOrang[5] = {uSangatSedikit, uSedikit, uSedang, uBanyak, uSangatBanyak};
            N_orang[j] = data_uOrang[j];
    
            kondisiSuhu = max(N_suhu[i], kondisiSuhu);
            kondisiOrang = max(N_orang[j], kondisiOrang);
    
            /* Metode COA (Centre Of Area)*/
            min[set] = min(N_suhu[i], N_orang[j]);
            pembil  += Min[set] * fuzzy_set[i][j];
            penyeb  += Min[set];
            delay(5);
            set ++;
          }
        }
      }
      centre_of_area = pembil / penyeb;
      Keluaran = centre_of_area;
    }
    
    void basis_Aturan_output() {
      if (kondisiSuhu == uDingin && kondisiOrang == uSangatSedikit)OutputFuzzy = "Vslow";
      else if (kondisiSuhu == uDingin && kondisiOrang == uSedikit)OutputFuzzy = "Vslow";
      else if (kondisiSuhu == uDingin && kondisiOrang == uSedang)OutputFuzzy = "Slow";
      else if (kondisiSuhu == uDingin && kondisiOrang == uBanyak)OutputFuzzy = "Slow";
      else if (kondisiSuhu == uDingin && kondisiOrang == uSangatBanyak)OutputFuzzy = "Med";
    
      else if (kondisiSuhu == uSejuk && kondisiOrang == uSangatSedikit)OutputFuzzy = "Vslow";
      else if (kondisiSuhu == uSejuk && kondisiOrang == uSedikit)OutputFuzzy = "Slow";
      else if (kondisiSuhu == uSejuk && kondisiOrang == uSedang)OutputFuzzy = "Slow";
      else if (kondisiSuhu == uSejuk && kondisiOrang == uBanyak)OutputFuzzy = "Med";
      else if (kondisiSuhu == uSejuk && kondisiOrang == uSangatBanyak)OutputFuzzy = "Fast";
    
      else if (kondisiSuhu == uNormal && kondisiOrang == uSangatSedikit)OutputFuzzy = "Slow";
      else if (kondisiSuhu == uNormal && kondisiOrang == uSedikit)OutputFuzzy = "Slow";
      else if (kondisiSuhu == uNormal && kondisiOrang == uSedang)OutputFuzzy = "Med";
      else if (kondisiSuhu == uNormal && kondisiOrang == uBanyak)OutputFuzzy = "Fast";
      else if (kondisiSuhu == uNormal && kondisiOrang == uSangatBanyak)OutputFuzzy = "Vfast";
    
      else if (kondisiSuhu == uPanas && kondisiOrang == uSangatSedikit)OutputFuzzy = "Med";
      else if (kondisiSuhu == uPanas && kondisiOrang == uSedikit)OutputFuzzy = "Med";
      else if (kondisiSuhu == uPanas && kondisiOrang == uSedang)OutputFuzzy = "Fast";
      else if (kondisiSuhu == uPanas && kondisiOrang == uBanyak)OutputFuzzy = "Vfast";
      else if (kondisiSuhu == uPanas && kondisiOrang == uSangatBanyak)OutputFuzzy = "Vfast";
    
      else if (kondisiSuhu == uSangatPanas && kondisiOrang == uSangatSedikit)OutputFuzzy = "Fast";
      else if (kondisiSuhu == uSangatPanas && kondisiOrang == uSedikit)OutputFuzzy = "Fast";
      else if (kondisiSuhu == uSangatPanas && kondisiOrang == uSedang)OutputFuzzy = "Vfast";
      else if (kondisiSuhu == uSangatPanas && kondisiOrang == uBanyak)OutputFuzzy = "Vfast";
      else if (kondisiSuhu == uSangatPanas && kondisiOrang == uSangatBanyak)OutputFuzzy = "Vfast";
    }
    
    void Output() {
      //uMember_suhu_count();
      basis_Aturan_output();
      Tampil_Serial();
      Tampil_LCD();
    }
    
    void Tampil_Serial() {
      //Tampil Serial
      Serial.print(" Temp : ");
      Serial.print(temp());
      Serial.print(" *C ");
      Serial.print(" ");
      tampil_member_suhu();
      if (kondisiSuhu == N_suhu[0])Serial.print("Cold");
      else if (kondisiSuhu == N_suhu[1])Serial.print("Cool");
      else if (kondisiSuhu == N_suhu[2])Serial.print("Normal");
      else if (kondisiSuhu == N_suhu[3])Serial.print("Hot");
      else if (kondisiSuhu == N_suhu[4])Serial.print("Very Hot");
    
      Serial.print(" | Count : ");
      Serial.print(count);
      Serial.print(" ");
      tampil_member_count();
      if (kondisiOrang == N_orang[0])Serial.print("Very Low");
      else if (kondisiOrang == N_orang[1])Serial.print("Low");
      else if (kondisiOrang == N_orang[2])Serial.print("Medium");
      else if (kondisiOrang == N_orang[3])Serial.print("High");
      else if (kondisiOrang == N_orang[4])Serial.print("Very High");
    
      Serial.print(" | ");
      if (OutputFuzzy == "Vslow")     Serial.print("Fan : Very Slow");
      else if (OutputFuzzy == "Slow") Serial.print("Fan : Slow");
      else if (OutputFuzzy == "Med")  Serial.print("Fan : Medium");
      else if (OutputFuzzy == "Fast") Serial.print("Fan : Fast");
      else if (OutputFuzzy == "Vfast")Serial.print("Fan : Very Fast");
      Serial.print(" LV : ");
      Serial.print(Keluaran);
      Serial.print("%");
      Serial.print(" PWM : ");
      Serial.print(Kecepatan);
      Serial.println();
    }
    
    void Tampil_LCD() {
      lcd.backlight();
      if (millis() - lastTime_LCD > 5000) {
        state_LCD = 1;
        lastTime_LCD = millis();
      }
      if (millis() > lastTime_LCD + 2500) {
        state_LCD = 2;
      }
    
      if (state_LCD == 1) {
        lcd.setCursor (0, 0);
        lcd.print("Temp:");
        lcd.print((int)temp());
        lcd.print("C ");
        if (kondisiSuhu == N_suhu[0])lcd.print("   Cold");
        if (kondisiSuhu == N_suhu[1])lcd.print("   Cool");
        if (kondisiSuhu == N_suhu[2])lcd.print(" Normal");
        if (kondisiSuhu == N_suhu[3])lcd.print("    Hot");
        if (kondisiSuhu == N_suhu[4])lcd.print("VeryHot");
    
        lcd.setCursor (0, 1);
        lcd.print("Cont:");
        lcd.print((int)count);
        lcd.print(" ");
        lcd.setCursor (7, 1);
        if (kondisiOrang == N_orang[0])lcd.print("  VeryLow");
        if (kondisiOrang == N_orang[1])lcd.print("      Low");
        if (kondisiOrang == N_orang[2])lcd.print("   Medium");
        if (kondisiOrang == N_orang[3])lcd.print("     High");
        if (kondisiOrang == N_orang[4])lcd.print(" VeryHigh");
      }
      else if (state_LCD == 2) {
        lcd.setCursor (0, 0);
        lcd.print("  PWM: ");
        lcd.print((float)Keluaran);
        lcd.print("%   ");
        lcd.setCursor (0, 1);
        if (OutputFuzzy == "Vslow")     lcd.print("   Very Slow    ");
        else if (OutputFuzzy == "Slow") lcd.print("      Slow      ");
        else if (OutputFuzzy == "Med")  lcd.print("     Medium     ");
        else if (OutputFuzzy == "Fast") lcd.print("      Fast      ");
        else if (OutputFuzzy == "Vfast")lcd.print("   Very Fast    ");
      }
    }
    void uMember_suhu_count() {
      Serial.print(" Temp : ");
      Serial.print(temp());
      Serial.print(" *C ");
      Serial.print(" ");
      Serial.print("Cold:");
      Serial.print(uDingin);
      Serial.print(" Cool:");
      Serial.print(uSejuk);
      Serial.print(" Nor:");
      Serial.print(uNormal);
      Serial.print(" Hot:");
      Serial.print(uPanas);
      Serial.print(" VHot:");
      Serial.print(uSangatPanas);
      Serial.print(" ");
    
      Serial.print(" | Count : ");
      Serial.print(count);
      Serial.print(" ");
      Serial.print("VLow:");
      Serial.print(uSangatSedikit);
      Serial.print(" Low:");
      Serial.print(uSedikit);
      Serial.print(" Med:");
      Serial.print(uSedang);
      Serial.print(" High:");
      Serial.print(uBanyak);
      Serial.print(" VHigh:");
      Serial.println(uSangatBanyak);
    }
    
    void tampil_member_suhu() {
      //if (uDingin != 0.00) {
        Serial.print("Cold:");
        Serial.print(uDingin);
      //}
      //if (uSejuk != 0.00) {
        Serial.print(" Cool:");
        Serial.print(uSejuk);
      //}
      //if (uNormal != 0.00) {
        Serial.print(" Nor:");
        Serial.print(uNormal);
      //}
      //if (uPanas != 0.00) {
        Serial.print(" Hot:");
        Serial.print(uPanas);
      //}
      //if (uSangatPanas != 0.00) {
        Serial.print(" VHot:");
        Serial.print(uSangatPanas);
      //}
      Serial.print(" ");
    }
    
    void tampil_member_count() {
      //if (uSangatSedikit != 0.00) {
        Serial.print("VLow:");
        Serial.print(uSangatSedikit);
      //}
      //if (uSedikit != 0.00) {
        Serial.print(" Low:");
        Serial.print(uSedikit);
      //}
      //if (uSedang != 0.00) {
        Serial.print(" Med:");
        Serial.print(uSedang);
      //}
      //if (uBanyak != 0.00) {
        Serial.print(" High:");
        Serial.print(uBanyak);
      //}
      //if (uSangatBanyak != 0.00) {
        Serial.print(" VHigh:");
        Serial.print(uSangatBanyak);
      //}
      Serial.print(" ");
    }
    

    Arduino Elektronika Robotic

    Light Follower Robot Arduino Dengan LDR

    MUHAMMAD ILHAM 6 Comments

    Waktu itu dapat pesanan project robot sederhana dari guru salah satu sekolah smk untuk bahan pembelajaran katanya, nah robot tersebut akan yang akan di bahas kali ini, jadi robot itu adalah light follower robot atau robot pengikut cahaya, robot ini merupakan robot yang berjenis mobile robot atau robot dengan menggunakan roda.

    Light follower robot ini tidak jauh beda dengan robot line follower hanya saja perbedaannya jika line follower mengikuti track garis lain halnya dengan robot light follower ini mengkuti cahaya, artinya robot akan berjalan jika diberi cahaya pada sensor, dimana robot akan berjalan  ke arah sesuai dengan sensor mana yang terkena cahaya.

    Sensor yang digunakan yaitu sensor LDR (light dependent resistor) pada robot ini menggunakan 3 sensor LDR yang dipasang di depan robot dengan menghadap depan robot, samping kanan robot dan samping kiri robot, sebagai pengendali pergerakan robot dan pemeroses siyal sensor digunakan arduino sebagai mikrokontroler robot ini.

    Komponen yang dibutuhkan 
    • 1x Arduino Uno
    • 2x Motor DC
    • 1x Driver Motor H-Bridge L298N
    • 3x LDR (light dependent resistor)
    • 3x Resistor 10k
    • 1x Switch ON/OFF
    • 1x Baterai 9V (di video menggunakan 4x baterai AA)
    • Kabel secukupnya
    • Chasis robot (robot ini menggunakan acrylic)
    • Spacer
    Rangkaian/wiring robot
    Jika arah putaran motor tidak sesuai, balik kabel motor yang terhubung dengan output driver motor, untuk baterai bisa menggunakan baterai 9V atau 12V.


    👉 UNTUK PEMESANAN ATAU CUSTOM PROJECT 👈



    Program/coding arduino langsung copy ke software arduino dan upload ke arduino


    /**************************
      light follower robot v2
      www.muhilham.com
      08/01/2020
    ***********************/
    
    #define pin_MOTOR_DIRL 2
    #define pin_MOTOR_PWML 3
    #define pin_MOTOR_DIRR 4
    #define pin_MOTOR_PWMR 5
    
    #define Kec_Min -170
    #define Kec_Max  220 // Max = 255
    
    const int8_t pinSensor[3] = {A0, A1, A2}; // array pin sensor
    int16_t limitSensor[3]; // array limit sensor
    int16_t correction = 100; // nilai koreksi kalibrasi sensor
    
    void setup() {
      Serial.begin(9600);
      pinMode(pin_MOTOR_DIRL, OUTPUT);
      pinMode(pin_MOTOR_PWML, OUTPUT);
      pinMode(pin_MOTOR_DIRR, OUTPUT);
      pinMode(pin_MOTOR_PWMR, OUTPUT);
    
      for (byte i = 0; i < 3; i++) { // kalibrasi sensor
        pinMode(pinSensor[i], INPUT);
        limitSensor[i] = analogRead(pinSensor[i]) + correction;
        if (limitSensor[i] > 1023) limitSensor[i] = 1023;
        delay(50);
      }
    }
    
    void loop() {
      Serial.print("|");
      Serial.print(limitSensor[0]);
      Serial.print("|");
      Serial.print(limitSensor[1]);
      Serial.print("|");
      Serial.print(limitSensor[2]);
      Serial.print("| |");
    
      Serial.print(analogRead(pinSensor[0]));
      Serial.print("|");
      Serial.print(analogRead(pinSensor[1]));
      Serial.print("|");
      Serial.print(analogRead(pinSensor[2]));
      Serial.print("| |");
    
      followLight();
    }
    
    void followLight() {
      int16_t sensor = BacaSensor();
    
      switch (sensor) {
        case 0b000 : driveMotor(0, 0); Serial.println("|  Stop"); break;        // Belok kiri
        case 0b001 : driveMotor(Kec_Max, Kec_Max / 2); Serial.println("|  Belok Kanan"); break;       // Belok kanan
        case 0b011 : driveMotor(Kec_Max / 2, Kec_Max / 3); Serial.println("|  Serong Kanan"); break;  // Serong kanan
        case 0b010 : driveMotor(Kec_Max, Kec_Max); Serial.println("|  Lurus"); break;          // Lurus
        case 0b111 : driveMotor(Kec_Max, Kec_Max); Serial.println("|  Lurus"); break;          // Lurus
        case 0b110 : driveMotor(Kec_Max / 3, Kec_Max / 2); Serial.println("|  Serong Kiri"); break;   // Serong kiri
        case 0b100 : driveMotor(Kec_Max / 2, Kec_Max); Serial.println("|  Belok Kiri"); break;        // Belok kiri
        case 0b101 : driveMotor(Kec_Max, Kec_Max); Serial.println("|  Lurus"); break;        // Belok kiri
      }
    }
    
    int16_t BacaSensor() {
      int16_t bitSensor = 0;
    
      for (byte i = 0; i < 3; i++) {
        if (analogRead(pinSensor[i]) > limitSensor[i]) {
          bitSensor = bitSensor | (0b100 >> i);
          Serial.print("1");
        } else Serial.print("0");
      }
    
      return bitSensor;
    }
    
    
    void driveMotor(int16_t Left, int16_t Right) {
      if (Left > 0) {
        digitalWrite(pin_MOTOR_DIRL, LOW);
      } else {
        digitalWrite(pin_MOTOR_DIRL, HIGH);
        Left = 255 + Left;
      }
      analogWrite(pin_MOTOR_PWML, Left);
    
      if (Right > 0) {
        digitalWrite(pin_MOTOR_DIRR, LOW);
      } else {
        digitalWrite(pin_MOTOR_DIRR, HIGH);
        Right = 255 + Right;
      }
      analogWrite(pin_MOTOR_PWMR, Right);
    }
    

    IoT

    Kontrol Lampu Dengan Suara Menggunakan Android Melalui Internet [Speech Recognition]

    MUHAMMAD ILHAM 10 Comments


    Pada kesempatan kali ini saya akan membahas sebuah teknologi yang menarik untuk di bahas tentunya, yaitu Internet Of Things atau sering disingkat IoT, merupakan konsep yang bertujuan dengan memanfaatkan koneksi internet diharapkan dapat dihasilkan teknologi yang dapat mempermudah pekerjaan manusia, sederhananya penerapannya sebagai remote kontrol jarak jauh, yang akan dibahas pada artikel kali ini.

    Adapun penerapan IoT yang akan dibahas kali ini adalah menyalakan dan mematikan lampu dengan menggunakan suara dengan memanfaatkan speech recognition yang ada di smartphone android, nantinya alat yang dibuat mampu mengendalikan lampu melalui jarak jauh dengan syarat adanya koneksi internet.

    Masuk ke pembahasan mengenai pengendalian lampu dengan suara dari jarak jauh, adapun komponen yang dibutuhkan untuk membuatnya diataranya, Wemos D1 yang merupakan komponen utama pada project kali ini karena fungsi dari wemos ini sebagai penghubung alat atau perangkat yang akan dikendalikan dengan koneksi internet kelebihan dari wemos ini bisa diprogram dengan menggunakan software Arduino IDE jadi bisa lebih mudah dalam pembuatan program atau codingnya, adapun komponen berikutnya yaitu Relay yang berfungsi sebagai saklar pemutus dan penghubung sumber listrik ke beban lampu.

    Komponen yang digunakan
    • Wemos D1 Mini
    • Module Relay 5V
    • Transistor BC557
    • Resistor 10k
    • Lampu
    • Projectboard
    • Kabel Jumper Secukupnya
    • Smartphone Android
    Berikut ini block diagram sistem

    Sistem pengendalian ini dirancang agar dapat menyalakan dan mematikan lampu menggunakan suara menggunakan android melalui internet, prinsip kerjanya terdapat wemos sebagai penerima perintah dari android dimana perintah dikirim menggunakan koneksi internet, agar wemos dan android dapat bekomunikasi digunakan sebuah web server thingspeak yang dapat menyimpan data yang kirim oleh android yang kemudian wemos akan menerima data yang dikirim oleh android, kemudian data di proses oleh wemos untuk pengendalian relay.

    Rangkaian/Wiring Elektrical

    Membuat channel di web thingspeak

    1. Pergi ke thingspeak.com
    2. Jika belum memiliki akun silahkan buat akun terlebih dahulu jika sudah langsung Sign In saja
    3. Kemudian buatlah Channel baru
    4. Setelah berhasil membuat channel masuk ke Channel setting kemudian tambahkan field
    5. Masuk ke API Keys catat Channel ID dan Read API Keys
    6. Setelah itu masukkan Channel ID dan Read API Keys pada coding arduino kemudian upload coding dan tes dengan aplikasi android, kemudian lihat pada Private View apakah data yang dikirim masuk pada field yang dibuat
    Silahkan copy program ke software Arduino IDE

    /**************************
     Kontrol lampu dengan suara menggunakan android melalui internet
     [Speech Recognition]
     www.muhilham.com
     15/07/2018
    ***********************/
    
    #include 
    #include 
    
    WiFiClient TSpeak_client;
    
    const char* namawifi = "Roy Anak IndiHome"; // nama acces point wifi 
    const char* password = "1234554321"; // password wifi
    unsigned long myChannelNumber = 483487; // isi channel ID anda 
    const char* myReadAPIKey = "Read API Key"; // Isi dengan read api key anda
    const int Lampu1 = D5;
    const int LED = D4;
    
    void setup() {
      Serial.begin(115200);
      pinMode(LED, OUTPUT);
      pinMode(Lampu1, OUTPUT);
      digitalWrite(Lampu1, HIGH);
      digitalWrite(LED, HIGH);
      Serial.println("** SETUP **");
      Serial.println();
      delay(500);
      WIFI_Connect();
      ThingSpeak.begin(TSpeak_client);
    }
    
    void WIFI_Connect() {
      digitalWrite(LED, HIGH);
      WiFi.disconnect();
      WiFi.mode(WIFI_AP_STA);
      WiFi.begin(namawifi, password);
      Serial.println();
      Serial.print("Menghubungkan Dengan ");
      Serial.println(namawifi);
      // wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(250);
        digitalWrite(LED, LOW);
        Serial.print(".");
        delay(250);
        digitalWrite(LED, HIGH);
      }
    
      // Terhubung dengan acces point
      Serial.println();
      Serial.println("-- WIFI TERHUBUNG --");
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
      Serial.println();
      digitalWrite(LED, LOW);
    }
    
    void loop() {
    
      if (WiFi.status() != WL_CONNECTED) {
        delay(500);
        ESP.wdtDisable();
        Serial.println("WiFi Terputus, RESET WEMOS !");
        digitalWrite(LED, HIGH);
      }
      else {
    
        int Field1 = ThingSpeak.readIntField(myChannelNumber, 1, myReadAPIKey); // mengambil/membaca data pada filed 1
        Serial.print("Field 1 : ");
        Serial.println(Field1);
    
        if (Field1 == 1) {
          digitalWrite(Lampu, HIGH); 
          Serial.println("LAMPU MATI");
        }
        if (Field1 == 2) {
          digitalWrite(Lampu1, LOW);
          Serial.println("LAMPU NYALA");
        }
      }
    }
    


    Update : Server dengan Google Firebase


    Pembaharuan dengan server Firebase ini membuat respon lebih cepat dibandingkan dengan server Thingspeak yang versi gratis, mungin berbeda juka menggunakan thingpeak yang berbayar. Namun pada server firebase versi spark yang merupakan versi gratis dari firebase menurut saya respon server nya sudah cepet, sama - sama gratis kan kalau saya ya mending pilih yang ini.

    Untuk versi update dengan firebase ini rangkaian yang di gunakan tidak berbeda, hanya saja berbeda di aplikasi android dan program wemos nya saja.

    Membuat database Google Firebase
    • Pergi ke console.firebase.google.com login dengan akun google kamu
    • Kemudian buat project baru dengan memilih Add project
    • Pada panel sebelah kiri, klik Database pilih Realtime Database
    • Buat struktur database seperti berikut


    • Catat FirebaseURL kamu


    • Selain FirebaseURL kita juga butuh Secret Code database, catat juga



    Konfigurasi Aplikasi Android dan Program Wemos
    • Pergi ke ai2.appinventor.mit.edu login dengan akun google kamu
    • Kemudian Import file .aia aplikasi android yang sudah saya buat, dwonload disini



    • Atur Komponen firebase dengan Secret Code dan FirebaseURL yang kamu catat tadi


    • Untuk konfigurasi program wemos atur juga dengan Secret Code dan FirebaseURL yang kamu catat tadi, dan jangan lupa mengatur koneksi WiFi


    Tampilan Aplikasi Android

    Program terbaru dengan Firebase, lengkapi terlebih dahulu library yang digunakan


    /**************************
      Kontrol lampu dengan suara menggunakan android melalui internet
      [Speech Recognition]
      www.muhilham.com
      2018
    ***********************/
     
    #include  // Memasukkan library wemos
    #include  // Memasukkan library database (firebase)
    const char FIREBASE_HOST[] = "smart-lamp-voice-controlled.firebaseio.com"; // domain database firebase
    const char FIREBASE_AUTH[] = "hbt3lUQ4TDyj6CYv4C6uCq19tlVmXe0QbZ7qQghj"; // kode rahasia database (firebase)
    const char WIFI_SSID[] = "NAMA WIFI"; // Nama SSID wifi yang akan dihubungkan dengan alat
    const char WIFI_PASSWORD[] = "PASSWORD WIFI"; // Password wifi yang akan dihubungkan dengan alat
    // WEMOS
    const int Relay = D5; // pin digital yang digunakan untuk mengaktifkan relay
    const int LED = D6; // pin untuk led buitltin wemos
    // NODE MCU
    //const int Relay = 14; // pin digital D5 (untuk mengaktifkan relay)
    //const int LED = 2; // pin digital D4 (led buitltin Node MCU)
    bool lastState = false;
    void setup() { // fungsi program yang dijalankan sekali saat mikrokontroller di beri sumber listrik
      Serial.begin(115200); // baudrate / kecepatan serial monitor
      pinMode(Relay, OUTPUT); // set pin relay(D5) sebagai output
      pinMode(LED, OUTPUT); // set pin LED (D4) sebagai output
      digitalWrite(LED, HIGH); // set pin LED high (3.3 volt) matikan LED
      WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // hubungkan dengan WIFI
      Serial.print("Menghubungkan"); // tampilkan pada serial monitor
      while (WiFi.status() != WL_CONNECTED) { // selagi wifi tidak terhubung jalankan program didalamnya
        Serial.print(".");
        digitalWrite(LED, LOW);  // hidupkan led
        delay(600); // waktu tunda 600 milidetik
        digitalWrite(LED, HIGH); // matikan led
        delay(500); // waktu tunda 500 milidetik
      }
      Serial.println();
      Serial.println("Terhubung");
      digitalWrite(LED, LOW); // hidupkan led
      Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); // hubungkan dengan database (firebase)
    }
    void loop() { // program perulangan
      String stateLOAD = Firebase.getString("Relay1"); // ambil data dari database
      if (stateLOAD == "\"off\"" && lastState) { // jika data in = 1 jalankan program dibawah nya
        digitalWrite(Relay, LOW); // non aktifkan relay (matikan lampu)
        digitalWrite(LED, HIGH); // matikan LED builtin
        Serial.println("Relay 1 Off");
        lastState = false;
      } else if (stateLOAD == "\"on\"" && !lastState) { // jika data in = 2 jalankan program dibawah nya
        digitalWrite(Relay, HIGH); // aktifkan relay (hidupkan lampu)
        digitalWrite(LED, LOW); // hidupkan LED builtin
        Serial.println("Relay 1 On");
        lastState = true;
      }
      if (WiFi.status() != WL_CONNECTED) { // jika tidak terputus dari wifi reset wemos
        ESP.restart(); // restart
      }
    }
    


    Arduino Elektronika PCB

    Membuat Running LED Dengan Program Menggunakan Arduino Atmega328

    MUHAMMAD ILHAM Comment



    Sebelumnya saya sudah membuat sebuah artikel mengenai running led atau led berjalan, yang dimana pada artikel sebelumnya running led yang dibuat menggunakan IC 4017 dan IC timer NE555 atau tanpa program, artikel sebelumnya baca disini.

    Pada artikel kali ini masih sama, masih  membuat running led namun perbedaan nya kali ini menggunakan arduino atau mikrokontroler atmega328 yang dimana digunakan sebuah chip yang bisa di isi dengan program/coding, program yang akan dibuat kali ini adalah membuat led tersebut menyala secara bergantian.

    Karena running led yang akan dibuat dengan menggunakan program maka komponen yang digunakan berbeda dengan running led sebelumnya. Adapun komponen yang digunkan untuk membuat running led dengan program ini adalah sebagai berikut:
    • Arduino Uno (digunakan sebagai downloader IC ATmega328)
    • IC ATmega328/ATmega8 1x
    • Dioda 1N4007 1x
    • Kapasitor 22pF 2x
    • Kapasitor 100n 1x
    • Resistor Variabel 100k 1x
    • Crystal 16.000Mhz 1x
    • LED 5mm 20x
    • PCB Polos
    Rangkaian atau skematik running led menggunakan program sebagai berikut :

    Untuk desain saya akan membuat pada pcb dimana ic atmega328/atmega8 (ic dengan bootloder arduino) nantinya diprogram pada arduino uno, setelah selesai diprogram ic yang sudah diprogram dipindahkan pada rangkaian pcb yang dibuat.

    Penjelasan sedikit mengenai rangkaian, rangkian ini merupakan sistem minimun mikrokontroler dasar pada unumnya dimana digunakan crystal external dan capasitor sebagai pembangkit frekuensinya, pada pembuatan running led ini pin yang digunakan saya sesuaikan dengan pin dari arduino uno yang menggunakan ic atmega328/atmega8 untuk pin yang digunakan ada pin digital out untuk led dan pin analog in untuk mengatur kecepatan pergantian nyala led.

    Untuk pinout diagram dari arduino uno dapat dilihat pada gambar berikut :

    Brikut ini desain layout PCB yang saya buat dengan menggunakan software EAGLE.

    Program/coding arduino silahkan langsung copy ke software arduino dan langsung upload ke  mikrokontroler.


    /**************************
     Running LED
     www.muhilham.com
     14/07/2018
    ***********************/
    
    const int pinLED[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    int delayLED;
    
    void setup() {
      //Serial.begin(9600);
      for (int i = 0; i < 10; i++) {
        pinMode(pinLED[i], OUTPUT);
      }
      for (int i = 0; i < 10; i++) {
        digitalWrite(pinLED[i], HIGH);
        delay(200);
      }
      for (int i = 0; i < 10; i++) {
        digitalWrite(pinLED[i], LOW);
        delay(100);
      }
    }
    
    void loop() {
      delayLed = analogRead(A0);
    
      for (int i = 0; i < 10; i++) {
        digitalWrite(pinLED[i], HIGH);
        delay(delayLED);
        digitalWrite(pinLED[i], LOW);
      }
      //Serial.println(delayLED);
    }
    
    Elektronika PCB

    Membuat Running LED Dengan IC 4017 dan Timer NE555

    MUHAMMAD ILHAM Comment


    Setelah sekian lama tidak update dikarenakan kesibukan kuliah dan kesibukan lain diluar sana yang membuat saya tidak sempat untuk menulis ataupun membuat sesuatu yang bisa dibagikan di blog ini.

    Namun pada kesempatan kali ini saya akan membagikan sedikit tentang cara membuat running LED dengan IC 4017 dan sebuah IC Timer NE555.

    Sebelum masuk ke pembuatan, mari kita bahas sedikit tentang apa itu running led, jadi apasih sebenarnya running led itu?

    Jika di terjemahkan dari bahasa luar negerinnya yaitu bahasa inggris running led itu merupakan led berjalan hehe.. :), yang dimaksud berjalan disini pada rangkaian terdapat beberapa led yang nantinya akan nyala bergantian secara berurutan dengan kecepatan yang dapat diatur.

    Running led ini merupakan rangkaian dasar yang bisa dibuat saat ingin belajar tentang pembuatan rangkaian dan di terapkan ke PCB, biasanya proyek ini dibuat saat smk jurusan elektronika, dengan rangkaian yang cukup sederhana maka tingkat keberhasilan yang cukup besar hanya saja dibutuhkan analisa dan ketelitian. 

    Adapun untuk komponen yang digunakan pun mudah di dapat ditoko komponen  elektronika tentunya, berikut ini beberapa komponen yang dibutuhkan untuk membuat running led atau led berjalan.
    • Dioda 1N4007 1x
    • Kapasitor 22uF/16V 1x
    • Kapasitor 4.7uF/16V 1x
    • Resistor 1K 1x
    • Resistor 4.7K 1x
    • Resistor Variabel 100K 1x
    • IC 4017 1x
    • IC NE555N 1x
    • LED 5mm 20x
    Setelah komponen sudah lengkap kita masuk ke rangkaian atau skematik running led sebagai berikut:
    Sedikit penjelasan dari rangkaian digunkan 20 LED yang terhubung dengan IC 4017 merupakanjenis IC CMOS yang berupakan IC gerbang logika dalam kemasan IC dan memiliki 10 output yang bekerja atau aktif secara bergantian, untuk mengaktifkan output ini terdapat pin clock yang terhubung dengan output IC NE555.

    Selaian IC 4017 terdapat IC NE555 yang juga merupakan komponen penting pada running led ini, dimana fungsinya sebagai penghasil clock atau pulse untuk mengaktifkan output IC 4017, terdapat sebuah potensiometer atau resistor variabel yang berfungsi untuk mengatur waktu tunda (delay) dari output IC NE555, sumber yang digunakan pada project kali ini menggunakan sumber 5V DC.

    Berikut ini desain layout PCB yang saya buat menggunakan software EAGLE.
    Setelah layout di cetak pada PCB dan di etching kemudian dipasang komponen dan di solder.

    Arduino Elektronika Robotic

    Line Follower Robot Using PID Control

    MUHAMMAD ILHAM 7 Comments


    Line Follower Robot merupakan robot yang dapat mengikuti garis, sebagai peng-indera robot ini menggunakan sensor yang  berguna untuk membaca atau mendeteksi garis, warna garis yang biasa di gunakan adalah putih untuk base/dasar lapangan warna hitam dan garis hitam untuk base/dasar lapangan putih, dengan dua warna berbeda itu sensor dapat mendeteksi garis dengan cara membedakan warna yang gelap dan warna yang terang.

    Untuk sensor yang biasa digunakan untuk membaca garis diantaranya sensor photodioda, phototransistor, infrared maupun sensor LDR (Light Dependent Resistor), untuk robot yang saya buat kali ini menggunakan sensor photodioda kenapa sensor itu, karena sensor ini mudah didapat yang banyak dijual di toko komponen elektronika dan harga yang juga terjangkau tentunya.

    Gambar Ilustrasi Mekanisme Pembacaan Sensor Garis.

    Kemudian untuk pemeroses atau otak dari robot ini menggunakan mikrokontroler, untuk robot line follower kali ini saya menggunakan mikrokontroler arduino yaitu arduino uno fungsi dari mikro untuk memproses data dari sensor dan kemudian mengontrol motor sebagai aktuator penggerak robot, mikrokontroler ini di isi dengan program atau coding yang akan mengatur robot untuk bernavigasi mengikuti garis.

    Lalu bagaimana robot bisa dengan baik bernavigasi mengikuti garis, yaap.. kita masuk pada inti dari robot ini yaitu sistem kontrol PID pada robot line follower, dengan menerapkan kontroler PID yang tepat pada robot line follower pergerakan robot akan lebih halus dibandingkan menggunakan kontrol ON-OFF.

    Apa itu PID?
    PID singkatan dari Proporsional Integral Derivative, merupakan sebuah algoritma kontrol yang sudah lama ada dan sangat populer digunakan pada sistem kontrol di industri maupun dibidang robotic, sistem kendali ini dapat digunakan pada sistem yang memiliki umpan balik (feedback), kontrol PID ini akan menghitung nilai error, yaitu perbedaan antara nilai setpoint (nilai yang diinginkan) dan variabel prosses terukur (process variable), kontrol ini akan mencoba untuk megurangi nilai error agar menuju ke setpoint yang diinginkan.

    Diagram Blok Kontrol PID

    Bentuk Kontroler PID Diskrit

    Diagram Blok Penerapan Kontrol PID Pada Robot Line Follower
    • Setpoint, merupakan parameter nilai yang diinginkan.
    • Process Variable, merupakan bobot nilai sensor yang dibaca sesuai dengan pembacaan sensor saat itu.
    • Error, merupakan nilai kesalahan yang di dapat dari ( Setpoint - Process Variable ).
    Kontrol PID Pada Robot Line Follower
    Robot line follower yang akan di kontrol degan PID kali ini menggunakan 8 sensor, garis yang digunakan dengan lebar 2-3 cm yang memungkinkan mengenai 2 sensor kemudian lakukan mapping pada sensor untuk mendapatkan nilai process variable, untuk 8 sensor hasil mapping nilai process variable kurang lebih sebagai berikut :

        /** 1 di asusmsikan sensor mengenai garis **/
        case 0b00000001 : NilaiPosisi = -10; break;
        case 0b00000111 : NilaiPosisi = -9; break;
        case 0b00000011 : NilaiPosisi = -8; break;
        case 0b00000010 : NilaiPosisi = -7; break;
        case 0b00001110 : NilaiPosisi = -6; break;
        case 0b00000110 : NilaiPosisi = -5; break;
        case 0b00000100 : NilaiPosisi = -4; break;
        case 0b00011100 : NilaiPosisi = -3; break;
        case 0b00001100 : NilaiPosisi = -2; break;
        case 0b00001000 : NilaiPosisi = -1; break;
        case 0b00011000 : NilaiPosisi = -0; break;
        case 0b00010000 : NilaiPosisi =  1; break;
        case 0b00110000 : NilaiPosisi =  2; break;
        case 0b00111000 : NilaiPosisi =  3; break;
        case 0b00100000 : NilaiPosisi =  4; break;
        case 0b01100000 : NilaiPosisi =  5; break;
        case 0b01110000 : NilaiPosisi =  6; break;
        case 0b01000000 : NilaiPosisi =  7; break;
        case 0b11000000 : NilaiPosisi =  8; break;
        case 0b11100000 : NilaiPosisi =  9; break;
        case 0b10000000 : NilaiPosisi =  10; break;
    

    kondisi ideal robot adalah pada saat sensor berada pada posisi 00011000 (nilai 1 di asumsikan sensor mengenai garis) atau NilaiPosisi = 0 dan Setpoint = 0 merupakan posisi ideal robot line follower jika NilaiPosisi tidak = 0 berarti robot tidak pada posisi ideal dan artinya ada nilai error, pada kondisi error output PID akan mengeluarkan hasil kendalinya sesuai dengan besaran error yang terjadi dan kemudian akan dikalkulasikan dengan nilai base PWM yang ditentukan untuk menjadi PWM ke motor kiri dan kanan.

    Formula perhitungan PWM motor kiri dan kanan sebagai berikut :
    motorKi = BasePWM - outPID;      ( Motor Kiri )
    motorKa = BasePWM + outPID;    ( Motor Kanan )

    Pada pemrograman robot line follower perhitungan PID ditulis sebagai berikut :

    double Error = 0, SumError = 0, LastError = 0;
    double BasePWM = 250; 
    double Kp = 43;       // Proporsional 
    double Ki = 0.2;      // Integral     
    double Kd = 145;      // Diferensial
    double Ts = 1;        // Time sampling
    
    /**** Fungsi perhitungan PID ****/
    void lineFollow() {
      robotPosition();
      int SetPoint = 0;                      // Setpoint yang diinginkan
      Error = SetPoint - NilaiPosisi;        // Error
      double DeltaError = Error - LastError; // Delta Error (Selisih error sekarang e(t) dengan error sebelumya e(t-1))
      SumError += LastError;                 // Akumulasi error
      double P = Kp * Error;                 // Kontrol proporsional
      double I = Ki * SumError * Ts;         // Kontrol integral
      double D = ((Kd / Ts) * DeltaError);   // Kontrol derivative
      LastError = Error;                     // Error sebelumnya
      outPID = P + I + D;                    // Output PID
      double motorKi = BasePWM - outPID;     // Motor Kiri
      double motorKa = BasePWM + outPID;     // Motor Kanan
      /*** Pembatasan kecepatan ***/
      if (motorKi > Kec_Max)motorKi = Kec_Max;
      if (motorKi < Kec_Min)motorKi = Kec_Min;
      if (motorKa > Kec_Max)motorKa = Kec_Max;
      if (motorKa < Kec_Min)motorKa = Kec_Min;
      driveMotor(motorKi, motorKa);
    }
    

    Tuning Kontroler PID Robot Line Follower
    Proses tuning bertujuan untuk menentukan nilai yang tepat untuk parameter aksi kontrol proporsional, integral, derivative pada robot line follower, proses tuning dilakukan dengan menggunkan metode tuning Ziegler-Nichols metode ini dilakukan dengan cara memberikan kontrol proporsional pada sistem close loop dan plant di dalamnya.

    Kemudian memberikan nilai Kcr (kontrol proporsional), nilai Ki = 0 (kontrol integral) dan Kd = 0 (kontrol derivative) hingga sistem memperlihatkan grafik yang berosilasi terus menerus secara teratur contoh pada gambar berikut :
    Dari grafik osilasi yang berkesinambungan dan dari penguatan Kcr kemudian dapatkan nilai Pcr (periode kritis) untuk mendapatkan nilai Kp, Ki, Kd dihitung sesuai aturan Ziegler-Nichols sebagai berikut:
    Setelah nilai Kp, Ki, Kd di dapatkan kemudian masukkan pada program line follower, jika semua nilai parameter sudah tepat maka robot akan bergerak mengikuti garis dengan baik dan akan didapatkan grafik yang memperlihatkan respon posisi yang selalu menuju setpoint seperti gambar berikut :

    Untuk hasilnya silahkan lihat pada video berikut.

    Referensi : 
    • https://id.wikipedia.org/wiki/PID
    Newer Posts Older Posts Home

    Popular Posts

    • Membuat Gerbang Otomatis [Arduino Controlled Gate Barrier with Ultrasonic Sensor HC-SR04]
    • Line Follower Robot Using PID Control
    • Membuat Mobil Remote Control dengan Arduino [RC Car Control with Bluetooth]
    • Light Follower Robot Arduino Dengan LDR
    • Cara Memperbaiki Kipas Angin Mati Total [Tidak Berputar Sama Sekali]

    Categories

    Elektronika Arduino Tips dan Trik Robotic Tutorial IoT Software Arduino Tutorial PCB STM32

    Recent Posts

     
    Copyright © MUHILHAM • Electronics Hobbyist and Maker. All Rights Reserved.