1+ // EasyOledUI. Version: 0.9.0
2+ // Esta libreria solamente funciona con la version 1.0.6 del paquete para la ESP32.
3+ // Aun se debe identificar por que razon falla con las nuevas versiones.
4+ // -----------------------------------------------------------------------
5+ // Hardware usado:
6+ // - OLED I2C de 128x64 pixeles.
7+ // - Circuito de cuatro botones mediante resistencias (un ADC detecta la tecla precionada según voltaje).
8+ // - Transistor para manejar motor de vibracion, se activa al pricionar un boton
9+ // -----------------------------------------------------------------------
10+
11+
12+ // Configuración de pantalla OLED
13+ // -----------------------------------------------------------------------
14+ // #include <Adafruit_SSD1306.h> // Ya se incluye en la libreria UI_OLED.h
15+ #include < EasyOledUI.h> // ya incluye otras librarias requeridas
16+
17+ // Pines de I2C
18+ #define I2C_SDA 22
19+ #define I2C_SCL 21
20+
21+ // Definicion del tamaño de la pantalla:
22+ #define SCREEN_WIDTH 128 // OLED display width, in pixels
23+ #define SCREEN_HEIGHT 64 // OLED display height, in pixels
24+
25+ // Parametros de la pantalla:
26+ #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
27+ #define SCREEN_ADDRESS 0x3C // /< See datasheet for Address; usually 0x3D for 128x64, 0x3C for 128x32
28+
29+
30+ // Configuración de los botones y buzzer
31+ // -----------------------------------------------------------------------
32+ #define pinBuzzer 12 // Pin del buzzer
33+ #define pinTransistor 33 // Pin del transistor
34+ #define pinDeLosBotones 36 // pin con ADC donde están conectados los botones
35+ uint8_t tipoBotonesDisp = 0 ; // Define el tipo de botones, 0 para fila de 4 botones, 1 para cruceta
36+ int limitesDeLect[] = {100 ,4095 ,3900 ,3000 ,2700 ,2000 ,1600 ,1000 ,600 }; // limite de no presionado, limte min y max de cada boton
37+ // Order: {do nothing threshold, 1Max, 1Min, 2Max, 2Min, 3Max, 3Min, 4Max, 4Min}
38+
39+
40+ // Creación de las instancias
41+ // -----------------------------------------------------------------------
42+ UI_OLED ui; // crear objeto de UI
43+ menu menuPrincipal; // Menu inicial de la UI
44+ menu menuSecundario; // Menu secuandario de la UI
45+ botones botones; // Botones que manejan la UI
46+
47+ void setup () {
48+
49+ Serial.begin (115200 ); // inicia el puerto serial a 115200 baudios
50+
51+ // Definir comportamiento de pines
52+ // ?????????????????????????????????????????????????????????????????????????????????//
53+ pinMode (pinBuzzer, OUTPUT);
54+ pinMode (pinTransistor, OUTPUT);
55+
56+ // Dejar apagado el motor de vibracion conectado al transistor (durante el arranque)
57+ // ?????????????????????????????????????????????????????????????????????????????????//
58+ digitalWrite (pinTransistor, LOW);
59+
60+ // Sonido de arranque mediante buzzer
61+ // ?????????????????????????????????????????????????????????????????????????????????//
62+ digitalWrite (pinBuzzer, HIGH);
63+ vTaskDelay (pdMS_TO_TICKS (10 ));
64+ digitalWrite (pinBuzzer, LOW);
65+
66+ // Poner a funcionar la UI
67+ // ?????????????????????????????????????????????????????????????????????????????????//
68+ crearUI (); // Funcion que inicia la la pantalla y crea la UI
69+ iniciarUI (3000 ); // Funcion que inica agrega la ejecución de la UI al multitasking nativo del ESP32
70+
71+ inicializarAcciones ();
72+ }
73+
74+
75+ bool callBackEjecutarAccionExterna (int menuActual, int opcionActual){}
76+
77+
78+ void loop () {
79+ // put your main code here, to run repeatedly:
80+ }
81+
82+
83+ // Crea la ui que se mustra en la pantalla
84+ void crearUI (){
85+ // Asociar la pantalla a la UI y inicializar:
86+ // ---------------------------------------------------------------------------------------
87+ Adafruit_SSD1306 display (SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
88+ ui.asociarPantalla (display); // Asociar la pantalla al UI
89+ ui.setupPantallaOled (I2C_SDA, I2C_SCL); // Iniciar la ui junto con la pantalla: Se indican los pines de I2C
90+ // Nota:
91+ // Si la pantalla es por SPI, se debe cambiar ui.setupPantallaOled() por el proceso de inicio correspondiente.
92+ // Por el momento, ui.setupPantallaOled() solamente soporta I2C.
93+
94+ // Creacion del menu principal
95+ // ---------------------------------------------------------------------------------------
96+ // Definir la opciones mostradas en la pantalla:
97+ String titulosM0[] = {
98+ " Musica" ,
99+ " Patron de vibracion" ,
100+ " Animacion" ,
101+ " Invertir colores" ,
102+ " Opcion 04" ,
103+ " Opcion 05" };
104+
105+ // Definir las funciones que ejecutan en cada opcion del menu O
106+ FuncionUI accionesM0[] = {
107+ AccM00,
108+ AccM01,
109+ AccM02,
110+ AccM03,
111+ NULL ,
112+ NULL , // Dejar en NULL si no se desea hacer nada: Indica error O1. Poner funcion vacia si se quiere eliminar el error.
113+ };
114+
115+ // Agregar el menu creado
116+ int numDeOpciones = (sizeof (titulosM0)/sizeof (titulosM0[0 ])); // Determinar la cantidad de elementos de este menu
117+ menuPrincipal.configurarMenu (0 , numDeOpciones, " Menu inicial" , titulosM0, accionesM0); // Configurar el menu: (numero de menu, cantidad de opciones, titulo, opciones, opcion inicial)
118+ // menuPrincipal.imprimirOpcionesEnSerial(); // Para depuracion: Imprime por serial la opciones del menu
119+
120+ // Creacion de un menu secundario
121+ // ---------------------------------------------------------------------------------------
122+ // Definir la opciones mostradas en la pantalla:
123+ String titulosMenuSecundario[] = {
124+ " Sonido 10" ,
125+ " Sonido 11" ,
126+ " Sonido 12" ,
127+ " Sonido 13" ,
128+ " Sonido 14" };
129+
130+ // Definir las funciones que ejecutan en cada opcion del menu 1
131+ FuncionUI accionesM1[] = {
132+ AccM10,
133+ AccM11,
134+ AccM12,
135+ AccM13,
136+ AccM14,
137+ };
138+
139+ // Agregar el menu creado
140+ int numDeOpcionesSec = (sizeof (titulosMenuSecundario)/sizeof (titulosMenuSecundario[0 ])); // determinar la cantidad de elementos
141+ menuSecundario.configurarMenu (1 , numDeOpcionesSec, " Musica" , titulosMenuSecundario, accionesM1);
142+ // menuSecundario.imprimirOpcionesEnSerial(); // funcion de depuracion
143+
144+ // Asociar los menus creados a la ui
145+ // ---------------------------------------------------------------------------------------
146+ menu todosLosMenus[] = {menuPrincipal,menuSecundario}; // Vector de los menus
147+ ui.asociarMenu (2 , todosLosMenus);
148+ // ui.imprimirTitulosDeMenusSerial(); // funcion de depuracion
149+
150+ // Configurar botones:
151+ // ---------------------------------------------------------------------------------------
152+ botones.iniciar (pinDeLosBotones, tipoBotonesDisp, limitesDeLect, pinTransistor); // int pin = 36, uint8_t tipo = 0, int *limitesDeLectura = NULL
153+ ui.asociarBotones (botones);
154+ // attachInterrupt(digitalPinToInterrupt(ui.botonesUI.pinBotones), handleInterrupt, CHANGE); // agregar una rutina de interrupcion a los botones. No funciono
155+
156+ // Mostrar mensaje de bienvenida
157+ // ---------------------------------------------------------------------------------------
158+ ui.mostrarMensaje (" Bienvenido" ); // Prueba de enviar un mensaje
159+ vTaskDelay (pdMS_TO_TICKS (1000 )); // Esperar para no borrar el mensaje y poder verlo
160+ }
161+
162+
163+
164+ // Funciones de las acciones
165+ // ====================================================
166+
167+ // Menu principal M0
168+ void AccM00 (){
169+ ui.menuActual = 1 ; // Cambiar a otro menu
170+ }
171+
172+ void AccM01 (){
173+ Serial.println (" Activando vibracion" );
174+ ui.mostrarMensaje (" Vibrando" ); // Mostrar un mensaje temporalmente
175+
176+ // Patron de vibracion
177+ for (int i;i<5 ;i++){
178+ digitalWrite (pinTransistor, HIGH);
179+ vTaskDelay (pdMS_TO_TICKS (50 ));
180+ digitalWrite (pinTransistor, LOW);
181+ vTaskDelay (pdMS_TO_TICKS (100 ));
182+ }
183+ for (int i;i<3 ;i++){
184+ digitalWrite (pinTransistor, HIGH);
185+ vTaskDelay (pdMS_TO_TICKS (70 ));
186+ digitalWrite (pinTransistor, LOW);
187+ vTaskDelay (pdMS_TO_TICKS (60 ));
188+ }
189+ for (int i;i<5 ;i++){
190+ digitalWrite (pinTransistor, HIGH);
191+ vTaskDelay (pdMS_TO_TICKS (50 ));
192+ digitalWrite (pinTransistor, LOW);
193+ vTaskDelay (pdMS_TO_TICKS (100 ));
194+ }
195+ }
196+
197+ void AccM02 (){
198+ // Ejecutar test de lineas
199+ testdrawrect ();
200+ }
201+
202+ void testdrawrect (void ) {
203+ ui.display .clearDisplay ();
204+
205+ for (int16_t i=0 ; i<ui.display .height ()/2 ; i+=2 ) {
206+ ui.display .drawRect (i, i, ui.display .width ()-2 *i, ui.display .height ()-2 *i, SSD1306_WHITE);
207+ ui.display .display (); // Update screen with each newly-drawn rectangle
208+ vTaskDelay (pdMS_TO_TICKS (10 ));
209+ }
210+ // vTaskDelay(pdMS_TO_TICKS(1000));
211+ }
212+
213+ bool estadoInvversionPantalla = false ;
214+ void AccM03 (){
215+ estadoInvversionPantalla = !estadoInvversionPantalla;
216+ ui.display .invertDisplay (estadoInvversionPantalla);
217+ }
218+
219+ // Menu secundario M1
220+ void AccM10 (){
221+ // Cancion 1 con el buzzer
222+ for (int i ;i<10 ; i++){
223+ digitalWrite (pinBuzzer, HIGH);
224+ vTaskDelay (pdMS_TO_TICKS (10 ));
225+ digitalWrite (pinBuzzer, LOW);
226+ vTaskDelay (pdMS_TO_TICKS (100 ));
227+ digitalWrite (pinBuzzer, HIGH);
228+ vTaskDelay (pdMS_TO_TICKS (20 ));
229+ digitalWrite (pinBuzzer, LOW);
230+ }
231+ }
232+
233+ void AccM11 (){
234+ // Cancion 2 con el buzzer
235+ for (int i ;i<10 ; i++){
236+ digitalWrite (pinBuzzer, HIGH);
237+ vTaskDelay (pdMS_TO_TICKS (10 ));
238+ digitalWrite (pinBuzzer, LOW);
239+ vTaskDelay (pdMS_TO_TICKS (100 ));
240+ digitalWrite (pinBuzzer, HIGH);
241+ vTaskDelay (pdMS_TO_TICKS (20 ));
242+ digitalWrite (pinBuzzer, LOW);
243+ }
244+ }
245+
246+ void AccM12 (){
247+ // Cancion 3 con el buzzer
248+ for (int i ;i<10 ; i++){
249+ digitalWrite (pinBuzzer, HIGH);
250+ vTaskDelay (pdMS_TO_TICKS (10 ));
251+ digitalWrite (pinBuzzer, LOW);
252+ vTaskDelay (pdMS_TO_TICKS (50 ));
253+ digitalWrite (pinBuzzer, HIGH);
254+ vTaskDelay (pdMS_TO_TICKS (30 ));
255+ digitalWrite (pinBuzzer, LOW);
256+ }
257+ }
258+
259+ void AccM13 (){
260+ // Cancion 4 con el buzzer
261+ for (int i ;i<10 ; i++){
262+ digitalWrite (pinBuzzer, HIGH);
263+ vTaskDelay (pdMS_TO_TICKS (10 ));
264+ digitalWrite (pinBuzzer, LOW);
265+ vTaskDelay (pdMS_TO_TICKS (100 ));
266+ digitalWrite (pinBuzzer, HIGH);
267+ vTaskDelay (pdMS_TO_TICKS (20 ));
268+ digitalWrite (pinBuzzer, LOW);
269+ }
270+ }
271+
272+ void AccM14 (){
273+ // Cancion 5 con el buzzer
274+ for (int i ;i<10 ; i++){
275+ digitalWrite (pinBuzzer, HIGH);
276+ vTaskDelay (pdMS_TO_TICKS (10 ));
277+ digitalWrite (pinBuzzer, LOW);
278+ vTaskDelay (pdMS_TO_TICKS (200 ));
279+ digitalWrite (pinBuzzer, HIGH);
280+ vTaskDelay (pdMS_TO_TICKS (20 ));
281+ digitalWrite (pinBuzzer, LOW);
282+ }
283+ }
284+ // ====================================================
285+
286+
287+
288+
289+
290+ // Configuracion del multitasking
291+ // ---------------------------------------------------------------------
292+
293+ // Definicion de la terea que actualiza la UI constantemenete
294+ void IRAM_ATTR tareaUI (void * parameters){
295+ // Tarea que mantiene funcionando el UI de la OLED
296+ while (true ){
297+ ui.update ();
298+ vTaskDelay (pdMS_TO_TICKS (20 )); // Delay para no sobrecargar tarea
299+ }
300+ vTaskDelete (NULL );
301+ }
302+
303+ // Configuracion de la tarea que ejecuta la UI
304+ // TaskHandle_t TaskHandle_1;
305+ void iniciarUI (int stack) { // stack> 1000
306+ BaseType_t tar1 = xTaskCreatePinnedToCore (
307+ tareaUI, // Funcion que se llama se llama en la tarea
308+ " UI-OLED" , // Nombre de la tarea (para depuracion)
309+ stack, // Tamaño del stack em bytes
310+ NULL , // Parameter to pass
311+ 1 , // Prioridad de la tarea
312+ NULL , // Task handle, NULL si no tiene
313+ 1 // Nucleo en el que corre
314+ );
315+ }
0 commit comments