Vamos a programar #100 - Speedometer M. Versión Final.

 Hola de nuevo a todos, el día de hoy empezaremos a ver la versión final del velocímetro.

Este proyecto fue iniciado mas o menos por el 2018 y ha sufrido una serie de cambios a lo largo del tiempo, si bien la última versión que fue publicada funcionaba bien, poco a poco se fueron agregando funciones para hacerlo funcionar de manera optima con el mínimo de hardware posible (de ahí que nunca le agregue ningún tipo de botón). Finalmente, tras días de pruebas y pruebas, he decidido finalizar con este proyecto porque finalmente ha alcanzado el nivel de confiabilidad para poder usarse en el día a día.


Primero que nada, veamos el código que hace funcionar a "Speeedometer M"


// Incluir la libreria para la pantalla
#include <LiquidCrystal.h>
// Pines usados en la pantalla extraido de los ejemplos incluidos en la libreria
const int rs = 13, en = 12, d4 = 11, d5 = 10, d6 = 9, d7 = 8;
// iniciar el objeto LiquidCrystal
LiquidCrystal lcd(rs , en , d4 , d5 , d6 , d7);
// Este es el valor que debes de modificar para que funcione correctamente
// Puedes ver instrucciones en https://xworkforall.blogspot.mx/2018/03/vamos-programar-49.html
const float Llanta = 1.9572;
//Algunas variables
const int HallSensor1 = 3;
const int LED1 =  7;
const int LED2 = 6;
const int LED3 = 5;
int Vuelta = 0;
unsigned long OldTime = 0;
float Distancia = 0.0;
float Speed = 0.0;
int ledState = LOW;
int VoltSensor = 0;
float BattVolt = 0.0;

// v=99.99
char BuffVelocity[15];
//d=999.99
char BuffDistance[15];
//R=999999
char BuffRevolution[15]; 
//V=4.2
char BuffBattery[15];

//Incializar todo
void setup() {
  //Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("@XWork");
  pinMode(HallSensor1, INPUT);
  attachInterrupt(digitalPinToInterrupt(HallSensor1) , GetVelocity , LOW);
  pinMode(LED1 , OUTPUT);
  pinMode(LED2 , OUTPUT);
  pinMode(LED3 , OUTPUT);
}

// Calcular la velocidad
void GetVelocity() {
  if (millis() - OldTime > 70) {
    Speed = Llanta / ((float)( millis() - OldTime) / 1000) * 3.6;
    OldTime = millis();
    Distancia = Distancia + Llanta / 1000;
    Vuelta += 1;
    if (ledState == LOW)
      ledState = HIGH;
    else 
      ledState = LOW;
  }
}
//Bucle principal
void loop() {
  VoltSensor = analogRead(A5);
  BattVolt = (VoltSensor * (10.0 / 1023.0));

  dtostrf(Speed , 5 , 2 , BuffVelocity);
  dtostrf(Distancia , 6 , 2, BuffDistance);
  sprintf(BuffRevolution , "R=%6d", Vuelta);
  dtostrf(BattVolt , 5 , 1, BuffBattery);
  
  lcd.setCursor(0, 0);
  lcd.print("d=");
  lcd.setCursor(2 , 0);
  lcd.print(BuffDistance);
  
  lcd.setCursor(9, 0);
  lcd.print("v=");
  lcd.setCursor(11, 0);
  lcd.print(BuffVelocity);
  
  lcd.setCursor(0,1);
  lcd.print(BuffRevolution);
  
  lcd.setCursor(9,1);
  lcd.print("V=");
  lcd.print(BuffBattery);
  
  digitalWrite(LED1 , ledState);
  digitalWrite(LED2 , ledState);
  digitalWrite(LED3 , ledState);
  
  if ((millis() - OldTime) > 3000){
    ledState = LOW;
    Speed = 0.0;
  }
}


Si haz seguido el proyecto desde el inicio, te darás cuenta que la mayoría de las funciones han cambiado un poco y algunos de los elementos que en ocasiones usamos para algunos post, los retomamos para llegar a está versión. Antes de continuar, voy a responder a unas cuantas preguntas que surgieron durante todo el proceso. La primera de ellas: ¿Cuánta es la máxima distancia que se puede alcanzar con el diseño original? La respuesta es relativamente sencilla, ya que usamos seis espacios de la pantalla y usamos tres para los enteros, una para el punto y dos para los decimales; la máxima distancia posible es 999.99 km, que es mas que suficiente para la mayoría de las personas, pero aquí es donde viene la parte "truculenta". La parte donde se llevan la cuenta de las revoluciones, el máximo posible es de 999,999 vueltas, en el caso de una llanta 24x2.25, la circunferencia es de 1.95m por lo que al multiplicar por el número de vueltas máximo obtenemos 1,949,998.05m máximo o lo que es lo mismo 1949km y esto bastaría para desbordar la parte de la distancia.

Otro dato que cambio fue la información que se usa para la batería. En algún momento del desarrollo, pensé en incluir un icono de batería, pero cada una de las baterías son diferentes y por lo tanto no es factible escribir el código ya que es casi una garantía que la pila no es igual en la mayoría de los casos. y por ejemplo, la pila que yo uso era de un teléfono y traía consigo una protección que corta la corriente cuando la pila alcanza 2.5v, pero una pila Sony VTC6 recomienda que el voltaje nunca baje de los 3v.

Es posible usar una pantalla de 20x4, pero la 16x2 es mas compacta y además, permite tener todo de manera lo mas sencilla posible.

Por último, he actualizado el proyecto en easyeda y he hecho el PCB de la mejor manera posible y es posible ordenarlos, pero quiero resaltar que aun no los he probado (o no al momento de que esto fue escrito) y eso se debe a que van a tardar un par de semanas. De todos modos, se pueden seguir las conexiones del diagrama y hacerlo en un placa perforada a mano.

O mandarlas a fabricar (que repito, aun no he probado.)

Y bien por ahora es todo, tal y cómo lo mencioné al principio, ya no voy a publicar mas actualizaciones, pienso que todo funciona cómo debe, pero además todo está disponible para que cada quien lo modifique a cómo lo necesite, recuerda que puedes hacer el pedido desde JLCPCB y además puedes descargar el código desde mi DropBox para que lo modifiques a tu gusto.

Los leo luego

2 comentarios