🤖 DESKTOP PET - ROBOT MEJA INTERAKTIF
dengan NodeMCU ESP8266 & OLED (2 Karakter)
📑 DAFTAR ISI
🎯 Apa Itu Desktop Pet?
Desktop Pet adalah robot mini interaktif yang diletakkan di meja kerja, dengan wajah ekspresif di layar OLED yang bisa berkedip, melihat ke sekeliling, bahkan bereaksi saat disentuh. Proyek ini seperti "Tamagotchi" versi modern yang berwujud robot kecil imut di meja Anda!
✅ Biaya sangat murah (Rp 100.000 - 150.000)
✅ Hanya butuh 2 komponen utama (NodeMCU + OLED)
✅ Tidak perlu koneksi internet (100% offline)
✅ Bisa dikembangkan dengan berbagai sensor
✅ Cocok untuk belajar pemrograman ESP8266 dan grafis OLED
📊 10 Manfaat Memiliki Desktop Pet
Berikut adalah alasan mengapa Anda perlu membuat Desktop Pet sendiri:
| No | Manfaat | Keterangan |
|---|---|---|
| 1 | Menghilangkan stres | Hewan peliharaan digital yang lucu di meja kerja |
| 2 | Meningkatkan fokus | Gerakan mata yang lucu membuat suasana lebih rileks |
| 3 | Media belajar IoT | Proyek sempurna untuk memahami ESP8266 dan OLED |
| 4 | Hadiah unik | Bisa dijadikan kado untuk teman yang suka elektronika |
| 5 | Interaktif | Bisa bereaksi saat disentuh (dengan touch sensor) |
| 6 | Kustomisasi tinggi | Bisa mengganti karakter sesuai keinginan |
| 7 | Portofolio proyek | Menambah nilai portfolio IoT Anda |
| 8 | Murah | Hanya dengan komponen bekas pun bisa |
| 9 | Edukasi anak | Mengenalkan elektronika dan coding pada anak |
| 10 | Bisa dikembangkan | Tambahkan suara, LED, atau sensor lain |
🛠 Alat & Bahan yang Diperlukan
Karena Anda sudah memiliki pengalaman dengan NodeMCU dari proyek sebelumnya, Anda hanya perlu:
| Komponen | Spesifikasi | Fungsi | Estimasi Harga |
|---|---|---|---|
| NodeMCU ESP8266 | ESP-12E, CH340/CP2102 | Otak alat + koneksi | Rp 60.000 - 85.000 |
| Layar OLED 0.96" | 128x64, I2C, SSD1306 | Menampilkan wajah karakter | Rp 40.000 - 65.000 |
| Kabel Jumper F-F | 4 buah | Koneksi | Rp 5.000 - 10.000 |
| Touch Sensor (opsional) | TP223 Capacitive | Deteksi sentuhan | Rp 10.000 - 20.000 |
| Kabel Micro USB | Support data | Power & upload | Rp 15.000 - 30.000 |
Total biaya minimal: Rp 105.000 - 160.000 (jika sudah punya kabel USB)
🔌 Skema Koneksi (Wiring)
Koneksi sangat sederhana karena OLED menggunakan protokol I2C:
| Layar OLED | NodeMCU ESP8266 | GPIO | Keterangan |
|---|---|---|---|
| VCC | 3.3V | - | Tegangan 3.3V (JANGAN 5V!) |
| GND | GND | - | Ground |
| SCL | D1 | GPIO5 | Clock I2C |
| SDA | D2 | GPIO4 | Data I2C |
🤖 KARAKTER 1: Robot Mo-chan
Mo-chan adalah karakter robot bergaya anime dengan mata bulat besar, pupil hitam dengan sorotan putih (efek berbinar), dan ekspresi yang sangat imut. Karakter ini terinspirasi dari maskot-maskot anime Jepang yang lucu dan menggemaskan.
✨ Fitur Khusus Mo-chan
📝 Kode Program Mo-chan
/*
PROJECT: Desktop Pet - Robot Mo-chan Edition
BOARD: NodeMCU ESP8266
DISPLAY: OLED 128x64 SSD1306
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ========== KONFIGURASI ==========
#define TOUCH_PIN D3
bool useTouchSensor = false;
// ========== VARIABEL ==========
unsigned long lastBlink = 0;
unsigned long lastEyeMove = 0;
unsigned long lastExpressionChange = 0;
unsigned long lastIdleAnimation = 0;
bool eyesOpen = true;
int eyeDirection = 0; // 0:center, 1:kiri, 2:kanan, 3:atas, 4:bawah
int expression = 0; // 0:normal, 1:happy, 2:surprised, 3:sleep, 4:wink, 5:angry
bool isBlinking = false;
int blinkStep = 0;
bool isPetting = false;
unsigned long pettingEndTime = 0;
// ========== GAMBAR KOTAK BINGKAI ==========
void drawBoxFrame(int x, int y, int w, int h) {
display.drawRoundRect(x, y, w, h, 5, SSD1306_WHITE);
display.drawRect(x + 1, y + 1, w - 2, h - 2, SSD1306_WHITE);
}
// ========== GAMBAR MATA MO-CHAN ==========
void drawMoChanEyes() {
int leftEyeX = 44, rightEyeX = 84, eyeY = 32;
int pupilOffsetX = 0, pupilOffsetY = 0;
switch(eyeDirection) {
case 1: pupilOffsetX = -5; break;
case 2: pupilOffsetX = 5; break;
case 3: pupilOffsetY = -4; break;
case 4: pupilOffsetY = 4; break;
}
// Kotak bingkai
drawBoxFrame(leftEyeX - 15, eyeY - 12, 30, 24);
drawBoxFrame(rightEyeX - 15, eyeY - 12, 30, 24);
if(expression == 3) {
// Tidur
display.drawLine(leftEyeX - 10, eyeY, leftEyeX + 10, eyeY, SSD1306_WHITE);
display.drawLine(rightEyeX - 10, eyeY, rightEyeX + 10, eyeY, SSD1306_WHITE);
display.setCursor(leftEyeX - 18, eyeY - 8); display.print("z");
display.setCursor(leftEyeX - 14, eyeY - 12); display.print("Z");
}
else if(expression == 1) {
// Bahagia ^^
display.drawLine(leftEyeX - 8, eyeY - 2, leftEyeX - 3, eyeY - 6, SSD1306_WHITE);
display.drawLine(leftEyeX - 3, eyeY - 6, leftEyeX + 3, eyeY - 6, SSD1306_WHITE);
display.drawLine(leftEyeX + 3, eyeY - 6, leftEyeX + 8, eyeY - 2, SSD1306_WHITE);
display.drawLine(rightEyeX - 8, eyeY - 2, rightEyeX - 3, eyeY - 6, SSD1306_WHITE);
display.drawLine(rightEyeX - 3, eyeY - 6, rightEyeX + 3, eyeY - 6, SSD1306_WHITE);
display.drawLine(rightEyeX + 3, eyeY - 6, rightEyeX + 8, eyeY - 2, SSD1306_WHITE);
}
else if(expression == 2) {
// Terkejut O.O
display.fillCircle(leftEyeX, eyeY, 10, SSD1306_WHITE);
display.fillCircle(rightEyeX, eyeY, 10, SSD1306_WHITE);
display.fillCircle(leftEyeX + pupilOffsetX, eyeY + pupilOffsetY, 4, SSD1306_BLACK);
display.fillCircle(rightEyeX + pupilOffsetX, eyeY + pupilOffsetY, 4, SSD1306_BLACK);
}
else if(expression == 4) {
// Wink
display.fillCircle(leftEyeX, eyeY, 9, SSD1306_WHITE);
display.fillCircle(leftEyeX + pupilOffsetX, eyeY + pupilOffsetY, 5, SSD1306_BLACK);
display.drawLine(rightEyeX - 8, eyeY, rightEyeX + 8, eyeY, SSD1306_WHITE);
}
else if(isBlinking) {
// Kedip
display.drawLine(leftEyeX - 10, eyeY, leftEyeX + 10, eyeY, SSD1306_WHITE);
display.drawLine(rightEyeX - 10, eyeY, rightEyeX + 10, eyeY, SSD1306_WHITE);
}
else {
// Normal
display.fillCircle(leftEyeX, eyeY, 9, SSD1306_WHITE);
display.fillCircle(rightEyeX, eyeY, 9, SSD1306_WHITE);
display.fillCircle(leftEyeX + pupilOffsetX, eyeY + pupilOffsetY, 5, SSD1306_BLACK);
display.fillCircle(rightEyeX + pupilOffsetX, eyeY + pupilOffsetY, 5, SSD1306_BLACK);
display.fillCircle(leftEyeX + pupilOffsetX - 2, eyeY + pupilOffsetY - 2, 2, SSD1306_WHITE);
display.fillCircle(rightEyeX + pupilOffsetX - 2, eyeY + pupilOffsetY - 2, 2, SSD1306_WHITE);
}
}
// ========== GAMBAR WAJAH MO-CHAN ==========
void drawMoChanFace() {
// Kepala bulat
display.drawCircle(64, 32, 26, SSD1306_WHITE);
// Antena
display.fillRect(62, 4, 4, 8, SSD1306_WHITE);
display.fillCircle(64, 2, 4, SSD1306_WHITE);
// Hidung
display.fillTriangle(62, 44, 66, 44, 64, 48, SSD1306_WHITE);
// Mulut
if(expression != 2) {
display.drawLine(56, 52, 60, 54, SSD1306_WHITE);
display.drawLine(60, 54, 68, 54, SSD1306_WHITE);
display.drawLine(68, 54, 72, 52, SSD1306_WHITE);
}
// Pipi
display.fillCircle(42, 42, 3, SSD1306_WHITE);
display.fillCircle(86, 42, 3, SSD1306_WHITE);
}
// ========== SPLASH SCREEN ==========
void showSplash() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(15, 20);
display.println("Mo-chan");
display.setTextSize(1);
display.setCursor(20, 45);
display.println("Desktop Pet");
display.display();
delay(2000);
}
// ========== SETUP & LOOP ==========
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
for(;;);
}
display.clearDisplay();
showSplash();
if(useTouchSensor) pinMode(TOUCH_PIN, INPUT);
}
void loop() {
unsigned long now = millis();
// Kedip setiap 3 detik
if(!isBlinking && (now - lastBlink > 3000)) {
isBlinking = true;
lastBlink = now;
}
if(isBlinking && (now - lastBlink > 150)) {
isBlinking = false;
}
// Gerakan mata setiap 4 detik
if(now - lastEyeMove > 4000) {
eyeDirection = (eyeDirection + 1) % 5;
lastEyeMove = now;
}
display.clearDisplay();
drawMoChanFace();
drawMoChanEyes();
display.display();
delay(30);
}
⚡ KARAKTER 2: Pikachu (Pokemon)
Pikachu adalah karakter Pokemon paling ikonik di dunia! Dengan telinga panjang runcing berujung hitam, pipi merah yang bisa bersinar seperti listrik, dan ekor petir yang khas, Pikachu akan menjadi teman meja yang sempurna untuk para penggemar Pokemon.
✨ Fitur Khusus Pikachu
📝 Kode Program Pikachu
/*
PROJECT: Desktop Pet - Pikachu Edition
BOARD: NodeMCU ESP8266
DISPLAY: OLED 128x64 SSD1306
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ========== VARIABEL ==========
unsigned long lastBlink = 0;
unsigned long lastEyeMove = 0;
unsigned long lastCheekGlow = 0;
bool eyesOpen = true;
int eyeDirection = 0;
int expression = 0;
bool isBlinking = false;
bool cheeksGlowing = false;
// ========== GAMBAR TELINGA PIKACHU ==========
void drawPikachuEars() {
// Telinga kiri
int earLeftX[] = {28, 20, 28};
int earLeftY[] = {20, 5, 8};
display.fillTriangle(earLeftX[0], earLeftY[0], earLeftX[1], earLeftY[1], earLeftX[2], earLeftY[2], SSD1306_WHITE);
// Ujung hitam
int earLeftTipX[] = {24, 20, 28};
int earLeftTipY[] = {12, 5, 8};
display.fillTriangle(earLeftTipX[0], earLeftTipY[0], earLeftTipX[1], earLeftTipY[1], earLeftTipX[2], earLeftTipY[2], SSD1306_BLACK);
// Telinga kanan
int earRightX[] = {100, 108, 100};
int earRightY[] = {20, 5, 8};
display.fillTriangle(earRightX[0], earRightY[0], earRightX[1], earRightY[1], earRightX[2], earRightY[2], SSD1306_WHITE);
// Ujung hitam
int earRightTipX[] = {104, 108, 100};
int earRightTipY[] = {12, 5, 8};
display.fillTriangle(earRightTipX[0], earRightTipY[0], earRightTipX[1], earRightTipY[1], earRightTipX[2], earRightTipY[2], SSD1306_BLACK);
}
// ========== GAMBAR WAJAH PIKACHU ==========
void drawPikachuFace() {
// Kepala
display.fillCircle(64, 34, 26, SSD1306_WHITE);
display.drawCircle(64, 34, 26, SSD1306_WHITE);
// Pipi merah
if(cheeksGlowing || expression == 1) {
display.fillCircle(44, 42, 6, SSD1306_WHITE);
display.fillCircle(84, 42, 6, SSD1306_WHITE);
} else {
display.fillCircle(44, 42, 5, SSD1306_WHITE);
display.fillCircle(84, 42, 5, SSD1306_WHITE);
}
// Hidung
display.fillCircle(64, 44, 2, SSD1306_BLACK);
// Mulut
if(expression == 2) {
display.drawCircle(64, 54, 5, SSD1306_WHITE);
display.fillCircle(64, 54, 2, SSD1306_BLACK);
} else {
display.drawLine(56, 52, 60, 56, SSD1306_WHITE);
display.drawLine(60, 56, 68, 56, SSD1306_WHITE);
display.drawLine(68, 56, 72, 52, SSD1306_WHITE);
}
// Alis
if(expression == 5) {
display.drawLine(48, 26, 56, 30, SSD1306_WHITE);
display.drawLine(72, 30, 80, 26, SSD1306_WHITE);
} else {
display.drawLine(48, 26, 56, 26, SSD1306_WHITE);
display.drawLine(72, 26, 80, 26, SSD1306_WHITE);
}
}
// ========== GAMBAR MATA PIKACHU ==========
void drawPikachuEyes() {
int leftEyeX = 52, rightEyeX = 76, eyeY = 34;
int pupilOffsetX = 0, pupilOffsetY = 0;
switch(eyeDirection) {
case 1: pupilOffsetX = -4; break;
case 2: pupilOffsetX = 4; break;
case 3: pupilOffsetY = -3; break;
case 4: pupilOffsetY = 3; break;
}
if(expression == 3) {
display.drawLine(leftEyeX - 6, eyeY, leftEyeX + 6, eyeY, SSD1306_WHITE);
display.drawLine(rightEyeX - 6, eyeY, rightEyeX + 6, eyeY, SSD1306_WHITE);
}
else if(expression == 1) {
display.drawLine(leftEyeX - 5, eyeY - 1, leftEyeX - 2, eyeY - 4, SSD1306_WHITE);
display.drawLine(leftEyeX - 2, eyeY - 4, leftEyeX + 2, eyeY - 4, SSD1306_WHITE);
display.drawLine(leftEyeX + 2, eyeY - 4, leftEyeX + 5, eyeY - 1, SSD1306_WHITE);
display.drawLine(rightEyeX - 5, eyeY - 1, rightEyeX - 2, eyeY - 4, SSD1306_WHITE);
display.drawLine(rightEyeX - 2, eyeY - 4, rightEyeX + 2, eyeY - 4, SSD1306_WHITE);
display.drawLine(rightEyeX + 2, eyeY - 4, rightEyeX + 5, eyeY - 1, SSD1306_WHITE);
}
else if(isBlinking) {
display.drawLine(leftEyeX - 6, eyeY, leftEyeX + 6, eyeY, SSD1306_WHITE);
display.drawLine(rightEyeX - 6, eyeY, rightEyeX + 6, eyeY, SSD1306_WHITE);
}
else {
display.fillCircle(leftEyeX, eyeY, 6, SSD1306_WHITE);
display.fillCircle(rightEyeX, eyeY, 6, SSD1306_WHITE);
display.fillCircle(leftEyeX + pupilOffsetX, eyeY + pupilOffsetY, 3, SSD1306_BLACK);
display.fillCircle(rightEyeX + pupilOffsetX, eyeY + pupilOffsetY, 3, SSD1306_BLACK);
display.fillCircle(leftEyeX + pupilOffsetX - 1, eyeY + pupilOffsetY - 1, 1, SSD1306_WHITE);
display.fillCircle(rightEyeX + pupilOffsetX - 1, eyeY + pupilOffsetY - 1, 1, SSD1306_WHITE);
}
}
// ========== GAMBAR EKOR PIKACHU ==========
void drawPikachuTail() {
int tailX[] = {105, 112, 108, 115, 110};
int tailY[] = {52, 48, 44, 40, 36};
for(int i = 0; i < 4; i++) {
display.drawLine(tailX[i], tailY[i], tailX[i+1], tailY[i+1], SSD1306_WHITE);
}
}
// ========== SETUP & LOOP ==========
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
for(;;);
}
display.clearDisplay();
display.setTextSize(2);
display.setCursor(10, 20);
display.println("Pika!");
display.display();
delay(2000);
}
void loop() {
unsigned long now = millis();
if(!isBlinking && (now - lastBlink > 3500)) {
isBlinking = true;
lastBlink = now;
}
if(isBlinking && (now - lastBlink > 150)) {
isBlinking = false;
}
if(now - lastEyeMove > 4500) {
eyeDirection = (eyeDirection + 1) % 5;
lastEyeMove = now;
}
if(now - lastCheekGlow > 8000) {
cheeksGlowing = true;
lastCheekGlow = now;
delay(300);
cheeksGlowing = false;
}
display.clearDisplay();
drawPikachuEars();
drawPikachuFace();
drawPikachuEyes();
drawPikachuTail();
display.display();
delay(30);
}
📊 Perbandingan Kedua Karakter
| Aspek | Mo-chan (Robot) | Pikachu (Pokemon) |
|---|---|---|
| Gaya | Robot anime imut | Pokemon ikonik |
| Ciri Khas | Kotak bingkai mata, sorotan ganda | Telinga panjang, pipi merah, ekor petir |
| Ekspresi | Normal, bahagia, terkejut, tidur, wink, marah | Normal, bahagia, terkejut, tidur, marah |
| Fitur Unik | Efek sorotan mata berbinar | Efek listrik di pipi |
| Kesulitan Kode | ⭐️⭐️⭐️ Menengah | ⭐️⭐️⭐️⭐️ Agak kompleks |
🐛 Troubleshooting (8 Masalah Umum)
| No | Masalah | Solusi |
|---|---|---|
| 1 | OLED tidak menyala | Cek VCC ke 3.3V (BUKAN 5V!). Coba ganti alamat I2C ke 0x3D |
| 2 | Error "Adafruit_SSD1306.h" | Install library Adafruit SSD1306 dan Adafruit GFX via Library Manager |
| 3 | Gagal upload ke NodeMCU | Tekan tombol FLASH saat proses "Connecting..." |
| 4 | Port COM tidak terdeteksi | Instal driver CH340/CP2102, coba ganti kabel USB |
| 5 | Tampilan rusak/berkedip | Kurangi delay di loop, atau periksa power supply |
| 6 | Touch sensor tidak bekerja | Pastikan useTouchSensor = true, cek koneksi SIG ke D3 |
| 7 | Ekspresi tidak berganti | Periksa variabel expression dan timer di loop |
| 8 | NodeMCU panas | Jangan sambungkan VCC OLED ke 5V, periksa korsleting |
🚀 10 Ide Pengembangan Lebih Lanjut
Setelah berhasil membuat Desktop Pet, Anda bisa mengembangkannya menjadi lebih canggih:
- ➕ Touch Sensor Interaktif - Tambahkan sensor sentuhan TP223, Desktop Pet akan bereaksi saat dielus (ekspresi bahagia)
- 🔊 Buzzer / Suara - Tambahkan buzzer untuk mengeluarkan suara "Pika pika!" atau "Beep" saat ekspresi berganti
- 💡 LED RGB - Tambahkan LED WS2812 di sekitar mata untuk efek cahaya warna-warni
- 🎤 Sensor Suara (MIC) - Desktop Pet bereaksi terhadap tepuk tangan atau suara keras
- 🌡️ Sensor Suhu & Kelembaban - Tampilkan suhu ruangan di bagian bawah layar
- 🔋 Monitor Baterai - Tampilkan level baterai jika menggunakan power bank portabel
- 📱 Bluetooth Control - Gunakan HC-05 untuk mengubah ekspresi dari smartphone
- 🌙 Mode Malam Otomatis - Gunakan LDR untuk mendeteksi gelap, ubah ekspresi jadi tidur
- 🕒 Jam Digital - Tambahkan fitur jam di pojok layar menggunakan NTP (perlu WiFi)
- 🖨️ Casing 3D Print - Buat badan robot dengan printer 3D, desain karakter yang berdiri
❓ FAQ (Pertanyaan yang Sering Diajukan)
| Pertanyaan | Jawaban |
|---|---|
| Apakah perlu koneksi internet? | Tidak perlu! Desktop Pet berjalan 100% offline. WiFi hanya untuk pengembangan NTP clock. |
| Bisa pakai Arduino Uno? | Bisa, tapi perlu pin A4 (SDA) dan A5 (SCL) untuk I2C, serta adaptasi kode. |
| Berapa lama baterai bertahan? | Dengan power bank 10.000mAh, bisa 12-24 jam non-stop. |
| Bisa menambah karakter lain? | Bisa! Modifikasi fungsi drawFace() dan drawEyes() sesuai karakter yang diinginkan. |
| Apakah bisa untuk pemula? | Proyek ini level Mahir, tapi dengan panduan lengkap ini, pemula yang tekun pasti bisa! |
📦 Kesimpulan
Selamat! Anda telah berhasil membuat Desktop Pet dengan dua pilihan karakter: Robot Mo-chan yang imut bergaya anime, dan Pikachu yang ikonik dari Pokemon. Proyek ini membuktikan bahwa dengan komponen sederhana (NodeMCU + OLED), Anda bisa menciptakan robot interaktif yang lucu dan menghibur.
☐ Menggambar grafis di OLED dengan Adafruit GFX
☐ Membuat animasi mata berkedip dan lirik
☐ Mengimplementasikan berbagai ekspresi karakter
☐ (Opsional) Interaksi dengan touch sensor
☐ Dasar-dasar pemrograman ESP8266 untuk animasi real-time
Proyek ini juga menjadi fondasi yang sempurna untuk pengembangan lebih lanjut. Jangan ragu untuk bereksperimen dengan karakter baru, menambahkan sensor, atau membuat casing 3D yang keren. Selamat berkarya dan semoga Desktop Pet Anda menemani setiap momen produktif di meja kerja!
Tidak ada komentar:
Posting Komentar