📰 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.
• 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
| Komponen | Spesifikasi | Fungsi |
|---|---|---|
| NodeMCU ESP8266 | ESP-12E Module | Otak dari sistem, mengontrol semua fungsi |
| OLED Display | 128x64 SSD1306 | Menampilkan berita dan antarmuka |
| Kabel Jumper | Female to Female | Menghubungkan komponen |
| Power Supply | USB 5V / Micro USB | Sumber daya |
🔌 Skema Rangkaian
Berikut adalah koneksi antara NodeMCU ESP8266 dengan OLED Display SSD1306 (I2C):
| NodeMCU ESP8266 | OLED SSD1306 |
|---|---|
| 3.3V | VCC |
| GND | GND |
| D1 (GPIO5) | SCL |
| D2 (GPIO4) | SDA |
📦 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 cadanganconnectWiFi()- Menghubungkan ke jaringan WiFitryFetchOnlineNews()- Mengambil berita dari RSS TempodisplayNewsTicker()- Membuat efek scrolling beritadisplayHeadline()- Menampilkan berita utama di tengah
⚠️ Troubleshooting Umum
| Masalah | Penyebab | Solusi |
|---|---|---|
| Layar OLED kosong | Koneksi salah | Periksa kabel SDA/SCL |
| WiFi tidak konek | SSID/password salah | Periksa kembali kredensial |
| Teks tidak berjalan | Delay terlalu besar | Kurangi nilai delay di loop |
| Berita tidak update | Koneksi internet bermasalah | Cek koneksi router |
| Compile error | Library tidak lengkap | Instal 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
Tidak ada komentar:
Posting Komentar