LEDS INTELIGENTES

Proyecto para la Práctica 2 de la asignatura de Diseño de Sistemas Empotrados.

Índice:

  • Introducción.
  • Implementación y pasos dados.
  • Materiales.
  • Código.
  • Problemas encontrados.
  • Casos de uso.
  • Video de ejecución.
  • Reparto de tareas.
  • Autores.

Introducción:

A lo largo de este blog explicaremos diferentes apartados y características de nuestro trabajo de Sistemas Empotrados, que para resumir consiste en una matriz de LEDs que puede encenderse o apagarse con un sensor de proximidad o con un mando, además con este mismo mando se pueden seleccionar las diferentes funcionalidades de la lampara, como controlar la intensidad según la distancia a la que se ponga la mano, ver diferentes animaciones con los leds, hacer que los leds se muevan según la música que detecta un sensor de sonido, seleccionar el temporizador que apagará la matriz una vez haya transcurrido el tiempo que indique el usuario y finalmente enviar mensajes con el móvil a la matriz mediante Bluetooth.

Implementación y pasos dados:

Para la creación de la Lámpara Inteligente, llevamos a cabo un proceso de desarrollo progresivo: empezamos desde los aspectos de alto nivel y de ahí fuimos avanzando hasta llegar al desarrollo completo y final del proyecto.

Primero definimos concretamente cuáles serían las funciones que tendría nuestra lampara. Se hicieron varias propuestas, pensamos en hacer una lámpara tradicional de la que se pudiera controlar la estructura, el color, intensidad, etc.., después se propuso que fuera una tira de leds para poder usar efectos con las luces. Finalmente llegamos a la conclusión final de hacer una lampara con una matriz de leds con diferentes funciones.

Tras concretar las definiciones del sistema empezamos con la creación de cada una de las funciones de manera independiente una de otra. Entre los miembros del grupo nos repartimos estas funciones para que cada uno pudiera centrarse en la investigación y desarrollo de un aspecto concreto del proyecto. En un primer momento se utilizaron leds independientes en lugar de la matriz para facilitar el testeo y la creación inicial de las funciones.

Es también que en este momento empezamos a centrarnos en empotrar el sistema. Como nuestro objetivo era hacer una lámpara que se pudiera tener en una habitación o un salón, la estructura tenia que ser pequeña. También buscábamos que fuera de diseño minimalista, ya que así podría adaptarse a cualquier ambiente. Como conclusión elegimos un diseño en forma de caja rectangular con huecos para encajar la matriz de leds , el sensor de proximidad y el receptor del mando, dejando en el interior el resto de componentes.

Una vez ya contábamos con la mayoría de las funciones y la estructura hardware, nos juntamos todos los miembros en una serie de sesiones para juntar todas las partes del código, terminar de perfeccionar algunos aspectos del funcionamiento y principalmente corregir errores. Debido a que habíamos hecho las funciones independientes unas de otras, al momento de juntarlas se nos presentaron grandes problemas: de repente cosas que funcionaban ya no iban de la forma correcta. Tuvimos que pasar horas solucionando problemas que encontramos con la función del temporizador y del Bluetooth, además de calibrar mejor las funciones de música y del sensor de proximidad, para finalmente obtener la versión final del proyecto.

Fue gracias a este esfuerzo en conjunto y a las horas que dedicamos que logramos crear nuestro proyecto: la Lampara Inteligente.

Materiales

Componentes Hardware

  • Arduino Uno
    • Es el microcontrolador principal del proyecto, encargado de recibir datos de los sensores, procesarlos y gestionar las funciones de la lámpara inteligente.
  • Sensor de Ultrasonidos
    • Permite medir la proximidad de un objeto para encender o apagar la lámpara y ajustar la intensidad de la luz según la distancia detectada.
  • Mando IR
    • Un control remoto que permite cambiar entre los modos de funcionamiento de la lámpara.
  • Sensor IR
    • Recibe las señales enviadas por el mando a distancia para que el sistema interprete las órdenes y las ejecute.
  • Matriz de leds 8×32
    • Cuatro matrices de 8×8 leds que se encienden, muestran formas, palabras o patrones luminosos personalizados.
  • Módulo Bluetooth
    • Permite conectar la lámpara a un dispositivo móvil para enviar palabras y cambiar la velocidad con las que estas aparecen en la matriz de leds.
  • Sensor de Sonido
    • Detecta sonido y dependiendo del volumen genera distintos efectos visuales en la matriz de leds.
  • Batería de 9V
    • Proporciona la energía necesaria para el funcionamiento del sistema, asegurando la portabilidad y la autonomía del dispositivo.

Otros Materiales

  • Breadboard
    • Tablero de conexiones.
  • Cables
  • Caja de Madera
ComponentesPrecio
Arduino Uno19.99
Sensor ultrasonidos6.99
Mando IR y sensor IR6.81
Matriz de leds 8×3212.99
Sensor bluetooth10.99
Sensor de sonido6.49
Batería 9V3.5
Breadbroad~5
Cables~2
Caja madera10
Total84.76

Código

#include <IRremote.h>   // biblioteca  para el control remoto
#include <SoftwareSerial.h> // biblioteca para el bluetooth
#include "LedControl.h" // biblioteca  para la matriz de leds
#include <MD_MAX72xx.h> // biblioteca para la matriz de leds (bluetooth)

// ------------------------------------------------------------ Declaracion de variables ----------------------------------------------------------------------------------------
// Definir el valor de los botones de mi mando
#define Boton_ON 0xBA45FF00
#define Boton_0 0xE916FF00
#define Boton_1 0xF30CFF00
#define Boton_2 0xE718FF00
#define Boton_3 0xA15EFF00
#define Boton_4 0xF708FF00
#define Boton_5 0xE31CFF00
#define Tecla_SUMAR 0xF609FF00

// Variables para la matriz de leds
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW // definir matriz de leds
#define NUM_OF_MATRIX 4
#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10
int BT_Rx = 7;
int BT_Tx = 6;

LedControl lc = LedControl(DATA_PIN, CLK_PIN, CS_PIN, NUM_OF_MATRIX);  // el control de la matriz de leds se hace mediante la libreria ...
MD_MAX72XX letrero = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, NUM_OF_MATRIX); // matriz de leds
SoftwareSerial BT(BT_Rx,BT_Tx); // bluetooth

// Conector para el control remoto
int receptorMando = 3;   //  receptor de infrarrojos

// Variables para el sensor de sonido
float sensor = 0; // Variable para guardar el estado del sensor de sonido
int soundSensor = A0;  // Conector analógico para el sensor de sonido

// Tiempo Base Temporizador:
#define TIEMPO_BASE 5000

// variables para el temporizador
unsigned long tiempo_restante = 0; // Tiempo restante en milisegundos
unsigned long inicio_temporizador = 0; // Momento en que comenzó el temporizador
bool temporizador_activo = false;
bool matriz_encendida = false; // Indica si la matriz está encendida
String mensaje2 = "TEMPORIZADOR";

// variables para el control de la lampara
int modo;
bool on= true;

// variables para el bluetooth
String mensaje = "Hola";
String vel;
String proximo_mensaje;
long valor;
long velSlide = 100;
long velSlide2 = 50;

// variables sensor proximidad
int trigPin = 9;
int echoPin = 8;

float distancia_cm, intensidad;
int mediciones_prox;

float   filteredSignalValues[] = {165,160,156,154,150,147,145, 143, 140}; // rangos para mi sensor de sonido

byte d1_0[8]= {0x00,0x00,0x00,0x00,0x00,0x00,0xCF,0xFF}; // dibujos de las animaciones del sonido
byte d2_0[8]= {0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0xFF};
byte d3_0[8]= {0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xFF};
byte d4_0[8]= {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF};

byte d1_1[8]= {0x00,0x00,0x00,0x00,0x00,0x33,0xF3,0xFF};
byte d2_1[8]= {0x00,0x00,0x00,0x00,0x00,0x30,0xFC,0xFF};
byte d3_1[8]= {0x00,0x00,0x00,0x00,0x00,0xCC,0xCF,0xFF};
byte d4_1[8]= {0x00,0x00,0x00,0x00,0x00,0x30,0xF3,0xFF};

byte d1_2[8]= {0x00,0x00,0x00,0x00,0x12,0xB3,0xFF,0xFF};
byte d2_2[8]= {0x00,0x00,0x00,0x00,0x30,0x30,0x3D,0xFF};
byte d3_2[8]= {0x00,0x00,0x00,0x00,0x00,0x0C,0xCE,0xFF};
byte d4_2[8]= {0x00,0x00,0x00,0x00,0x02,0x66,0xF7,0xFF};

byte d1_3[8]= {0x00,0x00,0x00,0x92,0x92,0xB7,0xF7,0xFF};
byte d2_3[8]= {0x00,0x00,0x00,0x10,0x34,0x34,0xFD,0xFF};
byte d3_3[8]= {0x00,0x00,0x00,0x00,0x44,0x4C,0xDE,0xFF};
byte d4_3[8]= {0x00,0x00,0x00,0x40,0x64,0x66,0xFF,0xFF};

byte d1_4[8]= {0x00,0x00,0x0C,0x8C,0xCC,0xEE,0xFE,0xFF};
byte d2_4[8]= {0x00,0x00,0x20,0x30,0x34,0x76,0xFF,0xFF};
byte d3_4[8]= {0x00,0x00,0x00,0x08,0x4C,0xCD,0xFF,0xFF};
byte d4_4[8]= {0x00,0x00,0x00,0x21,0xA5,0xE7,0xFF,0xFFF};

byte d1_5[8]= {0x00,0x04,0x04,0x04,0x26,0x6E,0xFF,0xFF};
byte d2_5[8]= {0x00,0x20,0x20,0xB2,0xB3,0xF7,0xFF,0xFF};
byte d3_5[8]= {0x00,0x00,0x08,0x48,0xCD,0xED,0xEF,0xFF};
byte d4_5[8]= {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF};

byte d1_6[8]= {0x00,0x40,0x48,0x4C,0x6E,0xEE,0xFF,0xFF};
byte d2_6[8]= {0x00,0x20,0x22,0x2A,0xAF,0xEF,0xFF,0xFF};
byte d3_6[8]= {0x00,0x08,0x88,0x88,0xDD,0xFD,0xFF,0xFF};
byte d4_6[8]= {0x00,0x00,0x08,0x89,0xBB,0xFF,0xFF,0xFF};

byte d1_7[8]= {0x00,0x00,0x00,0x00,0x00,0x00,0xCF,0xFF};
byte d2_7[8]= {0x02,0x26,0x26,0xB6,0xBF,0xFF,0xFF,0xFF};
byte d3_7[8]= {0x00,0x81,0x89,0x89,0xAD,0xBF,0xFF,0xFF};
byte d4_7[8]= {0x00,0x81,0x89,0x8B,0xCB,0xDF,0xFF,0xFF};

byte d1_8[8]= {0x0C,0x0C,0x2C,0xBD,0xFF,0xFF,0xFF,0xFF};
byte d2_8[8]= {0x26,0x26,0xA6,0xB6,0xBE,0xFF,0xFF,0xFF};
byte d3_8[8]= {0x01,0x09,0x2D,0xAD,0xFD,0xFF,0xFF,0xFF};
byte d4_8[8]= {0x08,0x29,0x29,0xAB,0xFF,0xFF,0xFF,0xFF};

//animacion olas
byte ola_0[8]= {0x00,0x00,0x00,0x3C,0x7E,0xFF,0xFF,0xFF}; 
byte ola_1[8]= {0x00,0x00,0x00,0x1E,0x3F,0xFF,0xFF,0xFF};
byte ola_2[8]= {0x00,0x00,0x00,0x0F,0x9F,0xFF,0xFF,0xFF};
byte ola_3[8]= {0x00,0x00,0x00,0x87,0xCF,0xFF,0xFF,0xFF};
byte ola_4[8]= {0x00,0x00,0x00,0xC3,0xE7,0xFF,0xFF,0xFF};
byte ola_5[8]= {0x00,0x00,0x00,0xE1,0xF3,0xFF,0xFF,0xFF};
byte ola_6[8]= {0x00,0x00,0x00,0xF0,0xF9,0xFF,0xFF,0xFF};
byte ola_7[8]= {0x00,0x00,0x00,0x78,0xFC,0xFF,0xFF,0xFF};

int olass[]={ola_0, ola_1,ola_2,ola_3,ola_4,ola_5,ola_6,ola_7};

// ----------------------------------------------------------------- Setup ---------------------------------------------------------------------------------------------------------

void setup() {
  //Inicializar sensor mando  
  IrReceiver.begin(receptorMando, DISABLE_LED_FEEDBACK); 

  //Declarar el sensor de sonido como input
  pinMode (soundSensor, INPUT);
  
  lc.shutdown(0,false);
  lc.setIntensity(0,3);
  lc.clearDisplay(0);
  lc.shutdown(1,false);
  lc.setIntensity(1,3);
  lc.clearDisplay(1);
  lc.shutdown(2,false);
  lc.setIntensity(2,3);
  lc.clearDisplay(2);
  lc.shutdown(3,false);
  lc.setIntensity(3,3);
  lc.clearDisplay(3);

  // inicializar matriz de leds y bluetooth
  letrero.begin();
  BT.begin(9600);
  letrero.control(MD_MAX72XX::INTENSITY,5 );
  letrero.control( MD_MAX72XX::UPDATE, false );

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  Serial.begin(9600); 
}

void loop() {
  sensor = analogRead (soundSensor); // leo el valor del sensor (me devuelve valores entre 0 y 1023) segun el volumen. De menos (0) a más (1023)
  mediciones_prox=0;

  do{
      distancia_cm = CalcularDistancia();
      if(distancia_cm<50.0){
        mediciones_prox++;
      }
  } while((distancia_cm<50.0)&&(mediciones_prox<5));

  if ((mediciones_prox==2)||(mediciones_prox==3)){

   if(on==true){
        apagarMatriz();
        on=false;
      }
      else {
        encenderMatriz();
        on=true;
      }
  }

  if (IrReceiver.decode()) { // Si se ha pulsado un boton del mando
    Serial.println(on); 
    Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
    if (IrReceiver.decodedIRData.decodedRawData == Boton_ON){   
      if(on==true){
        apagarMatriz();
        on=false;
      }
      else {
        encenderMatriz();
        on=true;
      }
    }

    // Nueva lógica para sumar tiempo
    if (IrReceiver.decodedIRData.decodedRawData == Tecla_SUMAR) {
        if (temporizador_activo) {
            sumarTiempo(5000); // Sumar 5 segundos
        }
    }

    if (IrReceiver.decodedIRData.decodedRawData == Boton_0){
      modo=0;
    } 
    if (IrReceiver.decodedIRData.decodedRawData == Boton_1){
      modo=1;  
    }   
    if (IrReceiver.decodedIRData.decodedRawData == Boton_2){
      modo=2;
    }
    if (IrReceiver.decodedIRData.decodedRawData == Boton_3){
      modo=3;
    }
    if (IrReceiver.decodedIRData.decodedRawData == Boton_4){
      modo=4;
    }
    if (IrReceiver.decodedIRData.decodedRawData == Boton_5){
      modo=5;
    }
    IrReceiver.resume(); // continuo recibiendo señales
  }

  if(on){
    switch(modo){
      case 0:
        while(distancia_cm<50.0){
          distancia_cm = CalcularDistancia();
        VariarIntensidad(&intensidad, distancia_cm);
        }
      break;

      case 1:
          actualizar_mensaje(&modo);
          slide_text( velSlide );          
      break;

      case 2:
        Musica(sensor);
      break;

      case 3: 
      if (modo != -1) {
        if (!temporizador_activo) {
          letrero.clear(); // Limpiar la matriz
          slide_text2( velSlide2 );
          letrero.clear(); // Limpiar nuevamente la matriz después del mensaje
          encenderMatriz(); //Enciende la Matriz
          iniciarTemporizador(); // Inicia el temporizador
        }
      }
      break;

      case 4:
        iluminacionCuadros();
      break;

      case 5:
        olas();
      break;    
    }
  }
  if (temporizador_activo) {
      actualizarTemporizador();
    }
}

// --------------------------------------------------------------------- Funciones --------------------------------------------------------------------------------------------------
void encenderMatriz(){
    for(int fila = 0; fila < 8; fila++){
    for(int columna = 0; columna < 8; columna++){
      lc.setLed(0,fila, columna, true);
      lc.setLed(1,fila, columna, true);
      lc.setLed(2,fila, columna, true);
      lc.setLed(3,fila, columna, true);
    }
  }
}

void apagarMatriz(){
    for(int fila = 0; fila < 8; fila++){
    for(int columna = 0; columna < 8; columna++){
      lc.setLed(0,fila, columna, false);
      lc.setLed(1,fila, columna, false);
      lc.setLed(2,fila, columna, false);
      lc.setLed(3,fila, columna, false);
    }
  }
}

float CalcularDistancia(){
  float duration_us, distance_cm;
  // generate 10-microsecond pulse to TRIG pin
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // measure duration of pulse from ECHO pin
  duration_us = pulseIn(echoPin, HIGH);

  // calculate the distance
  distance_cm = 0.017 * duration_us;

  delay(150);
  return distance_cm;
}

void VariarIntensidad(float *intensidad, float distancia){
  int int_round;
  Serial.print("Entra a variar intensidad");
  *intensidad = 10.0 - distancia/5;
  int_round = (int)*intensidad;
   Serial.print("esta es la intensidad: ");
   Serial.println(*intensidad);
    delay(500);
  //En vez de un LED que sea la matriz
  lc.setIntensity(0,int_round);
  lc.setIntensity(1,int_round);
  lc.setIntensity(2,int_round);
  lc.setIntensity(3,int_round);
  delay(200);
}

// Función para iniciar el temporizador
void iniciarTemporizador() {
  if (!temporizador_activo) {
    //Serial.println("Iniciando temporizador");
    tiempo_restante = TIEMPO_BASE; // Reinicia el tiempo restante
    inicio_temporizador = millis();
    temporizador_activo = true;
  } 
}

// Función para sumar tiempo al temporizador
void sumarTiempo(unsigned long tiempo_adicional) {
  tiempo_restante += tiempo_adicional;
}

void actualizarTemporizador() {
  unsigned long tiempo_actual = millis();
  unsigned long tiempo_transcurrido = tiempo_actual - inicio_temporizador;

  if (tiempo_transcurrido >= tiempo_restante) {
    apagarMatriz();
    temporizador_activo = false;
    modo = -1;
  } else {
    unsigned long tiempo_restante_actual = tiempo_restante - tiempo_transcurrido;
    Serial.print("Tiempo restante: ");
    Serial.println(tiempo_restante_actual);
  }
}

void Musica(float signal){
 if (signal > filteredSignalValues[0]) {
    pintarMatriz(d1_8,0);
    pintarMatriz(d2_8,1);
    pintarMatriz(d3_8,2);
    pintarMatriz(d4_8,3);   
  } else if (signal <= filteredSignalValues[0] && signal > filteredSignalValues[1]) {
    pintarMatriz(d1_7,0);
    pintarMatriz(d2_7,1);
    pintarMatriz(d3_7,2);
    pintarMatriz(d4_7,3);
  } else if (signal <= filteredSignalValues[1] && signal > filteredSignalValues[2]) {
    pintarMatriz(d1_6,0);
    pintarMatriz(d2_6,1);
    pintarMatriz(d3_6,2);
    pintarMatriz(d4_6,3);
    Serial.println("if 3");
  } else if (signal <= filteredSignalValues[2] && signal > filteredSignalValues[3]) {
    pintarMatriz(d1_5,0);
    pintarMatriz(d2_5,1);
    pintarMatriz(d3_5,2);
    pintarMatriz(d4_5,3);
  } else if (signal <= filteredSignalValues[3] && signal > filteredSignalValues[4]) {
    pintarMatriz(d1_4,0);
    pintarMatriz(d2_4,1);
    pintarMatriz(d3_4,2);
    pintarMatriz(d4_4,3);
  } else if (signal <= filteredSignalValues[4] && signal > filteredSignalValues[5]) {
    pintarMatriz(d1_3,0);
    pintarMatriz(d2_3,1);
    pintarMatriz(d3_3,2);
    pintarMatriz(d4_3,3);
  } else if (signal <= filteredSignalValues[5] && signal > filteredSignalValues[6]) {
    pintarMatriz(d1_2,0);
    pintarMatriz(d2_2,1);
    pintarMatriz(d3_2,2);
    pintarMatriz(d4_2,3);
  } else if (signal <= filteredSignalValues[6] && signal > filteredSignalValues[7]) {
    pintarMatriz(d1_1,0);
    pintarMatriz(d2_1,1);
    pintarMatriz(d3_1,2);
    pintarMatriz(d4_1,3);
  } else {
    pintarMatriz(d1_0,0);
    pintarMatriz(d2_0,1);
    pintarMatriz(d3_0,2);
    pintarMatriz(d4_0,3);

    Serial.println("...");
  }
}

void pintarMatriz(byte character [], int display){
  int i = 0;
    for(i=0;i<8;i++)
    {
       lc.setRow(display,i,character[i]);
    }
  delay(3);

}

void iluminacionCuadros(){
  encenderMatriz();
  for(int i = 4; i >0; i--){
    lc.setIntensity(i,10);
    delay(500);
    lc.setIntensity(i,0);
  }  
}

void olas(){
for(int i = 0; i < 4; i++){
    pintarMatriz(olass[i],0);
    pintarMatriz(olass[i],1);
    pintarMatriz(olass[i],2);
    pintarMatriz(olass[i],3);}
}

// Código para el modo bluetooth
// FUNCIÓN MENSAJE
void actualizar_mensaje(int *mode){

  Serial.print(*mode);

  while( BT.available()){
    Serial.print("Entra al bluetooth");
 
    char c = BT.read();

    if (c=='*'){
        vel =  proximo_mensaje;
        valor = vel.toFloat();
        velSlide=map(valor,0,100,200,5);
      proximo_mensaje = "";
    
      break;
    }    
  
    if( c == '\n' ){
      mensaje = proximo_mensaje;
      proximo_mensaje = "";
     
      break;
    }
    else
     proximo_mensaje+=c;
  }
}
 
// FUNCIÓN SCROLL TEXTO
void slide_text(int ms_delay){
  int col = 0;
  int last_pos;
  bool completo = false;
  
  letrero.clear();
 
  while( completo == false ){
    last_pos = printText(col, mensaje);
    
    delay(ms_delay);
    col++;
    if( last_pos > (int)letrero.getColumnCount() )
      completo = true;
  }
}

void slide_text2(int ms_delay){
  int col = 0;
  int last_pos;
  bool completo = false;
  
  letrero.clear();
 
  while( completo == false ){
    last_pos = printText(col, mensaje2);
    
    delay(ms_delay);
    col++;
    if( last_pos > (int)letrero.getColumnCount() )
      completo = true;
  }
}
 
int printText(int pos, const String text){

  int w;
  
  for( int i = 0; i < text.length(); i++ ){
     
    w = letrero.setChar( pos, text[i] );    
    pos = pos - w;
    //Serial.println(pos); 
    letrero.setColumn(pos, B00000000);
    
    pos = pos - 1;
    
    if( pos < 0 )
      break;
  }
  letrero.update();
  return pos;
}

Problemas encontrados y Soluciones:

Tuvimos una serie de problemas con nuestro proyecto a lo largo del desarrollo de este, pero por suerte fuimos capaces de solucionarlos sin grandes contratiempos.
Algunos de estos fueron:

El problema de la animación de las olas y el sensor de sonido: Aquí lo que ocurría es que hicimos una versión inicial de las animaciones de las olas y del sensor del sonido sin hacerlo que funcione con el mando de primeras, pero al intentar juntarlo con el código del mando dejaban de funcionar las animaciones. Terminamos arreglándolo añadiendo los «switch case» en el código para separar cada funcionalidad de la lámpara.

Pulsadores estropeados: Cuando estábamos haciendo versiones iniciales del temporizador, lo queríamos probar primero con un pulsador y un led en la placa, en vez de con el mando y la matriz de leds, ya que sería bastante más sencillo probarlo así. El problema es que ninguno de los pulsadores que venían con nuestra caja Arduino funcionaba bien, por lo que tuvimos que hacerlo que funcionase con el mando de primeras, por suerte no fue muy difícil de implementar.

Funcionamiento impredecible del Sensor de Proximidad: También tuvimos problemas con el sensor de proximidad, y es que había veces que poniendo la mano encima se apagaba o encendía la matriz de leds, lo cual no debería de ocurrir, si no que debería simplemente de regular la intensidad de la matriz, para apagarla o encenderla hay que hacer una pasada con la mano, como se puede apreciar en el vídeo de la funcionalidad.
También ocurría lo contrario, que queríamos apagarla o encenderla haciendo una pasada con la mano y algunas veces no lo hacía y otras sí. Por suerte, la solución fue bastante sencilla, únicamente tuvimos que cambiar en el código el bucle del sensor de proximidad por un «do while» en vez del «for», que era el que estaba causando problemas.

¿Memoria de la placa Arduino saturada?: Aquí no sabemos a ciencia cierta cual era el problema, pero sospechamos que se saturaba la memoria del Arduino cuando juntábamos todo el código de la lámpara, y es que al probarlo todo junto, el bluetooth simplemente no funcionaba, no hacía nada. Después de estar bastante tiempo probando cosas, comenzamos a quitar serial prints del código que eran innecesarios y nos dimos cuenta de que ahora si funcionaba, pero a medias, y es que sí que dejaba escribir palabras para mostrarlas en la matriz, pero solamente palabras cortas, por lo que seguía sin funcionar correctamente. Finalmente quitamos la mayoría de serial prints que no eran necesarios y ya si que funcionaba todo a la perfección.

Casos de uso:

Gracias a las diversas opciones presentes que hemos añadido mediante los sensores y programando, nuestro proyecto podría utilizarse en gran cantidad de casos, siendo algunos de estos:

Mesita de noche. La lámpara se puede utilizar como en una mesita de noche, ya que funciones como cambiar la intensidad o el temporizador permiten emplear la lámpara para funciones como leer un libro o la posibilidad de que se apague de manera automática en un tiempo cuando ya estés durmiendo. Además el usar el sensor de proximidad facilita el no tener que buscar un interruptor por la noche y sin apenas luz.

Luz para niños con miedo a la oscuridad. Gracias al temporizador puedes dejar la lámpara encendida hasta que el niño se duerma y una vez que lo esté dejar que se apague sola gracias al temporizador.

Decoración ambiental para creadores de contenido. Con los diferentes patrones predefinidos, así como el sensor de sonido y la posibilidad de escribir palabras, nuestra matriz podría emplearse por creadores de contenido en sus vídeos o directos como decoración de fondo, dando así un toque personal y la posibilidad de dejar mensajes escritos para sus seguidores.

Cartel o señal de advertencia nocturna. Al igual que en el caso anterior el poder escribir palabras resulta muy útil, ya que por la noche necesitas que un cartel o señal tenga algún tipo de iluminación, y con nuestro proyecto podría utilizarse con un mensaje específico y después volver a utilizarse en otro caso. Además el diseño compacto permite que pueda colocarse ocupando poco espacio y de una manera sencilla y cómoda.

Reparto de tareas:

En cuanto al reparto del trabajo, lo hemos segmentado por funcionalidades que queríamos añadir, es decir, cada uno de los miembros se ha centrado principalmente en uno de los componentes de este y ha desarrollado las funciones que lo acontecen. Las funciones relacionadas con el sensor de ultrasonidos, como el controlar la intensidad, y la creación del soporte físico fueron desarrolladas por Víctor Manuel Moreno, las funciones del temporizador por Eduard Florea Florea, del funcionamiento del Bluetooth se encargó Héctor Santamaría y de las animaciones y la música Angie Natalia Prieto.

Una vez que conseguíamos implementar la funcionalidad deseada del sensor con un código más básico (que no estaba unido al resto de sensores) se juntaba con el código que ya llevábamos implementado con el resto de sensores y la matriz. Nos juntamos todos en una serie de sesiones para unir todas las partes del código y solucionar los errores que surgían en el proceso.

De esta manera hemos podido trabajar todos sin tener que coincidir en horarios y hemos optimizado y repartido de manera equitativa todo el proyecto.

Video Explicativo y Demostración

Autores:

  • Víctor Manuel Moreno Gutiérrez
  • Eduard Florea Florea
  • Héctor Santamaría Teclemayer
  • Angie Natalia Prieto Cuadros

También te podría gustar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *