16 Apr 2021

Membuat 110+ Project IoT menggunakan Shield ESP32 IoT Starter Kit

Halo agan agan sekalian, biar diem dirumahnya tidak terlalu membosankan, mari kita buat shield ESP32 plus beberapa komponen sensornya yang bisa bikin agan betah dirumah ngulik project IoT, karena terdapat lebih dari 110+ tutrial yang bisa agan ikutin, mulai dari tahap awal pengenalan hingga membuat project weather station.

Ikutin tutorial ini nanti agan bakal ditunjukin alat-alat dan komponen apa saja yang diperlukan serta bagaimana cara membuatnya.

Jika agan ingin membuat PCB dan sedang mencari jasa cetak PCB, bisa langsung order saja ke PCBWAY.COM, harganya lebih murah $5 bisa mendapatkan papan PCB 10 keping dengan kualitas PCB yang sangat bagus.

Daftar Komponen:

  • 1 x PCB ESP32 IoT Starter Kit (PCBWay)
  • 1 x ESP32 DEVKIT V1 board 30 pin
  • 1 x Micro SD adapter module
  • 1 x OLED I2C 128x64
  • 1 x Humidity and Temperature sensor DHT11/DHT22
  • 1 x Temperature sensor DS18B12
  • 1 x Motion sensor PIR AM312
  • 1 x Environmental sensor BME280/BMP280
  • 1 x 3 axis Acc. and Gyro sensor MPU6050
  • 1 x LDR (Photoresistor)
  • 4 x LED 5mm
  • 1 x RGB LED 5mm common cathode
  • 1 x LED 3mm
  • 1 x Active BUzzer
  • 2 x Tact Switch 6x6mm
  • 1 x Potentiometer 10K Ohm
  • 1 x Relay 5V DC
  • 1 x NPN Transistor BC547
  • 1 x Diode 1N4148
  • 8 x Resistor 330 Ohm
  • 4 x Resistor 10K Ohm
  • 1 x Resistor 1K Ohm
  • 2 x Resistor 4,7K Ohm
  • 1 x Capacitor 100uF/16V
  • 1 x Terminal Screw 2 pin 5mm
  • 2 x Female Header 15 pin
  • 2 x Male Header 15 pin
  • 1 x Male Header 7pin, 5pin, 4pin, 3pin & 2pin
  • 1 x Double Male Header 4 pin & 2 pin
  • 10 x Jumper cap

  • Order PCB (PCBWAY)

    Untuk membuat proyek ini kamu perlu memesan prototipe PCB di PCBWAY. Cara pemesanannya sangat mudah, kamu akan mendapatkan 10 keping PCB seharga $5 dengan kualitas PCB yang sangat bagus.

    Langkah-langkah order:

    1. SignUp/Log in di pcbway.com

    2. Buka tautan proyek PCB ini.

    3. Klik Tambahkan ke troli.

    4. Tunggu sebentar untuk review PCB, lalu Klik Check Out.

    Memasang Komponen

    Pasang semua komponen pada PCB mengikuti gambar/simbol komponen yang ada pada bagian atas PCB, untuk lebih jelasnya dapat mengikuti step by step pada video youtube.

    Menyolder Komponen

    Solder semua kaki komponen pada bagian bawah PCB, untuk lebih jelasnya dapat mengikuti step by step pada video youtube.

    Kemudian potong kaki komponen yang panjang menggunakan tang pemotong, hati-hati ketika memotong pastikan memakai kacamata safety.

    Memasang Modul ESP32

    Tipe ESP32 board yang digunakan pada shield ini adalah ESP32 DEVKIT V1, pasangkan ESP32 board tersebut pada socket female yang sudah tersedia 2 x 15pin.

    ESP32 IoT Starter Kit Sudah Ready

    Sekarang shield ESP32 IoT Starter Kit agan sudah jadi, waktunya untuk mulai praktek pertamanya.

    Agan-agan bisa ikutin saja semua tutorialnya ada di situs randomnerdtutorial.com.

    Test Hardware

    Pada website randomnerdtutorial.com project-esp32 dibawah judul topik Display pilih tutorial OLED Temperature.

    Pada tutorial ini komponen yang akan digunakan adalah ESP32, DHT11 dan OLED. Agan memerlukan satu kabel jumper female to female untuk menghubungkan pin GPIO14 ke pin DHT11

    Kemudian program ESP32 melalui komputer menggunakan software Arduino IDE menggunakan kode program dibawah ini:

    Catatan: Software Arduino IDE agan harus sudah disetting untuk dapat digunakan untuk memprogram ESP32 sebelumnya bisa ikutin tutorial sebelumnya.

    
    /*********
      Rui Santos
      Complete project details at https://randomnerdtutorials.com  
    *********/
    
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_Sensor.h>
    #include <DHT.h>
    
    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    
    // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
    
    #define DHTPIN 14     // Digital pin connected to the DHT sensor
    
    // Uncomment the type of sensor in use:
    #define DHTTYPE    DHT11     // DHT 11
    //#define DHTTYPE    DHT22     // DHT 22 (AM2302)
    //#define DHTTYPE    DHT21     // DHT 21 (AM2301)
    
    DHT dht(DHTPIN, DHTTYPE);
    
    void setup() {
      Serial.begin(115200);
    
      dht.begin();
    
      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;);
      }
      delay(2000);
      display.clearDisplay();
      display.setTextColor(WHITE);
    }
    
    void loop() {
      delay(5000);
    
      //read temperature and humidity
      float t = dht.readTemperature();
      float h = dht.readHumidity();
      if (isnan(h) || isnan(t)) {
        Serial.println("Failed to read from DHT sensor!");
      }
      // clear display
      display.clearDisplay();
      
      // display temperature
      display.setTextSize(1);
      display.setCursor(0,0);
      display.print("Temperature: ");
      display.setTextSize(2);
      display.setCursor(0,10);
      display.print(t);
      display.print(" ");
      display.setTextSize(1);
      display.cp437(true);
      display.write(167);
      display.setTextSize(2);
      display.print("C");
      
      // display humidity
      display.setTextSize(1);
      display.setCursor(0, 35);
      display.print("Humidity: ");
      display.setTextSize(2);
      display.setCursor(0, 45);
      display.print(h);
      display.print(" %"); 
      
      display.display(); 
    }
    

    Mencoba Semua Project ESP32

    Selanjutnya, agan dapat mencoba semua tutorial di randomnerdtutorial ESP32 mulai dari tutorial pengenalan hingga project IoT yang menarik.

    Agan memerlukan beberapa tambahan komponen untuk menyelesaikan semua latihan dalam tutorial, yaitu kabel jumper dupont female to female 10cm, motor servo SG90 dan kabel micro USB.

    1 Apr 2021

    Kit Elektronik Latihan Menyolder - Robadge#2 Flip-Flop

    Bagi agan-agan yang baru mengenal elektronik dan ingin belajar, terutama latihan menyolder komponen dasar ke papan PCB. Bisa coba Soldering Kit Robadge#2, selain bisa sebagai sarana latihan menyolder, Kit ini juga bentuknya lucu dan berfungsi sebagai rangkaian Flip-Flop (lampu LED kedap-kedip) yang bisa agan-agan pasang jadi bross menyala dibaju.


    Untuk mendapatkan Soldering Kit Robadge#2 bisa order di tokopedia.com/bluino.

    Atau jika agan ingin order PCB saja dengan jumlah lebih banyak, bisa langsung order saja PCBnya di PCBWAY.COM, harganya lebih murah $5 bisa mendapatkan papan PCB 10 keping dengan kualitas PCB yang sangat bagus. Bisa order melalui link PCB Robadge#2 disini.

    Gambar Rangkaian

    Berikut gambar rangkaiannya seperti dibawah:

    Daftar Komponen:

    • 1x PCB Robadge#2
    • 2x Transistor NPN BC527
    • 2x LED 5mm
    • 2x C 100uF/16V
    • 2x R 100 ohm 1/4W
    • 2x R 10K ohm 1/4W
    • 1x Saklar SPDT SS12D00G3
    • 1x Baterai Coin CR2032
    • 1x Dudukan Baterai Coin CR2032
    • 1x Pin Peniti besi

    LANGKAH-LANGKAH PERAKITAN

    Pasang Komponen

    Lubang kaki komponen resistor didisain untuk ukuran 1/6W. Namun masih bisa menggunakan ukuran yang lebih besar 1/4W, caranya dengan menekuk salah satu sisi kaki resistor seperti terlihan digambar, kemudian memasukannya ke lubang kaki komponen di PCB.
    Untuk pemasangan komponen lainnya mudah saja cukup dimasukan ke lubang kaki komponen di PCB mengikuti lambang/simbol pada papan PCB.

    Perhatikan jangan sampai terbailik pemasangannya, untuk kaki komponen yang lebih panjang berarti Positif.

    Menyolder Komponen

    Setelah semua komponen terpasang pada PCB, balikan PCB tersebut kemudian solder satu persatu dari setiap kaki komponen. Gunakan tang pemotong untuk memotong sisa kaki komponen yang panjang.

    Menyolder Dudukan Baterai

    Pasangkan dudukan baterai pada bagian belakang PCB kemudian solder kedua kakinya pada bagian depan PCB.

    Menyolder Pin Peniti

    Gunakan tang untuk membantu memegang Pin peniti ketika disolder, supaya tidak melukai tangan karena panas. Ketika menyolder perlu menempelkan mata solder cukup lama supaya timah bisa menempel dengan PCB dan Pin peniti.

    Memasang Baterai

    Baterai yang digunakan adalah tipe Cr2032 3V yang biasa digunakan untuk jam. Ketika memasang baterai jangan sampai terbalik kutub positif (tandanya terdapat tulisan) berada diatas atau menghadap keluar.

    Menuliskan Nama

    Pada bagian bawah dari PCB terdapat area putih, agan bisa menuliskan nama agan sendiri atau tulisan yang agan inginkan menggunakan spidol permanen.

    Menyalakan

    Untuk meyalakannya pada bagian depan terdapat saklar, geser ke kanan posisi ON dan agan akan melihat lampu LED pada bagian mata robot kedip bergantian.

    3 Mar 2021

    Membuat Arduino Uno Bluetooth Sendiri Bisa Upload Sketch Lewat Bluetooth | DIY Bluino One

    Halo agan semuanya, sekarang ane mau nunjukin kepada agan bagaimana membuat papan arduino uno sendiri yang dapat mengunggah kode/sketch melalui bluetooth HC-05, sistem minimum berbasis arduino ini bisa disebut "DIY Bluino One".

    Jadi dalam tutorial ini agan bisa melihat gambar rangkaian DIY Bluino One, menyetak PCB di PCBWay, menyolder komponen dan menyeting modul bluetooth HC-05. Disisi agan akan menggunakan 2 komponen SMD (AMS117 3V3 / 5V), karena tidak semua dapat menyolder banyak komponen SMD dengan mudah. Selain itu, komponen bukan jenis SMD biasanya harganya lebih murah.

    Saya juga telah buat video detail langkah demi langkah seluruh prosesnya di youtube, jadi jika agan tidak ingin membaca seluruh tutorial ini, tonton video nya saja.

    Ikutin tutorial ini nanti agan bakal ditunjukin alat-alat dan komponen apa saja yang diperlukan serta bagaimana cara membuatnya.

    Artikel ini dengan bangga disponsori oleh PCBWAY. Jika agan ingin membuat PCB dan sedang mencari jasa cetak PCB, bisa langsung order saja ke PCBWAY.COM, harganya lebih murah $5 bisa mendapatkan papan PCB 10 keping dengan kualitas PCB yang sangat bagus.

    Daftar Komponen:

    Daftar Komponen:

  • 1 x PCB DIY Bluino One (PCBWAY)
  • 1 x Bluetooth HC-05 module
  • 1 x USB to TTL CP2102 Module
  • 1 x IC Atmega328P DIP
  • 1 x IC Socket 28 Pin
  • 1 x Voltage Regulator AMS1117 3V3
  • 1 x Voltage Regulator AMS1117 5V
  • 1 x Crystal 16MHz
  • 1 x Diode 1N4001
  • 1 x LED Red 3mm
  • 1 x LED Yellow 3mm
  • 2 x Resistor 1K Ohm
  • 1 x Resistor 10K Ohm
  • 1 x Resistor 20K Ohm
  • 2 x Capacitor 100uF/16V
  • 4 x Capacitor 0.1uF (104)
  • 2 x Capacitor 22pF (22)
  • 1 x DC Barrel Socket 5.5mm
  • 1 x Tact Switch 6x6mm
  • 1 x SPDT Slide Switch
  • 1 x 10 Pin Male Header
  • 2 x 8 Pin Male Header
  • 2 x 6 Pin Male Header
  • 2 x 3 Pin Male Header

  • Order PCB (PCBWAY)

    Untuk membuat proyek ini kamu perlu memesan prototipe PCB di PCBWAY. Cara pemesanannya sangat mudah, kamu akan mendapatkan 10 keping PCB seharga $5 dengan kualitas PCB yang sangat bagus.

    Langkah-langkah order:

    1. SignUp/Log in di pcbway.com

    2. Buka tautan proyek PCB ini.

    3. Klik Tambahkan ke troli.

    4. Tunggu sebentar untuk review PCB, lalu Klik Check Out.

    Menyolder Komponen SMD

    Proyek kali ini memiliki dua komponen SMD, jangan khawatir komponen ini tidak terlalu sulit untuk disolder karena ukurannya cukup besar, agan hanya membutuhkan pinset sebagai alat bantu untuk menahan komponen saat disolder. Langkah pertama beri lapisan timah pada tembaga PCB untuk tempat kaki komponen SMD.

    Kemudian ditahan menggunakan pinset lalu di panaskan kembali timah hingga menempel dengan kaki komponen SMD.

    Memasang Komponen

    Pasang semua komponen pada PCB mengikuti gambar/simbol komponen yang ada pada bagian atas PCB, untuk lebih jelasnya dapat mengikuti step by step pada video youtube.

    Menyolder Komponen

    Solder semua kaki komponen pada bagian bawah PCB, untuk lebih jelasnya dapat mengikuti step by step pada video youtube.

    Kemudian potong kaki komponen yang panjang menggunakan tang pemotong, hati-hati ketika memotong pastikan memakai kacamata safety.

    Menseting Parameter pada Bluetooth HC-05

    Pada dasarnya dalam langkah ini adalah cara mengubah parameter pada HC-05 melalui AT Command, langkah ini sama dengan tutorial sebelumnya di Instructables disini. Modul Bluetooth HC-05 yang bisa digunakan pada project ini adalah yang memiliki versi firmware 2.0 atau 3.0, karena HC-05 dengan versi firmware 4.0 tidak memiliki parameter POLAR untuk dirubah.

    Dengan mengikuti step dibawah ini agan akan menseting beberapa parameter HC-05:

    1. Hubungkan bluetooth HC-05 dengan USB ke modul TTL CP2102 mengikuti gambar rangkaian berikut
    2. Press and hold button on HC-05 while you powered the CP2102 (to enter AT+Command mode)
    3. Open Serial Monitor on Arduino IDE or other Serial Software
    4. Set baudrate to 38400 and set end of send string with "Both NL & CR" (New Line & Carriage Return)
    5. Kirim text di bawah untuk merubah parameter HC-05:
      • AT+NAME=XXXX
      • AT+UART=115200,0,0
      • AT+POLAR=1,0

    Menyolder bluetooth HC-05 ke PCB

    Setelah selesai merubah parameter pada modul bluetooth HC-05. Selanjutnya lepas kondom plastik pada modul bluetooth HC-05. Kemudian potong kaki male pin header pada sisi yang panjangnya (lihat gambar) atau ikuti langkah pada video

    Pasangkan modul bluetooth HC-05 pada bagian atas PCB, bisa juga bantu direkatkan menggunakan double tape.

    Terakhir solder pada bagian belakang PCB

    Memasang IC Atemega328 dan modul CP2102

    IC Atemega328 yang digunakan harus memiliki boot-loader Arduino Uno didalamnya, agan bisa mengisi boot-loader ini dengan menggunakan Arduino lain sebagai alatnya untuk caranya bisa googling saja, tapi jika agan gak mau ribet disarankan beli aja IC Atmega328 yang sudah terisi boot-loader Arduino uno didalamnya harganya murah tidak jauh beda dengan IC Atmega yang kosong, banyak dijual di tokopedia.

    Dalam proyek ini juga menggunakan modul USB to TTL CP2102, agan juga dapat menggunakan modul USB to TTL jenis lain seperti FTDI232, hanya saja tidak akan bisa dipasang langsung ke soket di PCB, agan perlu kabel jumper untuk menghubungkan antar pin yang sesuai.

    Selesai: Coba Upload Sketch Lewat Bluetooth

    Sudah sampai langkah ini berarti agan sudah selesai merakit hardware "DIY Bluino One" (Arduino Uno Bluetooth). Nah sekarang saatnya mencoba upload sketch pertama ke hardware, cara upload sketch nya bisa menggunakan software Arduino IDE di komputer cara upload bisa melalui bluetooth atau USB. Cara lain agan dapat upload sketch menggunakan smartphone Android bisa melalui Bluetooth atau USB OTG. Install aplikasi Bluino Loader di Google Playstore.

    18 Jan 2021

    Membuat Robot Mobil RC Kamera Menggunakan ESP32 Cam

    Halo agan agan sekalian, kalau pernah punya mobil-mobilan remote control alias RC sekarng mungkin sudah biasa, tapi kalau mobil RC nya ada kamera kayanya sedikit luar biasa. Apalagi kalau agan sendiri yang buatnya tambah luar biasa.

    Ikutin tutorial ini nanti agan bakal ditunjukin alat-alat dan komponen apa saja yang diperlukan serta bagaimana cara membuatnya.

    Jika agan ingin membuat PCB dan sedang mencari jasa cetak PCB, bisa langsung order saja ke PCBWAY.COM, harganya lebih murah $5 bisa mendapatkan papan PCB 10 keping dengan kualitas PCB yang sangat bagus.

    Daftar Komponen:

  • 1 x PCB ESP32-Cam Motor Shield (PCBWAY)
  • 1 x ESP32-Cam Board
  • 1 x USB to TTL CP2102 Module
  • 1 x IC L293D Driver Motor
  • 2 x Transistor NPN BC547
  • 1 x Voltage Regulator 5V AMS1117
  • 1 x Diode 1N4001
  • 1 x LED Red 3mm
  • 5 x Resistor 10K Ohm
  • 2 x Resistor 1K Ohm
  • 1 x Capacitor 100uF/16V
  • 1 x Active Buzzer 5V
  • 1 x Tact Switch
  • 1 x SPDT Slide Switch
  • 3 x 2 Pin Terminal Block Screw
  • 4 x 10 pin Male Header
  • 1 x 8 pin Female Header
  • 1 x 6 pin Female Header
  • 2 x 8 pin Long Legs Female Header

  • Order PCB (PCBWAY)

    Untuk membuat proyek ini kamu perlu memesan prototipe PCB di PCBWAY. Cara pemesanannya sangat mudah, kamu akan mendapatkan 10 keping PCB seharga $5 dengan kualitas PCB yang sangat bagus.

    Langkah-langkah order:

    1. SignUp/Log in di pcbway.com

    2. Buka tautan proyek PCB ini.

    3. Klik Tambahkan ke troli.

    4. Tunggu sebentar untuk review PCB, lalu Klik Check Out.

    Menyolder Komponen SMD

    Proyek kali ini memiliki satu komponen SMD, jangan khawatir komponen ini tidak terlalu sulit untuk disolder karena ukurannya cukup besar, agan hanya membutuhkan pinset sebagai alat bantu untuk menahan komponen saat disolder. Langkah pertama beri lapisan timah pada tembaga PCB untuk tempat kaki komponen SMD.

    Kemudian ditahan menggunakan pinset lalu di panaskan kembali timah hingga menempel dengan kaki komponen SMD.

    Memasang Komponen

    Pasang semua komponen pada PCB mengikuti gambar/simbol komponen yang ada pada bagian atas PCB, untuk lebih jelasnya dapat mengikuti step by step pada video youtube.

    Menyolder Komponen

    Solder semua kaki komponen pada bagian bawah PCB, untuk lebih jelasnya dapat mengikuti step by step pada video youtube.

    Kemudian potong kaki komponen yang panjang menggunakan tang pemotong, hati-hati ketika memotong pastikan memakai kacamata safety.

    Memasang Socket ESP32-Cam

    Terdapat dua jenis female pin header 8 pin yang akan digunakan, yaitu dengan kaki yang pendek dan kaki yang panjang.
    Untuk kaki yang pendek bengkokan semua kaki pin menggunakan tang hingga membentuk sudut 90 derajat.

    Kemudian pasang pada PCB bagian depan seperti terlihat pada gambar.

    Langkah selanjutnya solder pada bagian belakang PCB.

    Jenis yang kedua female pin header 8 pin dengan kaki yang panjang, disini menggunakan sebanyak 2 buah.
    Pertama bengkokan terlebih dahulu salah satu female pin header.

    Setelah itu sambungkan dengan cara memasukan ke female pin header yang satunya lagi dan jangan terlalu dalam. Pastikan setiap pin tersambung dengan menggunakan multitester untuk mengetes continuity.
    Setelah itu lem menggunakan power glue supaya tidak mudah terlepas.

    Dengan bantuan ESP32-Cam board sebagai mal pasangkan pada PCB.

    Langkah terakhir solder pada bagian belakang PCB.

    Memasang IC, ESP32-Cam & USB to TTL Modul

    Pasang IC L293D pada soket IC, lihat posisinya jangan terbalik. Kemudian pasang modul USB to TTL CP2102 yang sudah memiliki pin header.

    Memasang ESP32-Cam Motor Shield ke Chassis

    Agan bisa menggunakan chasis custom untuk mobil robot yang banyak dipasaran bisa didapat dari toko online yang biasa digunakan untuk membangun robot manggunakan Arduino Uno, karena ukuran PCB dan jarak lubang sama dengan Arduino Uno.
    Untuk jumlah roda/motor penggerak tidak masalah jika agan menggunakan empat atau dua motor, sebenarnya output dari ESP32-Cam Motor Shield motor hanya dua yaitu kiri dan kanan, kalau ingin menggunakan empat roda/motor penggerak hanya dipasang secara paralel, berikut gambar rangkaiannya.

    Hubungkan motor kiri dan motor kanan ke terminal sekrup pada output driver motor ESP32-Cam Motor Shield. Hubungkan baterai 2 x 18650 3.7V ke sekrup terminal catu daya pada ESP32-Cam Motor Shield.

    Mengisi Program ke ESP32-Cam Board

    Untuk membuat WiFi Kamera RC Car berfungsi dan dapat dikendalikan oleh smartphone Android, agan harus memprogram ESP32-Cam terlebih dahulu. Caranya cukup mudah hanya cukup menggunakan smartphone Android tidak memerlukan lagi Laptop/PC, ikuti langkah berikut:

    - Install ESP32 Camera WiFi Robot Car dari Google Playstore.

    - Hubungkan antara smartphone Android dengan ESP32-Cam Motor Shield menggunakan kabel USB dan USB OTG adapter. (pastikan HP agan support USB OTG)

    - Untuk menjadikan ESP32-Cam board siap untuk diisi program, dalam kondisi menyala agan perlu menekan serta menahan tombol GPIO0 kemudian menekan tombol reset pada ESP32-Cam board. setelah itu lepas kan keduanya maka sekarang posisi chip ESP32 siap untuk diisi program melalui USB to TTL CP2102.

    - Buka aplikasi ESP32 Camera Wifi Robot Car, pada menu bar atas tekan icon Circuit diagram & Code. Kemudian setelah terbuka tampilan gambar rangkaian dan kode pada menu bar atasnya tekan ikon tiga titik (menu lainnya), buka pilihan Motor Driver to be Used lalu pilih ESP32-Cam Motor Shield, kemudian buka pilihan Upload Firmware Via lalu pilih USB OTG, jika ingin menghubungkan Mobil RC ke sebuah router jaringan rumah agan bisa set SSID name & Password. Setelah selesai konfigurasi langkah selanjutnya tekan ikon UPLOAD, dan tunggu sampai proses uploadnya selesai. Terakhir tekan tombol reset untuk menjalankan program.

    Selain mengisi program melalui smartphone Android, agan dapat juga memprogram ESP32-Cam melalui komputer menggunakan software Arduino IDE menggunakan kode program dibawah ini:

    Catatan: Software Arduino IDE agan harus sudah disetting untuk dapat digunakan untuk memprogram ESP32 sebelumnya.

    Simpan sketch di bawah dengan nama file "esp32cam_wifi_robot_car_l293d.ino"

    
    #include "esp_camera.h"
    #include <WiFi.h>
    #include <ArduinoOTA.h>
    
    /* Wifi Crdentials */
    String sta_ssid = "$your_ssid_maximum_32_characters";     // set Wifi network you want to connect to
    String sta_password = "$your_pswd_maximum_32_characters";   // set password for Wifi network
    
    /* define CAMERA_MODEL_AI_THINKER */
    #define PWDN_GPIO_NUM     32
    #define RESET_GPIO_NUM    -1
    #define XCLK_GPIO_NUM      0
    #define SIOD_GPIO_NUM     26
    #define SIOC_GPIO_NUM     27
    #define Y9_GPIO_NUM       35
    #define Y8_GPIO_NUM       34
    #define Y7_GPIO_NUM       39
    #define Y6_GPIO_NUM       36
    #define Y5_GPIO_NUM       21
    #define Y4_GPIO_NUM       19
    #define Y3_GPIO_NUM       18
    #define Y2_GPIO_NUM        5
    #define VSYNC_GPIO_NUM    25
    #define HREF_GPIO_NUM     23
    #define PCLK_GPIO_NUM     22
    
    /* Defining motor and servo pins */
    extern int DRV_A = 12;
    extern int DRV_B = 13;
    extern int DIR_A = 14;
    extern int DIR_B = 15;
    
    extern int ledVal = 20;  // setting bright of flash LED 0-255
    
    extern int ledPin = 4;  // set digital pin GPIO4 as LED pin (use biult-in LED)
    extern int buzzerPin = 2;  // set digital pin GPIO2 as LED pin (use Active Buzzer)
    extern int servoPin = 2;  // set digital pin GPIO2 as servo pin (use SG90)
    
    unsigned long previousMillis = 0;
    
    void startCameraServer();
    
    void initServo() {
      ledcSetup(8, 50, 16); /*50 hz PWM, 16-bit resolution and range from 3250 to 6500 */
      ledcAttachPin(servoPin, 8);
    }
    
    void initLed() {
      ledcSetup(7, 5000, 8); /* 5000 hz PWM, 8-bit resolution and range from 0 to 255 */
      ledcAttachPin(ledPin, 7);
    }
    
    void setup() {
      Serial.begin(115200);         // set up seriamonitor at 115200 bps
      Serial.setDebugOutput(true);
      Serial.println();
      Serial.println("*ESP32 Camera Remote Control - L293D Bluino Shield*");
      Serial.println("--------------------------------------------------------");
    
      // Set all the motor control pin to Output
      pinMode(DRV_A, OUTPUT);
      pinMode(DRV_B, OUTPUT);
      pinMode(DIR_A, OUTPUT);
      pinMode(DIR_B, OUTPUT);
      
      pinMode(ledPin, OUTPUT); // set the LED pin as an Output
      pinMode(buzzerPin, OUTPUT); // set the buzzer pin as an Output
      pinMode(servoPin, OUTPUT); // set the servo pin as an Output
    
      // Initial state - turn off motors, LED & buzzer
      digitalWrite(DRV_A, LOW);
      digitalWrite(DRV_B, LOW);
      digitalWrite(DIR_A, LOW);
      digitalWrite(DIR_B, LOW);
      digitalWrite(ledPin, LOW);
      digitalWrite(buzzerPin, LOW);
      digitalWrite(servoPin, LOW);
    
      /* Initializing Servo and LED */
      initServo();
      initLed();
      
      camera_config_t config;
      config.ledc_channel = LEDC_CHANNEL_0;
      config.ledc_timer = LEDC_TIMER_0;
      config.pin_d0 = Y2_GPIO_NUM;
      config.pin_d1 = Y3_GPIO_NUM;
      config.pin_d2 = Y4_GPIO_NUM;
      config.pin_d3 = Y5_GPIO_NUM;
      config.pin_d4 = Y6_GPIO_NUM;
      config.pin_d5 = Y7_GPIO_NUM;
      config.pin_d6 = Y8_GPIO_NUM;
      config.pin_d7 = Y9_GPIO_NUM;
      config.pin_xclk = XCLK_GPIO_NUM;
      config.pin_pclk = PCLK_GPIO_NUM;
      config.pin_vsync = VSYNC_GPIO_NUM;
      config.pin_href = HREF_GPIO_NUM;
      config.pin_sscb_sda = SIOD_GPIO_NUM;
      config.pin_sscb_scl = SIOC_GPIO_NUM;
      config.pin_pwdn = PWDN_GPIO_NUM;
      config.pin_reset = RESET_GPIO_NUM;
      config.xclk_freq_hz = 20000000;
      config.pixel_format = PIXFORMAT_JPEG;
      //init with high specs to pre-allocate larger buffers
      if(psramFound()){
        config.frame_size = FRAMESIZE_UXGA;
        config.jpeg_quality = 10;
        config.fb_count = 2;
      } else {
        config.frame_size = FRAMESIZE_SVGA;
        config.jpeg_quality = 12;
        config.fb_count = 1;
      }
    
      // camera init
      esp_err_t err = esp_camera_init(&config);
      if (err != ESP_OK) {
        Serial.printf("Camera init failed with error 0x%x", err);
        return;
      }
    
      //drop down frame size for higher initial frame rate
      sensor_t * s = esp_camera_sensor_get();
      s->set_framesize(s, FRAMESIZE_QVGA);
    
      // Set NodeMCU Wifi hostname based on chip mac address
      char chip_id[15];
      snprintf(chip_id, 15, "%04X", (uint16_t)(ESP.getEfuseMac()>>32));
      String hostname = "esp32cam-" + String(chip_id);
    
      Serial.println();
      Serial.println("Hostname: "+hostname);
    
      // first, set NodeMCU as STA mode to connect with a Wifi network
      WiFi.mode(WIFI_STA);
      WiFi.begin(sta_ssid.c_str(), sta_password.c_str());
      Serial.println("");
      Serial.print("Connecting to: ");
      Serial.println(sta_ssid);
      Serial.print("Password: ");
      Serial.println(sta_password);
    
      // try to connect with Wifi network about 10 seconds
      unsigned long currentMillis = millis();
      previousMillis = currentMillis;
      while (WiFi.status() != WL_CONNECTED && currentMillis - previousMillis <= 10000) {
        delay(500);
        Serial.print(".");
        currentMillis = millis();
      }
    
      // if failed to connect with Wifi network set NodeMCU as AP mode
      IPAddress myIP;
      if (WiFi.status() == WL_CONNECTED) {
        Serial.println("");
        Serial.println("*WiFi-STA-Mode*");
        Serial.print("IP: ");
        myIP=WiFi.localIP();
        Serial.println(myIP);
        delay(2000);
      } else {
        WiFi.mode(WIFI_AP);
        WiFi.softAP(hostname.c_str());
        myIP = WiFi.softAPIP();
        Serial.println("");
        Serial.println("WiFi failed connected to " + sta_ssid);
        Serial.println("");
        Serial.println("*WiFi-AP-Mode*");
        Serial.print("AP IP address: ");
        Serial.println(myIP);
        delay(2000);
      }
    
      // Start camera server to get realtime view
      startCameraServer();
      Serial.print("Camera Ready! Use 'http://");
      Serial.print(myIP);
      Serial.println("' to connect ");
    
      ArduinoOTA.begin();   // enable to receive update/upload firmware via Wifi OTA
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      ArduinoOTA.handle();
    }
    

    Simpan sketch di bawah dengan nama file "app_httpd.cpp"

    
    #include "esp_http_server.h"
    #include "esp_timer.h"
    #include "esp_camera.h"
    #include "img_converters.h"
    #include "Arduino.h"
    
    /* Initializing pins */
    extern int DRV_A;
    extern int DRV_B;
    extern int DIR_A;
    extern int DIR_B;
    extern int ledPin;
    extern int buzzerPin;
    extern int servoPin;
    extern int ledVal;
    
    typedef struct {
            httpd_req_t *req;
            size_t len;
    } jpg_chunking_t;
    
    #define PART_BOUNDARY "123456789000000000000987654321"
    static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
    static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
    static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
    
    httpd_handle_t stream_httpd = NULL;
    httpd_handle_t camera_httpd = NULL;
    
    
    static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){
        jpg_chunking_t *j = (jpg_chunking_t *)arg;
        if(!index){
            j->len = 0;
        }
        if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK){
            return 0;
        }
        j->len += len;
        return len;
    }
    
    static esp_err_t capture_handler(httpd_req_t *req){
        camera_fb_t * fb = NULL;
        esp_err_t res = ESP_OK;
        int64_t fr_start = esp_timer_get_time();
    
        fb = esp_camera_fb_get();
        if (!fb) {
            Serial.printf("Camera capture failed");
            httpd_resp_send_500(req);
            return ESP_FAIL;
        }
    
        httpd_resp_set_type(req, "image/jpeg");
        httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
    
        size_t fb_len = 0;
        if(fb->format == PIXFORMAT_JPEG){
            fb_len = fb->len;
            res = httpd_resp_send(req, (const char *)fb->buf, fb->len);
        } else {
            jpg_chunking_t jchunk = {req, 0};
            res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk)?ESP_OK:ESP_FAIL;
            httpd_resp_send_chunk(req, NULL, 0);
            fb_len = jchunk.len;
        }
        esp_camera_fb_return(fb);
        int64_t fr_end = esp_timer_get_time();
        Serial.printf("JPG: %uB %ums", (uint32_t)(fb_len), (uint32_t)((fr_end - fr_start)/1000));
        return res;
    }
    
    static esp_err_t stream_handler(httpd_req_t *req){
        camera_fb_t * fb = NULL;
        esp_err_t res = ESP_OK;
        size_t _jpg_buf_len = 0;
        uint8_t * _jpg_buf = NULL;
        char * part_buf[64];
    
        static int64_t last_frame = 0;
        if(!last_frame) {
            last_frame = esp_timer_get_time();
        }
    
        res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
        if(res != ESP_OK){
            return res;
        }
    
        while(true){
            fb = esp_camera_fb_get();
            if (!fb) {
                Serial.printf("Camera capture failed");
                res = ESP_FAIL;
            } else {
                if(fb->format != PIXFORMAT_JPEG){
                    bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
                    esp_camera_fb_return(fb);
                    fb = NULL;
                    if(!jpeg_converted){
                        Serial.printf("JPEG compression failed");
                        res = ESP_FAIL;
                    }
                } else {
                    _jpg_buf_len = fb->len;
                    _jpg_buf = fb->buf;
                }
            }
            if(res == ESP_OK){
                size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
                res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
            }
            if(res == ESP_OK){
                res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
            }
            if(res == ESP_OK){
                res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
            }
            if(fb){
                esp_camera_fb_return(fb);
                fb = NULL;
                _jpg_buf = NULL;
            } else if(_jpg_buf){
                free(_jpg_buf);
                _jpg_buf = NULL;
            }
            if(res != ESP_OK){
                break;
            }
            int64_t fr_end = esp_timer_get_time();
    
            int64_t frame_time = fr_end - last_frame;
            last_frame = fr_end;
            frame_time /= 1000;
        }
    
        last_frame = 0;
        return res;
    }
    
    
    static esp_err_t cmd_handler(httpd_req_t *req){
        char*  buf;
        size_t buf_len;
        char variable[32] = {0,};
        char value[32] = {0,};
    
        buf_len = httpd_req_get_url_query_len(req) + 1;
        if (buf_len > 1) {
            buf = (char*)malloc(buf_len);
            Serial.println(buf);
            if(!buf){
                httpd_resp_send_500(req);
                return ESP_FAIL;
            }
            if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
                if (httpd_query_key_value(buf, "var", variable, sizeof(variable)) == ESP_OK &&
                    httpd_query_key_value(buf, "val", value, sizeof(value)) == ESP_OK) {
                } else {
                    free(buf);
                    Serial.println(buf);
                    httpd_resp_send_404(req);
                    return ESP_FAIL;
                }
            } else {
                free(buf);
                Serial.println(buf);
                httpd_resp_send_404(req);
                return ESP_FAIL;
            }
            Serial.println(buf);
            free(buf);
        } else {
            httpd_resp_send_404(req);
            Serial.println(ESP_FAIL);
            return ESP_FAIL;
        }
    
        int val = atoi(value);
        sensor_t * s = esp_camera_sensor_get();
        int res = 0;
    
        if(!strcmp(variable, "framesize")) {
            if(s->pixformat == PIXFORMAT_JPEG) res = s->set_framesize(s, (framesize_t)val);
        }
        else if(!strcmp(variable, "quality")) res = s->set_quality(s, val);
        else if(!strcmp(variable, "contrast")) res = s->set_contrast(s, val);
        else if(!strcmp(variable, "brightness")) res = s->set_brightness(s, val);
        else if(!strcmp(variable, "saturation")) res = s->set_saturation(s, val);
        else if(!strcmp(variable, "gainceiling")) res = s->set_gainceiling(s, (gainceiling_t)val);
        else if(!strcmp(variable, "colorbar")) res = s->set_colorbar(s, val);
        else if(!strcmp(variable, "awb")) res = s->set_whitebal(s, val);
        else if(!strcmp(variable, "agc")) res = s->set_gain_ctrl(s, val);
        else if(!strcmp(variable, "aec")) res = s->set_exposure_ctrl(s, val);
        else if(!strcmp(variable, "hmirror")) res = s->set_hmirror(s, val);
        else if(!strcmp(variable, "vflip")) res = s->set_vflip(s, val);
        else if(!strcmp(variable, "awb_gain")) res = s->set_awb_gain(s, val);
        else if(!strcmp(variable, "agc_gain")) res = s->set_agc_gain(s, val);
        else if(!strcmp(variable, "aec_value")) res = s->set_aec_value(s, val);
        else if(!strcmp(variable, "aec2")) res = s->set_aec2(s, val);
        else if(!strcmp(variable, "dcw")) res = s->set_dcw(s, val);
        else if(!strcmp(variable, "bpc")) res = s->set_bpc(s, val);
        else if(!strcmp(variable, "wpc")) res = s->set_wpc(s, val);
        else if(!strcmp(variable, "raw_gma")) res = s->set_raw_gma(s, val);
        else if(!strcmp(variable, "lenc")) res = s->set_lenc(s, val);
        else if(!strcmp(variable, "special_effect")) res = s->set_special_effect(s, val);
        else if(!strcmp(variable, "wb_mode")) res = s->set_wb_mode(s, val);
        else if(!strcmp(variable, "ae_level")) res = s->set_ae_level(s, val);
        else {
            res = -1;
        }
    
        if(res){
            return httpd_resp_send_500(req);
        }
    
        httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
        return httpd_resp_send(req, NULL, 0);
    }
    
    static esp_err_t status_handler(httpd_req_t *req){
        static char json_response[1024];
    
        sensor_t * s = esp_camera_sensor_get();
        char * p = json_response;
        *p++ = '{';
    
        p+=sprintf(p, "\"framesize\":%u,", s->status.framesize);
        p+=sprintf(p, "\"quality\":%u,", s->status.quality);
        p+=sprintf(p, "\"brightness\":%d,", s->status.brightness);
        p+=sprintf(p, "\"contrast\":%d,", s->status.contrast);
        p+=sprintf(p, "\"saturation\":%d,", s->status.saturation);
        p+=sprintf(p, "\"special_effect\":%u,", s->status.special_effect);
        p+=sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode);
        p+=sprintf(p, "\"awb\":%u,", s->status.awb);
        p+=sprintf(p, "\"awb_gain\":%u,", s->status.awb_gain);
        p+=sprintf(p, "\"aec\":%u,", s->status.aec);
        p+=sprintf(p, "\"aec2\":%u,", s->status.aec2);
        p+=sprintf(p, "\"ae_level\":%d,", s->status.ae_level);
        p+=sprintf(p, "\"aec_value\":%u,", s->status.aec_value);
        p+=sprintf(p, "\"agc\":%u,", s->status.agc);
        p+=sprintf(p, "\"agc_gain\":%u,", s->status.agc_gain);
        p+=sprintf(p, "\"gainceiling\":%u,", s->status.gainceiling);
        p+=sprintf(p, "\"bpc\":%u,", s->status.bpc);
        p+=sprintf(p, "\"wpc\":%u,", s->status.wpc);
        p+=sprintf(p, "\"raw_gma\":%u,", s->status.raw_gma);
        p+=sprintf(p, "\"lenc\":%u,", s->status.lenc);
        p+=sprintf(p, "\"hmirror\":%u,", s->status.hmirror);
        p+=sprintf(p, "\"dcw\":%u,", s->status.dcw);
        p+=sprintf(p, "\"colorbar\":%u", s->status.colorbar);
        *p++ = '}';
        *p++ = 0;
        httpd_resp_set_type(req, "application/json");
        httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
        return httpd_resp_send(req, json_response, strlen(json_response));
    }
    
    
    static esp_err_t state_handler(httpd_req_t *req){
        char*  buf;
        size_t buf_len;
        char cmd[32] = {0,};
    
        buf_len = httpd_req_get_url_query_len(req) + 1;
        if (buf_len > 1) {
            buf = (char*)malloc(buf_len);
            Serial.println(buf);
            
            if(!buf){
                httpd_resp_send_500(req);
                return ESP_FAIL;
            }
            
            if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
                if (httpd_query_key_value(buf, "cmd", cmd, sizeof(cmd)) == ESP_OK) {
                  
                } else {
                    free(buf);
                    Serial.print("*");
                    Serial.println(ESP_FAIL);
                    httpd_resp_send_404(req);
                    return ESP_FAIL;
                }
            } else {
                free(buf);
                Serial.print("**");
                Serial.println(ESP_FAIL);
                httpd_resp_send_404(req);
                return ESP_FAIL;
            }
            free(buf);
            
        } else {
            Serial.print("***");
            Serial.println(ESP_FAIL);
            httpd_resp_send_404(req);
            return ESP_FAIL;
        }
    
        int res = 0;
    
        if(!strcmp(cmd, "F")) {
          Serial.println("Forward");
          digitalWrite(DRV_A, HIGH);
          digitalWrite(DRV_B, HIGH);
          digitalWrite(DIR_A, HIGH);
          digitalWrite(DIR_B, HIGH);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "B")) {
          Serial.println("Backward");
          digitalWrite(DRV_A, HIGH);
          digitalWrite(DRV_B, HIGH);
          digitalWrite(DIR_A, LOW);
          digitalWrite(DIR_B, LOW);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "R")) {
          Serial.println("Turn Right");
          digitalWrite(DRV_A, HIGH);
          digitalWrite(DRV_B, HIGH);
          digitalWrite(DIR_A, LOW);
          digitalWrite(DIR_B, HIGH);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "L")) {
          Serial.println("Turn Left");
          digitalWrite(DRV_A, HIGH);
          digitalWrite(DRV_B, HIGH);
          digitalWrite(DIR_A, HIGH);
          digitalWrite(DIR_B, LOW);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "G")) {
          Serial.println("Forward Left");
          digitalWrite(DRV_A, HIGH);
          digitalWrite(DRV_B, LOW);
          digitalWrite(DIR_A, HIGH);
          digitalWrite(DIR_B, HIGH);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "H")) {
          Serial.println("Backward Left");
          digitalWrite(DRV_A, HIGH);
          digitalWrite(DRV_B, LOW);
          digitalWrite(DIR_A, LOW);
          digitalWrite(DIR_B, LOW);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "I")) {
          Serial.println("Forward Right");
          digitalWrite(DRV_A, LOW);
          digitalWrite(DRV_B, HIGH);
          digitalWrite(DIR_A, HIGH);
          digitalWrite(DIR_B, HIGH);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "J")) {
          Serial.println("Backward Right");
          digitalWrite(DRV_A, LOW);
          digitalWrite(DRV_B, HIGH);
          digitalWrite(DIR_A, LOW);
          digitalWrite(DIR_B, LOW);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "S")) {
          Serial.println("Stop");
          digitalWrite(DRV_A, LOW);
          digitalWrite(DRV_B, LOW);
          digitalWrite(DIR_A, LOW);
          digitalWrite(DIR_B, LOW);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "V")) {
          Serial.println("Horn On");
          digitalWrite(buzzerPin, HIGH);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "v")) {
          Serial.println("Horn Off");
          digitalWrite(buzzerPin, LOW);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "W")) {
          Serial.println("LED On");
          ledcWrite(7, ledVal);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if(!strcmp(cmd, "w")) {
          Serial.println("LED Off");
          ledcWrite(7, 0);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else if (!strcmp(cmd, "x")){
          Serial.println("Flash Light : Low (20)");
          ledVal = 20;
          ledcWrite(7, ledVal);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "y")){
          Serial.println("Flash Light : Medium (50)");
          ledVal = 50;
          ledcWrite(7, ledVal);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "z")){
          Serial.println("Flash Light : Bright (100)");
          ledVal = 100;
          ledcWrite(7, ledVal);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }    
        else if (!strcmp(cmd, "Z")){
          Serial.println("Flash Light : Super Bright (255)");
          ledVal = 255;
          ledcWrite(7, ledVal);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }   
        
        /* Controlling the servo motor angle with PWM */
        /* ledcWrite(Channel, Dutycycle) dutycycle range : 3250-6500*/
        else if (!strcmp(cmd, "0")){
          Serial.println("Servo 0 (3250)");
          ledcWrite(8, 3250);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "1")){
          Serial.println("Servo 1 (3575)");
          ledcWrite(8, 3575);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "2")){
          Serial.println("Servo 2 (3900)");
          ledcWrite(8, 3900);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "3")){
          Serial.println("Servo 3 (4225)");
          ledcWrite(8, 4225);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "4")){
          Serial.println("Servo 4 (4550)");
          ledcWrite(8, 4550);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "5")){
          Serial.println("Servo 5 (4875)");
          ledcWrite(8, 4875);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "6")){
          Serial.println("Servo 6 (5200)");
          ledcWrite(8, 5200);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "7")){
          Serial.println("Servo 7 (5525)");
          ledcWrite(8, 5525);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "8")){
          Serial.println("Servo 8 (5850)");
          ledcWrite(8, 5850);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "9")){
          Serial.println("Servo 9 (6175)");
          ledcWrite(8, 6175);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        else if (!strcmp(cmd, "q")){
          Serial.println("Servo q (6500)");
          ledcWrite(8, 6500);
          httpd_resp_set_type(req, "text/html");
          return httpd_resp_send(req, "OK", 2);
        }
        
        else {
            res = -1;
        }
    
        if(res){
            return httpd_resp_send_500(req);
        }
    
        httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
        return httpd_resp_send(req, NULL, 0);
    }
    
    
    void startCameraServer(){
        httpd_config_t config = HTTPD_DEFAULT_CONFIG();
        
    
        httpd_uri_t status_uri = {
            .uri       = "/status",
            .method    = HTTP_GET,
            .handler   = status_handler,
            .user_ctx  = NULL
        };
    
        httpd_uri_t cmd_uri = {
            .uri       = "/control",
            .method    = HTTP_GET,
            .handler   = cmd_handler,
            .user_ctx  = NULL
        };
    
        httpd_uri_t capture_uri = {
            .uri       = "/capture",
            .method    = HTTP_GET,
            .handler   = capture_handler,
            .user_ctx  = NULL
        };
    
       httpd_uri_t stream_uri = {
            .uri       = "/stream",
            .method    = HTTP_GET,
            .handler   = stream_handler,
            .user_ctx  = NULL
        };
    
       httpd_uri_t state_uri = {
            .uri       = "/state",
            .method    = HTTP_GET,
            .handler   = state_handler,
            .user_ctx  = NULL
        };
    
        Serial.printf("Starting web server on port: '%d'", config.server_port);
        if (httpd_start(&camera_httpd, &config) == ESP_OK) {
            httpd_register_uri_handler(camera_httpd, &cmd_uri);
            httpd_register_uri_handler(camera_httpd, &capture_uri);
            httpd_register_uri_handler(camera_httpd, &status_uri);
            httpd_register_uri_handler(camera_httpd, &state_uri);
        }
    
        config.server_port += 1;
        config.ctrl_port += 1;
        Serial.printf("Starting stream server on port: '%d'", config.server_port);
        if (httpd_start(&stream_httpd, &config) == ESP_OK) {
            httpd_register_uri_handler(stream_httpd, &stream_uri);
        }
    }
    

    Mainkan Mobil RC Wifi Camera

    Mobil RC Wifi Camera dapat dikontrol melalui smartphone Android dengan dua cara, dikontrol langsung antara smartphone Android ke ESP32-Cam (mode AP), dengan cara hubungkan smartphone Android ke SSID Wifi dari ESP32-Cam kemudian atur alamat IP pada aplikasi menjadi 192.168.4.1.

    Cara kedua adalah ESP32-Cam (mode STA), dimana smartphone Android terhubung ke jaringan Wifi router yang sama kemudian atur alamat IP pada aplikasi sesuai dengan alamat IP yang dimiliki oleh ESP32-Cam (contoh:192.168.0.2).