Engineer
AUSTRALIA • + Follow
Edit Project
Components
|
ESP32-S3-WROOM-1-N16R8Espressif Systems
|
x 1 | |
|
SMT 3x6x2.5MM 2PIN Tactile Tact Push Button Micro Switch Self-reset Momentary |
x 1 | |
![]() |
PEC11H-4220K-S0024BOURNS INC.
|
x 1 |
Tools, APP Software Used etc.
![]() |
KiCADKicad
|
|
![]() |
Autodesk Fusion 360Autodesk
|
Description
YTM Music Controller
This works by registering input from the button and rotary encoder then sending it to the computer through the ESP via an API which adjusts the music playing accordingly.
Code
ESP Code
Arduino
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <iostream>
#include <sstream>
#include <string>
#include "FS.h"
#include <Encoder.h>
// Define your Wi-Fi credentials
const char* ssid = "";
const char* password = "";
String titleCheck = "";
int x1 = 0;
WiFiClient wifiClient;
// Create an instance of the ILI9341 display
#define TFT_CS D2
#define TFT_DC D1
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
#define ENCODER_A_PIN D3
#define ENCODER_B_PIN D4
#define BUTTON_PIN 12
#define PREV_BTN_PIN D0
#define NEXT_BTN_PIN D8
Encoder myEncoder(ENCODER_A_PIN, ENCODER_B_PIN);
long oldPosition = -999;
long newPosition = 0;
int volume = 0;
boolean isButtonPressed = false;
long lastUpdateMillis = 0;
boolean isButtonPressed1 = false;
long lastUpdateMillis1 = 0;
boolean isButtonPressed2 = false;
long lastUpdateMillis2 = 0;
void ICACHE_RAM_ATTR handleKey() {
isButtonPressed = true;
}
void ICACHE_RAM_ATTR handleKey1() {
isButtonPressed1 = true;
}
void ICACHE_RAM_ATTR handleKey2() {
isButtonPressed2 = true;
}
void setup() {
Serial.begin(115200);
pinMode(A0, INPUT);
if (!SPIFFS.begin()) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
} else {
Serial.println("SPIFFS mounted successfully");
}
delay(100);
tft.begin();
tft.fillScreen(ILI9341_BLACK);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
myEncoder.write(0);
pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(BUTTON_PIN, handleKey, RISING);
pinMode(NEXT_BTN_PIN, INPUT);
attachInterrupt(NEXT_BTN_PIN, handleKey1, RISING);
pinMode(PREV_BTN_PIN,INPUT);
attachInterrupt(PREV_BTN_PIN,handleKey2,FALLING);
// Perform HTTP GET request
// getDataFromAPI();
}
void loop() {
Serial.println(digitalRead(PREV_BTN_PIN));
if (isButtonPressed && millis() - lastUpdateMillis > 50) {
isButtonPressed = false;
lastUpdateMillis = millis();
Serial.println("pressed");
sendVolume("togglePausePlay");
}
if (isButtonPressed1 && millis() - lastUpdateMillis1 > 50) {
isButtonPressed1 = false;
lastUpdateMillis1 = millis();
Serial.println("N-pressed");
nextPrev(true,false);
}
if (isButtonPressed2 && millis() - lastUpdateMillis2 > 50) {
isButtonPressed2 = false;
lastUpdateMillis2 = millis();
Serial.println("P-pressed");
nextPrev(false,true);
}
newPosition = myEncoder.read();
if (newPosition != oldPosition) {
int adjust = newPosition - oldPosition;
volume = volume - adjust;
if(volume > 100){
volume = 100;
}
if(volume < 0){
volume = 0;
}
sendVolume(String(volume));
oldPosition = newPosition;
} else{
getDataFromAPI();
}
delay(1000);
}
void sendVolume(String volumeString) {
HTTPClient http;
String link = "http://192.168.0.158:13091/volume/" + volumeString;
http.begin(wifiClient, link);
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK) {
Serial.println("ok");
} else {
Serial.printf("ERR", httpCode);
}
} else {
Serial.printf("ERR1:", httpCode);
}
http.end();
}
void nextPrev(boolean next, boolean prev) {
HTTPClient http;
String Nlink = "http://192.168.0.158:13091/next";
String Plink = "http://192.168.0.158:13091/prev";
String link;
if(next == true && prev == false){
link = Nlink;
} else if(next == false && prev == true){
link = Plink;
}
http.begin(wifiClient,link);
int httpCode = http.GET();
if (httpCode > 0){
if (httpCode == HTTP_CODE_OK){
Serial.println("Next/Prev ok");
}
}
http.end();
}
void getDataFromAPI() {
HTTPClient http;
http.begin(wifiClient,"http://192.168.0.158:13091/"); // Replace with your API endpoint URL
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
ESP.wdtFeed();
// Parse JSON data
const size_t capacity = JSON_OBJECT_SIZE(5) + 120;
Serial.println(capacity);
DynamicJsonDocument doc(capacity);
deserializeJson(doc, payload);
http.end();
String title = doc["title"];
String artist = doc["artist"];
double length = doc["length"];
double progress = doc["progress"];
uint8_t accentr = doc["accentr"];
uint8_t accentg = doc["accentg"];
uint8_t accentb = doc["accentb"];
doc.clear();
Serial.println(titleCheck);
Serial.println(title);
if(titleCheck == title){
displayData(artist, ".", progress, length, accentr, accentg, accentb);
} else{
titleCheck = title;
Serial.println(title);
Serial.println(titleCheck);
displayData(artist, title, progress, length, accentr, accentg, accentb);
}
} else {
Serial.println(httpCode);
Serial.println("Error on HTTP request");
}
} else {
Serial.print(httpCode);
Serial.println("Connection failed");
}
}
void displayRectColor(uint8_t r, uint8_t g, uint8_t b, int x, int y) {
uint16_t color = tft.color565(r, g, b);
tft.fillRect(x, y, 4,4, color);
}
void getImage(){
HTTPClient http;
http.begin(wifiClient,"http://192.168.0.158:13091/image/1"); // Replace with your API endpoint URL
int httpCode = http.GET();
if (httpCode > 0){
if(httpCode == HTTP_CODE_OK){
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
DynamicJsonDocument doc(ESP.getMaxFreeBlockSize() - 512);
deserializeJson(doc, payload);
http.end();
for(int x = 0;x<5;x++){
for(int i = 0;i<40;i++){
displayRectColor(doc["pixelData"][x][i][0],doc["pixelData"][x][i][1],doc["pixelData"][x][i][2],40+(i*4),20+(x*4));
}
}
doc.clear();
}
}
http.begin(wifiClient,"http://192.168.0.158:13091/image/2"); // Replace with your API endpoint URL
int httpCode2 = http.GET();
if (httpCode2 > 0){
if(httpCode2 == HTTP_CODE_OK){
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
DynamicJsonDocument doc(ESP.getMaxFreeBlockSize() - 512);
deserializeJson(doc, payload);
http.end();
for(int x = 0;x<5;x++){
for(int i = 0;i<40;i++){
displayRectColor(doc["pixelData"][x][i][0],doc["pixelData"][x][i][1],doc["pixelData"][x][i][2],40+(i*4),40+(x*4));
}
}
doc.clear();
}
}
http.begin(wifiClient,"http://192.168.0.158:13091/image/3"); // Replace with your API endpoint URL
int httpCode3 = http.GET();
if (httpCode3 > 0){
if(httpCode3 == HTTP_CODE_OK){
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
DynamicJsonDocument doc(ESP.getMaxFreeBlockSize() - 512);
deserializeJson(doc, payload);
http.end();
for(int x = 0;x<5;x++){
for(int i = 0;i<40;i++){
displayRectColor(doc["pixelData"][x][i][0],doc["pixelData"][x][i][1],doc["pixelData"][x][i][2],40+(i*4),60+(x*4));
}
}
doc.clear();
}
}
http.begin(wifiClient,"http://192.168.0.158:13091/image/4"); // Replace with your API endpoint URL
int httpCode4 = http.GET();
if (httpCode4 > 0){
if(httpCode4 == HTTP_CODE_OK){
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
DynamicJsonDocument doc(ESP.getMaxFreeBlockSize() - 512);
deserializeJson(doc, payload);
http.end();
for(int x = 0;x<5;x++){
for(int i = 0;i<40;i++){
displayRectColor(doc["pixelData"][x][i][0],doc["pixelData"][x][i][1],doc["pixelData"][x][i][2],40+(i*4),80+(x*4));
}
}
doc.clear();
}
}
ESP.wdtFeed();
getDataFromAPI();
http.begin(wifiClient,"http://192.168.0.158:13091/image/5"); // Replace with your API endpoint URL
int httpCode5 = http.GET();
if (httpCode5 > 0){
if(httpCode5 == HTTP_CODE_OK){
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
DynamicJsonDocument doc(ESP.getMaxFreeBlockSize() - 512);
deserializeJson(doc, payload);
http.end();
for(int x = 0;x<5;x++){
for(int i = 0;i<40;i++){
displayRectColor(doc["pixelData"][x][i][0],doc["pixelData"][x][i][1],doc["pixelData"][x][i][2],40+(i*4),100+(x*4));
}
}
doc.clear();
}
}
http.begin(wifiClient,"http://192.168.0.158:13091/image/6"); // Replace with your API endpoint URL
int httpCode6 = http.GET();
if (httpCode6 > 0){
if(httpCode6== HTTP_CODE_OK){
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
DynamicJsonDocument doc(ESP.getMaxFreeBlockSize() - 512);
deserializeJson(doc, payload);
http.end();
for(int x = 0;x<5;x++){
for(int i = 0;i<40;i++){
displayRectColor(doc["pixelData"][x][i][0],doc["pixelData"][x][i][1],doc["pixelData"][x][i][2],40+(i*4),120+(x*4));
}
}
doc.clear();
}
}
http.begin(wifiClient,"http://192.168.0.158:13091/image/7"); // Replace with your API endpoint URL
int httpCode7 = http.GET();
if (httpCode7 > 0){
if(httpCode7 == HTTP_CODE_OK){
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
DynamicJsonDocument doc(ESP.getMaxFreeBlockSize() - 512);
deserializeJson(doc, payload);
http.end();
for(int x = 0;x<5;x++){
for(int i = 0;i<40;i++){
displayRectColor(doc["pixelData"][x][i][0],doc["pixelData"][x][i][1],doc["pixelData"][x][i][2],40+(i*4),140+(x*4));
}
}
doc.clear();
}
}
http.begin(wifiClient,"http://192.168.0.158:13091/image/8"); // Replace with your API endpoint URL
int httpCode8 = http.GET();
if (httpCode8 > 0){
if(httpCode8 == HTTP_CODE_OK){
String payload = http.getString();
Serial.println("Received data:");
Serial.println(payload);
DynamicJsonDocument doc(ESP.getMaxFreeBlockSize() - 512);
deserializeJson(doc, payload);
http.end();
for(int x = 0;x<5;x++){
for(int i = 0;i<40;i++){
displayRectColor(doc["pixelData"][x][i][0],doc["pixelData"][x][i][1],doc["pixelData"][x][i][2],40+(i*4),160+(x*4));
}
}
doc.clear();
}
}
}
void drawCentreString(const String &buf, int x, int y, int txt_size)
{
int16_t x1, y1;
uint16_t w, h;
tft.setTextSize(txt_size);
tft.getTextBounds(buf, x, y, &x1, &y1, &w, &h);
Serial.println(w);
if(w > 230){
txt_size = txt_size - 0.1;
Serial.println(txt_size);
tft.setTextSize(txt_size);
tft.getTextBounds(buf, x, y, &x1, &y1, &w, &h);
}
ESP.wdtFeed();
Serial.println(w);
Serial.println("HERE");
tft.setCursor(x - w / 2, y);
tft.print(buf);
}
void displayData(String artist, String title, double progress, double length, uint8_t accentr, uint8_t accentg, uint8_t accentb) {
tft.setTextColor(ILI9341_WHITE,ILI9341_BLACK);
Serial.println(progress);
Serial.println(length);
double fill_px = (progress/length)*200;
if(fill_px > 200){
fill_px = 200;
}
Serial.println(fill_px);
tft.fillRect(0,(320/2)+110,240,40,ILI9341_BLACK);
uint16_t color = tft.color565(accentr, accentg, accentb);
Serial.println(accentr);
Serial.println(accentg);
Serial.println(accentb);
Serial.println(color);
tft.fillRoundRect(20,(320/2)+120,fill_px,20,50,color);
tft.drawRoundRect(20, (320/2)+120, 200, 20, 50, ILI9341_WHITE);
Serial.println(title);
if(title != "."){
Serial.println("TITLE CHECK HERE");
tft.fillRect(0,0,240,260,ILI9341_BLACK);
tft.setTextWrap(false);
drawCentreString(title,120,(320/2)+50,3);
drawCentreString(artist,120,(320/2)+80,2);
getImage();
}
}
CAD-Custom parts and enclosures
May 22,2024
84 views
YTM Music Controller
Device to control YouTube music playing on PC
84
1
0
Published: May 22,2024
Purchase
Donation Received ($)
PCBWay Donate 10% cost To Author
File Last Updated: 2024/05/22 (GMT+8)
File update record
2024-05-2218:08:27
CAD or technical drawing file is updated.
*PCBWay community is a shared platform and we are not responsible for any design issues.
Copy this HTML into your page to embed a link to order this shared project
Copy
Under the
Attribution-ShareAlike (CC BY-SA)
License.
- Comments(0)
- Likes(1)
You can only upload 1 files in total. Each file cannot exceed 2MB. Supports JPG, JPEG, GIF, PNG, BMP
0 / 10000
Remove
It looks like you have not written anything. Please add a comment and try again.
View More
-
Engineer May 22,2024
View More
VOTING
0 votes
- 0 USER VOTES
0.00
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Design
1/4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Usability
2/4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Creativity
3/4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Content
4/4
More by Engineer
You may also like
-
PCB Rule with resistor color code, full color printed with the UV technology
30 0 2 -
Robot with WiFi control and servos driven by ESP32
38 0 1 -
Commodore 1551 Drive Cartridge Replacement
206 0 2 -
RCMHardwareByte-v2.3
143 0 0 -
Terminal Curiosity PCB Ruler
364 0 1 -
(DIY) COMMODORE 64 DEAD-TEST (781220) DIAGNOSTIC CARTRIDGE
400 0 2 -
Creative Micro Designs Inc. CMD FD-2000 / FD-4000 3D Printable Case
429 0 0 -
Creative Micro Designs Inc. CMD FD-2000 / FD-4000 Metal Case
608 0 0