Introducción
Mesa de control multimedia con botones de pause, siguiente canción, anterior canción, favoritos para Spotify y control de volumen.
Materiales
Fundamentos:
La idea original era construir un botón de favoritos para Spotify, basándome siguiendo el estupendo trabajo de Rincón Ingenieril.
En esta web se explican todos los pasos necesarios para construir un botón de favoritos para Spotify.
Usando una placa compatible ESP8266 y a través de APIs se puede acceder a tu cuenta de Spotify y proclamar la canción que esté sonando en ese momento como favorita pulsando un botón.
Tan solo he añadido unas mejoras complementarias a través de una placa de arduino que maneje el control multimedia del PC. Para ello he usado una placa que es capaz de simular pulsaciones de teclado a través del USB. Es el caso de la arduino pro mini.
Controlaremos el volumen con un encoder rotativo con pulsador incorporado. Al presionar este pulsador, el volumen caerá al mínimo (bajará el volumen 50 veces) y minimizará todas las ventanas mostrando el escritorio (tecla windows+m).
Mediante 3 pulsadores podremos controlar además las funciones multimedia de siguiente canción, anterior canción y pause o play.
Conexión de los componentes
Como se observa, usaremos la placa ESP8266 tan solo para asignar la canción que está activa a favoritos, para este propósito tiene un pulsador asignado a D3. Por otro lado, cuando el pulsador es presionado y se obtiene respuesta OK mediante la aplicación API, a través del D7 se envía una señal positiva a la placa arduino Pro Micro a modo de confirmación.
Cuando la placa arduino Pro Micro recibe esta señal HIGH de confirmación, activa los leds WS2812B en azul para expresar que la canción ha sido añadida a favoritos con éxito. (La razón por la que los leds están conectados a la Pro Micro en vez de a la ESP8266 es que esta última funciona a 3.3v, no suficiente para encender los leds a 5V, además, estos leds también se encenderán en verde dependiendo del volumen multimedia).
Por otro lado, la placa Pro Micro tiene 3 pulsadores conectados en D5, D6 y D7 correspondientes a siguiente canción, anterior canción y pause.
El encoder control de volumen se conectará a D2 y D3. El pulsador incorporado se conectará a D4 para mutar y mostrar el escritorio.
Los leds WS2812b se conectarán a D9 que mostrará la magnitud del volumen.
Tener en cuenta que la placa ESP8266 funciona a 3.3V por lo que debe ser alimentada por Vin, ya que administraremos 5V a través del USB.
Para conectar la caja a la placa arduino Pro Micro he usado el alargador de USB de fácil fabricación.
Piezas STL para imprimir en 3D.
Programación
En el tutorial de El botón IoT de me gusta para Spotify – Rincón Ingenieril (rinconingenieril.es) se detallan los pasos para programar la ESP8266.
Arduino Pro micro
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
///////////////////////////////////////////////////////////////// #include "HID-Project.h" #include "Button2.h"; // https://github.com/LennartHennigs/Button2 #include "ESPRotary.h"; #include <Adafruit_NeoPixel.h> ///////////////////////////////////////////////////////////////// #define PIN 9 #define ROTARY_PIN1 3 #define ROTARY_PIN2 2 #define BUTTON_PIN 4 #define BUTTON_PLAY 6 #define BUTTON_NEXT 7 #define BUTTON_PREVIOUS 5 #define CLICKS_PER_STEP 4 // this number depends on your rotary encoder #define NUMPIXELS 15 Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); int volumen = 0; int volumen2 = 0; ///////////////////////////////////////////////////////////////// ESPRotary r = ESPRotary(ROTARY_PIN1, ROTARY_PIN2, CLICKS_PER_STEP); Button2 b = Button2(BUTTON_PIN); ///////////////////////////////////////////////////////////////// void setup() { pinMode (8, INPUT); Serial.begin(9600); delay(50); Serial.println("\n\nSimple Counter"); r.setChangedHandler(rotate); r.setLeftRotationHandler(showDirection); r.setRightRotationHandler(showDirection); b.setTapHandler(click); b.setLongClickHandler(resetPosition); pinMode (BUTTON_PLAY, INPUT_PULLUP); pinMode (BUTTON_NEXT, INPUT_PULLUP); delay (1000); pinMode (BUTTON_PREVIOUS, INPUT_PULLUP); for (int i = 50; i > 0; i--) { Consumer.write(MEDIA_VOLUME_DOWN); delay(1); } pixels.begin(); pixels.clear(); pixels.setPixelColor(0, pixels.Color(20, 0, 0)); pixels.show(); } void loop() { r.loop(); b.loop(); if (!digitalRead (BUTTON_PLAY)) { Consumer.write(MEDIA_PLAY_PAUSE); delay (500); } if (!digitalRead (BUTTON_NEXT)) { Consumer.write(MEDIA_NEXT); delay (500); } if (!digitalRead (BUTTON_PREVIOUS)) { Consumer.write(MEDIA_PREVIOUS); delay (500); } if (digitalRead (8)) { for (int i = 0; i < NUMPIXELS; i++) { // For each pixel... pixels.setPixelColor(i, pixels.Color(0, 0, 20)); } pixels.show(); delay (1000); for (int i = 0; i < volumen2; i++) { // For each pixel... pixels.setPixelColor(i, pixels.Color(0, 20, 0)); } for (int i = volumen2; i < NUMPIXELS; i++) { // For each pixel... pixels.setPixelColor(i, pixels.Color(0, 0, 0)); } pixels.show(); } } ///////////////////////////////////////////////////////////////// // on change void rotate(ESPRotary& r) { //Serial.println(r.getPosition()); volumen2 = map (volumen, 0, 100, 1, 15); Serial.println (volumen2); for (int i = 0; i < volumen2; i++) { // For each pixel... pixels.setPixelColor(i, pixels.Color(0, 20, 0)); } for (int i = volumen2; i < NUMPIXELS; i++) { // For each pixel... pixels.setPixelColor(i, pixels.Color(0, 0, 0)); } if (volumen == 0) { pixels.setPixelColor(0, pixels.Color(20, 0, 0)); } pixels.show(); } // on left or right rotation void showDirection(ESPRotary& r) { Serial.println(r.directionToString(r.getDirection())); if (r.directionToString(r.getDirection()) == "LEFT") { Consumer.write(MEDIA_VOLUME_DOWN); volumen = volumen - 2; if (volumen <= 0) { volumen = 0; } } if (r.directionToString(r.getDirection()) == "RIGHT") { Consumer.write(MEDIA_VOLUME_UP); volumen = volumen + 2; if (volumen >= 100) { volumen = 100; } } } // single click void click(Button2& btn) { Serial.println("Click!"); //Consumer.write(MEDIA_VOLUME_MUTE); for (int i = 50; i > 0; i--) { Consumer.write(MEDIA_VOLUME_DOWN); delay(1); } volumen = 0; Keyboard.press(KEY_RIGHT_GUI); //tecla windows Keyboard.press('m'); delay(100); Keyboard.releaseAll (); for (int i = 0; i < NUMPIXELS; i++) { // For each pixel... pixels.setPixelColor(i, pixels.Color(0, 0, 0)); } pixels.setPixelColor(0, pixels.Color(20, 0, 0)); pixels.show(); } // long click void resetPosition(Button2& btn) { // r.resetPosition(); // Consumer.write(MEDIA_STOP); Serial.println("Reset!"); } ///////////////////////////////////////////////////////////////// |