MÁQUINA DETECTORA DE RAYOS UV
1. Primero haremos la simulación del proyecto con Scratch 2. Construcción de la maqueta: a. Se utilizará madera para su construcción b. En la parte eléctrica, situaremos el sensor de rayos UV, diodos de 10mm, y una pantalla OLED para visualizar los datos
Maquina medidora de radiación UV
Grupo UV
Página 1 de 9
Mร QUINA DETECTORA DE RAYOS UV
Tablero de la mรกquina UV
Grupo UV
Pรกgina 2 de 9
MÁQUINA DETECTORA DE RAYOS UV Conexiones interiores
3. Programación con el IDE de Arduino: a. Elementos a programar en una Placa Arduino Uno: Sensor de rayos UV, diodos y pantalla OLED. b. Entender el sensor de rayos UV: Programar su detección. Usar el módulo UVM30A no puede ser más sencillo, basta con alimentarlo y leer el voltaje con el que representa el nivel de radiación ultravioleta que detecta. Puede alimentarse con tensiones entre 3 V y 5 V y puede entregar a la salida entre 0 y 1200 mV (aunque de hecho no supere el voltio). Como por encima de 1100 mV de salida corresponde a un índice UV extremadamente alto (un índice mayor que 10) se puede usar la referencia interna de 1100 mV para distribuir mejor la sensibilidad aunque renunciando a la posibilidad de determinar cuánto se supera el índice 10, sólo estimando que se alcanzado el 11, pero ahorrando un divisor de tensión para usar como referencia de entrada analógica en Arduino. Arduino UNO es un instrumento que interacciona con el entorno y a través de sus entradas analógicas se puede utilizar para tomar medidas de diversas magnitudes físicas, transformándolas en voltaje. Estas entradas utilizan por defecto como valor de referencia 5 volts. El problema surge a la hora de convertir estas entradas analógicas en valores de voltaje. Como el microcontrolador tiene una resolución de 10 bits, sólo proporcionará 1024 valores posibles de voltaje entre 0 y 5 volts, proporcionando a la salida medidas con ruido de difícil interpretación física. Para mejorar esta resolución se pueden utilizar dos técnicas, ya sea durante la toma de los datos o en su tratamiento posterior. Las medidas de voltajes entre 0 y 5 volts proporcionan valores con una resolución de 4.8828125mV (5V/1024bits). Para evitar que el salto entre dos medidas de valores consecutivos sea demasiado grande, se puede recurrir al aumento del número de medidas. Así, la lectura de un dato determinado vendrá dado por la media aritmética de todas las medidas realizadas por Arduino en un intervalo de tiempo determinado. No lo hemos hecho. Nuestras mediciones se realizaron con el sensor a la intemperie, sin contar con algún tipo de contenedor o cristal que lo protegiera. La radiación UV se mide en W/m2 y el cálculo del Índice UV (IUV) se calcula utilizando la siguiente formula: Grupo UV
Página 3 de 9
MĂ QUINA DETECTORA DE RAYOS UV đ??źđ?‘ˆđ?‘‰ = 0.25 ∗ (đ?‘&#x;đ?‘Žđ?‘‘đ?‘–đ?‘Žđ?‘?đ?‘–Ăłđ?‘› đ?‘ˆđ?‘‰ đ?‘’đ?‘› đ?‘Š/ đ?‘š2) El tiempo de lectura del GUVA-S12SD es bastante rĂĄpido y la respuesta razonablemente estable. En los montajes de prueba, la lectura analĂłgica que se realiza del mĂłdulo UVM30A desde Arduino, seguramente por la disposiciĂłn de los cables, no es tan buena como la que da el osciloscopio, aunque resulta mĂĄs que aceptable para medir el Ăndice UV y es de esperar que en un prototipo montado en un circuito impreso incluso mejore. En cualquier caso, para tratar de eliminar las desviaciones de posibles interferencias, el programa realiza varias mediciones, tantas como sea posible en cierto periodo de tiempo, y las promedia para establecer un valor que compara con los de la tabla del fabricante para calcular el Ăndice UV. Nuestro sensor nos proporciona una medida de voltaje en mV. El valor del indice de radiaciĂłn UV lo obtenemos a partir de su medida de voltaje, segĂşn el siguiente grĂĄfico con valores que nos proporciona el fabricante:
Importante: Puesto que la lectura analógica con analogRead() tiene una resolución de 10 bits (excepto en Arduino Due y en Arduino Zero, en los que puede configurarse a 12 bits) para obtener la tensión entregada por el módulo UVM30A hay que convertir el rango de 0 a 1023, que devuelve la función, al rango que va de 0 a 1100, que son los milivoltios que se han establecido como referencia con analogReference(). Para realizar la conversión hay que multiplicar por 1100 y dividir por 1023. En el primer programa de ejemplo se usa como una constante para hacerlo en una única operación y facilitar la lectura.  Tras grabarlas, testeamos nuestro sensor para ver si las detecta o no. c. Entender cómo funcionan los diodos:  Programar un semåforo d. Programar el sensor de rayos UV para encender y apagar el diodo correspondiente. Primera parte del proyecto. Grupo UV
PĂĄgina 4 de 9
MÁQUINA DETECTORA DE RAYOS UV e. Entender como programar una pantalla para visualizar resultados Entender la programación de la pantalla OLED ¿Cómo imprimir un texto en pantalla? #include "U8glib.h" U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);
// ESTA
ES MI PANTALLA y por eso uso este constructor
void draw(void) { // Los comandos gráficos para volver a dibujar la pantalla completa deben colocarse aquí //Para las fuentes y tamaño de las fuentes, ver este link https://github.com/olikraus/u8glib/wiki/fontsize
u8g.setFont(u8g_font_unifont);
//Aquí
he
escogido
esta
fuente
https://github.com/olikraus/u8glib/wiki/fontsize
//u8g.setFont(u8g_font_osb21); //Aquí la altura del pixel es de 21 y por lo tanto, no veríamos la frase "Hello Word!" completa. Se cortaría entre la r y la d de word
u8g.drawStr( 0, 22, "Hello World!"); //En el punto (0,22) escribe Hello Word! }
void setup(void) { // Pantalla giratoria Grupo UV
Página 5 de 9
Mร QUINA DETECTORA DE RAYOS UV // u8g.setRot180(); //Con 180 se invierte
// set SPI backup if required //u8g.setHardwareBackup(u8g_backup_avr_spi);
// Asigna el valor de color. El siguiente bucle Si___EN CASO CONTRARIO SI___ no se modifica
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255);
// Blanco
} else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) { u8g.setColorIndex(3);
// Intensidad mรกxima
} else if ( u8g.getMode() == U8G_MODE_BW ) { u8g.setColorIndex(1);
// pixel on
} else if ( u8g.getMode() == U8G_MODE_HICOLOR ) { u8g.setHiColorByRGB(255,255,255); }
pinMode(8, OUTPUT); //Puede anularse en este ejemplo }
Grupo UV
Pรกgina 6 de 9
MÁQUINA DETECTORA DE RAYOS UV
void loop(void) { /*U8glib necesita una construcción de programación especial, llamada "bucle de imagen". Normalmente se puede colocar en el procedimiento loop () del programa */ // Bucle de imagen u8g.firstPage(); do { draw(); } while( u8g.nextPage() );
// Si queremos reconstruir la imagen o palabra después de algún retraso, usaremos un delay() //delay(50); } ¿Cómo crear nuestro texto en el proyecto? #include "U8glib.h" U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);
// ESTA
ES MI PANTALLA y por eso uso este constructor int yPos = 0; void draw(void) { // Los comandos gráficos para volver a dibujar la pantalla completa deben colocarse aquí //Para las fuentes y tamaño de las fuentes, ver este link https://github.com/olikraus/u8glib/wiki/fontsize Grupo UV
Página 7 de 9
MÁQUINA DETECTORA DE RAYOS UV
u8g.setFont(u8g_font_unifont);
//Aquí
he
escogido
esta
fuente
https://github.com/olikraus/u8glib/wiki/fontsize
//u8g.setFont(u8g_font_osb21); //Aquí la altura del pixel es de 21 y por lo tanto, no veríamos la frase "Hello Word!" completa. Se cortaría entre la r y la d de word
u8g.drawStr( 0, yPos, "Hola Susana!"); //En el punto (0,yPos) escribe Hola Susana }
void setup(void) { // Pantalla giratoria // u8g.setRot180(); //Con 180 se invierte
// set SPI backup if required //u8g.setHardwareBackup(u8g_backup_avr_spi);
// Asigna el valor de color. El siguiente bucle Si___EN CASO CONTRARIO SI___ no se modifica
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255);
// Blanco
} Grupo UV
Página 8 de 9
Mร QUINA DETECTORA DE RAYOS UV else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) { u8g.setColorIndex(3);
// Intensidad mรกxima
} else if ( u8g.getMode() == U8G_MODE_BW ) { u8g.setColorIndex(1);
// pixel on
} else if ( u8g.getMode() == U8G_MODE_HICOLOR ) { u8g.setHiColorByRGB(255,255,255); }
pinMode(8, OUTPUT); //Puede anularse en este ejemplo }
void loop(void) { /*U8glib necesita una construcciรณn de programaciรณn especial, llamada "bucle de imagen". Normalmente se puede colocar en el procedimiento loop () del programa */ // Bucle de imagen u8g.firstPage(); do { draw(); } while( u8g.nextPage() );
Grupo UV
Pรกgina 9 de 9
MÁQUINA DETECTORA DE RAYOS UV // Si queremos reconstruir la imagen o palabra después de algún retraso, usaremos un delay() delay(50);
//Comenzamos el scroll if(yPos < 83){ // Si baja muy lento podríamos incrementarlo por un número más alto yPos++; } else{ // Cuando estamos en la posición yPos final de la pantalla, cambia su valor a 0. yPos = 0; } } Jugando con el Lazo imagen #include "U8glib.h"
//************************************************** // Mi constructor U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK); //**************************************************
void setup() {
Grupo UV
Página 10 de 9
MÁQUINA DETECTORA DE RAYOS UV u8g.setFont(u8g_font_unifont); u8g.setColorIndex(1); }
void loop() { u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); delay(1000); u8g.firstPage(); do { draw2(); } while( u8g.nextPage() ); delay(1000); }
/*Notarás que la "Primera Línea" y la "Segunda Línea" NUNCA aparecieron en la pantalla al mismo tiempo. En otras palabras, el "Lazo de Imagen" es, funcionalmente, un comando para pintar una nueva pantalla en un lienzo nuevo. */
void draw(){
Grupo UV
Página 11 de 9
MÁQUINA DETECTORA DE RAYOS UV u8g.drawStr( 0, 15, "Primera Linea"); }
void draw2(){ u8g.drawStr( 0, 35, "Segunda Linea"); }
/* Modifica tu void draw() y tu void draw2() por los siguientes y obtendrás la foma de "LIMPIAR PANTALLA" * void draw(){ u8g.drawStr( 0, 15, "Primera Linea"); u8g.drawStr( 0, 35, "Segunda Linea"); }
void draw2(){ // Este void esta vacío } f.
Crear nuestro programa del proyecto incluyendo la pantalla OLED en el programa del punto d.
g. Comprobar que el programa final se ejecuta correctamente con estas especificaciones: Al detectar los rayos solares, mide la radiación UV. Enciende el color del diodo correspondiente al índice de radiación detectada. Muestra el índice de radiación en la pantalla OLED. 4. Conclusiones y posibles mejoras
Grupo UV
Página 12 de 9
MÁQUINA DETECTORA DE RAYOS UV Una mejora sería calcular una media de voltaje para dar el valor del índice de radiación UV. Si lo hiciéramos así, el programa sería el siguiente: // Programa que muestra el voltaje e índice UV por puerto serial cada 5 minutos //Definimos las variables int analogPin0 = 0; // el pin que usamos con el sensor es el analógico 0 int NumMedidas = 10000; // número de medidas a realizar
void setup() { // Abre puerto serial y lo configura a 9600 bps Serial.begin(9600); } //Programa void loop() { int val0 = analogRead(analogPin0);// Lee el valor de la variable que almacena las lecturas del pin0 en val0 float tot0 = tot0 + (float)val0; // almacena suma de mediciones delay(300000); // intervalo de 5 minutos para la toma de las mediciones
float voltajemedia=(tot0*4.8828125/(float)NumMedidas); // se convierte valor a voltaje en mV y se calcula la media Serial.print(voltajemedia); // imprime por serial la media de voltaje //Esta media de voltaje lo programamos para que nos ofrezca el índice de radiación UV que se asocia con cada medida }
Grupo UV
Página 13 de 9