Komunikasi Serial Arduino dan Python: pyserial, CSV, dan Grafik Langsung
Komunikasi serial Arduino dan Python dengan pyserial: instal, temukan port, catat data sensor ke CSV, kirim perintah, dan gambar grafik langsung dengan matplotlib.
Komunikasi serial Arduino dan Python berarti program Python yang berjalan di komputermu bertukar data dengan Arduino lewat kabel USB. Arduino mengukur sensor dan menulis hasilnya ke port serial; Python membaca baris-baris itu dengan library pyserial, menyimpannya ke file CSV, menampilkannya sebagai grafik, atau mengambil keputusan lalu mengirim perintah balik ke Arduino. Dengan begitu kamu menggabungkan kendali hardware Arduino yang presisi dengan kekuatan Python untuk pengolahan data, grafik, AI, dan otomasi. Kamu juga tidak butuh modul tambahan: kabel USB yang kamu pakai untuk meng-upload sketch sudah cukup.
Di panduan ini kamu akan belajar langkah demi langkah cara menginstal pyserial, menemukan port Arduino secara otomatis, mencatat data sensor beserta timestamp ke file CSV, mengirim perintah LED dan PWM dari Python ke Arduino, dan menggambar grafik langsung dengan matplotlib. Setelah itu kita bahas cara memilih format data dan akhir baris, dua masalah yang paling membingungkan (error port sibuk dan board yang reset ketika port dibuka), serta apa bedanya kalau pekerjaan yang sama dilakukan dengan MicroPython di Raspberry Pi Pico. Contoh-contohnya ditulis untuk Arduino Uno; perubahan yang dibutuhkan untuk ESP32 dan Pico dijelaskan terpisah.

Bagaimana Arduino berkomunikasi dengan Python?
Chip USB-ke-serial di Arduino Uno (ATmega16U2 di board asli, biasanya CH340 di board klon) muncul di komputermu sebagai port serial virtual: COM3, COM4, dan seterusnya di Windows; /dev/cu.usbmodem… atau /dev/cu.usbserial-… di macOS; /dev/ttyACM0 atau /dev/ttyUSB0 di Linux. Setiap karakter yang ditulis Arduino dengan Serial.print() mengalir ke komputer lewat port ini sebagai byte; di sisi Python, pyserial membuka port seperti membuka file, lalu membaca dan menulis ke sana. Ada satu perbedaan penting: Arduino Uno tidak menjalankan kode Python. Board menjalankan kode Arduino yang ditulis dalam C++, komputer menjalankan Python, dan keduanya hanya berbicara lewat jalur serial. Supaya kedua sisi berbicara dalam bahasa yang sama, pengaturan berikut harus cocok:
| Pengaturan | Sisi Arduino | Sisi Python | Perhatikan |
|---|---|---|---|
| Port | Terbentuk otomatis lewat USB | serial.Serial("COM3", ...) | Nama port tergantung sistem operasi |
| Kecepatan (baud) | Serial.begin(115200) | serial.Serial(port, 115200) | Kalau berbeda, yang muncul karakter acak |
| Frame | 8 bit data, tanpa paritas, 1 stop bit (8N1) | Default pyserial juga 8N1 | Jarang perlu diubah |
| Akhir baris | Serial.println() menambahkan \r\n | readline() membaca sampai menemukan \n | Jangan lupa menambahkan \n ketika mengirim dari Python |
| Timeout | Serial.setTimeout(), default 1000 ms | timeout=1 (detik) | Dengan timeout=None, readline() menunggu selamanya |
Menginstal pyserial (Windows, macOS, Linux)
- Pastikan Python 3 sudah terinstal. Di Windows, centang kotak Add python.exe to PATH di layar pertama installer dari situs resmi Python; di macOS dan Linux, Python 3 biasanya sudah terpasang.
- Buka terminal (Command Prompt atau PowerShell di Windows) lalu ketik python -m pip install pyserial. Kalau Windows tidak mengenali perintah python, coba py -m pip install pyserial; di macOS dan Linux perintahnya mungkin python3 -m pip install pyserial.
- Cek instalasinya: python -c "import serial; print(serial.__version__)" harus menampilkan nomor versi seperti 3.5.
- Bagian grafik langsung juga membutuhkan matplotlib: python -m pip install matplotlib.
- Di Linux, tambahkan user-mu ke grup dialout supaya bisa membuka port: sudo usermod -a -G dialout $USER, lalu logout dan login lagi. Kalau pip menampilkan error externally-managed-environment di Raspberry Pi OS atau rilis Ubuntu terbaru, pakai sudo apt install python3-serial atau buat virtual environment dengan python3 -m venv dan jalankan pip di dalamnya.
Arduino ada di port mana? Menemukan port dengan Python
Cara termudah adalah melihat menu Tools > Port di Arduino IDE, tetapi Python juga bisa mendaftar port sendiri. Ketik python -m serial.tools.list_ports -v di terminal dan kamu akan melihat nama, deskripsi, dan ID hardware (VID:PID) setiap port. Kalau kamu tidak bisa membedakan baris mana yang Arduino, cabut board-nya, jalankan perintah itu lagi, dan catat port yang hilang. Di macOS, board yang sama muncul sebagai /dev/tty… sekaligus /dev/cu…; di Python, pakai yang diawali cu.

| Chip USB | Ada di mana | VID:PID | Nama yang tampil di Windows | Nama port di Linux |
|---|---|---|---|---|
| ATmega16U2 | Uno R3 asli, Mega 2560 | 2341:0043 (Uno) | Arduino Uno (COMx) | /dev/ttyACM0 |
| CH340 | Board klon Uno, Nano, dan Mega | 1A86:7523 | USB-SERIAL CH340 (COMx) | /dev/ttyUSB0 |
| CP2102 | ESP32 DevKit, NodeMCU | 10C4:EA60 | Silicon Labs CP210x USB to UART Bridge (COMx) | /dev/ttyUSB0 |
| FT232R | Nano lama, kabel FTDI | 0403:6001 | USB Serial Port (COMx) | /dev/ttyUSB0 |
| RP2040 (USB bawaan) | Raspberry Pi Pico dengan MicroPython | 2E8A:0005 | USB Serial Device (COMx) | /dev/ttyACM0 |
Fungsi di bawah mendaftar semua port dan, kalau mengenali sebuah board dari VID-nya, mengembalikan nama port board tersebut. Simpan kodenya sebagai port_bul.py, lalu di skrip lain kamu cukup menulis from port_bul import port_bul dan PORT = port_bul(), tanpa perlu mengubah nama port secara manual setiap kali.
1import serial.tools.list_ports
2
3# Bilinen USB yongalarının üretici kimlikleri (VID) / Vendor IDs of common USB chips
4BILINEN = {
5 0x2341: "Arduino (orijinal / genuine)",
6 0x2A03: "Arduino (orijinal / genuine)",
7 0x1A86: "CH340 (klon / clone)",
8 0x10C4: "CP210x (ESP32, NodeMCU)",
9 0x0403: "FTDI",
10 0x2E8A: "Raspberry Pi Pico",
11}
12
13
14def port_bul():
15 portlar = sorted(serial.tools.list_ports.comports())
16 for p in portlar:
17 print(p.device, "|", p.description, "|", p.hwid) # tüm portları listele / list every port
18 for p in portlar:
19 if p.vid in BILINEN:
20 print("Bulundu / found:", p.device, "->", BILINEN[p.vid])
21 return p.device
22 return None
23
24
25if __name__ == "__main__":
26 if port_bul() is None:
27 print("Kart yok: kabloyu ve surucuyu kontrol et / no board: check cable and driver")Mengirim data dari Arduino: sketch pertama
Contoh-contohnya memakai potensiometer yang terhubung ke pin A0: kaki tengah ke A0, satu kaki luar ke 5V, dan kaki lainnya ke GND. Sebagai pengganti potensiometer, kamu juga bisa merangkai LDR dengan resistor 10 kΩ sebagai pembagi tegangan. Sketch-nya mengambil pembacaan setiap 200 ms dan mengirim hasilnya sebagai satu baris dengan format waktu,nilai:
1// A0 değerini "millis,deger" CSV satırı olarak gönderir / Sends the A0 reading as a "millis,value" CSV line
2const int SENSOR_PIN = A0; // potansiyometrenin orta ucu / potentiometer wiper
3const unsigned long ARALIK = 200; // gönderim aralığı, ms / send interval, ms
4unsigned long sonGonderim = 0;
5
6void setup() {
7 Serial.begin(115200); // Python'daki hızla aynı olmalı / must match the baud rate in Python
8}
9
10void loop() {
11 if (millis() - sonGonderim >= ARALIK) { // delay() olmadan zamanlama / timing without delay()
12 sonGonderim = millis();
13 int deger = analogRead(SENSOR_PIN); // 0-1023
14 Serial.print(sonGonderim); // zaman damgası / timestamp
15 Serial.print(','); // ayırıcı / separator
16 Serial.println(deger); // sonuna \r\n ekler / appends \r\n
17 }
18}Memakai millis() alih-alih delay() memudahkanmu menambahkan pembacaan perintah dari Python ke loop yang sama nanti; detailnya ada di millis vs delay. Setelah meng-upload, buka Serial Monitor di 115200 baud dan kamu akan melihat baris seperti 2573,512 terus bergulir. Ini hanya pengecekan: selalu tutup Serial Monitor sebelum menjalankan skrip Python, kalau tidak port-nya akan sibuk. Kalau kamu baru mengenal Serial Monitor, panduan Serial Monitor Arduino akan membantu.
Membaca data Arduino dengan Python dan menyimpannya ke CSV
1import csv
2import time
3from datetime import datetime
4
5import serial
6
7PORT = "COM3" # macOS: /dev/cu.usbmodem14101, Linux: /dev/ttyACM0
8BAUD = 115200 # Arduino'daki Serial.begin ile aynı / same as Serial.begin on the Arduino
9
10with serial.Serial(PORT, BAUD, timeout=1) as ser, \
11 open("olcumler.csv", "w", newline="", encoding="utf-8") as dosya:
12 time.sleep(2) # Uno port açılınca resetlenir / the Uno resets when the port opens
13 ser.reset_input_buffer() # yarım kalmış eski veriyi at / drop stale, partial data
14 yazici = csv.writer(dosya)
15 yazici.writerow(["tarih", "zaman_ms", "deger", "volt"]) # başlık satırı / header row
16 print("Kayit basladi, durdurmak icin Ctrl+C / logging, press Ctrl+C to stop")
17 try:
18 while True:
19 satir = ser.readline().decode("utf-8", errors="ignore").strip()
20 parcalar = satir.split(",")
21 if len(parcalar) != 2:
22 continue # boş ya da beklenmeyen satır / empty or unexpected line
23 try:
24 zaman_ms, deger = int(parcalar[0]), int(parcalar[1])
25 except ValueError:
26 continue # bozuk satır / corrupted line
27 volt = deger * 5.0 / 1023 # Uno ADC: 0-1023 -> 0-5 V
28 yazici.writerow([datetime.now().isoformat(timespec="seconds"),
29 zaman_ms, deger, round(volt, 3)])
30 dosya.flush() # satırı hemen diske yaz / write the row to disk now
31 print(zaman_ms, deger, f"{volt:.2f} V")
32 except KeyboardInterrupt:
33 print("Durduruldu / stopped")Skrip ini membuka port dengan timeout=1: readline() menunggu akhir baris paling lama 1 detik, mengembalikan objek bytes kosong kalau tidak ada yang datang, dan loop tidak pernah macet. Data yang masuk bertipe bytes; decode() mengubahnya menjadi teks, strip() membuang \r\n di ujungnya, dan split(",") memecah baris menjadi kolom. time.sleep(2) dan reset_input_buffer() setelah port dibuka berfungsi membuang potongan baris yang datang selama Uno memulai ulang; alasannya akan kamu lihat di bawah. Membuka file dengan newline="" mencegah baris kosong di Windows, dan flush() memastikan pembacaan yang sudah tercatat tetap tersimpan di disk walaupun program tertutup tiba-tiba. Tekan Ctrl+C di terminal untuk menghentikan pencatatan.
Mengirim perintah dari Python ke Arduino
Komunikasinya berjalan dua arah. Sketch Arduino di bawah menunggu perintah yang datang baris demi baris: LED ON dan LED OFF menyalakan dan mematikan LED bawaan, PWM 128 mengatur kecerahan LED di pin 9, dan READ mengirim balik nilai di A0. Setiap perintah mendapat balasan singkat, jadi Python tahu perintah itu benar-benar diproses. Nilai resistor yang tepat untuk LED di pin 9 bisa kamu cari dengan kalkulator resistor LED; Apa Itu PWM? menjelaskan cara kerja PWM.
1// Python'dan gelen satır komutlarını işler / Handles line-based commands from Python
2const int LED_PIN = LED_BUILTIN; // Uno'da pin 13 / pin 13 on the Uno
3const int PWM_PIN = 9; // 220 ohm dirençli LED / LED with a 220 ohm resistor
4
5void setup() {
6 pinMode(LED_PIN, OUTPUT);
7 pinMode(PWM_PIN, OUTPUT);
8 Serial.begin(115200);
9 Serial.setTimeout(50); // readStringUntil en fazla 50 ms bekler / waits at most 50 ms
10 Serial.println("HAZIR"); // Python bu satırı bekler / Python waits for this line
11}
12
13void loop() {
14 if (Serial.available() > 0) {
15 String komut = Serial.readStringUntil('\n'); // satır sonuna kadar oku / read up to the newline
16 komut.trim(); // \r ve boşlukları sil / strip \r and spaces
17
18 if (komut == "LED ON") {
19 digitalWrite(LED_PIN, HIGH);
20 Serial.println("OK LED ON");
21 } else if (komut == "LED OFF") {
22 digitalWrite(LED_PIN, LOW);
23 Serial.println("OK LED OFF");
24 } else if (komut.startsWith("PWM ")) {
25 int deger = komut.substring(4).toInt(); // "PWM 128" -> 128
26 deger = constrain(deger, 0, 255); // 0-255 aralığında tut / keep it within 0-255
27 analogWrite(PWM_PIN, deger);
28 Serial.print("OK PWM ");
29 Serial.println(deger);
30 } else if (komut == "READ") {
31 Serial.println(analogRead(A0)); // A0 ölçümünü gönder / send the A0 reading
32 } else if (komut.length() > 0) {
33 Serial.print("ERR "); // bilinmeyen komut / unknown command
34 Serial.println(komut);
35 }
36 }
37}1import time
2
3import serial
4
5
6def komut_gonder(ser, komut):
7 ser.write((komut + "\n").encode("ascii")) # satır sonu şart / the newline is required
8 return ser.readline().decode("ascii", errors="ignore").strip() # cevabı bekle / wait for the reply
9
10
11with serial.Serial("COM3", 115200, timeout=2) as ser:
12 bitis = time.time() + 3 # en fazla 3 sn bekle / wait at most 3 s
13 while time.time() < bitis:
14 if ser.readline().strip() == b"HAZIR": # Arduino açıldı / the Arduino is up
15 break
16 print(komut_gonder(ser, "LED ON")) # OK LED ON
17 time.sleep(1)
18 print(komut_gonder(ser, "PWM 128")) # OK PWM 128
19 print("A0 =", komut_gonder(ser, "READ")) # A0 = 512
20 print(komut_gonder(ser, "LED OFF")) # OK LED OFFKesalahan paling umum di sisi Python adalah lupa menambahkan \n di akhir perintah: ketika readStringUntil('\n') tidak menemukan akhir baris, Arduino menunggu selama waktu yang diatur dengan Serial.setTimeout() dan baru setelah itu memproses perintahnya. Di sketch ini waktunya 50 ms; dengan default 1000 ms, setiap perintah akan tertunda satu detik. write() hanya menerima bytes, jadi kamu perlu mengubah teks dengan encode() atau dengan menaruh b di depannya (b"LED ON\n"). Skrip ini pertama-tama menunggu baris HAZIR (artinya “siap”) paling lama 3 detik: karena Uno memulai ulang ketika port dibuka, perintah yang langsung dikirim akan masuk ke bootloader dan hilang. Membaca balasan setelah setiap perintah, yaitu pola permintaan dan respons, menjaga kedua sisi tetap sinkron dan mencegah buffer penuh; buffer penerima Uno hanya 64 byte.
Format data dan akhir baris: mana yang sebaiknya dipilih?
Jalur serial hanya memberimu aliran byte; kamulah yang harus menandai di mana satu pembacaan berakhir dan pembacaan berikutnya dimulai. Cara paling andal adalah menulis setiap pembacaan di barisnya sendiri dan mengakhiri setiap baris dengan \n. Format yang kamu pakai di dalam baris tergantung pada besar kecilnya proyekmu:
| Format | Contoh baris | Kelebihan | Kekurangan |
|---|---|---|---|
| Satu nilai | 512 | Format paling sederhana; Serial Plotter Arduino bisa langsung menggambarnya | Kalau ada beberapa nilai, tidak jelas mana yang mana |
| CSV | 2573,512,23.5 | Singkat; Excel dan pandas bisa langsung membacanya | Urutan kolom harus sama di kedua sisi |
| Kunci:nilai | suhu:23.5,lembap:41 | Mudah dibaca; Serial Plotter menampilkan labelnya | Lebih panjang dan sedikit lebih repot di-parse |
| JSON | {"t":23.5,"h":41} | Di Python cukup satu baris dengan json.loads() | Format paling panjang; membebani RAM Uno yang terbatas |
| Biner (binary) | 2 byte: 0x02 0x00 | Pilihan paling cepat dan paling ringkas | Tidak bisa dibaca manusia; butuh modul struct dan byte awal |
Akhir baris juga sering membingungkan. Serial.println() menambahkan dua karakter di akhir setiap baris: carriage return (\r, CR) dan line feed (\n, LF). readline() di Python hanya menunggu \n, jadi \r tertinggal di ujung baris; strip() membuang keduanya. Daftar akhir baris di Serial Monitor Arduino IDE menawarkan No Line Ending, New Line, Carriage Return, dan Both NL & CR; ketika kamu menguji sketch Arduino di Serial Monitor sebelum memakai Python, pilih New Line supaya karakter yang terkirim sama dengan yang dikirim Python. Untuk angka desimal, tentukan jumlah digitnya seperti di Serial.print(temperature, 1); di Uno, sprintf tidak mendukung format floating-point (%f), jadi mencoba mencetak desimal dengan sprintf akan menghasilkan tanda tanya, bukan angkanya.
| Baud rate | Byte per detik (8N1) | Baris 12 byte per detik | Kapan dipakai |
|---|---|---|---|
| 9600 | 960 | 80 | Sensor lambat, kabel panjang, contoh sketch lama |
| 57600 | 5.760 | 480 | Pengukuran berkecepatan sedang |
| 115200 | 11.520 | 960 | Grafik langsung, ESP32, dan sebagian besar proyek baru |
Di jalur serial, setiap byte dikirim sebagai 10 bit termasuk start bit dan stop bit, jadi 115200 baud berarti sekitar 11.520 byte per detik. Untuk baris 12 byte yang terdiri dari 25730,1023 ditambah akhir baris (\r\n), ada ruang hingga 960 baris per detik. Kalau kecepatan di kedua sisi berbeda, karakter acak mengalir di jalur dan Python memunculkan UnicodeDecodeError. Antara 5 dan 20 pembacaan per detik sudah lebih dari cukup untuk mata manusia dan sebagian besar sensor; mengirim jauh lebih sering daripada yang dibutuhkan hanya memperlambat grafik dan membuat file membengkak.
Menggambar grafik langsung dengan matplotlib
1from collections import deque
2
3import matplotlib.pyplot as plt
4import serial
5from matplotlib.animation import FuncAnimation
6
7ser = serial.Serial("COM3", 115200, timeout=0.1)
8N = 200 # ekrandaki ölçüm sayısı / readings on screen
9veri = deque([0] * N, maxlen=N) # eskiler kendiliğinden düşer / old values drop out
10
11fig, ax = plt.subplots()
12cizgi, = ax.plot(range(N), list(veri))
13ax.set_ylim(0, 1023) # Uno ADC aralığı / Uno ADC range
14ax.set_xlabel("Ornek / sample")
15ax.set_ylabel("A0")
16
17
18def guncelle(_):
19 while ser.in_waiting: # biriken bütün satırları oku / read every queued line
20 parca = ser.readline().decode("utf-8", errors="ignore").strip().split(",")
21 if len(parca) == 2 and parca[1].isdigit():
22 veri.append(int(parca[1]))
23 cizgi.set_ydata(list(veri))
24 return (cizgi,)
25
26
27ani = FuncAnimation(fig, guncelle, interval=50, blit=True, cache_frame_data=False) # ani silinmemeli / keep ani
28plt.show()
29ser.close()Grafiknya dibangun di atas deque yang menyimpan 200 pembacaan terakhir: setiap nilai baru ditambahkan di kanan dan nilai tertua otomatis terbuang dari kiri. FuncAnimation memanggil fungsi guncelle (artinya “perbarui”) setiap 50 ms. Loop while ser.in_waiting di dalam fungsi itu penting: sekarang Arduino mengirim 5 baris per detik, tetapi begitu kamu menaikkan lajunya, membaca hanya satu baris per frame membuat grafik tertinggal dari waktu nyata; loop ini membaca semua baris yang mengantre dan menjaga grafik tetap mutakhir. Jangan hapus variabel ani: kalau tidak ada variabel yang merujuk ke objek animasi, Python membuangnya lewat garbage collection dan jendelanya membeku. Pakai set_ylim(0, 4095) untuk ESP32 dan set_ylim(0, 65535) untuk Pico. Kalau kamu cuma ingin melihat sekilas, Serial Plotter di Arduino IDE sudah cukup; kelebihan Python adalah kamu bisa menyimpan grafiknya, menggabungkan beberapa sumber, dan mengolah datanya sekaligus.
Error port sibuk dan masalah auto-reset
Sebuah port serial hanya bisa dibuka oleh satu program dalam satu waktu. Kalau Serial Monitor atau Serial Plotter Arduino IDE terbuka ketika skrip Python-mu berjalan, ada skrip Python lain yang memegang port, atau software yang memindai port, seperti program printer 3D, berjalan di latar belakang, kamu akan mendapat could not open port 'COM3': PermissionError(13, 'Access is denied.', None, 5) di Windows dan Resource busy atau Device or resource busy di macOS dan Linux. Berlaku juga sebaliknya: selama skrip Python membiarkan port terbuka, Arduino IDE tidak bisa meng-upload kode. Karena itu, pakai konstruksi with serial.Serial(...) as ser: di skripmu; port akan tertutup otomatis ketika blok selesai atau terjadi error. Biasakan menghentikan skrip dengan Ctrl+C sebelum meng-upload.
Masalah kedua lebih licin: di Arduino Uno, Nano, dan Mega, jalur DTR dari chip USB terhubung ke pin RESET prosesor melalui kapasitor 100 nF. Rangkaian ini ada supaya IDE bisa me-restart board secara otomatis ketika meng-upload, tetapi setiap kali pyserial membuka port, DTR juga berubah dan board ikut reset. Board pertama-tama menunggu satu atau dua detik di bootloader, lalu menjalankan sketch-mu dari awal. Perintah yang kamu kirim selama waktu itu hilang, dan kamu bisa melewatkan baris-baris pertama yang dicetak Arduino di setup(). Solusinya adalah menunggu dengan time.sleep(2) setelah membuka port atau, yang lebih andal, menunggu Arduino mengirim baris seperti HAZIR; contoh perintah di atas melakukan persis itu. Buka port sekali di awal program dan biarkan terbuka sampai akhir: loop yang membuka dan menutup port untuk setiap pembacaan akan me-reset board berulang-ulang.
Kalau ingin mencegah reset sepenuhnya, ada dua cara. Lewat software: buat port dalam keadaan tertutup dengan ser = serial.Serial(), atur ser.port dan ser.baudrate, tulis ser.dtr = False, lalu panggil ser.open(). Cara ini biasanya berhasil di Windows; di Linux dan macOS, sistem operasi mungkin tetap mengubah DTR ketika port dibuka. Lewat hardware: pasang kapasitor 10 µF di antara pin RESET dan GND Uno, dengan kaki positif di RESET. Board dengan USB bawaan seperti Leonardo, Micro, dan Raspberry Pi Pico tidak me-restart ketika port dibuka; di board ini, baris yang dicetak kodemu sebelum Python terhubung bisa hilang, jadi lebih aman mengirim pesan penting ketika sebuah perintah datang.
Komunikasi serial Python dengan ESP32
Semua kode Python di sini juga bekerja dengan ESP32; kamu hanya perlu mengubah beberapa hal di sisi Arduino. Untuk input analog, pakai salah satu pin ADC1 (misalnya GPIO 34). ADC ESP32 beresolusi 12 bit dan memetakan 0–3,3 V ke 0–4095, jadi hitung tegangannya di Python dengan deger * 3.3 / 4095. Ketika menyala, ESP32 mencetak pesan startup-nya sendiri di 115200 baud, seperti rst:0x1 (POWERON_RESET),boot:0x13; skrip di atas melewati baris yang tidak bisa diubah menjadi angka, jadi pesan ini tidak menimbulkan masalah. Tergantung rangkaian auto-reset board dan sistem operasinya, ESP32 juga bisa me-restart ketika port dibuka, jadi jeda tunggu dan baris HAZIR juga membantu di sini. Chip USB-nya biasanya CP2102 atau CH340. Kalau kamu lebih suka tanpa kabel, ESP32 bisa mengirim data yang sama lewat Wi-Fi; lihat panduan WebSocket ESP32 dan mencatat data ESP32 ke Google Sheets. Kalau ini ESP32 pertamamu, baca dulu Apa Itu ESP32?.
Raspberry Pi Pico dan MicroPython: apa bedanya?

Cara lain untuk mempertemukan Python dan hardware adalah menjalankan Python langsung di board. Raspberry Pi Pico bisa diprogram dengan MicroPython: membaca sensor, mengendalikan LED, dan pengaturan waktu semuanya dikerjakan di dalam Pico dengan sintaks Python. Namun, MicroPython adalah versi ramping dari Python desktop; matplotlib, pandas, dan OpenCV tidak berjalan di Pico. Jadi kalau kamu ingin mencatat data, menggambar grafik, atau mengolahnya dengan AI, Pico pun tetap kamu hubungkan ke Python di komputermu. Kode pyserial di artikel ini juga bekerja dengan Pico; kamu hanya perlu menyesuaikan nama port, rentang nilai, dan cara membaca balasan perintah, seperti dijelaskan di bawah.
| Fitur | Arduino + Python di PC | Pico + MicroPython (mandiri) | Pico + Python di PC |
|---|---|---|---|
| Di mana Python berjalan? | Hanya di komputer; board menjalankan C++ | Di dalam Pico | Di kedua sisi: MicroPython di Pico, Python di komputer |
| Perlu komputer? | Ya, data diolah di komputer | Tidak, berjalan dari daya USB atau baterai | Ya |
| Library yang tersedia | pyserial, matplotlib, pandas, numpy, OpenCV (library Python desktop) | Modul terbatas seperti machine dan time | Semua library di komputer |
| Baud rate | Penting, harus sama di kedua sisi | Tidak memakai port serial | Tidak berpengaruh, data mengalir dengan kecepatan USB |
| Reset ketika port dibuka | Ya di Uno, Nano, dan Mega | Tidak ada | Tidak |
| Kapan dipilih | Kamu sudah punya Arduino dan butuh library siap pakai | Perangkat mandiri yang sederhana | Kamu ingin satu bahasa (Python) di kedua sisi |
Kode MicroPython di bawah adalah versi Pico dari contoh Arduino di atas: kode ini membaca potensiometer di GP26 setiap 200 ms, mengirim hasilnya dengan format waktu,nilai yang sama, dan menerima perintah LED yang sama. Di sini, padanan Serial di Arduino adalah print() dan sys.stdin; berkat select.poll(), loop pengukuran tetap berjalan selama menunggu perintah.
1# Pico'ya main.py adıyla kaydet / save it on the Pico as main.py
2import sys
3import select
4import time
5from machine import ADC, Pin
6
7led = Pin("LED", Pin.OUT) # Pico ve Pico W dahili LED / onboard LED on Pico and Pico W
8pot = ADC(26) # GP26 = ADC0, potansiyometre orta ucu / potentiometer wiper
9okuyucu = select.poll()
10okuyucu.register(sys.stdin, select.POLLIN) # USB'den veri gelince haber ver / notify when USB data arrives
11
12son = time.ticks_ms()
13while True:
14 if okuyucu.poll(0): # bekleyen komut var mı? / is a command waiting?
15 komut = sys.stdin.readline().strip()
16 if komut == "LED ON":
17 led.on()
18 print("OK LED ON")
19 elif komut == "LED OFF":
20 led.off()
21 print("OK LED OFF")
22 if time.ticks_diff(time.ticks_ms(), son) >= 200: # 200 ms'de bir ölçüm / one reading every 200 ms
23 son = time.ticks_ms()
24 print("{},{}".format(son, pot.read_u16())) # zaman,değer (0-65535) / time,value (0-65535)Simpan kodenya ke Pico sebagai main.py dengan Thonny, lalu tutup Thonny, cabut kabel USB Pico, dan colokkan lagi: Thonny memakai port serial Pico sendiri, jadi selama Thonny terhubung skrip Python-mu tidak bisa membuka port, dan Thonny juga menghentikan program yang sedang berjalan ketika terhubung; setelah board menyala ulang, main.py berjalan otomatis. Baud rate tidak berpengaruh di port USB Pico; berapa pun nilai yang kamu tulis di Python, data mengalir dengan kecepatan USB. read_u16() mengembalikan nilai dari 0 sampai 65535, jadi hitung tegangannya dengan deger * 3.3 / 65535. Karena Pico mengirim baris pengukuran tanpa henti, readline() di skrip perintah di atas bisa mengembalikan baris pengukuran, bukan balasan; dengan Pico, teruslah membaca sampai kamu mendapat baris yang diawali OK. Contoh ini tidak punya baris HAZIR maupun perintah PWM dan READ; tambahkan ke kode Pico kalau kamu membutuhkannya. Hati-hati kalau kamu mengirim data biner dari komputer: byte 0x03 berarti Ctrl+C di MicroPython dan menghentikan programmu; kamu bisa menonaktifkannya dengan micropython.kbd_intr(-1). Kalau kamu baru mengenal Pico, Apa Itu Raspberry Pi Pico? dan dasar-dasar MicroPython adalah awal yang bagus.
Ide proyek dengan Arduino dan Python
- Pencatat suhu dan kelembapan: tulis hasil pembacaan DHT11 ke CSV sekali per menit, lalu buat grafik iklim kamarmu selama seminggu di Excel atau dengan pandas.
- Kendali lampu dari komputer: kendalikan modul relay dengan perintah ON dan OFF yang dikirim dari Python, lalu gabungkan dengan timer atau perintah suara.
- Grafik jarak langsung: gambar grafik jarak yang diukur HC-SR04 dengan matplotlib. Kalau sensornya kamu putar dengan servo, cara yang sama bisa dipakai untuk menggambar layar radar.
- Layar status PC: biarkan Python membaca penggunaan CPU dan memori dengan library psutil lalu mengirimnya ke Arduino, yang menampilkannya di layar OLED.
- Kamera pelacak wajah: OpenCV menemukan posisi wajah di gambar, Python mengubahnya menjadi sudut lalu mengirimkannya, dan Arduino memutar kamera dengan motor servo.
- Keyboard shortcut buatanmu sendiri: biarkan tombol di Arduino mengirim satu baris ketika ditekan, lalu Python membacanya dan membuka program atau menjalankan shortcut di komputer.
Kesalahan umum dan cara mengatasinya
| Error atau gejala | Penyebab | Solusi |
|---|---|---|
| “ModuleNotFoundError: No module named 'serial'” | pyserial tidak terinstal untuk interpreter Python yang menjalankan skrip; VS Code atau Thonny mungkin memakai Python yang berbeda | Jalankan python -m pip install pyserial dengan interpreter yang sama dan pilih interpreter yang benar di editormu |
| “AttributeError: module 'serial' has no attribute 'Serial'” | Paket serial yang salah terinstal atau file-mu bernama serial.py | pip uninstall serial lalu pip install pyserial; ganti nama file-mu |
| “could not open port 'COM3': PermissionError(13, 'Access is denied.', None, 5)” | Port sedang terbuka di program lain: Serial Monitor, Serial Plotter, atau skrip kedua | Tutup program lain itu; pakai konstruksi with di skripmu |
| “could not open port 'COM5': FileNotFoundError(2, 'The system cannot find the file specified.', None, 2)” | Nama port salah atau board tidak terpasang | Cari nama yang benar dengan python -m serial.tools.list_ports -v |
| “[Errno 13] Permission denied: '/dev/ttyACM0'” | User Linux-mu tidak punya izin mengakses port serial | sudo usermod -a -G dialout $USER, lalu logout dan login lagi |
| Karakter acak atau UnicodeDecodeError | Baud rate berbeda, atau noise ketika startup | Pakai kecepatan yang sama di kedua sisi; tambahkan decode(errors="ignore") dan reset_input_buffer() |
| readline() selalu mengembalikan b'' | Arduino tidak mengirim akhir baris (print, bukan println), port salah, atau board masih booting | Pakai println, cek port dan kecepatannya, perbesar timeout |
| “ValueError: invalid literal for int() with base 10” | Baris yang terpotong, kosong, atau tidak terduga diubah menjadi angka | Bungkus konversinya dengan try/except dan cek jumlah kolom |
| Perintah pertama diabaikan | Uno reset ketika port dibuka dan perintahnya masuk ke bootloader | Tunggu baris HAZIR atau tunggu 2 detik setelah membuka port |
| Grafik tertinggal dari waktu nyata | Hanya satu baris yang dibaca per frame, jadi data menumpuk di buffer | Baca semua baris dengan loop in_waiting dan kirim lebih jarang |
| Kode tidak bisa di-upload selama skrip berjalan | Python sedang memegang port | Hentikan skrip dengan Ctrl+C, lalu upload |
Membuat Arduino dan Python berbicara lewat port serial adalah cara tercepat untuk mengubah proyek sensor sederhana menjadi sistem yang mencatat data, menggambar grafik, dan bisa dikendalikan dari komputermu. Mulailah dengan membaca satu nilai dan mencetaknya, lalu simpan ke CSV, dan tambahkan perintah serta grafik paling akhir; di setiap langkah, pastikan baud rate dan akhir baris cocok di kedua sisi. Di aplikasi BlueGrays kamu akan menemukan proyek langkah demi langkah lengkap dengan skema rangkaian dan kode untuk mengukur cahaya dengan LDR, suhu dan kelembapan dengan DHT11, jarak dengan HC-SR04, serta komunikasi serial antara dua Arduino, jadi kamu bisa cepat membangun sumber data yang akan kamu baca dengan Python.
Pertanyaan umum
Apakah Arduino bisa diprogram dengan Python?
Python tidak berjalan di dalam Arduino Uno, Nano, atau Mega; board ini diprogram dengan bahasa Arduino berbasis C++ di Arduino IDE. Python berjalan di komputer dan berbicara dengan board lewat port serial menggunakan pyserial; kamu juga bisa meng-upload contoh StandardFirmata dan mengendalikan pin langsung dari Python dengan library seperti pyFirmata2. Kalau kamu ingin Python berjalan di board itu sendiri, pilih Raspberry Pi Pico atau ESP32, yang mendukung MicroPython.
Bagaimana cara menginstal pyserial?
Jalankan python -m pip install pyserial di terminal dan tulis import serial di kodemu. Nama paketnya pyserial, tetapi modul yang kamu impor bernama serial; pip install serial menginstal paket yang sama sekali berbeda dan berujung pada AttributeError. Di Linux, kamu juga perlu menambahkan user-mu ke grup dialout.
Bagaimana cara mengetahui Arduino-ku ada di port COM mana?
Lihat Tools > Port di Arduino IDE atau jalankan python -m serial.tools.list_ports -v di terminal. Di Windows, bagian Ports (COM & LPT) di Device Manager juga menampilkan port-nya. Kalau ragu, cabut board-nya lalu tampilkan daftar port lagi; port yang hilang adalah milik Arduino.
Bagaimana cara mengirim data dari Python ke Arduino?
Buka port dengan serial.Serial dan kirim byte seperti ser.write(b"LED ON\n"); jangan lupa mengubah teks dengan encode() dan menambahkan akhir baris. Di sisi Arduino, cek data yang masuk dengan Serial.available() dan baca barisnya dengan Serial.readStringUntil('\n'). Karena Uno reset ketika port dibuka, tunggu sekitar 2 detik sebelum mengirim perintah pertama.
Bisakah Serial Monitor Arduino dan Python dipakai bersamaan?
Tidak, sebuah port serial hanya bisa dibuka oleh satu program dalam satu waktu; program kedua akan mendapat error Access is denied atau Resource busy. Kamu bisa mengolah data yang masuk di Python sekaligus mencetaknya ke layar. Kalau kamu butuh dua kanal terpisah, hubungkan konverter USB-TTL kedua ke Arduino dan buat port serial kedua dengan SoftwareSerial.
Kenapa Arduino-ku reset ketika Python membuka port?
Di Uno, Nano, dan Mega, jalur DTR chip USB terhubung ke pin RESET melalui kapasitor, sehingga board memulai ulang setiap kali port dibuka; rangkaian ini dibutuhkan supaya IDE bisa meng-upload kode. Tunggu 2 detik setelah membuka port, atau tunggu baris dari Arduino yang memberi tahu bahwa ia sudah siap. Untuk mencegah reset sepenuhnya, kamu bisa memasang kapasitor 10 µF di antara RESET dan GND, tetapi kapasitor itu harus dilepas sebelum meng-upload.
Proyek untuk dibuat setelah membaca ini
Lihat semua proyek
Mengukur Intensitas Cahaya dengan LDR
Ingin melihat seberapa terang kamarmu dalam bentuk angka? LDR, komponen kecil yang bereaksi terhadap cahaya, mengukur cahaya di sekitarnya, dan Arduino menulis nilainya ke layar komputermu setiap sete

Pengukuran Jarak HC-SR04 (Tampilan Serial)
Sensor HC-SR04 bekerja persis seperti kelelawar yang mencari jalan dalam gelap: ia mengirim suara yang tidak bisa kamu dengar, mendengarkan pantulannya, dan mengukur seberapa jauh benda di depannya. A

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

Membaca Intensitas Cahaya dengan Modul LDR ESP32
Memantau secara real-time di Serial Monitor nilai ADC mentah modul LDR dan persentase cahaya relatif yang dihitung dari nilai acuan gelap dan terang. Persentase ini bukan pengukuran lux. Mengajarkan logika kalibrasi modul. Ideal dikerjakan sebelum Proyek 10, karena dipakai untuk menentukan nilai ambang.

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

Komunikasi Dua Arah Antara 2 Arduino
Dua Arduino disambung dengan kabel dan saling berbicara: tekan tombol di satu board dan lampu di board lain menyala, tekan lagi dan lampunya mati. Kedua board menjalankan program yang sama, jadi masin

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

Pencatat Data Suhu ESP32 (DHT22 + RTC DS1307 + microSD + OLED)
Buat pencatat suhu bercap waktu dengan ESP32! Baca suhu/kelembapan DHT22 setiap menit, ambil waktu sebenarnya dari RTC DS1307, dan catat ke kartu microSD sebagai CSV. OLED menampilkan suhu langsung (font besar), kelembapan, cap waktu, dan penghitung catatan. File /temp_log.csv bisa dibuka di Excel, Google Sheets, atau Python pandas; cocok untuk rumah kaca, suhu kamar, data laboratorium, penyimpanan makanan, atau sarang lebah.
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

