Código Alcoholímetro Arduino UNO

Amigos, estoy con un proyecto de mi hijo y necesitamos ayuda con arreglar un pequeño código,
NO sabemos nada de estos temas soy Administrador de empresas y necesitamos hacer un Alcoholimetro, sucede que ya logré hacer el código.

La idea es que lea el código, lo despliegue en la pantalla, eso funciona, paralelamente si la lectura es superior a 4, encienda un buzzer y un led rojo, y si la lectura es menor a 4, mantener encendido un led verde.

lo que sucede mal es que cuando solo tengo en el código la parte desplegar la lectura funciona bien, pero cuando adjunto las líneas correspondientes al funcionamiento del buzzer y led, las lecturas me les agrega un UNO como prefijo de la lectura que no se de donde sale, por si me pueden ayudar a corregir.

Gracias

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);

#define p_clk 3
#define p_rst 2
#define p_mq3 A0



int s_mq3,val_i=0;
byte i_acentuada[8] = {
  0b00001,
  0b00010,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00000
};
void setup() 
{
  lcd.init();
  lcd.createChar(0, i_acentuada);
  lcd.backlight();
  Serial.begin(115200);
    lcd.setCursor(2,0);
  lcd.print("Alcohol");
  lcd.write((uint8_t)0);
  lcd.print("metro");
  pinMode(p_clk,OUTPUT);
  pinMode(p_rst,OUTPUT);
  pinMode(13,OUTPUT);  // Configura el Pin 13 como salida para un zumbador y como salida visual para la alarma
  pinMode(12,OUTPUT);
  digitalWrite(p_rst,1);
  delay(1);
  digitalWrite(p_rst,0);
  for(int x=0;x<50;x++)
  {
        val_i=val_i+analogRead(p_mq3);
    delay(10);
  }
  val_i=val_i/50;
  Serial.println(val_i);
  
}
void loop() {
  s_mq3 = analogRead(p_mq3);
  Serial.print("ADC sensor = ");
  Serial.println(s_mq3);
  s_mq3 = map(s_mq3,val_i,900,0,9);
  Serial.print("Nivel Alcohol = ");
  Serial.println(s_mq3);
  lcd.setCursor(0,1);
  lcd.print("NA(0-9): ");
  lcd.setCursor(10,1);
  lcd.print(s_mq3);


    if(s_mq3>0)
 {
 for(int x=1;x<=s_mq3;x++) 
    {
      digitalWrite(p_clk,1);
      delay(1);
      digitalWrite(p_clk,0);
    }
 digitalWrite(p_rst,1);
 delay(100);
 digitalWrite(p_rst,0);
  }

 if(s_mq3<4) // Si la medida de alcohol es mayor de valor limite
    digitalWrite(12, HIGH);   // Enciende el zumbador conectado al Pin 13 y también este LED
    else { // Si el valor de la medida de alcohol es menor al valor limite apaga el zumbador y al led del pin 13
   digitalWrite(12, LOW);  // Apaga el zumbador conectado al Pin 13 y también este LED
    }
    
  if(s_mq3>=4) // Si la medida de alcohol es mayor de valor limite
    digitalWrite(13, HIGH);   // Enciende el zumbador conectado al Pin 13 y también este LED
   else { // Si el valor de la medida de alcohol es menor al valor limite apaga el zumbador y al led del pin 13
   digitalWrite(13, LOW);  // Apaga el zumbador conectado al Pin 13 y también este LED
    }

delay (100);
}

¿El "UNO" es un número o el carácter "i_acentuada"?

¿Mostrarías una foto de tu LCD? Además, el siguiente es el método preferido para mostrar el código:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

#define p_clk 3
#define p_rst 2
#define p_mq3 A0

int s_mq3, val_i = 0;
byte i_acentuada[8] = {
  0b00001,
  0b00010,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00000
};
void setup()
{
  lcd.init();
  lcd.createChar(0, i_acentuada);
  lcd.backlight();
  Serial.begin(115200);
  lcd.setCursor(2, 0);
  lcd.print("Alcohol");
  lcd.write((uint8_t)0);
  lcd.print("metro");
  pinMode(p_clk, OUTPUT);
  pinMode(p_rst, OUTPUT);
  pinMode(13, OUTPUT); // Configura el Pin 13 como salida para un zumbador y como salida visual para la alarma
  pinMode(12, OUTPUT);
  digitalWrite(p_rst, 1);
  delay(1);
  digitalWrite(p_rst, 0);
  for (int x = 0; x < 50; x++)
  {
    val_i = val_i + analogRead(p_mq3);
    delay(10);
  }
  val_i = val_i / 50;
  Serial.println(val_i);

}
void loop() {
  s_mq3 = analogRead(p_mq3);
  Serial.print("ADC sensor = ");
  Serial.println(s_mq3);
  s_mq3 = map(s_mq3, val_i, 900, 0, 9);
  Serial.print("Nivel Alcohol = ");
  Serial.println(s_mq3);
  lcd.setCursor(0, 1);
  lcd.print("NA(0-9): ");
  lcd.setCursor(10, 1);
  lcd.print(s_mq3);

  if (s_mq3 > 0)

  {
    for (int x = 1; x <= s_mq3; x++)
    {
      digitalWrite(p_clk, 1);
      delay(1);
      digitalWrite(p_clk, 0);
    }
    digitalWrite(p_rst, 1);
    delay(100);
    digitalWrite(p_rst, 0);
  }

  if (s_mq3 < 4) // Si la medida de alcohol es mayor de valor limite
    digitalWrite(12, HIGH); // Enciende el zumbador conectado al Pin 13 y también este LED
  else { // Si el valor de la medida de alcohol es menor al valor limite apaga el zumbador y al led del pin 13
    digitalWrite(12, LOW); // Apaga el zumbador conectado al Pin 13 y también este LED
  }

  if (s_mq3 >= 4) // Si la medida de alcohol es mayor de valor limite
    digitalWrite(13, HIGH); // Enciende el zumbador conectado al Pin 13 y también este LED
  else { // Si el valor de la medida de alcohol es menor al valor limite apaga el zumbador y al led del pin 13
    digitalWrite(13, LOW); // Apaga el zumbador conectado al Pin 13 y también este LED
  }

  delay (100);
}

Claro, Gracias por apoyarme

La rutina comienza bien, pero después de un par de lecturas en el sensor me pone ese 1 después de la lectura correcta y hasta comienza a ponerme lecturas negativas. Creo hice bien al pegar el codigo. me dejas saber y de nuevo gracias.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);

#define p_clk 3
#define p_rst 2
#define p_mq3 A0



int s_mq3,val_i=0;
byte i_acentuada[8] = {
  0b00001,
  0b00010,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00000
};
void setup() 
{
  lcd.init();
  lcd.createChar(0, i_acentuada);
  lcd.backlight();
  Serial.begin(115200);
    lcd.setCursor(2,0);
  lcd.print("Alcohol");
  lcd.write((uint8_t)0);
  lcd.print("metro");
  pinMode(p_clk,OUTPUT);
  pinMode(p_rst,OUTPUT);
  pinMode(13,OUTPUT);  // Configura el Pin 13 como salida para un zumbador y como salida visual para la alarma
  pinMode(12,OUTPUT);
  digitalWrite(p_rst,1);
  delay(1);
  digitalWrite(p_rst,0);
  for(int x=0;x<50;x++)
  {
        val_i=val_i+analogRead(p_mq3);
    delay(10);
  }
  val_i=val_i/50;
  Serial.println(val_i);
  
}
void loop() {
  s_mq3 = analogRead(p_mq3);
  Serial.print("ADC sensor = ");
  Serial.println(s_mq3);
  s_mq3 = map(s_mq3,val_i,900,0,9);
  Serial.print("Nivel Alcohol = ");
  Serial.println(s_mq3);
  lcd.setCursor(0,1);
  lcd.print("NA(0-9): ");
  lcd.setCursor(10,1);
  lcd.print(s_mq3);


    if(s_mq3>0)
 {
 for(int x=1;x<=s_mq3;x++) 
    {
      digitalWrite(p_clk,1);
      delay(1);
      digitalWrite(p_clk,0);
    }
 digitalWrite(p_rst,1);
 delay(100);
 digitalWrite(p_rst,0);
  }

 if(s_mq3<4) // Si la medida de alcohol es menor de 3
    digitalWrite(12, HIGH);   // Enciende el prende led conectado al Pin 12 
    else { // Si el valor de la medida de alcohol es menor al valor limite apaga el led del pin 12
   digitalWrite(12, LOW);  // Apaga el led conectado al Pin 12
    }
    
  if(s_mq3>=4) // Si la medida de alcohol es mayor de 4
    digitalWrite(13, HIGH);   // Enciende el zumbador conectado al Pin 13 y también este LED
   else { // Si el valor de la medida de alcohol es menor al valor limite apaga el zumbador y al led del pin 13
   digitalWrite(13, LOW);  // Apaga el zumbador conectado al Pin 13 y también este LED
    }

delay (100);
}

Hola @momocr he probado tu codigo no con tu sensor que no lo tengo pero si con el mq135 y todo parece ir bien, al menos detecta el gas de un mechero, sin dar ninguna impresion raras en el lcd.

Si te esta dando valores negativos es por el calculo de la funcion map, porque el valor inicial de val_i es superior (*) que los posteriores leidos del sensor y almacenado en la variable s_mq3
El uno puede ser producido por una lectura anomala que da como resultado un 11 a la salida del map. Añade despues de la impresion de s_mq3 un par de espacios en blanco para borrarlo.

¿Que conectas en los pines 2 y 3 ?

Edicion: (*): Me pasa cuando inicio el codigo sin tener conectado el sensor o fallando la conexion al pin analogico en el inicio.

Prueba así a ver si ese "1" es un caracter residual (yo no puedo hacerlo en este momento)

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);

#define p_clk 3
#define p_rst 2
#define p_mq3 A0



int s_mq3,val_i=0;
byte i_acentuada[8] = {
  0b00001,
  0b00010,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00000
};
void setup() 
{
  lcd.init();
  lcd.createChar(0, i_acentuada);
  lcd.backlight();
  Serial.begin(115200);
    lcd.setCursor(2,0);
  lcd.print("Alcohol");
  lcd.write((uint8_t)0);
  lcd.print("metro");
  pinMode(p_clk,OUTPUT);
  pinMode(p_rst,OUTPUT);
  pinMode(13,OUTPUT);  // Configura el Pin 13 como salida para un zumbador y como salida visual para la alarma
  pinMode(12,OUTPUT);
  digitalWrite(p_rst,1);
  delay(1);
  digitalWrite(p_rst,0);
  for(int x=0;x<50;x++)
  {
        val_i=val_i+analogRead(p_mq3);
    delay(10);
  }
  val_i=val_i/50;
  Serial.println(val_i);
  
}
void loop() {
  s_mq3 = analogRead(p_mq3);
  Serial.print("ADC sensor = ");
  Serial.println(s_mq3);
  s_mq3 = map(s_mq3,val_i,900,0,9);
  Serial.print("Nivel Alcohol = ");
  Serial.println(s_mq3);
  lcd.setCursor(0,1);
  lcd.print("NA(0-9): ");
  lcd.setCursor(10,1);
  lcd.print(s_mq3);
  lcd.print("  "); // dos espacios

    if(s_mq3>0)
 {
 for(int x=1;x<=s_mq3;x++) 
    {
      digitalWrite(p_clk,1);
      delay(1);
      digitalWrite(p_clk,0);
    }
 digitalWrite(p_rst,1);
 delay(100);
 digitalWrite(p_rst,0);
  }

 if(s_mq3<4) // Si la medida de alcohol es menor de 3
    digitalWrite(12, HIGH);   // Enciende el prende led conectado al Pin 12 
    else { // Si el valor de la medida de alcohol es menor al valor limite apaga el led del pin 12
   digitalWrite(12, LOW);  // Apaga el led conectado al Pin 12
    }
    
  if(s_mq3>=4) // Si la medida de alcohol es mayor de 4
    digitalWrite(13, HIGH);   // Enciende el zumbador conectado al Pin 13 y también este LED
   else { // Si el valor de la medida de alcohol es menor al valor limite apaga el zumbador y al led del pin 13
   digitalWrite(13, LOW);  // Apaga el zumbador conectado al Pin 13 y también este LED
    }

delay (100);
}

Saludos

PD: Cambia urgentemente el título del tema porque te van a llamar la atención, el título de ser descriptivo del problema independientemente de que Costa Rica necesite ayuda (o no, no lo sé). :crazy_face:

1 Like

Gracias, por tomarte el tiempo de ayudarme, ya incluí la línea vamos a probar, en los pines 2 y 3, nada.

Gracias, voy a probar, jaja, Gracias por la recomendación, ya cambié el título.

¿Entonces para que haces?

 digitalWrite(p_rst,1);
  delay(1);
  digitalWrite(p_rst,0);

en el setup y:

    if(s_mq3>0)
 {
 for(int x=1;x<=s_mq3;x++) 
    {
      digitalWrite(p_clk,1);
      delay(1);
      digitalWrite(p_clk,0);
    }
 digitalWrite(p_rst,1);
 delay(100);
 digitalWrite(p_rst,0);
  }

En el loop. Quitanos si no hacen nada.

1 Like

Si pero no quitaste la palabra "Ayuda" que es obvia (salvo que solo pases a saludar :grimacing: )

Gracias, cambiado,

saludos, como comenté NADA sé de estos temas, pero estoy apoyando a mi hijo con este proyecto, ya el código esta bastante estable y logré hacerlo leyendo mucho y con aportes de varias personas y hasta algunos caprichos personales he logrado incluir.

ahora, la solicitud es, será posible alguien me ayuda a incluir la explicación sencilla en cada linea, //, tengo alguna idea de que hace pero expresarlo en términos correctos me es complicado, se agradece la ayuda.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);

#define p_clk 3
#define p_rst 2
#define p_mq3 A0



int s_mq3,val_i=0;
byte i_acentuada[8] = {
  0b00001,
  0b00010,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00000
};
void setup() 
{
  lcd.init();
  lcd.createChar(0, i_acentuada);
  lcd.backlight();
  Serial.begin(115200);
    lcd.setCursor(2,0);
  lcd.print("Alcohol");
  lcd.write((uint8_t)0);
  lcd.print("metro");
  pinMode(p_clk,OUTPUT);
  pinMode(p_rst,OUTPUT);
  pinMode(13,OUTPUT);  // Configura el Pin 13 como salida para un zumbador y como salida visual para la alarma
  pinMode(12,OUTPUT);  // para led verde 
  digitalWrite(p_rst,1);
  delay(1);
  digitalWrite(p_rst,0);
  for(int x=0;x<50;x++)
  {
        val_i=val_i+analogRead(p_mq3);
    delay(10);
  }
  val_i=val_i/50;
  Serial.println(val_i);
  
}
void loop() {
  s_mq3 = analogRead(p_mq3);
  Serial.print("ADC sensor = ");
  Serial.println(s_mq3);
  s_mq3 = map(s_mq3,val_i,900,0,9);
  Serial.print("Nivel Alcohol = ");
  Serial.println(s_mq3);
  lcd.setCursor(0,1);
  lcd.print("NA(0-9): ");
  lcd.setCursor(10,1);
  lcd.print(s_mq3);
  lcd.print("  "); // dos espacios


    if(s_mq3>0)
 {
 for(int x=1;x<=s_mq3;x++) 
    {
      digitalWrite(p_clk,1);
      delay(1);
      digitalWrite(p_clk,0);
    }
 digitalWrite(p_rst,1);
 delay(100);
 digitalWrite(p_rst,0);
  }

 if(s_mq3>0 && s_mq3<4) // Si la medida de alcohol es menor de 4 y mayor a 1, led verde prende
    digitalWrite(12, HIGH);   // Enciende el prende led conectado al Pin 12 
    else { // Si el valor de la medida de alcohol es menor al valor limite apaga el led del pin 12
   digitalWrite(12, LOW);  // Apaga el led conectado al Pin 12
    }
    
  if(s_mq3>=4) // Si la medida de alcohol es mayor de 4
    digitalWrite(13, HIGH);   // Enciende el zumbador conectado al Pin 13 y también este LED
   else { // Si el valor de la medida de alcohol es menor al valor limite apaga el zumbador y  led del pin 13
   digitalWrite(13, LOW);  // Apaga el zumbador conectado al Pin 13 y también este LED
    }

delay (100);
}

Como dices en el post #6 que en los pines 2 y 3 no tenias conectado nada me tomo la libertad de suprimir del codigo todo lo referente a ellos. De todas formas sin saber lo que era no tenia ni idea de para que servia ni que podia estar conectado a ellos.
Veamos si asi lo entiendes mejor, ya lo simplificas como mas te guste.

//Se le dice al compilador las lbrerias necesarias a usar
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

/*Le incicamos a libreria del lcd el nombre (lcd (*)), la direccion (0x27), para comunicarse
  con la LCD y que esta tiene 2 lineas de 16 caracteres */
LiquidCrystal_I2C lcd(0x27, 16, 2);


#define p_mq3 A0 // cada vez que escribamos p_mq3 el compilador lo cambiara por el pin A0

int s_mq3, val_i = 0;// Se cean dos variables de tipo entero y a la segunda se le asigna como valor 0
//aunque s_mq3 por defecto tambien se crea con valor 0. Hubiera valido con: int s_mq3, val_i;

// Se define  un caracter especial que por defecto no trae la libreria de la pantalla (observa  el dibujito que crean los unos)
byte i_acentuada[8] = {
  0b00001,
  0b00010,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100
};


void setup() {// todo lo incluido dentro del setup se ejecutara una sola vez

  lcd.init(); // inicia la pantalla (lcd el nombre que le dimos antes)
  lcd.createChar(0, i_acentuada);//Guarda el caracter especial que creamos antes en la posicion 0 en memoria de libreria
  lcd.backlight(); // Encendemos la luz de fondo del lcd

  /*Antes deciamos lcd. para referirnos a la pantalla lcd, ahora decimos Serial. porque nos referimos a otro dispositivo.
    Serial es el puerto de comunicaciones por defecto para comunicarnos con el pc con el Monitor serie o con un dispositivo
    serie conectado a los pines cero y uno */
  Serial.begin(115200); // fijamos la velocidad en baudios de la comunicacion

  lcd.setCursor(2, 0);//preparamos la lcd para que empiece a escribir en el tercer caracter de la linea 1
  lcd.print("Alcohol");//escribimos, ojo ahora el cursor queda en 9,0
  lcd.write((uint8_t)0);//escribimos el caracter especial "í" definido y cargado anteriormente (cursor en 10,0)
  lcd.print("metro");// escribimos, se queda el cursor en (14,0)

  pinMode(13, OUTPUT); // Configura el Pin 13 como salida para un zumbador y como salida visual para la alarma
  pinMode(12, OUTPUT);// Configura el Pin 12 como salida para el led verde

  for (int x = 0; x < 50; x++) {
  //leemos y acumulamos 50 lecturas del sensor en val_i
    val_i = val_i + analogRead(p_mq3);// al valor actual de val_i le sumamos una nueva lectura del sensor
    delay(10);// espera 10 milisegundos
  }
  val_i = val_i / 50;// al dividir por 50 hacemos la media de las 50 lecturas,supongo que es una especie de calibracion inicial.

  Serial.println(val_i);// imprimimos en el pc el valor calculado
}

void loop() {// lo incluido en el loop se repetira indefinidamente.
  s_mq3 = analogRead(p_mq3);// leemos el sensor
  Serial.print("ADC sensor = ");// se escribe el texto en el pc sin cambiar de linea
  Serial.println(s_mq3); //se escribe el valor leido del sensor en el pc y se cambia de linea

  /*Se transforman, adaptan, etc.  proporcionalmente los valores de s_mq3, (lecturas del sensor), de los valores que realmente se pueden
    leer que van de val_i , (recuerda que en val_i calculamos la media de 50 lecturas como calibracion en aire sin alcohol), a 900 ,(valor
    que no se de donde sale yo pondria 1023 que es el maximo posible),a los valores que nos interesa imprimir de cero a nueve.*/
  s_mq3 = map(s_mq3, val_i, 900, 0, 9);
  // Lee en ayuda/referencia la funcion map para mas claridad.

  Serial.print("Nivel Alcohol = ");// se escribe el texto en el pc sin cambiar de linea
  Serial.println(s_mq3);//se escribe el valor leido del sensor en el pc y se cambia de linea
  //como ahora empezamos por lcd. se actuara sobre la pantalla lcd
  lcd.setCursor(0, 1);//preparamos la lcd para que empiece a escribir en el primer caracter de la linea 2
  lcd.print("NA(0-9): ");//escribimos, ojo ahora el cursor queda en 9,1
  lcd.setCursor(10, 1); // al haber terminado el texto anterior con un espacio en blanco creo que esta linea podria sobrar
  lcd.print(s_mq3);//imprimimos donde este el cursor el valor ya "mapeado" de la lectura del sensor
  lcd.print("  "); // dos espacios para borrar posibles valores erroneos anteriores

  // el resto ya lo has comentado tu pero un poco mal, Te pongo los cambios en mayusculas.

  if (s_mq3 < 4) // Si la medida de alcohol es menor de 3
    digitalWrite(12, HIGH);   // Enciende el prende led conectado al Pin 12
  else { // SI NO SE CUMPLE LO ANTERIOR ES DECIR el valor de la medida de alcohol es MAYOR al valor limite apaga el led del pin 12
    digitalWrite(12, LOW);  // Apaga el led conectado al Pin 12
  }

  if (s_mq3 >= 4) // Si la medida de alcohol es mayor de 4
    digitalWrite(13, HIGH);   // Enciende el zumbador conectado al Pin 13 y también este LED
  else { // SI NO SE CUMPLE LO ANTERIOR ES DECIR el valor de la medida de alcohol es menor al valor limite apaga el zumbador y al led del pin 13
    digitalWrite(13, LOW);  // Apaga el zumbador conectado al Pin 13 y también este LED
  }

  delay (100);// espera de 100 milisegundos.
}
1 Like

De verdad se agradece. Genio.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.