MIT App Inventor Arduino Bluetooth: Membuat Aplikasi Android untuk HC-05
Kendalikan Arduino lewat Bluetooth dengan MIT App Inventor: pengkabelan HC-05, ListPicker, blok tombol dan slider, LED, relay, servo, data sensor, APK, dan solusi masalah Android 12.
Mengendalikan Arduino lewat Bluetooth dengan App Inventor adalah cara tercepat untuk membuat aplikasi Android sendiri tanpa menulis satu baris pun Java atau Kotlin. Di MIT App Inventor, lingkungan gratis berbasis browser buatan MIT, kamu menyeret tombol, slider, dan label teks ke layar, lalu menentukan fungsinya dengan blok yang saling mengunci seperti kepingan puzzle. Ponsel terhubung ke modul Bluetooth HC-05 yang tersambung ke Arduino; setiap ketukan di aplikasi dikirim ke Arduino sebagai perintah teks pendek, dan Arduino mengirim balik pembacaan sensornya ke ponsel dengan cara yang sama.
Di akhir panduan ini kamu akan punya aplikasi remote yang benar-benar berfungsi: ListPicker yang terhubung ke HC-05 dari sebuah daftar, tombol yang menyalakan dan mematikan LED dan relay, dua slider yang mengatur kecerahan LED dan sudut servo, serta label yang menampilkan suhu dan kelembapan langsung dari DHT11. Kamu akan membahas kode Arduino, setiap blok App Inventor, cara membuat APK, dan solusi masalah izin Bluetooth yang muncul sejak Android 12, langkah demi langkah. Kalau belum pernah memakai HC-05, baca dulu sebentar panduan Modul Bluetooth HC-05.

Apa itu App Inventor, dan bagaimana ia berkomunikasi dengan Arduino?
MIT App Inventor adalah lingkungan pengembangan aplikasi gratis buatan Massachusetts Institute of Technology (MIT); kamu masuk dengan akun Google dan memakainya di browser. Ada dua tampilan: di Designer kamu menyusun aplikasi dengan menyeret komponen, dan di editor Blocks kamu menulis aturan seperti “ketika tombol diklik, lakukan ini” dengan blok berwarna-warni. Untuk mencoba aplikasi tanpa menginstalnya, kamu memakai aplikasi MIT AI2 Companion dari Play Store; setelah selesai, satu klik saja menghasilkan file APK yang bisa diinstal.
Di sisi Bluetooth, pekerjaannya dilakukan oleh komponen BluetoothClient. Komponen ini memakai SPP (Serial Port Profile) dari Bluetooth klasik, persis bahasa yang dipakai HC-05. Hasilnya adalah kabel serial tak terlihat antara ponsel dan Arduino: ketika aplikasi mengirim “L1” dengan blok SendText, Arduino membaca dua karakter itu dengan bt.read(), sama seperti kalau kamu mengetiknya di Serial Monitor. Semua yang dikirim Arduino dengan bt.print() sampai di blok ReceiveText di ponsel. Di sisi Arduino tidak dibutuhkan library khusus Bluetooth.
| Lapisan | Tugas | Di proyek ini |
|---|---|---|
| Antarmuka (Designer) | Komponen yang tampil di layar | ListPicker, 5 Button, 2 Slider, Label |
| Logika (Blocks) | Blok yang bereaksi terhadap event | Event Click, PositionChanged, dan Timer |
| BluetoothClient | Koneksi SPP, mengirim dan menerima data | Connect, SendText, ReceiveText |
| HC-05 | Jembatan antara Bluetooth dan UART | 9600 baud, PIN 1234 |
| Arduino | Menafsirkan perintah, mengendalikan output, membaca sensor | LED, relay, servo, DHT11 |
Yang kamu butuhkan
| Komponen | Jumlah | Catatan |
|---|---|---|
| Arduino Uno (atau Nano) | 1 | Kode dan pin sama di keduanya |
| Modul Bluetooth HC-05 atau HC-06 | 1 | Bluetooth klasik; HM-10 (BLE) tidak bisa dipakai dengan cara ini |
| Resistor 1 kΩ dan 2 kΩ | Masing-masing 1 | Pembagi tegangan untuk pin RXD HC-05 (2,2 kΩ juga bisa) |
| LED dan resistor 220 Ω | Masing-masing 1 | LED yang bisa diredupkan (D5, PWM) |
| Modul relay 5 V | 1 | Untuk menyalakan beban seperti lampu atau kipas |
| Motor servo SG90 | 1 | Kendali 0–180° dengan slider |
| Sensor suhu dan kelembapan DHT11 | 1 | Data yang ditampilkan di ponsel |
| Ponsel Android | 1 | HC-05 tidak bisa dipakai dengan iPhone |
| Breadboard dan kabel jumper | — | GND bersama itu wajib |





Pengkabelan: HC-05, LED, relay, servo, dan DHT11
Board HC-05 punya regulator, jadi pin VCC-nya menerima 5 V, tetapi pin datanya memakai logika 3,3 V. Arduino membaca sinyal 3,3 V dari pin TXD modul tanpa masalah; namun sinyal TX 5 V dari Arduino sebaiknya sampai ke pin RXD lewat pembagi tegangan: D11 → 1 kΩ → RXD, RXD → 2 kΩ → GND. Dengan begitu RXD mendapat 5 × 2 / 3 ≈ 3,3 V. Kita menghubungkan HC-05 ke D10 dan D11 dengan SoftwareSerial alih-alih pin serial hardware Uno (0 dan 1), jadi kamu bisa meng-upload kode ketika modul masih terpasang dan tetap memakai Serial Monitor untuk debugging. Resistor LED bisa kamu periksa dengan kalkulator resistor LED.
| Koneksi | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC HC-05 | 5V | Tidak perlu (Bluetooth bawaan) | VBUS (5 V) |
| GND HC-05 | GND | — | GND |
| TXD HC-05 | D10 (RX SoftwareSerial) | — | GP1 (UART0 RX) |
| RXD HC-05 | D11, lewat pembagi 1 kΩ / 2 kΩ | — | GP0 (UART0 TX), tanpa pembagi |
| LED (+ 220 Ω) | D5 (PWM) | GPIO 2 (LED bawaan) | GP15 |
| IN modul relay | D7 | GPIO 26 | GP14 |
| Sinyal servo (oranye) | D9 | — (bisa ditambahkan dengan ESP32Servo) | GP13 |
| Data DHT11 | D2 | GPIO 4 | GP16 |
Protokol komunikasi: apa yang akan dikirim ponsel?
Sebelum menulis kode, tentukan “bahasa” yang akan dipakai ponsel dan Arduino. Di proyek ini setiap perintah berupa huruf, diikuti angka, dan diakhiri karakter baris baru (\n, ASCII 10). Baris baru ini sangat penting: data Bluetooth bisa datang terpotong-potong, dan ketika “S1” dan “35” datang terpisah, Arduino menunggu baris baru lalu memproses “S135” sebagai satu perintah. Karena perintahnya berupa teks yang bisa dibaca, kamu juga bisa mencobanya secara manual dengan aplikasi terminal Bluetooth apa pun.
| Perintah | Arah | Arti |
|---|---|---|
| L1 / L0 | Ponsel → Arduino | Nyalakan LED penuh / matikan |
| P0 … P255 | Ponsel → Arduino | Kecerahan LED (nilai analogWrite) |
| R1 / R0 | Ponsel → Arduino | Aktifkan / lepaskan relay |
| S0 … S180 | Ponsel → Arduino | Sudut servo (derajat) |
| 24.5;41 | Arduino → ponsel | Suhu (°C) dan kelembapan (%), dipisahkan titik koma |
Selain teks, App Inventor juga bisa mengirim satu byte (0–255) dengan blok Send1ByteNumber, yang dibaca Arduino langsung sebagai angka. Cara ini singkat dan cepat, tetapi hanya cocok untuk satu slider: kalau dua slider dan empat tombol semuanya mengirim byte, Arduino tidak bisa membedakan apakah angka 90 yang datang itu sudut servo atau tingkat kecerahan. Format huruf + angka + baris baru memang butuh beberapa byte lebih, tetapi pada 9600 baud kira-kira 960 karakter lewat setiap detik, jadi kamu tidak akan merasakan bedanya.
Kode Arduino
Library Servo dan SoftwareSerial sudah tersedia di Arduino IDE. Untuk DHT11, instal DHT sensor library (Adafruit) dari Library Manager; ketika ditanya soal dependensi, pilih Install all agar Adafruit Unified Sensor ikut terpasang. Karena kita tidak memakai pin 0 dan 1, HC-05 tidak perlu dicabut ketika meng-upload.
1#include <SoftwareSerial.h>
2#include <Servo.h>
3#include <DHT.h>
4
5SoftwareSerial bt(10, 11); // RX, TX → HC-05 TXD, RXD (bölücü üzerinden / via divider)
6Servo servo;
7DHT dht(2, DHT11); // DHT11 veri pini D2 / data pin D2
8
9const int LED_PIN = 5; // PWM destekli pin / PWM-capable pin
10const int ROLE_PIN = 7;
11const int SERVO_PIN = 9;
12const int ROLE_ACIK = LOW; // çoğu röle modülü LOW ile çeker / most relay modules are active LOW
13const int ROLE_KAPALI = HIGH;
14
15String komut = ""; // gelen satırın tamponu / buffer for the incoming line
16unsigned long sonGonderim = 0;
17
18void komutIsle(String k) {
19 k.trim(); // boşluk ve \r temizle / strip spaces and \r
20 if (k.length() == 0) return;
21 Serial.println(k); // hata ayıklama / debugging
22 char tur = k.charAt(0); // komut harfi / command letter
23 int deger = k.substring(1).toInt(); // harften sonraki sayı / number after the letter
24
25 switch (tur) {
26 case 'L': // L1 / L0 → LED aç, kapat / LED on, off
27 analogWrite(LED_PIN, deger == 1 ? 255 : 0);
28 break;
29 case 'P': // P0..P255 → parlaklık / brightness
30 analogWrite(LED_PIN, constrain(deger, 0, 255));
31 break;
32 case 'R': // R1 / R0 → röle / relay
33 digitalWrite(ROLE_PIN, deger == 1 ? ROLE_ACIK : ROLE_KAPALI);
34 break;
35 case 'S': // S0..S180 → servo açısı / servo angle
36 servo.write(constrain(deger, 0, 180));
37 break;
38 }
39}
40
41void setup() {
42 pinMode(LED_PIN, OUTPUT);
43 pinMode(ROLE_PIN, OUTPUT);
44 digitalWrite(ROLE_PIN, ROLE_KAPALI); // açılışta röle kapalı / relay off at start
45 servo.attach(SERVO_PIN);
46 servo.write(90); // orta konum / centre position
47 dht.begin();
48 Serial.begin(9600); // Seri Monitör / Serial Monitor
49 bt.begin(9600); // HC-05 veri modu hızı / HC-05 data mode baud rate
50}
51
52void loop() {
53 // 1) Telefondan gelen komutları satır satır oku / read commands from the phone line by line
54 while (bt.available()) {
55 char c = bt.read();
56 if (c == '\n') { // satır bitti / line complete
57 komutIsle(komut);
58 komut = "";
59 } else if (komut.length() < 16) { // aşırı uzun satırı kes / cap overlong lines
60 komut += c;
61 }
62 }
63
64 // 2) 2 saniyede bir sensör verisini gönder / send sensor data every 2 seconds
65 if (millis() - sonGonderim >= 2000) {
66 sonGonderim = millis();
67 float t = dht.readTemperature();
68 float h = dht.readHumidity();
69 if (!isnan(t) && !isnan(h)) {
70 bt.print(t, 1); // örnek / example: 24.5
71 bt.print(';');
72 bt.print(h, 0); // örnek / example: 41
73 bt.print('\n'); // println değil, \r gitmesin / not println, no \r
74 }
75 }
76}- Buffer baris: loop() menambahkan setiap karakter yang masuk ke variabel komut (perintah); ketika \n datang, baris itu diteruskan ke komutIsle() lalu buffer dikosongkan. Karakter lebih dari 16 dibuang, jadi data sampah tidak bisa memenuhi memori.
- trim(): Beberapa aplikasi terminal juga menambahkan \r di akhir baris; trim() menghapusnya bersama spasi, jadi “L1\r” tetap dikenali sebagai “L1”.
- Huruf dan angka: charAt(0) memberikan huruf perintah dan substring(1).toInt() angka sesudahnya. constrain() menjepit nilai ke rentang yang aman; meskipun ponsel tidak sengaja mengirim 300, servo tidak pernah didorong lebih dari 180°.
- Pengiriman tanpa blocking: Sensor dibaca setiap 2 detik dengan millis(). Karena tidak ada delay(), perintah yang datang di sela-selanya diproses tanpa jeda; detailnya ada di millis vs delay.
- print('\n') alih-alih println: println() mengakhiri baris dengan \r\n. App Inventor hanya memakai \n sebagai pemisah, jadi \r akan menempel di akhir nilai kelembapan; mengirim \n saja membuat penguraian di ponsel tetap bersih.
- Relay active-LOW: Kebanyakan modul relay menyala ketika IN menjadi LOW. Kalau relay-mu menyala dengan HIGH, cukup tukar nilai konstanta ROLE_ACIK (nyala) dan ROLE_KAPALI (mati).
Mendesain antarmuka di App Inventor (Designer)
- Buka ai2.appinventor.mit.edu di browser, masuk dengan akun Google, lalu buat proyek bernama BlueGraysRemote lewat Projects > Start new project.
- Dari grup Layout di Palette, seret sebuah HorizontalArrangement; masukkan ListPicker (Text: Hubungkan), Button (Text: Putuskan), dan Label (Text: Belum terhubung) ke dalamnya.
- Tambahkan dua HorizontalArrangement lagi di bawahnya: isi yang pertama dengan tombol LED Nyala dan LED Mati, yang kedua dengan tombol Relay Nyala dan Relay Mati. Mengatur Width tombol menjadi Fill parent membuatnya lebih mudah diketuk.
- Tambahkan dua Slider: untuk kecerahan MinValue 0, MaxValue 255, ThumbPosition 0; untuk servo MinValue 0, MaxValue 180, ThumbPosition 90. Letakkan Label di atas masing-masing yang menjelaskan fungsinya.
- Tambahkan dua Label lagi untuk suhu dan kelembapan, lalu naikkan FontSize-nya menjadi sekitar 20.
- Dari grup Connectivity tambahkan BluetoothClient; di panel Properties atur DelimiterByte menjadi 10 dan centang NoLocationNeeded.
- Dari grup Sensors tambahkan Clock; atur TimerInterval menjadi 200 dan hapus centang TimerEnabled. Timer akan kita nyalakan dengan blok setelah koneksi terbentuk.
| Komponen | Nama (Rename) | Pengaturan utama |
|---|---|---|
| ListPicker | LP_Connect | Text: Hubungkan |
| Button × 5 | BTN_Disconnect, BTN_LedOn, BTN_LedOff, BTN_RelayOn, BTN_RelayOff | Width: Fill parent (selebar wadah) |
| Slider | SLD_Brightness | MinValue 0, MaxValue 255 |
| Slider | SLD_Servo | MinValue 0, MaxValue 180, ThumbPosition 90 |
| Label | LBL_Status, LBL_Temp, LBL_Hum | FontSize 20 (untuk nilai) |
| BluetoothClient | BluetoothClient1 | DelimiterByte 10, NoLocationNeeded dicentang |
| Clock | Clock1 | TimerInterval 200, TimerEnabled mati |
Menghubungkan ke HC-05 dengan ListPicker
Pertama, pasangkan (pair) HC-05 di pengaturan Bluetooth ponsel (PIN-nya biasanya 1234, kalau tidak 0000). Langkah ini wajib: BluetoothClient1.AddressesAndNames hanya menampilkan perangkat yang sudah dipasangkan dan tidak memindai perangkat baru di sekitar. Setiap entri berupa teks dengan alamat MAC di depan dan nama perangkat di belakangnya, seperti “98:D3:31:F5:2A:10 HC-05”. Kamu bisa memberikan seluruh teks itu ke blok Connect; App Inventor sendiri membuang semua yang ada setelah spasi pertama. Blok ini mengembalikan true kalau koneksi berhasil dan false kalau gagal.
- Di event when LP_Connect.BeforePicking, letakkan set LP_Connect.Elements to BluetoothClient1.AddressesAndNames. Daftar akan terisi ulang dengan perangkat yang sudah dipasangkan setiap kali dibuka.
- Di event when LP_Connect.AfterPicking, tambahkan blok if dan pasang call BluetoothClient1.Connect address: LP_Connect.Selection di kondisinya.
- Di bagian then dari if, atur LBL_Status.Text menjadi “Terhubung” dan mulai membaca data dengan set Clock1.TimerEnabled to true; di bagian else, tulis “Koneksi gagal”.
- Di event when BTN_Disconnect.Click, pertama set Clock1.TimerEnabled to false, lalu call BluetoothClient1.Disconnect, dan terakhir atur LBL_Status.Text menjadi “Belum terhubung”. Menghentikan timer lebih dulu mencegah pembacaan dan pesan error setelah koneksi ditutup.
Mengirim data: tombol dan slider
Mengirim cukup dengan satu blok: call BluetoothClient1.SendText text. Ketika kamu mengetik “L1\n” di blok teks, App Inventor mengubah \n di akhir menjadi karakter baris baru. Mengirim ketika belum terhubung menimbulkan error 515, jadi membungkus setiap pengiriman dengan pemeriksaan if BluetoothClient1.IsConnected adalah kebiasaan yang baik. Untuk slider, angka digabungkan dengan huruf dan baris baru memakai blok join: join("S", round(thumbPosition), "\n").
| Event | Teks yang dikirim | Hasil di Arduino |
|---|---|---|
| BTN_LedOn.Click | L1\n | LED menyala dengan kecerahan penuh |
| BTN_LedOff.Click | L0\n | LED mati |
| BTN_RelayOn.Click | R1\n | Relay berbunyi klik dan menyala, lampu yang tersambung menyala |
| BTN_RelayOff.Click | R0\n | Relay terlepas |
| SLD_Brightness.PositionChanged | join("P", round(thumbPosition), "\n") (gabungkan P + nilai) | analogWrite(5, value) (atur kecerahan) |
| SLD_Servo.PositionChanged | join("S", round(thumbPosition), "\n") (gabungkan S + sudut) | servo.write(angle) (atur sudut) |
Selama kamu menggeser slider dengan jari, event PositionChanged terpicu puluhan kali per detik dan thumbPosition mengembalikan nilai pecahan seperti 87.4. Kalau kamu mengirim di setiap event, sudut yang sama dikirim berulang-ulang, buffer HC-05 penuh, dan servo bergerak tersendat dan terlambat. Solusinya sederhana: buat variabel bernama global lastAngle; kirim hanya kalau nilai yang dibulatkan dengan round(thumbPosition) berbeda darinya, lalu perbarui variabelnya. Dengan begitu data hanya dikirim ketika sudutnya benar-benar berubah. Terapkan trik yang sama pada slider kecerahan dengan global lastBrightness.
Menerima data: menampilkan nilai sensor di ponsel
Arduino mengirim baris “24.5;41” setiap 2 detik. App Inventor tidak punya event yang terpicu sendiri ketika data datang, jadi kita memakai komponen Clock untuk memeriksa “ada data baru?” secara berkala. Karena DelimiterByte sudah kita atur menjadi 10 di Designer, memberi blok ReceiveText nilai -1 sebagai numberOfBytes membuatnya membaca sampai karakter baris baru dan mengembalikan baris itu tanpa \n. Timer 200 ms memeriksa jauh lebih sering daripada datangnya data (setiap 2000 ms), jadi tidak ada yang menumpuk di buffer.
- Letakkan kondisi if BluetoothClient1.IsConnected di dalam when Clock1.Timer.
- Tambahkan kondisi kedua di dalamnya: call BluetoothClient1.BytesAvailableToReceive > 0.
- Simpan baris yang masuk ke variabel lokal dengan initialize local line to call BluetoothClient1.ReceiveText numberOfBytes: -1.
- Ubah baris itu menjadi list dengan blok split text line at ";": “24.5;41” menjadi list dua item [24.5, 41]. Simpan hasilnya di variabel lokal bernama parts.
- if length of list parts = 2, atur LBL_Temp.Text menjadi join("Suhu: ", select list item parts index 1, " °C") dan LBL_Hum.Text menjadi join("Kelembapan: ", select list item parts index 2, " %"). Memeriksa jumlah item mencegah baris yang baru setengah diterima atau rusak menimbulkan error.
Masalah izin Bluetooth di Android 12 ke atas
Izin Bluetooth berubah sejak Android 12 (API 31). Izin BLUETOOTH lama, yang diberikan otomatis ketika instalasi, digantikan oleh BLUETOOTH_CONNECT dan BLUETOOTH_SCAN, yang harus disetujui pengguna ketika aplikasi sedang berjalan; di pengaturan ponsel izin ini muncul sebagai izin Perangkat di sekitar (Nearby devices). Kalau belum diberikan, App Inventor membuka dialog izin pada percobaan pertama tetapi menghentikan blok yang sedang berjalan. Hasilnya adalah sederet gejala yang sudah sering terlihat: daftar terbuka kosong ketika pertama kali kamu mengetuk Hubungkan, muncul pesan “Error 908: The permission ... has been denied” (menyebut BLUETOOTH_CONNECT atau BLUETOOTH_SCAN), atau kalau pengguna pernah menolak sekali, aplikasi tidak pernah bertanya lagi.
- Di event when Screen1.Initialize, periksa versi Android: jika select list item (split Screen1.PlatformVersion at ".") index 1 ≥ 12, berikan nilai BluetoothConnect dari list Permission ke call Screen1.AskForPermission. Izin ini tidak ada di Android 11 ke bawah, dan memintanya di sana juga memicu error 908, jadi pemeriksaan versi itu penting.
- Di event when Screen1.PermissionGranted, kalau izin yang diberikan adalah BLUETOOTH_CONNECT (contains text: permissionName, piece: "CONNECT"), minta BluetoothScan berikutnya. AskForPermission hanya menerima satu izin sekali panggil, jadi kamu merangkainya seperti ini.
- Di event when Screen1.PermissionDenied, pakai Notifier untuk menampilkan pesan dengan jalur “Setelan > Aplikasi > BlueGraysRemote > Izin > Perangkat di sekitar > Izinkan”. Menangani event ini menampilkan penjelasan yang jelas kepada pengguna alih-alih kotak error mentah.
- Biarkan NoLocationNeeded tetap dicentang pada BluetoothClient di Designer; opsi ini memberi tahu Android bahwa aplikasi tidak memakai Bluetooth untuk menentukan lokasi pengguna.
- Selalu uji juga dengan APK: izin AI2 Companion milik aplikasi Companion, sedangkan APK-mu meminta izinnya sendiri setelah diinstal.
| Error | Arti | Solusi |
|---|---|---|
| “Error 507: Unable to connect. Is the device turned on?” | Tidak bisa terhubung ke modul | Periksa daya HC-05, pastikan tidak sedang terhubung ke ponsel lain, dan periksa pairing-nya; kalau masih gagal, hapus centang Secure pada BluetoothClient lalu coba lagi |
| “Error 515: Not connected to a Bluetooth device.” | Mengirim atau membaca tanpa koneksi | Bungkus blok pengiriman dan Clock dengan pemeriksaan IsConnected |
| “Error 516: Unable to write: Broken pipe” | Koneksi terputus di tengah jalan (daya hilang, di luar jangkauan) | Hentikan Clock, panggil Disconnect, lalu hubungkan ulang; beri servo dan relay catu daya sendiri |
| “Error 908: The permission … has been denied” | Tidak ada izin Perangkat di sekitar di Android 12+ | Minta lewat blok atau berikan manual di Setelan |
| Daftar terbuka kosong | Modul belum dipasangkan, atau izinnya baru saja diminta | Pasangkan HC-05 di pengaturan ponsel; setelah memberi izin, ketuk Hubungkan lagi |
Menguji aplikasi dan membuat APK
Selama pengembangan kamu tidak perlu menginstal APK setiap kali ada perubahan. Instal aplikasi MIT AI2 Companion dari Play Store; dengan komputer dan ponsel di jaringan Wi-Fi yang sama, pilih Connect > AI Companion di App Inventor lalu pindai kode QR atau masukkan kode 6 karakter yang tampil di layar. Setiap perubahan yang kamu buat di Designer atau di blok langsung muncul di ponsel. Ketika aplikasi sudah selesai, buat file yang bisa diinstal seperti ini:
- Pilih Screen1 di Designer dan isi AppName (nama yang tampil di ponsel), Icon (PNG persegi), VersionCode, dan VersionName.
- Dari menu atas pilih Build > Android App (.apk). Proses build biasanya memakan waktu satu atau dua menit.
- Setelah selesai, muncul jendela berisi kode QR dan tombol unduh. Kamu bisa memindai kode QR dengan ponsel untuk langsung mengunduh file, atau menyimpan APK di komputer lalu menyalinnya ke ponsel lewat USB. Tautan QR hanya berlaku sebentar (sekitar 2 jam).
- Ketika kamu membuka APK di ponsel, Android meminta izin agar browser atau pengelola file-mu boleh menginstal aplikasi yang tidak dikenal. Kalau Play Protect menampilkan peringatan, kamu bisa melanjutkan dengan opsi tetap instal di bagian detail; peringatan ini umum untuk aplikasi dari luar Play Store dengan tanda tangan yang tidak dikenal.
- Pada peluncuran pertama aplikasi, setujui izin Perangkat di sekitar, ketuk Hubungkan, lalu pilih HC-05 dari daftar.
Aplikasi yang sama dengan ESP32, tanpa HC-05

ESP32 klasik punya Bluetooth klasik dan BLE bawaan sekaligus. Library BluetoothSerial menampilkan ESP32 ke ponsel sebagai perangkat SPP, jadi aplikasi yang baru kamu buat bisa dipakai tanpa diubah sedikit pun. Pasangkan perangkat bernama “BlueGrays-ESP32” di pengaturan Bluetooth ponsel, pilih dari daftar di aplikasi, dan selesai. Hati-hati: ESP32-S3, ESP32-C3, dan ESP32-C6 hanya mendukung BLE; board ini tidak punya BluetoothSerial, dan di sisi App Inventor kamu butuh ekstensi BluetoothLE. Untuk bekerja dengan BLE, lihat panduan Bluetooth dan BLE ESP32.
1#include "BluetoothSerial.h"
2#include <DHT.h>
3
4BluetoothSerial SerialBT;
5DHT dht(4, DHT11); // DHT11 veri pini GPIO 4 / data pin GPIO 4
6
7const int LED_PIN = 2; // çoğu DevKit'te kart üstü LED / onboard LED on most DevKits
8const int ROLE_PIN = 26;
9
10String komut = "";
11unsigned long sonGonderim = 0;
12
13void setup() {
14 pinMode(ROLE_PIN, OUTPUT);
15 digitalWrite(ROLE_PIN, HIGH); // aktif LOW röle kapalı / active-LOW relay off
16 dht.begin();
17 SerialBT.begin("BlueGrays-ESP32"); // telefonda görünecek ad / name shown on the phone
18}
19
20void loop() {
21 while (SerialBT.available()) {
22 char c = SerialBT.read();
23 if (c == '\n') {
24 komut.trim();
25 int deger = komut.substring(1).toInt();
26 if (komut.startsWith("L")) {
27 analogWrite(LED_PIN, deger == 1 ? 255 : 0); // LED aç, kapat / LED on, off
28 } else if (komut.startsWith("P")) {
29 analogWrite(LED_PIN, constrain(deger, 0, 255)); // parlaklık / brightness
30 } else if (komut.startsWith("R")) {
31 digitalWrite(ROLE_PIN, deger == 1 ? LOW : HIGH); // röle / relay
32 }
33 komut = "";
34 } else if (komut.length() < 16) {
35 komut += c;
36 }
37 }
38
39 if (millis() - sonGonderim >= 2000) { // Uno koduyla aynı biçim / same format as the Uno
40 sonGonderim = millis();
41 float t = dht.readTemperature();
42 float h = dht.readHumidity();
43 if (!isnan(t) && !isnan(h)) {
44 SerialBT.print(t, 1);
45 SerialBT.print(';');
46 SerialBT.print(h, 0);
47 SerialBT.print('\n');
48 }
49 }
50}Kode ini memahami perintah yang sama dengan versi Uno dan mengirim data dalam format “suhu;kelembapan” yang sama; perintah S diabaikan karena tidak ada servo yang terpasang. Library Servo Arduino tidak bekerja di ESP32; untuk menambahkan servo, instal library ESP32Servo dan pakai panggilan attach() dan write() yang sama, misalnya di GPIO 13. Beri daya modul relay dari pin VIN (5 V); kalau input IN-nya tidak berpindah dengan andal oleh sinyal 3,3 V dari ESP32, pilih modul relay yang kompatibel dengan 3,3 V. Untuk detailnya, lihat Apa Itu Modul Relay?
Dengan Raspberry Pi Pico dan MicroPython

Raspberry Pi Pico standar tidak punya Bluetooth, jadi HC-05 dihubungkan ke pin UART0 (GP0 dan GP1). Karena pin Pico bekerja di 3,3 V, kali ini tidak perlu pembagi tegangan; beri daya modul dari pin VBUS, yang membawa 5 V dari USB. Pico W dan Pico 2 W punya Bluetooth bawaan, tetapi MicroPython hanya mendukung BLE di board tersebut; untuk berkomunikasi dengan BluetoothClient klasik di App Inventor, HC-05 tetap jalan termudah. Kode di bawah memahami perintah yang sama, menggerakkan servo dengan PWM 50 Hz, dan mengirim data dalam format yang sama; modul dht sudah tersedia di firmware MicroPython Pico.
1from machine import UART, Pin, PWM
2import dht
3import time
4
5bt = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1)) # GP0 → HC-05 RXD, GP1 ← HC-05 TXD
6led = PWM(Pin(15))
7led.freq(1000)
8role = Pin(14, Pin.OUT, value=1) # aktif LOW röle kapalı / active-LOW relay off
9servo = PWM(Pin(13))
10servo.freq(50) # servo 50 Hz ister / servos need 50 Hz
11sensor = dht.DHT11(Pin(16))
12
13def komut_isle(k):
14 if not k:
15 return
16 tur, deger = k[0], int(k[1:] or 0) # harf + sayı / letter + number
17 if tur == 'L':
18 led.duty_u16(65535 if deger == 1 else 0)
19 elif tur == 'P':
20 led.duty_u16(min(max(deger, 0), 255) * 257) # 0-255 → 0-65535
21 elif tur == 'R':
22 role.value(0 if deger == 1 else 1)
23 elif tur == 'S':
24 aci = min(max(deger, 0), 180)
25 servo.duty_ns(544000 + aci * 1856000 // 180) # 544-2400 µs darbe / pulse
26
27tampon = b''
28son = time.ticks_ms()
29while True:
30 if bt.any():
31 tampon += bt.read()
32 while b'\n' in tampon: # tam satır geldi mi? / full line received?
33 satir, tampon = tampon.split(b'\n', 1)
34 try:
35 komut_isle(satir.decode().strip())
36 except ValueError:
37 pass # bozuk komutu atla / skip malformed command
38 if len(tampon) > 32:
39 tampon = b'' # satır sonu hiç gelmedi / no newline arrived
40 if time.ticks_diff(time.ticks_ms(), son) >= 2000:
41 son = time.ticks_ms()
42 try:
43 sensor.measure()
44 bt.write('{:.1f};{}\n'.format(sensor.temperature(), sensor.humidity()))
45 except OSError:
46 pass # sensör okunamadı / sensor read failed
47 time.sleep_ms(10)Ide proyek dengan App Inventor dan Arduino
- Mobil kendali Bluetooth: Petakan tombol arah ke huruf F, B, L, dan R lalu gerakkan motor dengan L298N; setiap langkahnya ada di panduan Mobil Robot Arduino.
- Panel rumah pintar: Kendalikan lampu, stopkontak, dan kipas dari satu layar dengan modul relay empat kanal; untuk ide, lihat proyek rumah pintar Arduino.
- Lampu pemilih warna: Atur nilai merah, hijau, dan biru LED RGB secara terpisah dengan tiga slider.
- Lengan robot: Tambahkan satu slider untuk setiap sendi dan kendalikan motor servo dari ponselmu.
- Pemantau rumah kaca: Tampilkan pembacaan DHT11 dan sensor kelembapan tanah di ponsel, lalu tambahkan tombol yang menyalakan pompa ketika tanah mulai kering.
- Kendali suara: Pakai komponen SpeechRecognizer di App Inventor untuk membuat aplikasi yang mengirim L1 ketika kamu mengucapkan “nyalakan lampu”.
Kesalahan umum dan cara mengatasinya
- Aplikasi terhubung tetapi LED tidak menyala: Kabel TXD dan RXD HC-05 tertukar, atau pin SoftwareSerial di kode tidak cocok dengan rangkaian. TXD modul harus ke RX Arduino (D10).
- Perintah diabaikan: \n tidak ada di blok teks; Arduino menunggu baris baru. Periksa apakah perintah yang masuk muncul di Serial Monitor.
- Karakter kacau: Baud rate HC-05 berbeda dengan bt.begin(). Modul dikirim dengan 9600 baud; kalau sudah diubah dengan perintah AT, sesuaikan kodenya.
- Servo bergetar atau koneksi terputus: Servo menarik turun jalur 5 V Arduino; beri daya dari catu daya 5 V terpisah dan satukan GND-nya. Getaran ringan juga bisa berasal dari SoftwareSerial yang sebentar memblokir interrupt ketika menerima data; untuk solusi permanen, pakai Arduino Mega atau ESP32, yang punya port serial hardware cadangan. Sesekali servo juga bisa melompat ke sudut yang salah sejenak: library DHT mematikan interrupt sekitar 5 ms di setiap pembacaan, dan perintah yang datang tepat pada momen itu bisa rusak; perintah berikutnya dari slider akan membetulkannya.
- Nilai di ponsel tertinggal: Interval Clock lebih panjang daripada interval pengiriman Arduino, jadi baris-baris menumpuk. Buat TimerInterval lebih pendek daripada interval pengiriman.
- Aplikasi membeku: DelimiterByte masih 0, atau Arduino tidak mengakhiri barisnya dengan \n; ReceiveText(-1) menunggu pemisah yang tidak pernah datang.
- Tidak bisa di iPhone: HC-05 memakai Bluetooth klasik, yang tidak diizinkan iOS. iPhone butuh modul BLE (HM-10) atau ESP32.
Menggabungkan App Inventor dan Arduino adalah cara paling seru untuk belajar pengembangan aplikasi mobile dan elektronika dalam satu proyek. Setelah koneksi dan protokolnya siap, kerangka yang sama bisa menjadi mobil, rumah pintar, atau remote rumah kaca; yang berubah hanyalah huruf apa yang dikirim oleh tombol. Di aplikasi BlueGrays kamu akan menemukan proyek Kendalikan LED dari Ponselmu lewat Bluetooth dan Mobil Kendali Bluetooth dengan L298N langkah demi langkah, lengkap dengan skema rangkaian dan kode.
Pertanyaan umum
Apakah aplikasi Bluetooth App Inventor bisa dipakai di iPhone?
Tidak dengan HC-05 atau HC-06. Modul ini memakai Bluetooth klasik (SPP), dan iOS tidak mengizinkan aplikasi biasa membuka koneksi serial semacam ini. Untuk berkomunikasi dengan iPhone, kamu perlu beralih ke modul BLE seperti HM-10 atau ke ESP32; untuk proyek HC-05, ponsel Android adalah pilihan yang paling bebas masalah.
Mengapa daftar perangkat Bluetooth di App Inventor kosong?
AddressesAndNames hanya menampilkan perangkat yang sudah dipasangkan dengan ponsel, jadi pasangkan dulu HC-05 di pengaturan Bluetooth dengan PIN 1234. Di Android 12 ke atas, daftar juga terbuka kosong pada kali pertama kalau izin Perangkat di sekitar belum diberikan; berikan izinnya lalu ketuk Hubungkan lagi. Pastikan juga Bluetooth sudah menyala.
Bagaimana cara mengatasi error 507 di App Inventor?
Error 507 berarti “Unable to connect. Is the device turned on?”: ponsel tidak bisa membuka koneksi ke modul. Pastikan HC-05 mendapat daya, LED-nya berkedip cepat, dan tidak sedang terhubung ke ponsel lain. Kalau masalahnya berlanjut, hapus pairing lalu pasangkan ulang, atau coba matikan properti Secure pada BluetoothClient.
Bagaimana cara membuat APK di App Inventor?
Buka proyeknya dan klik Build > Android App (.apk) di menu atas. Setelah build selesai, pindai kode QR dengan ponselmu atau unduh APK ke komputer lalu salin ke ponsel. Ketika instalasi, kamu perlu mengizinkan instalasi aplikasi yang tidak dikenal.
Bisakah App Inventor terhubung ke ESP32 lewat Bluetooth?
Bisa. Dengan library BluetoothSerial, ESP32 klasik berperilaku seperti perangkat SPP, dan BluetoothClient di App Inventor terhubung ke sana sama seperti ke HC-05. ESP32-S3 dan ESP32-C3 hanya mendukung BLE, jadi di board tersebut kamu butuh ekstensi BluetoothLE.
Bisakah aplikasi App Inventor-ku diterbitkan di Google Play?
Bisa. Opsi Android App Bundle (.aab) di menu Build menghasilkan file yang bisa di-upload ke Google Play; kamu butuh akun developer Google Play. Pembaruan harus ditandatangani dengan kunci yang sama, jadi cadangkan keystore-mu dengan Projects > Export keystore.
Proyek untuk dibuat setelah membaca ini
Lihat semua proyek
LED Berkedip
"Halo" pertama di dunia elektronika: menyalakan dan mematikan satu LED. Arduino menyalakan dan mematikan LED dengan jeda singkat, sehingga cahayanya berkedip cepat. Kamu melihat dengan cara paling sed

Suhu dan Kelembapan dengan DHT11
Seberapa hangat kamarmu, dan apakah udaranya lembap atau kering? Sensor DHT11 mengukur suhu dan kelembapan, dan Arduino menulis nilainya di layar LCD dua baris, diperbarui setiap beberapa detik. Jika

Kendalikan LED dari Ponselmu lewat Bluetooth
Latihan kecil untuk menyalakan dan mematikan lampu kamarmu dari ponsel. Modul Bluetooth meneruskan huruf yang dikirim dari ponselmu ke Arduino; satu huruf menyalakan LED merah, huruf lain menyalakan L

Mobil Kendali Bluetooth dengan L298N
Jadikan ponselmu remote dan kendarai mobil robotmu sendiri. Arduino menerima perintah dari aplikasi remote control di ponselmu lewat modul Bluetooth dan memutar roda dengan driver motor; mobil maju, m

Menggunakan Motor Servo
Lengan motor servo kecil berputar ke tiga posisi bergantian: penuh ke awal, tepat ke tengah, dan penuh ke akhir, menunggu dua detik di setiap perhentian. Arduino memberi tahu motor sudut mana yang har

Menggunakan LED RGB
Tiga warna tersembunyi di dalam satu LED: LED RGB menyala merah, lalu hijau, lalu biru, setiap warna menyala setengah detik dan mati setengah detik, sebelum siklusnya dimulai lagi. Yang kamu butuhkan

Menyalakan Bohlam 220V dengan Tombol Tekan
Selama kamu menahan tombol, bohlam 220 volt sungguhan tetap menyala, dan mati begitu kamu melepasnya. Sinyal kecil Arduino tidak bisa langsung menyalakan bohlam, jadi relay, sakelar yang dikendalikan

Komunikasi Satu Arah Antara 2 Arduino
Kamu membuat dua Arduino berbicara lewat satu kabel: tekan tombol di satu board dan LED di board lain menyala, tekan lagi dan LED mati. Board pengirim melaporkan tekanan tombol dengan pesan singkat, d
Artikel lainnya
Aplikasi BlueGrays
Rakit rangkaian ini langkah demi langkah di ponselmu
Skema pengkabelan, kode, dan daftar komponen dalam satu layar. 200+ proyek Arduino, ESP32, dan Pico siap dibuat.
Pindai dengan ponselmu
Arahkan kamera ke kode ini dan toko aplikasi di ponselmu akan terbuka.
atau buka toko aplikasi

