Vamos a programar #82 - Actualizando el velocímetro - Spedometer M V2.

Hola de neuvo a todos, el día de hoy vamos a ver cómo actualizar el velocímetro que previamente ya habíamos hecho a la versión 2.0


Después de varios meses de espera, finalmente he decidido actualizar el velocímetro a la siguiente versión. Ademas de hacer mejoras en la construcción, decidí actualizar el código para hacerlo un poco mas eficiente y funcional.

"Mejorando la casa"

La primera construcción la hice en una caja de plástico barato y no era muy estable que digamos, y debido a eso en situaciones de terreno muy empedrado, la débil construcción hacia que el velocímetro fallara. Por eso hice una caja de acrílico (los pasos no lo muestro, ya que es una caja y me quedo horrible) unida con silicon frió y tornillos, gracias a eso las pruebas que he hecho en terrenos realmente accidentados, han sido exitosas. Antes cuando estaba en la caja de plástico, en algunos caminos se reiniciaba (supongo que por la vibración), pero ahora ya no.

Además de manera opcional, incluí un LED de color rojo para saber cuando es que está en operación, no ayuda en nada pero siempre resulta util saber que cuando la luz está encendida, lo demás también debería.

En sustitución del la placa Arduino Uno, decidí usar directamente el micro-controlador ATMEGA328p (en un futuro post veremos cómo hacer un "Minimal arduino").

Las conexiones y el código.

Para las conexiones, bastará con mirar el siguiente diagrama:
Y el siguiente código:

// 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;

const byte Batt100[] = {
	B01110,
	B11111,
	B11111,
	B11111,
	B11111,
	B11111,
	B11111,
	B11111
};

	const byte Batt75[] = {
	B01110,
	B10001,
	B11111,
	B11111,
	B11111,
	B11111,
	B11111,
	B11111
};

	const byte Batt50[] = {
	B01110,
	B10001,
	B10001,
	B10001,
	B11111,
	B11111,
	B11111,
	B11111
};

	const byte Batt25[] = {
	B01110,
	B10001,
	B10001,
	B10001,
	B10001,
	B10001,
	B11111,
	B11111
};

	const byte Batt0[] = {
	B01110,
	B10001,
	B10001,
	B10001,
	B10001,
	B10001,
	B10001,
	B11111
};

//Incializar todo
void setup() {
	//Serial.begin(9600);
	lcd.createChar(0, Batt0);
	lcd.createChar(1, Batt25);
	lcd.createChar(2, Batt50);
	lcd.createChar(3, Batt75);
	lcd.createChar(4, Batt100);
	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);
}
//Dibujar el icono de bateria***
void DrawBatt(int Value){
	lcd.setCursor(15, 1);
	if (Value > 90)
		lcd.write(byte(4));
	  if (Value < 91 && Value > 75 )
		lcd.write(byte(3));
		if (Value < 76 && Value > 50 )
		lcd.write(byte(2));
		if (Value < 51 && Value > 10 )
		lcd.write(byte(1));
		if (Value < 11 )
		lcd.write(byte(0));
}
// 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 / 1023.0)) * 100;
	lcd.setCursor(0, 0);
	lcd.print("v=");
	lcd.setCursor(2, 0);
	lcd.print(Speed);
	lcd.setCursor(8, 0);
	lcd.print("d=");
	lcd.setCursor(10, 0);
	lcd.print(Distancia);
	lcd.setCursor(0,1);
	lcd.print("Rev=");
	lcd.setCursor(4,1);
	lcd.print(Vuelta);
	DrawBatt(map(BattVolt, 300,405,1,100));
	digitalWrite(LED1, ledState);
	digitalWrite(LED2, ledState);
	digitalWrite(LED3, ledState);
	if ((millis() - OldTime) > 3000){
		ledState = LOW;
		Speed = 0.0;
	}
}

Lo primero que hay que resaltar es que es conveniente darse una vuelta por el post donde hicimos la primera version, ya que todos los fundamentos están en esa serie de posts.

Para esta versión se agregan solo dos resistencias y tres LED's. Hace unas cuantas semanas vimos cómo medir voltajes usando arduino, para eso usamos un divisor resistivo compuesto por dos resistencias de dos mega ohm y la parte media, la conectamos al pin A5. Cómo el voltaje está dividido a la mitad (puedes ver cómo funciona en el post de  de divisores resistivos), en lugar de medir los 4.2v solo mediríamos cómo máximo 2.1v que se resuelve si se multiplica por dos.

Algo que es muy importante resaltar, es que el indicador de la batería no es muy preciso, eso se debe principalmente a que no encontré una hoja de datos del modelo especifico y por las que encontre, si hay diferencia entre marca y marca por lo que hay que ajustar los niveles de acuerdo a lo que se especifique según el tipo de batería que uses.

Y bien, por ahora es todo. En el siguiente post, veremos una explicación detallada del código, por ahora intentare buscar una hoja de datos o trataré de implementar una forma un poco mas precisa de desplegar el porcentaje de la batería. El código cómo de costumbre lo puedes descargar de dropbox (es el mismo link pero actualizado).

Los leo luego.

No hay comentarios.