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
218 views
YTM Music Controller
Device to control YouTube music playing on PC
218
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 sharing platform. We are not responsible for any design issues and parameter issues (board thickness, surface finish, etc.) you choose.
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)
Upload photo
You can only upload 5 files in total. Each file cannot exceed 2MB. Supports JPG, JPEG, GIF, PNG, BMP
0 / 10000
It looks like you have not written anything. Please add a comment and try again.
You can upload up to 5 images!
Image size should not exceed 2MB!
File format not supported!
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
-
-
Helium IoT Network Sensor Development board | H2S-Dev V1.2
91 0 0 -
-
-
-
-
-
3D printed Enclosure Backplate for Riden RD60xx power supplies
176 1 1