12. Proyek Kontrol Motor DC dengan Arduino

12. PROYEK KONTROL MOTOR DC DENGAN ARDUINO

Tugas utama motor pada sistem kontrol adalah sebagai aktuator, yaitu mengubah besaran elektris menjadi besaran mekanis. Contoh aplikasi pengendalian motor adalah sebagai motor industri dan robot. Bagian ini akan dibahas bagaimana mengendalikan motor DC secara sederhana dengan Arduino. Hal ini akan menjadi landasan berpikir Anda saat pengembangan proyek yang lebih kompleks.

Motor DC adalah motor listrik yang memerlukan suplai tegangan arus searah pada kumparan medan untuk diubah menjadi energi gerak mekanik. Kumparan medan pada motor DC disebut stator (bagian yang tidak berputar) dan kumparan jangkar disebut rotor (bagian yang berputar). Motor arus searah, sebagaimana namanya, menggunakan arus langsung yang tidak langsung/ direct-unidirectional.

Motor DC memiliki 3 bagian atau komponen utama untuk dapat berputar sebagai berikut:

  • Kutub medan

Motor DC sederhana memiliki dua kutub medan: kutub utara dan kutub selatan. Garis magnetik energi membesar melintasi ruang terbuka diantara kutub-kutub dari utara ke selatan. Untuk motor yang lebih beşar atau lebih komplek terdapat satu atau lebih elektromagnet.

  • Current Elektromagnet atau Dinamo

Dinamo yang berbentuk silinder, dihubungkan ke as penggerak untuk menggerakan beban. Untuk kasus motor DC yang kecil, dinamo berputar dalam medan magnet yang dibentuk oleh kutub-kutub, sampai kutub utara dan selatan magnet berganti lokasi.

  • Commutator

Komponen ini terutama ditemukan dalam motor DC. Kegunaannya adalah untuk transmisi arus antara dinamo dan sumber daya.

Gambar 12.2 menunjukkan bagan jenis-jenis motor listrik, fokus kita adalah pada motor DC, kita tidak membahas bagaimana definisi dan cara kerja setiap jenis motor secara mendalam, melainkan langsung mengaplikasikannya dalam praktek dengan kontrol Arduino. Penjelasan yang baik mengenai motor DC dapat dibaca di situs berikut:

12.1. Perbedaan Stepper & Servo

perbedaan mendasar antara stepper tradisional dengan motor servo adalah dari Jerus motornya dan bagaimana motor tersebut dikontrol. Stepper biasanya menggunakan 50 sampai 100 kutub motor brushless, sedangkan motor servo umumnya hanya mernlliki 4 sampai 12 kutub. Kutub adalah area dalam sebuah motor dimana kutub magnet;c utaradanselatandihasilkanbaikituolehmagnetpermanenataupunarusyangmeiewati gulungan lilitan.

Stepper tidak membutuhkan encoder karena stepper dapat secara akurat bergerak antar kutub-kutub, namun pada servo, dengan hanya sedikit kutub yang dimilikinya, membutuhkan encoder untuk menjaga posisinya tetap pada jalurnya. Stepper sederhananya bergeraksecara inkrimental menggunakan pulsa (open-loop) sementara servo secara closed-loop menggunakan bantuan encoder.

12.2. Pengertian Motor Stepper

Motor stepper adalah salah satujenis motor DCyang dikendalikan dengan pulsa-pulsa digital. Prinsip kerja motor stepper adalah bekerja dengan mengubah pulsa elektronis menjadi gerakan mekanis diskrit dimana motor stepper bergerak berdasarkan urutan pulsa yang diberikan kepada motor stepper tersebut.

Prinsip kerja motor stepper adalah mengubah pulsa-pulsa input menjadi gerakan mekanis diskrit. Oleh karena itu untuk menggerakkan motor stepper diperlukan pengendali motor stepper yang membangkitkan pulsa-pulsa periodik.

Berikut ini adalah ilustrasi struktur motor stepper sederhana dan pulsa yang dibutuhkan untuk menggerakkannya :

Gambar diatas memberikan ilustrasi dari pulsa keluaran pengendali motor stepper dan penerapan pulsa tersebut pada motor stepper untuk menghasilkan arah putaran yang bersesuaian dengan pulsa kendali.

12.3. Pengertian Motor Servo

Servo Motor adalah motor DC yang dilengkapi rangkaian kendali dengan sistem closed feedback yang terintegrasi dalam motor tersebut. Pada motor servo posisi putaran sumbu (axis) dari motor akan diinformasikan kembali ke rangkaian kontrol yang ada di datam motor servo. Contoh Motor Servo Motor servo disusun dari sebuah motor DC, gearbox, variabel resistor (VR) atau potensiometer dan rangkaian kontrol. Potensiometer berfungsi untuk menentukan batas maksimum putaran sumbu (axis) motor servo. Sedangkan sudut dari sumbu motor servo diatur berdasarkan lebar pulsa yang pada pin kontrol motor servo.

Konstruksi Motor Servo Motor servo adalah motor yang mampu bekerja dua arah (CW dan CCW) dimana arah dan sudut pergerakan rotornya dapat dikendalikan dengan memberikan variasi lebar pulsa (duty cycle) sinyal PWM pada bagian pin kontrolnya. Jenis Motor Servo Motor Servo Standar 1800 Motor servo jenis ini hanya mampu bergerak dua arah (CWdan CCW) dengan defleksi masing-masing sudut mencapai 900 sehingga total defleksi sudut dari kanan – tengah — kiri adalah 1800.

Motor Servo Continuous Motor servo jenis ini mampu bergerak dua arah (CW dan CCW) tanpa batasan defleksi sudut putar (dapat berputar secara kontinyu). Pulsa Kontrol Motor Servo Operasional motor servo dikendalikan oleh sebuah pulsa selebar ± 20 ms, dimana lebar pulsa antara 0.5 ms dan 2 ms menyatakan akhir dari range sudut maksimum.

Apabila motor servo diberikan pulsa dengan besar 1.5 ms mencapai gerakan 900, maka bila kita berikan pulsa kurang dari 1.5 ms maka posisi mendekati 00 dan bila kita berikan pulsa lebih dari 1.5 ms maka posisi mendekati 1800.Pulsa Kendali Motor Servo Motor Servo akan bekerja secara baikjika pada bagian pin kontrolnya diberikan sinyal PWM dengan frekuensi 50Hz. Dimana pada saat sinyal dengan frekuensi 50 Hz tersebut dicapai pada kondisi Ton duty cycle 1.5ms, maka rotor dari motor akan berhenti tepat di tengah-tengah (sudut 00/netral).

Pada saat Ton duty cycle dari sinyal yang diberikan kurang dari 1.5 ms, maka rotor akan berputar ke berlawanan arah jarum jam (Counter Clock wise, CCW) dengan membentuk sudut yang besarnya linier terhadap besarnya Ton duty cycle, dan akan bertahan diposisi tersebut, dan sebaliknya.

12.4 Gerakan Servo SG-90 Otomatis Mulai 0° – 180°

Servo yang bergerak otomatis, menyapu mulai 00 sampai 1800 sering digunakan sebagai alat bantu sensor ultrasonic untuk memindai dan mendeteksi halangan yang ada di sekitar robot obstacle, seperti tampak pada gambar 12.5.

Gambar 12.5. Robot Dengan Servo & Ultrasonic Sensor

Percobaan yang akan dibuat adalah bagaimana menggerakkan motor servo dari kiri ke kanan (00 – 1800), kemudian bergerak kembali dari kanan ke kiri (1800 – 00). Perpindahan per derajat 450 dilakukan setiap 2 detik dan setiap perubahan derajat putaran akan menampilkan jarak rintangan yang ditangkap oleh sensor Ultrasonic pada LCD.

Kebutuhan Bahan

Bahan Jumlah Nilai Keterangan
Servo SG-90 1 pcs
Modul LCDI 602 lec 1 pcs
Modul Sensor Ultrasonic

HC-SR04

1 pcs
Bracket Plastik

Sensor Ultrasonic HCSR04

1 pcs

Diagram Sketch

Proyek ini membutuhkan library servo. Yang hanya dapat di-download di https://github.com/Arduino-libraries/Servo dan library Libraryc+Add LCD 12C. Kemudian install Servo-master-zip dari menu Arduino Sketch -> Include Library -> Add . zip Library.

Kode Program

#include <Servo.h>

#include <LiquidCrystal_I2C.h>

//Ultrasonic

const int pinTrigger = 8; // pin trigger HC-SR04

const int pinEcho =9; // pin echo HC-SR04

// Atur alamat LCD pada 0x27 untuk tampilan LCD 16 karakter 2 baris LiquidCrystal_I2C lcd(0x27, 16, 2);

// Karakter derajat

byte derajat[ ] ={

B01110,

B10001,

B10001,

B10001,

B01110,

B00000,

B00000,

B00000

};

// Servo

const int pinServo = 10; // pin Signal Servo

Servo myservo; // Membuat objek untuk mengendalikan servo

void setup(){

lcd.init(); // Inisialisasi LCD

lcd.createChar(0, derajat);

lcd.backlight(); // Menghidupkan backlight

lcd.setCursor(0,0);

lcd.print(“HITUNG JARAK”);

lcd.setCursor(0,1);

lcd.print(“& SERVO SWEEP”);

pinMode(pinTrigger, OUTPUT);// set pin trigger sebagai output

pinMode(pinEcho, INPUT); // set pin echo sebagai input

// attach pin servo pin

myservo.attach(pinServo);

}

void loop(){

rotasi_dan_jarak(0);

rotasi_dan_jarak(45);

rotasi_dan_jarak(90);

rotasi_dan_jarak(135);

rotasi_dan_jarak(180);

rotasi_dan_jarak(135);

rotasi_dan_jarak(90);

rotasi_dan_jarak(45);

}

void rotasi_dan_jarak(int deg) {

myservo.write(deg);

// Membersihkan pin pinTrigger selama 2 microdetik

digitalwrite(pinTrigger, LOW);

delayMicroseconds(2);

// Set pinTrigger menjadi HIGH selama 10 microdetik

digitalwrite(pinTrigger, HIGH);

delayMicroseconds(10);

digitalwrite(pinTrigger, LOW);

// Membaca pinEcho, mengembalikan waktu perjalanan gelombang suara dalam mikrodetik

long duration = pulseIn(pinEcho,HIGH);

int distanceCm = duration * 0.034 / 2; // Jarak dalam CM

lcd.setCursor(0,0);

lcd.print(“Posisi: “ + String(deg)); // Tampilkan derajat putaran

lcd.write(0);

lcd.setCursor(0,1);

lcd.print(“Jarak:“ + String(distancecm) +“ cm”); // Tampilkan Jarak rintangan

delay(2000); // Tunda per 2 detik

lcd.clear();

}

Adapun ilustrasi hasil akhirnya tampak seperti Gambar 12.6

Gambar 12.6. Gerakan Servo Otomatis

12.5 Kendali Arah Servo SG-90 Dengan Potensiometer

Proyek berikut masih serupa dengan proyek sebelumnya, namun kendali servo tidak bergerak dari kiri ke kanan dan sebaliknya secara otomatis, melainkan putaran servo dikendalikan Oleh potensiometer sesuai posisi potensiometer yang diputar, dimana potensiometer dihubungakan dengan input analog AO Arduino.

Bahan Jumlah Nilai Keterangan
Modul Servo SG-90 1 pcs
Modul LCDI 602 1 pcs
Potensiometer Mono 1 pcs 50K Ohm

Diagram Sketch

Karena potensiometer sebagai nilai masukkan yang bekerja secara analog bernilai antara 0— 1023 maka pada program dilakukan mapping nilai menjadi nilai derajat antara 00 – 1800 menggunakan fungsi map(nilaiPembacaanPotensiometer, 0, 1023, 0, 180).

Kode Program

#include <Servo.h>

#include <LiquidCrystal_I2C.h>

// Ultrasonic

#define pinTrigger = 8 // pin trigger HC-SR04

#define pinEcho = 9 // pin echo HC-SR04

#define pinPotensiometer A0 // pin potensiometer

// Atur alamat LCD pada 0x27 untuk tampilan LCD 16 karakter 2 baris LiquidCrystal_I2C lcd(0x27, 16, 2);

// Karakter derajat

byte derajat[ ]={

B01110,

B10001,

B10001,

B10001,

B01110,

B00000,

B00000,

B00000

};

// Servo

#define pinServo 10 // pin Signal Servo

Servo myservo; // Membuat objek untuk mengendalikan servo

int val;

void setup(){

Serial. begin(9600);

lcd.init(); // Inisialisasi LCD

lcd.createChar(0, derajat);

lcd.backlight(); //q Menghidupkan backlight

lcd. setCursor(0, 0);

lcd.print(“HITUNG JARAK”);

lcd.setCursor(0, 1);

lcd.print(“& SERVO SWEEP”);

pinMode(pinTrigger, OUTPUT); // set pin trigger sebagai output

pinMode(pinEcho, INPUT); // set pin echo sebagai input

// attach pin servo pin

ayservo.atrach(pinServo);

}

void loop(){

// Membersihkan pin pinTrigger selama 2 microdetik

digitalwrite(pinTrigger, LOW);

delayMicroseconds(2);

// Set pinTrigger menjadi HIGH selama 10 microdetik

digitalwrite(pinTrigger, HIGH);

delayMicroseconds(10);

digitalwrite(pinTrigger, LOW);

// Membaca pinEcho, mengembalikan waktu perjalanan gelombang suara dalam mikrodetik

long duration = pulseIn(pinEcho, HIGH);

int distanceCm = duration * 0.034 / 2; // Jarak satuan sentimeter

// Membaca nilai pin potensiometer val = analogRead(pinPotensiometer);

// Pemetaan skala nilai analog (0-1023) menjadi derajat (0-180)

val = map(val, 0, 1023, 0, 180);

// Atur posisi servo sesuai derajat yang ditentukan oleh potensiometer myservo.write(val);

// Tampilkan derajat putaran

lcd.setCursor(0,0);

lcd.print(“Posisi: “ + String(val));

lcd.write(0);

// Tampilkan jarak rintangan

lcd.setCursor(0,1);

lcd.print(“Jarak: “ + String(distanceCm) +“ cm”);

delay(15);

lcd.clear();

}

12.6 Robot Keseimbangan Dengan Sensor Gyroscope MPU6050 & Motor Drive L298N

Self Balanced Robot adalah robot yang bertumpu pada dua roda, dimana kecenderungan robot adalah jatuh secara vertikal seperti pada konsep pendulum. Robot keseimbangan mampu memulihkan posisi vertikal atau memiliki kemampuan untuk menyeimbangkan dengan sendirinya saat robot tersebut beroperasi bergerak maju, mundur dan belok.

Tugas kontrol program adalah menggerakkan setiap roda dan mengoreksi derajat sudut kemiringan saat robot bergerak maju atau mundur untuk dikembalikan pada posisi 0 derajat atau posisi vertikal yang disebut pemulihan posisi.

Untuk mengukur sudut kemiringan robot maka robot keseimbangan membutuhkan dua sensor:

  • Accelerometer, sensor yang digunakan untuk mengukur percepatan suatu objek. Accelometer mengukur percepatan dynamic dan static. Pengukuran dynamic adalah pengukuran percepatan pada objek bergerak, sedangkan pengukuran static adalah pengukuran terhadap gravitasi bumi. Untuk mengukUr sudut kemiringan (tilt), accelerometer dapat mengukur kekuatan gravitasi dan dengan informasi itu kita dapat memperoleh sudut robot.
  • Gyroscope, mengukur kecepatan sudut, jadi jika kita mengintegrasikan ukuran ini kita dapat memperoleh sudut robot dipindahkan. Masalah ukuran ini adalah bahwa itu tidak sempurna dan integrasi memiliki penyimpangan.

Agar bekerja stabil maka kedua sensor tersebut bekerja secara terintegrasi menjadi sensor fusion. Penggabungannya menggunakan metode Filter Kalman. Filter Kalman adalah algoritma dalam robotika yang memberikan hasil optimal dengan komputasi rendah. Untuk megetahui lebih mendalam, silahkan baca literasi mengenai PID dan Filter Kalman. Pada buku ini hanya dibahas bagaimana cara implementasinya dengan menggunakan library Arduino yang tersedia.

Gambar 12.8. Contoh Konstruksi Robot Keseimbangan

Secara umum kebutuhan komponen dasar untuk membuat robot keseimbangan adalah dua roda, dua motor DC, dua bracket siku sebagai penyangga antara roda dan motor, battrey, casing, modul driver motor L298 dan sensor accelorometer & gyroscope MPU6050 sebagai sensor pendeteksi derajat kemiringan.

Gambar 12.14 Pinout Arduino Nano

Module L298N (Gambar 12.12) selain berfungsi sebagai driver (penguatan/ amplifikasi) motor DC juga berfungsi sebagai kontrol arah putaran motor yang dikenal sebagai l’H-Bridge” dengan cara mengubah polaritas tegangan yang diumpankan pada motor DC. Dari perubahan polaritas tegangan tersebut kita dapat mengendalikan gerakan kedua motor, misal: maju, mundurı belok kiri atau belok kanan. llustrasi tampak seperti pada Gambar 12.15.

Kebutuhan Bahan

Bahan Jumlah Nilai Keterangan
Motor Driver 1.298N 1 pcs
Sensor Gyro & Accelorometer MPU6050 1 pcs
Roda + Motor DC 2 pcs
Battrey 9V 1 pcs
Casing akrilik + spacer secukupnya

Diagram Sketch

Hubungan kabel antar bagian dapat dibaca pada tabel berikut:

Kode program membutuhkan library berikut ini:

Kode Program

#include <PID_v1.h>

#include <LMotorController.h>

#include <I2Cdev.h>

#include <MPU6050_6Axis_MotionApps20.h>

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE

#include “Wire.h”

#endif

#define MIN_ABS_SPEED 20

MPU6050 mpu;

// MPU control/status vars

bool dmpReady = false; // set true if DMP init was successful

uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU

uint8_t devStatus; // return status after each device operation (0= success,

!0 = error)

uint16_t packetSize; // expected DMP packet size (default is 42 bytes)

uint16_t fifoCount; // count of all bytes currently in FIFO

uint8_t fifoBuffer[64];// FIFO storage buffer

// orientation/motion vars

Quaternion q;// [w, x,y,z] quaternion container

VectorFloat gravity; // [x, y, z] gravity vector

float ypr[3];// [yaw, pitch, roll] yaw/pitch/roll container and gravity vector

//PID

double originalsetpoint=173;

double setpoint = originalSetpoint;

double movingAngle0ffset=0.1;

double input,output;

//sesuaikan nilai Kp, Kd dan Ki dengan mencobanya

double Kp=60; // Sesuaikan nilai Kp, Kd, Ki dengan mencoba langsung

double Kd=2.4;

double Ki=90;

PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

double motorSpeedFactorLeft =1;

double motorSpeedFactorRight=1;

//MOTOR CONTROLLER

int ENA=7;

int IN1=8;

int IN2=9;

int IN3=10;

int IN4=11;

int ENB=12;

LMotorController motorController(ENA,IN1,IN2,ENB,IN3,IN4,motorspeed-

FactorLeft, motorSpeedFactorRight);

volatíle bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high

voíd dmpDataReady()

{

mpuInterrupt =true;

}

void setup()

{

// join I2C bus (I2Cdev library doesn’t do this automatically)

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE

wire.begin();

TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)

#elif I2CDEV_IMPLEMENTATION==I2CDEV_BUILTIN_FASTWIRE

Fastwire::setup(400, true);

#endif

mpu.initialize( );

devStatus = mpu.dmpInitialize( );

// supply your own gyro offsets here, scaled for min sensitivity

mpu. setXGyro0ffset(220);

mpu.setYGyroOffset(76);

mpu.setZGyroOffset(-85);

mpu.setZAccel0ffset(1788); // 1688 factory default for my test chip

// make sure it worked (returns 0 if so)

if (devStatus ==0)

{

// turn on the DMP, now that it’s ready

mpu.setDMPEnabled(true);

// enable Arduino interrupt detection

attachInterrupt(0, dmpDataReady, RISING);

mpuIntStatus =mpu.getIntStatus();

// set our DMP Ready flag so the main loop() function knows it’s okay to use it

dmpReady=true;

// get expected DMP packet size for later comparison

packetSize = mpu.dmpGetFIFOPacketSize();

//setup PID

pid.SetMode(AUTOMATIC);

pid.SetSampleTime(10);

pid.SetOutputLimits(-255, 255);

}

else

{

// ERROR!

// 1 = initial memory load failed

// 2 = DMP confguration updates failed

// (if it’s going to break, usually the code will be 1)

Serial.print(F(“DMP Initialization failed (code “));

Serial.print(devStatus);

Serial.println(F(“)”));

}

}

void loop()

{

// if programming failed, don’t try to do anything

if (!dmpReady) return;

// wait for MPU interrupt or extra packet(s) available

while (!mpuInterrupt && fifoCount < packetSize)

{

//no mpu data – performing PID calculations and output to motors

pid.Compute();

motorController.move(output, MIN_ABS_SPEED);

}

// reset interrupt flag and get INT_STATUS byte

mpuInterrupt = false;

mpuIntStatus = mpu.getIntStatus();

// get current FIFO count

fifoCount = mpu.getFIFOCount();

// check for overflow (this should never happen unless our code is too ineff-cient)

if ((mpuIntStatus & 0x10) || fifoCount == 1024)

{

// reset so we can continue cleanly

mpu.resetFIFO();

Serial.println(F(“FIFO overflow!”));

// otherwise, check for DMP data ready interrupt (this should happen fre-quently)

}

else if (mpuIntStatus & 0x02)

{

// wait for correct available data length, should be a VERY short wait

while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

// read a packet from FIFO

mpu.getFIFOBytes(fifoBuffer, packetSize);

// track FIFO count here in case there is > 1 packet available

// (this lets us immediately read more without waiting for an interrupt)

fifoCount -= packetSize;

mpu.dmpGetQuaternion(&q, fifoBuffer);

mpu.dmpGetGravity(&gravity,&q);

mpu.dmpGetYawPitchRol1(ypr, &q, &gravity);

input=ypr[1]*180 / M_PI + 180;

}

}

Dalam teori kontrol, menjaga variabel (dalam hal ini posisi robot) agar tetap stabil membutuhkan kontrol khusus, yaitu PID (proportional integral derivative). Setiap parameter mempunyai “gain”, disebut Kp, Ki dan Kd. PID untuk mengoreksi antara nilai yang kehendaki (atau input) dan nilai aktual (atau output). Perbedaan antara input dan output disebut “error”.

Pengendali PID menurunkan nilai error sekecil mungkin melalui penyesuaian output. Pada robot keseimbangan, input (derajat kemiringan yang diinginkan) diatur dengan software. MPU6050 membaca kemiringan robot saat ini dan mengumpannya ke algoritma PID, yang melakukan perhitungan untuk mengendalikan motor dan menjaga robot dalam posisi tegak.

PID membutuhkan nilai gain Kp, Ki dan Kd tetap terjaga pada kondisi nilai optimal. Beberapa insinyur menggunakan software seperti MATLAB untuk menghitung nilai-nilai tersebut secara otomatis. Namun untuk saat ini kita memberi nilai PID secara manual dengan langkah sebagai berikut:

  • Jadikan nilai Kp, Ki dan Kd menjai 0
  • Sesuikan nilai Kp. KP terlalu kecil membuat robot akan jatuh, karena tidak ada koreksi yang cukup, terlalu banyak KP akan membuat robot bolak-balik dengan liar. KP yang cukup baik akan membuat robot sedikit bolak-balik (atau berosilasi sedikit).
  • Setelah KP diatur, sesuaikan nilai Kd. Nilai Kd yang baik akan mengurangi osilasi sampai robot hampir stabil. Juga,jumlah Kd yang tepat akan membuat robot tetap berdiri, bahkan sekalipun didorong.
  • Terakhir, atur Ki. Robot akan terombang-ambing ketika dihidupkan, bahkan jika KP dan Kd diatur, tetapi akan stabil pada waktunya. Nilai Ki yang benar akan mempersingkat waktu yang diperlukan untuk menstabilkan robot.

Anda dapat mengembangkan robot keseimbangan tersebut dengan menambahkan kendali jarak jauh dengan menggunakan modul bluetooth HC-06 seperti yang pernah dijelaskan pada materi sebelumnya. Gambar 12.17 merupakan ilustrasi hasi proyek yang sudah dibuat.

Gambar 12.16 1/ustrasi Proyek Robot Keseimbangan

Gambar 12.17 Proyek Robot Keseimbangan Tampak Bawah

12.7 Obstacle Avoiding Robot (Robot Penghindar Halangan) & Remote Bluetooth

Robot penghindar rintangan atau obstacle avoiding robot adalah robot mobil yang bergerak secara otomatis. Robot akan bergerak maju sampai menemui halangan, kemudian robot akan mengubah arah geraknya ke kiri atau ke kanan, jika di Sisi kiri masih terhalang maka robot akan berbelok kanan, begitu pula sebaliknya.

Robot akan medeteksi adanya rintangan di depannya dengan bantuan sensor Ultrasonic HC-SR04 yang akan mengirimkan gelombang ultrasonic ke arah depan, kiri dan ke kanan secara terus menerus sampai gelombang ultrasonic diterima kembali saat ditemukan halangan. Dari rentang waktu pengiriman dan penerimaan gelombang ultrasonic tersebut maka dapat ditihitung berapa jarak antara benda penghalang dengan robot, teori perhitungannya telah dibahas pada bab sebelumnya. Sedangkan gerakan sensor ultrasonic HC-SR04 ke kiri dan ke kanan dengan menggunakan motor servo SG-90 yang bergerak secara konstan.

Gerakan robot juga bisa diatur secara manual dengan menggunakan smartphone Android melalui transmisi bluetooth, sehingga pada Arduino perlu ditambahkan modul bluetooth HC-06 sebagai penerima signal dari smartphone.

Berikut ini daftar karakter yang akan dikirim dari Smartphone Android ke Bluetooth HC-06.

Kode Keterangan Perintah
‘F’ Forward Robot bergerak maju
‘B’ Backward Robot bergerak mundur
‘L’ Left Robot berputar ke kiri
‘R’ Right Robot berputar ke kanan
‘S’ Stop Robot berhenti
‘A’ Automatic Robot diatur bergerak dengan sendirinya tanpa dikontrol dan secara otomatis robot akan menghindar ketika menemui halangan.
‘M’ Manual

Robot diatur bergerak atas kendali secara jarak jauh menggunakan smartphone dengan media transtnisi bluetooth.

Kebutuhan Bahan

Bahan Jumlah Nilai Keterangan
Sensor Ultrasonic HC-SR04

Untuk medeteksi penghalang

1 pcs
Modul Bluetooth HC-06 1 pcs
Servo Motor SG90

Untuk menggerakkan sensor ultrasonic ke kiri dan ke kanan

1 pcs
Motor Driver L298N

Sebagai pengendali arah H-Bridge dan kecepatan putaran motor servo.

1 pcs
Roda Universal

Sebagai roda penyeimbang

1 pcs
Roda + Bracket + Motor DC 2 pcs
Mini Project Board 1 pcs
Battey 9V (Rechargable) 1 pcs
Casing akrilik + Spacer Seperlunya

Jika bahan yang dibutuhkan sulit didapatkan, Anda dapat membelinya secara lengkap di marketplace seperti tampak pada Gambar 12.18, Anda tinggal menambahkan beberapa komponen seperti bluetooth HC-06, servo SG-90, dan driver motor L298N.

Gambar 12.18. Kit Case & Motor Obstacle Avoiding

Diagram Sketch

Pada proyek ini membutuhkan library Servo.h untuk mengendalikan motor servo (https://github.com/Arduino-libraries/Servo) dan library NewPing.h untuk mengendalikansensorultrasonic(https://github.com/microflo/NewPing.lnstallsemua file library .zip tersebut dari menu Arduino Sketch#lnclude Library4Add .zip Library.

Kode Program

#include <SoftwareSerial.h>

#include <NewPing.h>

#include <Servo.h>

SoftwareSerial Bluetooth(7,6); // RX, TX

#define pinServo 10

Servo myservo;

#define TRIGGER PIN 8

#define ECHO PIN 9

#define MAX_DISTANCE 500

NewPing sonar(TRIGGER_PIN, ECHO_PIN,MAX_DISTANCE);

#define MotorKiri IN1 2

#define MotorKiri_IN2 3

#defne MotorKanan_IN1 4

#defne MotorKanan_IN2 5

#define MotorKiri_EN 12

#define MotorKanan_EN 13

#defne 0B_range 30

unsigned int i = 0, pos = 0, current_distance =0;

unsigned int range0 = 0, range30 = 0, range60 = 0, range85 = 0, range99 x 0,

range95 = θ, range120 = 0, range150 = 0, range180=0;

unsígned long prevíous_millis = 0;

char serialData;

void setup()

Serial.begin(9600);

// Software Serial

Bluetooth.begin(9600);

myservo. attach(pinServo);

pinMode(MotorKiri_IN2, OUTPUT);

pinMode(MotorKiri_IN1, OUTPUT);

pinMode(MotorKanan_IN2, OUTPUT);

pinMode(MotorKanan_IN1, OUTPUT);

pinMode(MotorKiri_EN, OUTPUT);

pinMode(MotorKanan_EN,OUTPUT);

analogwrite(MotorKiri_EN,150);

analogWrite(MotorKanan_EN,150);

void brake()

{

//berhenti

digitalwrite(MotorKiri_IN1, LOW);

digitalwrite(MotorKiri_IN2, LOW);

digitalwrite(MotorKanan_IN1,LOW);

digitalwrite(MotorKanan_IN2, LOW);

}

void forward()

{

//bergerak maju

digitalwrite(MotorKiri_IN1, HIGH);

digitalwrite(MotorKiri_IN2, LOW);

digitalwrite(MotorKanan_IN1, HIGH);

digitalwrite(MotorKanan_IN2, LOW);

}

void forward_left()

{

//belok kiri dan bergerak maju

digitalwrite(MotorKiri_IN1, LOW);

digitalwrite(MotorKiri_IN2, LOW);

digitalwrite(MotorKanan_IN1, HIGH);

digítalwrite(MotorKanan_IN2, LOW);

}

void forward_right()

{

//belok kanan dan bergerak maju

digitalwrite(MotorKiri_IN1, HIGH);

digitalwrite(MotorKiri_IN2, LOW);

digitalwrite(MotorKanan_IN1, LOW);

digitalwrite(MotorKanan_IN2, LOW);

}

void backward()

{

//bergerak mundur

digitalwrite(MotorKiri_IN1, LOW);

digitalwrite(MotorKiri_IN2, HIGH);

digitalwrite(MotorKanan_IN1, LOW);

digitalwrite(MotorKanan_IN2, HIGH);

}

void backward_right()

{

//belok kanan dan bergerak mundur

digitalwrite(MotorKiri_IN1, LOW);

digitalwrite(MotorKiri_IN2, LOW);

digitalwrite(MotorKanan_IN1, LOW);

digitalWrite(MotorKanan_IN2, HIGH);

}

void backward_left()

{

//belok kiri dan bergerak mundur

digitalwrite(MotorKiri_IN1, LOW);

digitalwrite(MotorKiri_IN2,HIGH);

digitalwrite(MotorKanan_IN1, LOW);

digítalwrite(MotorKanan_IN2, LOW);

}

void left()

{

//belok kiri

digitalwrite(MotorKiri_IN1,LOW);

digitalwrite(MotorKiri_IN2,HIGH);

digitalwrite(MotorKanan_IN1,HIGH);

digitalWrite(MotorKanan_IN2,LOW);

}

void right()

{

//belok kanan

digitalwrite(MotorKiri_IN1, HIGH);

digitalwrite(MotorKiri_IN2, LOW);

digitalWrite(MotorKanan_IN1, LOW);

digitalwrite(MotorKanan_IN2,HIGH);

int range(int pos)

{

myservo.write(pos);

delay(300);

//current_distance = sonar.ping_cm(); //hitung jarak saat ini

current_distance = sonar.ping() / US_ROUNDTRIP_CM; //hitung jarak saat ini

if (current_distance == 0) current_distance =100; //jika jarak=0 maka jarak dijadikan 100

Serial.print1n(current_distance);

// jika jarak berada diantara 0 s / d 15 maka lakukan perintah di bawah

if (current_distance > 0 && current_distance <15){

Bluetooth.print(“B”); // berhenti

if (pos == 90) {

// jika servo menghadap ke depan (90 derajat) mundur

backward( );

delay(500);

}

if(pos < 90) {

// jika servo menghadap ke kiri (0-90 dereajat)

// maka robot akan belok ke kanan sambil mundur

backward_right();

delay(500);

}

if(pos > 90) {

// jika servo menghadap ke kiri (90-180 dereajat)

// maka robot akan belok ke kiri sambil mundur

backward_left();

delay(500);

}

return current_distance;

}

}

// Perintah bluetooth

// ‘A’ = SET BERGERAK OTOMATIS | M’=SET BERGERAK MANUAL DENGAN REMOTE

// ‘F’ = ROBOT BERGERAK MAJU | “B’=ROBOT BERGERAK MUNDUR

//”R’=ROBOT BELOK KANAN | “L’ = ROBOT BELOK KIRI

// ‘S’ = ROBOT BERHENTI

void loop(){

Automatic:

brake();

delay(300);

while(1){

if (Bluetooth.available() > 0) serialData = Bluetooth.read();

if (serialData == “M’) goto Manual;

above:

range90=0;

range90 = range(90);

delay(10);

while (range90 >= 0B_range ){

if (millis() – previous_millis > 2000) {

previous_millis= millis();

range(180);

delay(50);

range(0);

delay(50);

}

range90 = range(90);

analogWrite(Motorkiri_EN, 150);

analogWrite(Motorkanan_EN,150);

forward();

Bluetooth.print(“F”);

if (Bluetooth.available() > θ) serialData = Bluetooth.read();

íf (serialData == ‘M’) goto Manual;

}

brake();

if(range90 < 0B_range)

{

analogWrite(MotorKiri_EN, 100);

analogWrite(MotorKanan_EN, 100);

brake();

range60=0;

range60 = range(60);

delay(200);

range120=0;

range120 = range(120);

delay(200);

if (Bluetooth,available() > 0) serialData = Bluetooth.read();

if (serialData ==’M’) goto Manual;

if(range60 > 0B_range || range120 > 0B_range)

{

if (range60 >= range120) {

forward_right();

Bluetooth.print(“R”);

delay(50);

goto above;

} else if (range60 < range120) {

forward_left();

Bluetooth.print(“L”);

delay(50);

goto above;

}

}

if(range60 <0B_range && range120 < 0B_range)

{

above1:

range30=0;

range30= range(30);

delay(200);

range150=0;

range150 = range(150);

delay(200);

if (Bluetooth.available() > 0) serialData = Bluetooth.read();

if (serialData == ‘M’) goto Manual;

if (range30 > 0B_range || range150 > 0B_range)

{

if (range30 >=range150){

right();

Bluetooth.print(“R”);

delay(100);

goto above;

} else if (range30 < range150) {

left();

Bluetooth.print(“L”);

delay(100);

goto above;

}

}

if (range30 < 0B_range && range150 < 0B_range)

{

range0 =0;

range0 = range(0);

delay(200);

range180=0;

range180 = range(180);

delay(200);

if (Bluetooth.available() > 0) serialData = Bluetooth.read();

if (serialData == “M’) goto Manual;

if (range0 >0B_range || range180 > 0B_range )

{

if (range0 >= range180) {

backward_right();

Bluetooth.print(“R”);

delay(200);

goto above;

}

else if (range0 < range180) {

backward_left();

Bluetooth.print(“L”);

delay(200);

goto above;

}

}

if (range0 < 0B_range && range180 < 0B_range)

backward();

Bluetooth.print(“B”);

delay(200);

goto above1;

}

}

}

}

}

Manual:

brake();

delay(300);

while(1){

if (Bluetooth.available() > 0) serialData = Bluetooth.read();

if (serialData == “A’) goto Automatic;

if (serialData ==”F’) forward();

if (serialData ==“B’) backward();

if (serialData ==”S’) brake();

if (serialData ==“L’) left();

if (serialData ==”R’) right();

}

}

Jika pada kenyataannya terjadi kesalahan arah robot, misalnya arah robot seharusnya belok ke kiri tetapi malah ke kanan, seharusnya robot maju tetapi malah mundur maka artinya ada kesalahan polaritas tegangan. Untuk menanganinya ubah polaritas kabel motor DC yang terhubung ke motor driver L298N.

Sebelum mencoba hasil proyek yang dibuat maka kita harus mengaktifkan bluetooth pada mode pengaturan Android, kemudian membuka aplikasi Remote Bluetooth Controller Android yang pernah di-instal sebelumnya pada bab sebelumnya. Lakukan penyesuaian karakter pada setiap tombol remote dengan mengikuti karakter pada program Arduino.

 

Tinggalkan Komentar

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.