Commit 1bd91daa authored by Sebastián Fernández's avatar Sebastián Fernández

version 0 de prototipo

parent e200466e
# Medidor UV-C
## Requerimientos funcionales
Punteo de ideas.
### Para prototipo 0
- medir radiación
- reportar radiación instantanea
......@@ -14,18 +12,55 @@ Punteo de ideas.
- switch para indicar presencia de bandeja con máscaras
- leb blanco que enciende y apaga y buzzer para indicar fin de tiempo de desinfección
- si se usa display 7 segmentos:
- normalmente muestra información relacionada con la desinfección:
- rayitas en el centro ----- si no se detecta la bandeja con máscaras
- cuenta regresiva con tiempo faltante para terminar desinfección
- un botón muestra la radiación instantanea medida al ser presionada.
- un botón reinicia la cuenta regresiva de desinfección.
- en una parte muestra información indicando si no hay bandeja o la cuenta regresiva
- en otra parte se muestra la radiación instantanea
- si se usa un diplay tipo matriz de puntos
- en una fila muestra información indicando si no hay bandeja o la cuenta regresiva
- en otra fila se muestra la radiación instantanea
- un botón reinicia la cuenta regresiva de desinfección.
El funcionamiento es simple, cuando se detecta que se acciona el switch de presencia de mascara, calcula el tiempo necesario de desinfección de acuerdo a la radiación medida y
## Diagrama flujo prototipo 0
'''
0. POWER_UP
Mide radiación
Disp_power: <potencia_medida>
Disp_remain: <apagado>
-> Bandeja no presente: 1
1. NO_LOAD_PRESENT
Mide radiación (mW/cm2)
Disp_power: <potencia_medida>
Disp_remain: <apagado>
-> Insertan bandeja: 2
2. DOSE_CALCULATION
Tiempo dosis (s) = Dosis_objetivo (mJ/cm2) / radiación medida (mW/cm2)
Disp_power: <potencia_medida>
Disp_remain: <apagado>
-> Pasa a 3
3. DOSE_APPLY
Cuenta regresiva de tiempo transcurrido
Disp_power: <potencia_medida>
Disp_remain: <cuenta_regresiva>
-> Sacan bandeja : 1
-> Cuenta llega a 0 : 4
4. DOSE_END
Alarma sonora y visual.
Disp_power: <potencia_medida>
Disp_remain: <alterna entre 0000 y 8888>
-> Sacan bandeja: 1
'''
### Para versión con leds
......@@ -41,22 +76,29 @@ El funcionamiento es simple, cuando se detecta que se acciona el switch de prese
### Caja
### Plataforma
Arduino mini o ESP32 Pico
Arduino mini o ESP32
### Sensor UV
#### Sensores que se consiguen en Uruguay.
#### Sensores que existen en Uruguay.
Interfaz analógico: ML8511
Interfaz analógico: ML8511 **No hay stock***
https://www.robotec.com.uy/productos/S168
Interfaz digital: VEML6075
Interfaz digital: VEML6075 **No hay stock***
https://www.robotec.com.uy/productos/S281
#### Opciones a nivel mundial
GUVA-S12SD
Interfaz analógica: GUVA-S12SD
https://www.digikey.com/product-detail/en/genicom-co-ltd/GUVA-S12SD/2096-GUVA-S12SDCT-ND/9960959
### Display
### Sensores de bandeja
Magneticos para evitar roturas mecánicas.
https://articulo.mercadolibre.com.uy/MLU-444040526-sensores-magneticos-para-puertas-ventanas-o-portones-_JM?quantity=1#position=2&type=item&tracking_id=e96d47ce-e028-47d7-acd5-4289fe7948e9
## Otros proyectos
HYJEIA WIRELESS DOSIMETER:
......
/* Prototipo de medidor de radiación UV
* Sebastian Fernandez
* sebfer@fing.edu.uy
*
* Plataformas:
* - ESP32 de ESPRESSIF
*
* v0.1
*
*
* LedControl library
* Instalarla y editar
* #include <avr/pgmspace.h>
* https://github.com/wayoda/LedControl
*
*/
#include <pgmspace.h>
/*
Editar "LedControl.h" y cambiar
# include <avr\pgmspace.h>
por
#if (defined(__AVR__))
# include <avr\pgmspace.h>
# else
# include <pgmspace.h>
# endif
*/
#include "LedControl.h" // 8 digit 7 segment. MAX
#include <WiFi.h> // WiFi control for ESP32
/****************************************
* Aplication parameters
****************************************/
// WiFi access point
#define WIFI_AP_NAME "este"
#define WIFI_PASSWORD "lapropia"
// UV metering
int radiation_power_theorical = 20; // mW/cm2
//int target_dose = 2500; // mJ/cm2
int target_dose = 200; // mJ/cm2
// Main application loop delay
int quant = 100; //ms
// Period of sending information
//int send_delay = 600000; //10min = 10*60*1000 ms
int send_delay = 1000; //1seg = 1000 ms
/****************************************
* Platform parameters
****************************************/
// Main application loop timers
int quant_passed = 0;
//const int quants_per_sec = 1000 / quant;
const int quants_per_sec = 1000 / quant;
// Baud rate for debug serial
#define SERIAL_DEBUG_BAUD 115200
// the Wifi radio's status
int status = WL_IDLE_STATUS;
// 7 segment
LedControl lc=LedControl(12,27,14,1);
// pin 12 is connected to the DIN pin
// pin 27 is connected to the CLK pin
// pin 14 is connected to the CS pin
// 1 as we are only using 1 MAX7219
char digitos_disp1[4] = {};
char digitos_disp2[4] = {};
// alarma
const int alarm_led_pin = 26;
const int alarm_buz_pin = 25;
int alarm_state = LOW;
// load detection
const int load_status_pin = 33;
int load_present = LOW;
// Period of sending information
int send_passed = 0; // Time passed after data was sent, milliseconds.
// UV metering
int radiation_power = radiation_power_theorical;
int total_desinfection_time = target_dose/radiation_power ; // seconds
int remaining_desinfection_time = total_desinfection_time;
// States
enum State_enum {POWER_UP, NO_LOAD_PRESENT, DOSE_CALCULATION, DOSE_APPLY, DOSE_END};
uint8_t state = POWER_UP;
/****************************************
* SETUP
****************************************/
void setup() {
// Initialize serial for debugging
Serial.begin(SERIAL_DEBUG_BAUD);
// the zero refers to the MAX7219 number, it is zero for 1 chip
lc.shutdown(0,false);// turn off power saving, enables display
lc.setIntensity(0,10);// sets brightness (0~15 possible values)
lc.clearDisplay(0);// clear screen
// initialize alarm pins
pinMode(alarm_led_pin, OUTPUT);
ledcSetup(0,1E5,12);
ledcAttachPin(alarm_buz_pin,0);
// init load sensor pin
pinMode(load_status_pin, INPUT);
// Initialize Wifi
// Serial.println("==== wifi setup ====");
// WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
// InitWiFi();
}
/****************************************
* MAIN LOOP
****************************************/
void loop() {
delay(quant);
switch(state)
{
///////////////////////////////////////
case POWER_UP:
Serial.println("state: POWER_UP");
if(loadPresent()==LOW){
state = NO_LOAD_PRESENT;
}
lc.clearDisplay(0);
// Get radiation power and show it.
radiation_power = getRadiationPower();
snprintf(digitos_disp1,5,"%04d", radiation_power);
displayRadiationPower(digitos_disp1);
break;
///////////////////////////////////////
case NO_LOAD_PRESENT:
Serial.println("state: NO_LOAD_PRESENT");
if(loadPresent()==HIGH){
state = DOSE_CALCULATION;
}
lc.clearDisplay(0);
// Get radiation power and show it.
radiation_power = getRadiationPower();
snprintf(digitos_disp1,5,"%04d", radiation_power);
displayRadiationPower(digitos_disp1);
break;
///////////////////////////////////////
case DOSE_CALCULATION:
Serial.println("state: DOSE_CALCULATION");
state = DOSE_APPLY;
quant_passed = 0;
remaining_desinfection_time = total_desinfection_time;
break;
///////////////////////////////////////
case DOSE_APPLY:
Serial.println("state: DOSE_APPLY");
quant_passed += 1;
if (quant_passed >= quants_per_sec){
remaining_desinfection_time -=1;
quant_passed = 0;
}
if(loadPresent()==LOW){
state = NO_LOAD_PRESENT;
} else if (remaining_desinfection_time == 0){
state = DOSE_END;
quant_passed = 0;
alarm_state = LOW;
}
// Get radiation power and show it.
radiation_power = getRadiationPower();
snprintf(digitos_disp1,5,"%04d", radiation_power);
displayRadiationPower(digitos_disp1);
// Show remaining time
snprintf(digitos_disp2,5,"%04d", remaining_desinfection_time);
displayRemainingDesinfectionTime(digitos_disp2);
break;
///////////////////////////////////////
case DOSE_END:
Serial.println("state: DOSE_END");
quant_passed += 1;
if (quant_passed >= quants_per_sec){
quant_passed = 0;
alarm_state = not(alarm_state);
digitalWrite(alarm_led_pin, alarm_state);
if (alarm_state) {
ledcWriteTone(0,800);
snprintf(digitos_disp2,5,"%04d", 0);
displayRemainingDesinfectionTime(digitos_disp2);
}
else {
ledcWriteTone(0,0);
snprintf(digitos_disp2,5,"%04d", 8888);
displayRemainingDesinfectionTime(digitos_disp2);
}
}
if(loadPresent()==LOW){
state = NO_LOAD_PRESENT;
ledcWriteTone(0,0);
digitalWrite(alarm_led_pin, 0);
}
break;
}
// Reconnect to WiFi, if needed
/*
if (WiFi.status() != WL_CONNECTED) {
reconnect();
return;
}
*/
}
/****************************************
* AUX FUNCTIONS
****************************************/
int loadPresent()
{
// HIGH if load to germinize present
return digitalRead(load_status_pin);
}
int getRadiationPower()
{
return radiation_power_theorical;
}
void displayRadiationPower(const char *chars4) {
//lc.clearDisplay(0);
//for (int i = 0; i < 5 && chars4[i] != 0; i++) {
for (int i = 0; i < 4; i++) {
lc.setChar(0, 7 - i, chars4[i], false);
}
}
void displayRemainingDesinfectionTime(const char *chars4) {
//lc.clearDisplay(0);
for (int i = 0; i < 4; i++) {
Serial.print(i);
Serial.print("-->");
Serial.println(chars4[i]);
lc.setChar(0, 3 - i, chars4[i], false);
}
}
void InitWiFi()
{
Serial.println("Connecting to AP ...");
// attempt to connect to WiFi network
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
void reconnect() {
// Loop until we're reconnected
status = WiFi.status();
if ( status != WL_CONNECTED) {
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
}
/****************************************
* Trash
****************************************/
//lc.setRow(0,0,B00000001); // on g segment (center)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment