Go Down

Topic: Optimizacion de codigo (Read 170 times) previous topic - next topic

Mauroosl

Gente, buenas tardes.
 El codigo que les dejo al final es de un sensor de ultrasonido HC-SR04 con un display 16x2 I2C, marcando maximo, medio y minimo con 3 led's
1 led rojo como nivel minimo
1 led amarillo como nivel medio
1 led verde como nivel maximo
Junto con el led rojo se enciende un buzzer alertando.

Quisiera saber si hay alguna forma de mejorarlo. Saludos!

Code: [Select]

[code]
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int trigPin = 9;
const int echoPin = 10;
long duracion;
int distancia;
int ultimaDistancia = 0;
LiquidCrystal_I2C lcd(0x27,16,2);
void setup()
{
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
}
void loop()
{
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duracion = pulseIn(echoPin, HIGH);
  distancia = (duracion * 0.034) / 2;
  Serial.println(distancia);
  if(distancia != ultimaDistancia)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Distancia: "); // Prints string "Distance" on the LCD
    lcd.print(distancia);
    lcd.print(" cm");
    ultimaDistancia = distancia;
  }
  delay(500);
 
  if (distancia >=40 && distancia <= 400 )
    {
      analogWrite (13,200);
      analogWrite (6,0);
      analogWrite (7,0);
      lcd.setCursor(0,0);
      lcd.print("Distancia normal");
    }

   if (distancia >=20 && distancia <= 40 )
    {
      analogWrite (13,0);
      analogWrite (6,200);
      analogWrite (7,0);
      lcd.setCursor(0,0);
      lcd.print("Distancia dudosa");
    }
    if (distancia >=5 && distancia <= 20 )
    {
      analogWrite (13,0);
      analogWrite (11,255);
      delay (100);
      analogWrite (11,0);
      delay(100);
      analogWrite (6,0);
      analogWrite (7,200);
      lcd.setCursor(3,0);
      lcd.print("ALERTA!!!!");
    }
}
[/code]

gatul

No entiendo por qué usas PWM para encender los LED, yo usaría esos pines directamente como salida con
Code: [Select]

digitalWrite(13, HIGH);

Por ejemplo (obviamente hay que definirlo como OUTPUT en  setup() )

Te van a "retar" por los delay(). En lo personal no me molestan salvo que en ese tiempo perdido pudiese hacer otra cosa o interfieran con algún proceso.

Saludos

Mauroosl

Hola gatul, ahi lo arregle

Code: [Select]

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int trigPin = 9;
const int echoPin = 10;
long duracion;
int distancia;
int ultimaDistancia = 0;
LiquidCrystal_I2C lcd(0x27,16,2);
void setup()
{
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode (13, OUTPUT);
  pinMode (7, OUTPUT);
  pinMode (6, OUTPUT);
  pinMode (11,OUTPUT);
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
}
void loop()
{
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duracion = pulseIn(echoPin, HIGH);
  distancia = (duracion * 0.034) / 2;
  Serial.println(distancia);
  if(distancia != ultimaDistancia)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Distancia: "); // Prints string "Distance" on the LCD
    lcd.print(distancia);
    lcd.print(" cm");
    ultimaDistancia = distancia;
  }
  delay(500);
 
  if (distancia >=40 && distancia <= 400 )
    {
      digitalWrite (13,HIGH);
      digitalWrite (6,LOW);
      analogWrite (7,LOW);
      lcd.setCursor(0,0);
      lcd.print("Distancia normal");
    }

   if (distancia >=20 && distancia <= 40 )
    {
      digitalWrite (13,LOW);
      digitalWrite (6,HIGH);
      digitalWrite (7,LOW);
      lcd.setCursor(0,0);
      lcd.print("Distancia dudosa");
    }
    if (distancia >=5 && distancia <= 20 )
    {
      digitalWrite (13,LOW);
      digitalWrite (11,HIGH);
      delay (300);
      digitalWrite (11,LOW);
      delay(100);
      digitalWrite (6,LOW);
      digitalWrite (7,HIGH);
      lcd.setCursor(3,0);
      lcd.print("ALERTA!!!!");
    }
}

Lo que me esta pasando tambien, es que cuando me aparece escrito "alerta!!" se superpone con "distancia: 5cm"

gatul

Ahí ya no te puedo orientar, todavía no me he enredado con displays.

bosoft

#4
Nov 22, 2020, 09:25 am Last Edit: Nov 22, 2020, 09:25 am by bosoft
Hola
Tienes un fallo muy común en el uso del lcd.
Puedes hacer 2 cosas al presentar Alerta!!!

Code: [Select]

   if (distancia >=5 && distancia <= 20 )
    {
      digitalWrite (13,LOW);
      digitalWrite (11,HIGH);
      delay (300);
      digitalWrite (11,LOW);
      delay(100);
      digitalWrite (6,LOW);
      digitalWrite (7,HIGH);
// opción 1
      lcd.clear();   // borrar pantalla antes
      lcd.setCursor(3,0);
      lcd.print("ALERTA!!!!");
// fin opción 1
//-----------------------------------
// opción 2
      lcd.setCursor(0,0);
      lcd.print("   ALERTA!!!!   ");  // rellenar el resto de la linea con espacios
// fin opción 2
    }



Saludos



Mauroosl

#5
Nov 22, 2020, 01:54 pm Last Edit: Nov 22, 2020, 01:56 pm by Mauroosl
Actualizacion:

A continuacion dejo el codigo (que se podria decir que queda mejor que el anterior) junto con el diagrama hecho en Fritzing

Ahora el unico problema es que los led's iluminan poco, tienen una resistencia 1k Ohm cada una ( incluso el buzzer). Y si pongo el cable directo (sin resistencia) no hace efecto, es decir, me sigue iluminando poco

Code: [Select]

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int trigPin = 9;
const int echoPin = 10;
long duracion;
int distancia;
int ultimaDistancia = 0;
LiquidCrystal_I2C lcd(0x27,16,2);
void setup()
{
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
}
void loop()
{
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duracion = pulseIn(echoPin, HIGH);
  distancia = (duracion * 0.034) / 2;
  Serial.println(distancia);
  if(distancia >= 30 && distancia <= 200)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Distancia normal");
    lcd.setCursor (5, 1);
    lcd.print(distancia);
    lcd.print(" cm");
    ultimaDistancia = distancia;
    digitalWrite (6, LOW);
    digitalWrite (13, HIGH);
    digitalWrite (7, LOW);
  }
  delay(300);

    if(distancia >= 15 && distancia <= 30)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Distancia dudosa");
    lcd.setCursor (5, 1);
    lcd.print(distancia);
    lcd.print(" cm");
    ultimaDistancia = distancia;
    digitalWrite (6, HIGH);
    digitalWrite (13, LOW);
    digitalWrite (7, LOW);
  }
  //delay(300);


    if(distancia >= 5 && distancia <= 15)
  {
    lcd.clear();
    lcd.setCursor(5, 0);
    lcd.print("ALERTA");
    delay (500);
    digitalWrite (11, HIGH);
    delay (50);
    lcd.clear();
    lcd.setCursor (5, 1);
    lcd.print ("ALERTA");
    delay (500);
    digitalWrite (11, LOW);
    delay (50);
    lcd.clear ();
    digitalWrite (6, LOW);
    digitalWrite (13, LOW);
    digitalWrite (7, HIGH);
  }
}




gatul

#6
Nov 22, 2020, 08:28 pm Last Edit: Nov 22, 2020, 08:30 pm by gatul
Las resistencias para los diodos LED tienen que ser de 330 o 470 ohms para que trabajen aproximadamente a 15 o 10 mA, respectivamente.
Si igual no iluminan bien, prueba con otros diodos.

Revisa el último código porque olvidaste definir 6, 7 y 13 como OUTPUT.

surbyte

Hay algunas correccione para hacer en los condicionales.

Code: [Select]
   if (distancia >= 30 && distancia <= 200)  {

    if (distancia >= 15 && distancia < 30) {

    if (distancia >= 5 && distancia < 15) {


nunca pueden ser todos <= o >=
los límites deben contener a uno y no contenerlo a otro. Lo que planteo es una alternativa

Otra mejora posible es esta

Creas una función

Code: [Select]
int ultrasonido() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duracion = pulseIn(echoPin, HIGH);
return (duracion * 0.034) / 2;
}


y en el loop llamas asi

Code: [Select]
distancia = ultrasonido();
Serial.println(distancia);


Agregaría un par de detalles mas como por ejemplo, al final de los if poner
Code: [Select]
ultimaDistancia = distancia;
delay(300);


Y no repetir en cada condición ambas líneas de código.

Finalmente suelo sugerir el uso de sprintf en reemplazo de impresiones formateadas pero poca es la mejora en este caso.

Usa un solo lcd.clear() al comienzo y no lo repitas en cada condicional.


Go Up