#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Base64.h> // Pastikan library Base64 terpasang
// Konfigurasi LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat I2C, 16 kolom, 2 baris
// Koneksi Wi-Fi
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Konfigurasi Spotify API
const String client_id = "018684d321754891b8df31365e37dcca";
const String client_secret = "b7d2899ef59e4757a86b5539f65f1aee";
const String redirect_uri = "http://localhost/callback";
const String authorization_code = "AQBCDCRGw1rSLeF7FgGuW8Sy61cKIhWyQaDwL_2fNw5Gpsu8TUY0dpOab9rTLEZh-SdkpVR2IjYeVoyYjqQnwpXDKGp5St1fgOwFN0kRwT3UR638B65Na1EFsyWbOG7Nd3whpd2o0BXcQyavnmpzC-aSFxvpXreD1uTlrNlLh7dwrH-fY5473bAiNI7JkOa8zJTw9eBUPiK8SA
";
String access_token = "";
String refresh_token = "";
// Endpoint API Spotify
const String token_url = "https://accounts.spotify.com/api/token";
const String api_url = "https://api.spotify.com/v1/me/player/currently-playing";
// Fungsi untuk meng-encode Base64
String encodeBase64(String input) {
char inputBuffer[input.length() + 1];
input.toCharArray(inputBuffer, input.length() + 1);
char encoded[100]; // Buffer untuk hasil encode (sesuaikan jika input lebih panjang)
int len = Base64.encode(encoded, inputBuffer, input.length());
return String(encoded).substring(0, len);
}
// Fungsi untuk mendapatkan Access Token dari Authorization Code
void getAccessToken() {
HTTPClient http;
http.begin(token_url);
// Header untuk Basic Authorization
String credentials = client_id + ":" + client_secret;
String encodedCredentials = encodeBase64(credentials);
String auth = "Basic " + encodedCredentials;
http.addHeader("Authorization", auth);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Body request
String body = "grant_type=authorization_code&code=" + authorization_code + "&redirect_uri=" + redirect_uri;
int httpCode = http.POST(body);
String response = http.getString();
if (httpCode == 200) {
StaticJsonDocument<512> doc;
deserializeJson(doc, response);
access_token = doc["access_token"].as<String>();
refresh_token = doc["refresh_token"].as<String>();
}
http.end();
}
// Fungsi untuk Refresh Access Token
void refreshAccessToken() {
HTTPClient http;
http.begin(token_url);
String credentials = client_id + ":" + client_secret;
String encodedCredentials = encodeBase64(credentials);
String auth = "Basic " + encodedCredentials;
http.addHeader("Authorization", auth);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String body = "grant_type=refresh_token&refresh_token=" + refresh_token;
int httpCode = http.POST(body);
String response = http.getString();
if (httpCode == 200) {
StaticJsonDocument<512> doc;
deserializeJson(doc, response);
access_token = doc["access_token"].as<String>();
}
http.end();
}
// Fungsi untuk mendapatkan lagu yang sedang diputar
String getCurrentTrack() {
HTTPClient http;
http.begin(api_url);
http.addHeader("Authorization", "Bearer " + access_token);
int httpCode = http.GET();
String response = http.getString();
if (httpCode == 200) {
StaticJsonDocument<1024> doc;
deserializeJson(doc, response);
String songName = doc["item"]["name"].as<String>();
String artistName = doc["item"]["artists"][0]["name"].as<String>();
return songName + " - " + artistName;
} else if (httpCode == 401) {
refreshAccessToken();
return "Refreshing token...";
} else if (httpCode == 204) {
return "No song playing";
}
return "Error fetching track";
}
void setup() {
Serial.begin(115200);
Wire.begin();
lcd.begin(16, 2);
lcd.backlight();
lcd.print("Connecting WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
}
lcd.clear();
lcd.print("Fetching token...");
getAccessToken();
}
void loop() {
String currentTrack = getCurrentTrack();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(currentTrack.substring(0, 16));
lcd.setCursor(0, 1);
if (currentTrack.length() > 16) {
lcd.print(currentTrack.substring(16, 32));
}
delay(10000);
}