Jumat, 03 April 2026

Membuat News Ticker IoT dengan ESP8266 dan OLED Display

Membuat News Ticker IoT dengan ESP8266 dan OLED Display | Tutorial Lengkap

📰 Membuat News Ticker IoT dengan ESP8266 dan OLED Display

📋 Pendahuluan

Internet of Things (IoT) telah membuka peluang tak terbatas untuk menciptakan perangkat pintar yang dapat menampilkan informasi real-time. Salah satu proyek menarik yang bisa Anda buat adalah News Ticker - sebuah perangkat yang menampilkan berita bergulir secara otomatis menggunakan mikrokontroler ESP8266 dan layar OLED.

Artikel ini akan membahas secara lengkap bagaimana membuat News Ticker yang menampilkan berita terkini dalam bahasa Indonesia. Proyek ini cocok untuk pemula hingga menengah yang ingin belajar tentang konektivitas WiFi, tampilan grafis, dan pengambilan data dari internet.

✅ Keunggulan Proyek Ini:
• Menampilkan 20+ berita terbaru bahasa Indonesia
• Efek scrolling (berjalan) seperti running text
• Mode online dan offline otomatis
• Update berita setiap 10 menit
• Hemat memori dan daya

🛠️ Komponen yang Dibutuhkan

KomponenSpesifikasiFungsi
NodeMCU ESP8266ESP-12E ModuleOtak dari sistem, mengontrol semua fungsi
OLED Display128x64 SSD1306Menampilkan berita dan antarmuka
Kabel JumperFemale to FemaleMenghubungkan komponen
Power SupplyUSB 5V / Micro USBSumber daya

🔌 Skema Rangkaian

Berikut adalah koneksi antara NodeMCU ESP8266 dengan OLED Display SSD1306 (I2C):

NodeMCU ESP8266OLED SSD1306
3.3VVCC
GNDGND
D1 (GPIO5)SCL
D2 (GPIO4)SDA
⚠️ Catatan Penting: Pastikan koneksi I2C benar karena OLED menggunakan protokol I2C untuk komunikasi data. Periksa kembali koneksi sebelum menyalakan perangkat.

📦 Instalasi Library yang Diperlukan

Sebelum meng-upload kode, Anda perlu menginstal library berikut melalui Arduino IDE:

Cara Instalasi:

1. Buka Arduino IDE → Sketch → Include Library → Manage Libraries
2. Cari dan instal satu per satu:

- Adafruit GFX Library by Adafruit
- Adafruit SSD1306 by Adafruit  
- ArduinoJson by Benoit Blanchon
- ESP8266WiFi by ESP8266 Community
- ESP8266HTTPClient by ESP8266 Community

💻 Kode Program Lengkap

Berikut adalah kode lengkap untuk proyek News Ticker. Copy dan paste ke Arduino IDE:

/*
    PROJECT: News Ticker (Berita Bergulir dari Internet)
    BOARD: NodeMCU ESP8266
    DISPLAY: OLED 128x64 SSD1306
    BAHASA: Indonesia
*/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>

// ========== KONFIGURASI ==========
#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);

// Ganti dengan SSID dan Password WiFi Anda
const char* ssid = "7G";
const char* password = "forget22";

// ========== DATA BERITA INDONESIA (LENGKAP) ==========
String newsTitles[20];
int totalNews = 0;
String currentNews = "";
int scrollPosition = SCREEN_WIDTH;
int newsIndex = 0;
unsigned long lastUpdate = 0;
unsigned long lastScroll = 0;
bool wifiConnected = false;

// ========== FUNGSI MEMUAT BERITA INDONESIA ==========
void loadIndonesianNews() {
    newsTitles[0] = "Presiden Jokowi Resmikan Ibu Kota Nusantara (IKN) di Kalimantan Timur";
    newsTitles[1] = "BMKG: Waspada Cuaca Ekstrem dan Hujan Lebat di Jabodetabek";
    newsTitles[2] = "Harga BBM Pertalite dan Biosolar Resmi Naik per 1 Oktober 2024";
    newsTitles[3] = "Timnas Indonesia Kalahkan Arab Saudi 2-1 di Kualifikasi Piala Dunia";
    newsTitles[4] = "GoTo Catat Laba Bersih Pertama Kali Sepanjang Berdirinya Perusahaan";
    newsTitles[5] = "Pemerintah Salurkan Bantuan Langsung Tunai El Nino Rp 400 Ribu";
    newsTitles[6] = "Apple Resmi Buka Apple Developer Center Pertama di Asia Tenggara";
    newsTitles[7] = "Kereta Cepat Jakarta-Bandung Whoosh Mulai Beroperasi Penuh";
    newsTitles[8] = "Polisi Tangkap 50 Tersangka Judi Online Internasional di Bali";
    newsTitles[9] = "Alfamart Buka 1000 Gerai Baru dan Lowongan 5000 Karyawan";
    newsTitles[10] = "Jalan Tol Trans Sumatera Tersambung dari Lampung hingga Palembang";
    newsTitles[11] = "KAI Tambah 20 Kereta Api Baru untuk Liburan Natal dan Tahun Baru";
    newsTitles[12] = "Prabowo Siapkan Program Makan Siang Gratis untuk Pelajar";
    newsTitles[13] = "BPJS Kesehatan Naik Kelas, Ini Penjelasan Pemerintah";
    newsTitles[14] = "Shopee dan Tokopedia Gelar Harbolnas 12.12 Diskon Besar";
    newsTitles[15] = "Jokowi Teken Aturan Baru Bikin Izin Usaha Makin Mudah";
    newsTitles[16] = "BRI Catat Laba Rp 30 Triliun Sepanjang Tahun 2023";
    newsTitles[17] = "Free Fire dan Mobile Legends Jadi E-Sports Asian Games";
    newsTitles[18] = "Pembangunan LRT Jabodebek Resmi Beroperasi Penuh";
    newsTitles[19] = "Pertamina Pastikan Stok BBM Aman Selama Libur Nataru";
    totalNews = 20;
    
    Serial.println("✓ Berita Indonesia dimuat (20 judul)");
}

// ========== CONNECT WIFI ==========
bool connectWiFi() {
    display.clearDisplay();
    display.setTextSize(1);
    display.setCursor(15, 25);
    display.println("Menghubungkan");
    display.setCursor(25, 38);
    display.println("ke WiFi...");
    display.display();
    
    WiFi.begin(ssid, password);
    int attempts = 0;
    
    while (WiFi.status() != WL_CONNECTED && attempts < 20) {
        delay(500);
        Serial.print(".");
        attempts++;
    }
    
    Serial.println();
    
    if (WiFi.status() == WL_CONNECTED) {
        Serial.println("✓ WiFi Terhubung!");
        Serial.print("  IP Address: ");
        Serial.println(WiFi.localIP());
        
        display.clearDisplay();
        display.setCursor(20, 25);
        display.println("WiFi OK!");
        display.setCursor(10, 38);
        display.print(WiFi.localIP());
        display.display();
        delay(1500);
        return true;
    } else {
        Serial.println("✗ WiFi Gagal Terhubung!");
        display.clearDisplay();
        display.setCursor(15, 25);
        display.println("WiFi Gagal!");
        display.setCursor(15, 38);
        display.println("Mode Offline");
        display.display();
        delay(1500);
        return false;
    }
}

// ========== COBA AMBIL BERITA ONLINE ==========
void tryFetchOnlineNews() {
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("Mode offline - menggunakan berita lokal");
        return;
    }
    
    Serial.println("Mencoba mengambil berita online...");
    
    WiFiClientSecure client;
    client.setInsecure();
    HTTPClient https;
    
    String rssUrl = "https://api.rss2json.com/v1/api.json?rss_url=https://rss.tempo.co/nasional";
    https.begin(client, rssUrl);
    https.setTimeout(5000);
    
    int httpCode = https.GET();
    if (httpCode == HTTP_CODE_OK) {
        String payload = https.getString();
        DynamicJsonDocument doc(4096);
        DeserializationError error = deserializeJson(doc, payload);
        
        if (!error && doc.containsKey("items")) {
            JsonArray items = doc["items"];
            int count = 0;
            
            for (JsonObject item : items) {
                if (count < 15) {
                    const char* title = item["title"];
                    if (title && strlen(title) > 10) {
                        String cleanTitle = String(title);
                        cleanTitle.replace(""", "\"");
                        cleanTitle.replace("'", "'");
                        cleanTitle.replace("&", "&");
                        newsTitles[count] = cleanTitle;
                        count++;
                    }
                }
            }
            
            if (count > 0) {
                totalNews = count;
                Serial.print("✓ Berhasil mengambil ");
                Serial.print(totalNews);
                Serial.println(" berita online dari Tempo");
                return;
            }
        }
    }
    https.end();
    
    Serial.println("Gagal mengambil berita online, pakai berita lokal");
}

// ========== TAMPILAN NEWS TICKER (SCROLLING) ==========
void displayNewsTicker() {
    int tickerY = 52;
    
    display.fillRect(0, tickerY - 2, SCREEN_WIDTH, 13, SSD1306_BLACK);
    display.drawRect(0, tickerY - 2, SCREEN_WIDTH, 13, SSD1306_WHITE);
    
    if (totalNews > 0 && currentNews.length() > 0) {
        int textWidth = currentNews.length() * 6;
        
        display.setTextSize(1);
        display.setTextColor(SSD1306_WHITE);
        display.setCursor(scrollPosition, tickerY);
        display.print(currentNews);
        
        if (scrollPosition <= -textWidth) {
            scrollPosition = SCREEN_WIDTH;
            newsIndex++;
            if (newsIndex >= totalNews) {
                newsIndex = 0;
            }
            currentNews = newsTitles[newsIndex];
        }
    } else {
        display.setCursor(10, tickerY);
        display.print("Memuat berita...");
    }
}

// ========== HEADER DISPLAY ==========
void displayHeader() {
    display.drawLine(0, 14, SCREEN_WIDTH, 14, SSD1306_WHITE);
    
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(2, 2);
    display.print("NEWS TICKER");
    
    display.setCursor(SCREEN_WIDTH - 42, 2);
    if (WiFi.status() == WL_CONNECTED) {
        display.print("ONLINE");
    } else {
        display.print("OFFLINE");
    }
    
    display.setCursor(2, 22);
    display.setTextSize(0.6);
    display.print("Update: ");
    unsigned long minutes = (millis() - lastUpdate) / 60000;
    display.print(minutes);
    display.print("m lalu");
    
    if (totalNews > 0) {
        display.setCursor(SCREEN_WIDTH - 55, 22);
        display.print("Berita ");
        display.print(newsIndex + 1);
        display.print("/");
        display.print(totalNews);
    }
}

// ========== HEADLINE UTAMA ==========
void displayHeadline() {
    if (totalNews > 0) {
        display.setTextSize(0.7);
        display.setTextColor(SSD1306_WHITE);
        
        String headline = newsTitles[0];
        int yPos = 28;
        int maxChars = 22;
        int len = headline.length();
        
        display.fillRect(0, 24, SCREEN_WIDTH, 28, SSD1306_BLACK);
        
        for (int i = 0; i < len && yPos < 52; i += maxChars) {
            int endIdx = i + maxChars;
            if (endIdx > len) {
                endIdx = len;
            }
            String line = headline.substring(i, endIdx);
            display.setCursor(2, yPos);
            display.print(line);
            yPos += 8;
        }
        
        display.setTextSize(0.5);
        display.setCursor(SCREEN_WIDTH - 42, 25);
        display.print("HEADLINE");
    } else {
        display.fillRect(0, 24, SCREEN_WIDTH, 28, SSD1306_BLACK);
        display.setCursor(15, 35);
        display.setTextSize(0.8);
        display.print("Tidak ada berita");
    }
}

// ========== SPLASH SCREEN ==========
void showSplash() {
    display.clearDisplay();
    display.setTextSize(2);
    display.setCursor(10, 15);
    display.println("News");
    display.setCursor(10, 35);
    display.println("Ticker");
    display.setTextSize(1);
    display.setCursor(2, 55);
    display.println("Berita Indonesia");
    display.display();
    delay(2000);
}

// ========== SETUP ==========
void setup() {
    Serial.begin(115200);
    Serial.println("\n========================================");
    Serial.println("📰 NEWS TICKER - BERITA INDONESIA");
    Serial.println("========================================\n");
    
    if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
        Serial.println("OLED gagal diinisialisasi!");
        for (;;);
    }
    
    showSplash();
    
    wifiConnected = connectWiFi();
    loadIndonesianNews();
    
    if (wifiConnected) {
        tryFetchOnlineNews();
    }
    
    newsIndex = 0;
    scrollPosition = SCREEN_WIDTH;
    if (totalNews > 0) {
        currentNews = newsTitles[0];
    }
    
    lastUpdate = millis();
    display.clearDisplay();
    
    Serial.print("✓ Total ");
    Serial.print(totalNews);
    Serial.println(" berita siap ditampilkan");
}

// ========== LOOP UTAMA ==========
void loop() {
    if (wifiConnected && (millis() - lastUpdate > 600000)) {
        tryFetchOnlineNews();
        lastUpdate = millis();
    }
    
    if (millis() - lastScroll > 40) {
        scrollPosition -= 2;
        lastScroll = millis();
    }
    
    display.clearDisplay();
    displayHeader();
    displayHeadline();
    displayNewsTicker();
    display.display();
    
    delay(20);
}

⚙️ Cara Kerja Sistem

Berikut diagram alur kerja sistem:

Start → Inisialisasi OLED → Tampilkan Splash → Koneksi WiFi
                                                    ↓
                                            [Sukses?]
                                                ↓
                                    Yes → Ambil Berita Online
                                    No  → Gunakan Berita Offline
                                                ↓
                                    Tampilkan Header + Headline
                                                ↓
                                    Jalankan Scrolling News Ticker
                                                ↓
                                    Update setiap 10 menit (jika online)

Penjelasan Fungsi Penting:

  • loadIndonesianNews() - Memuat 20 berita offline cadangan
  • connectWiFi() - Menghubungkan ke jaringan WiFi
  • tryFetchOnlineNews() - Mengambil berita dari RSS Tempo
  • displayNewsTicker() - Membuat efek scrolling berita
  • displayHeadline() - Menampilkan berita utama di tengah

⚠️ Troubleshooting Umum

MasalahPenyebabSolusi
Layar OLED kosongKoneksi salahPeriksa kabel SDA/SCL
WiFi tidak konekSSID/password salahPeriksa kembali kredensial
Teks tidak berjalanDelay terlalu besarKurangi nilai delay di loop
Berita tidak updateKoneksi internet bermasalahCek koneksi router
Compile errorLibrary tidak lengkapInstal semua library yang diperlukan

🚀 Pengembangan Lebih Lanjut

Proyek ini dapat dikembangkan dengan fitur-fitur berikut:

  • Menambahkan efek suara - Buzzer untuk notifikasi berita baru
  • Kontrol jarak jauh - Menggunakan Blynk atau Firebase
  • Multiple display - Menampilkan berita di beberapa layar
  • Penyimpanan SD Card - Menyimpan berita untuk mode offline
  • Sensor gerak - Menyalakan display hanya saat ada orang
  • Mode malam - Kecerahan otomatis menyesuaikan waktu
🎉 Selamat! Anda telah berhasil membuat News Ticker IoT sendiri. Jangan lupa untuk menyesuaikan SSID dan password WiFi dengan jaringan Anda sebelum upload kode.

Tidak ada komentar:

Posting Komentar

Panduan Lengkap NodeMCU ESP8266 dan OLED 0.96" untuk Pemula

NodeMCU ESP8266 dan OLED 0.96" - Panduan Lengkap untuk Pemula 📟 NODEMCU ESP8266 DAN OLED 0.96" Panduan Lengkap untuk...