Solusi #3

Menggunakan NodeMCU

Jadi pilihan ketiga ini adalah pilihan yang terbaik menurut saya. Mengapa? Karena dengan menggunakan NodeMCU, rangkaian menjadi lebih praktis, tidak memerlukan kabel ke komputer, koneksi kontrol ke alat penggerak dilakukan secara nirkabel. Berikut ini langkah-langkah pembuatan alat penggerak kamera menggunakan NodeMCU.

1. Siapkan rangkaian NodeMCU seperti berikut. 


Ada 4 jenis komponen yang diperlukan dalam rangkaian di atas:
    • NodeMCU
    • Driver Motor (bisa L298 atau lainnya )
    • Motor Encoder
    • Limit Switch (LS1, LS2)
Keterangan rangkaian:
    • NodeMCU digunakan untuk membaca data posisi Encoder, mengirimkan datanya melalui Wi-Fi ke MQTT Broker, dan menerima data dari MQTT Broker melalui Wi-Fi untuk menggerakkan Motor.
    • Driver Motor digunakan untuk menguatkan sinyal NodeMCU agar mampu menggerakkan Motor.
    • Motor digunakan untuk menggerakkan kamera dan sensor Encoder memberikan data posisi.
    • Limit Switch LS1 dan LS2 ditempatkan di ujung-ujung rel, digunakan sebagai pembatas gerakan kamera, menghentikan Motor, dan khusus untuk LS1, digunakan sebagai titik 0 Encoder.
Koneksi kaki I/O NodeMCU:
    • D0 terhubung ke LS1, yang memutus/hubungkan D0 ke Ground
    • D1 terhubung ke LS2, yang memutus/hubungkan D1 ke Ground
    • D2 terhubung ke ENA L298
    • D3 terhubung ke IN1 L298
    • D4 terhubung ke IN2 L298
    • D5 terhubung ke output C1 Encoder
    • D6 terhubung ke output C2 Encoder

2. Buat program NodeMCU seperti berikut. 

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>
Encoder myEnc(D5, D6);
const char* ssid = "Oyeoye";
const char* password = "12345678";
const char* mqtt_server = "broker.mqttdashboard.com";
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long waktu = 0;
char pwm[4];
char posisi[5];
int out_maks = 50;
int out_min = -50;
int setpoin = 500;
float err0 = 0;
float error = 0;
float err_d = 0;
float err_i = 0;
float pid = 0;
float kp = 0.2;
float ki = 0.2;
float kd = 0.5;
int dead_maks = 10;
int dead_min = -10;
int ena = 0;
long output = 0;
long output1 = 0;
void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
  if (strcmp(topic, "posisiKamera") == 0) {
    posisi[0] = (char)payload[0];
    posisi[1] = (char)payload[1];
    posisi[2] = (char)payload[2];
    posisi[3] = (char)payload[3];
    posisi[4] = '\0';
    setpoin = atoi(posisi);
  }
  if (strcmp(topic, "pwmKamera") == 0) {
    pwm[0] = (char)payload[0];
    pwm[1] = (char)payload[1];
    pwm[2] = (char)payload[2];
    pwm[3] = '\0';
    out_maks = atoi(pwm);
    out_min = -out_maks;
  }
}
void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    if (client.connect(clientId.c_str())) {
      client.subscribe("posisiKamera");
      client.subscribe("pwmKamera");
    }
  }
}
void setup() {
  pinMode(BUILTIN_LED, OUTPUT);
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  myEnc.write(0);
  analogWriteRange(255);
  pinMode(D2,OUTPUT);
  pinMode(D3,OUTPUT);
  pinMode(D4,OUTPUT);
}
void loop() {
  if (!client.connected()) reconnect();
  output = myEnc.read();
  client.loop();
  if (millis() - waktu > 50) {
    waktu = millis();
    error = setpoin - output;
    err_i = error + err_i;
    if (err_i > out_maks) err_i = out_maks;
    if (err_i < out_min) err_i = out_min;
    pid = (error * kp) + (err_i * ki) + (err_d * kd);
    err_d = error - err0;
    err0 = error;
    if (error < dead_maks and error > dead_min) pid = 0;
    ena = abs(pid);
    if (ena > 255) ena = 255;
    if (ena < 0) ena = 0;
    analogWrite(D2, ena);
    if (pid < 0) {
      digitalWrite(D3, 1);
      digitalWrite(D4, 0);
    }
    if (pid > 0) {
      digitalWrite(D3, 0);
      digitalWrite(D4, 1);
    }
    if (output != output1) {
      String enkoder = String(output);
      client.publish("enkoderKamera", (char*) enkoder.c_str());
      output1 = output;
    }
  }
}


Keterangan program NodeMCU:
  • Program di atas memerlukan koneksi ke WiFi. Silahkan mengganti kode ssid dan password yang diwarnai merah di atas dengan ssid dan password WiFi yang digunakan.
  • Program di atas pada intinya membaca data posisi dari Encoder, kemudian membandingkannya dengan data posisi dari kontrol (yang diterima dari MQTT Broker), yang nilai selisih pembandingannya digunakan untuk mengatur gerakan Motor DC melalui Driver L298. 
  • Karena penggunaan selisih pembandingan ternyata menghasilkan motor berosilasi cukup besar, maka dalam program di atas diterapkan kontrol PID, yang bisa membuat motor berhenti ketika mencapai target posisi yang diinginkan.
  • Ada 3 variabel untuk mengatur motor DC melalui Driver L298, yaitu in1, in2 dan ena. Variabel in1 dan in2 digunakan untuk mengatur arah putaran. Apabila in1 = 1 dan in2 = 0, maka arah putaran akan searah jarum jam (cw), sebaliknya apabila in1 = 0 dan in2 = 1, maka arah putaran akan berlawanan jarum jam (ccw). Variabel ena digunakan untuk mengatur besarnya kecepatan, yang dibuat dengan sinyal PWM. Semakin besar nilai PWM (dari 0 - 255) diberikan, semakin besar kecepatan yang dihasilkan. 
  • Di samping sensor Encoder dan Driver Motor, ada 2 buah Limit Switch (LS1 dan LS2), yang digunakan untuk menghentikan motor, dan khusus untuk LS1, apabila aktif, akan mereset nilai Encoder, menggunakan instruksi myEnc.write(0).
  • Kemudian ketika motor berhenti karena menabrak Limit Switch, maka agar motor bisa digerakkan ke arah yang berlawanan, maka penghentian motor dilakukan dengan membuat 0, variabel arah (in1 atau in2) yang saat itu sedang bernilai 1. 

File unduhan:

  • Teman-teman bisa mengunduh file program NodeMCU di atas, di link ini: program NodeMCU
  • Program NodeMCU di atas memerlukan library PubSubClient dan Encoder. Teman-teman bisa mengunduh file library PubSubClient di: PubSubClient dan Encoder di: Encoder

 Upload Program:

  • Untuk mengupload program di atas ke board NodeMCU, teman-teman perlu mengatur pilihan Board di menu Tools, di ESP8266 Boards, dan pilih NodeMCU 1.0, seperti berikut:
 

    • Apabila pilihan Board ESP8266 belum muncul, teman-teman perlu mengunduh tambahan Board tersebut di Boards Manager. Namun sebelum membuka Boards Manager, isi kolom Additional Boards Manager URLs, yang ada di Preferences di menu File, dengan alamat: 

 https://arduino.esp8266.com/stable/package_esp8266com_index.json

 

    • Setelah itu, buka Boards Manager di menu Tools, di pilihan Board.
    • Kemudian ketik di kolom Boards Manager: "nodemcu", maka akan muncul pilihan esp8266. Klik Install.  
    • Setelah terinstal, klik Close. Kemudian pilih kembali Board NodeMCU 1.0, di piihan ESP8266 Boards,  di menu Tools. Kemudian pilih Port yang digunakan NodeMCU. Setelah semua selesai, klik tombol Upload.  

  

3. Buat program MIT App Inventor seperti berikut:




Keterangan program App Inventor:
  • Ada 2 tampilan pada program App Inventor, yaitu tampilan Designer, yang dapat digunakan untuk menempatkan objek-objek, baik yang terlihat oleh pengguna (seperti Label, Button, Slider, dll.), maupun yang tersembunyi (seperti mqtt contohnya). Tampilan kedua dinamai Block, yang digunakan untuk memprogram objek-objek yang telah ditempatkan di tampilan Designer. Terlihat pada gambar di atas, ada 5 subrutin program, yang berturut-turut berisi:
    • Subrutin when mqtt.ConnectionStateChanged: Subrutin ini digunakan untuk memeriksa apakah mqtt broker sudah terhubung, jika belum terhubung, maka diminta untuk menekan tombol connect, yang juga membuat aksi subscribe ke topic enkoderKamera.
    • Subrutin when mqtt.MessageReceived: Subrutin ini digunakan untuk mengambil data apabila topic yang di-subscribe (enkoderKamera) mempublish data. Data yang diambil tersebut kemudian ditampilkan di Label dan Slider Encoder.
    • Subrutin when button1.click: Subrutin ini digunakan untuk memutus/menghubungkan koneksi ke MQTT Broker dengan penekanan tombol.
    • Subrutin when Slider.PositionChanged: Subrutin ini digunakan untuk mempublish data melalui MQTT dengan topic pwmKamera. 
    • Subrutin when Slider2.PositionChanged: Subrutin ini digunakan untuk mempublish data melalui MQTT dengan topic posisiKamera. 
  • Program App Inventor di atas membutuhkan tambahan ekstensi mqtt. Unduh file ekstensi mqtt di link berikut ini: fileExtensiMQTT. Untuk menambahkan file ekstensi tersebut ke program App Inventor, buka Extension yang ada di bagian paling bawah dari Palette, dan kemudian tekan tombol Import Extension, dan arahkan ke lokasi file unduhan.  
  • Teman-teman dapat mengunduh program MIT App Inventor seperti gambar di atas di link ini: program App Inventor (aia)
  • Untuk file aplikasi hasil Build Android apk program di atas dapat diunduh di link ini: program aplikasi (apk)

 

4. Berikut ini video pembuatan dan hasil implementasinya:



Tidak ada komentar:

Posting Komentar