Calcular velocidad gps

Buenas noches de nuevo.

Siento ser pesado, pero esto de los calculos de velocidad me supera, he intentado simplificarlo mirando ejemplo de este foro y o no se buscar correctamente o los resultados no se incluirlos a mi proyecto.

El objetivo total es que memorice los kilometros recorridos en la eeprom y que antes de empezar a trabajar los cargue para poder tenerlo siempre al dia y controlado. El tema de la eeprom ya lo investigue y tengo el problema de separarlo en caracteres para almacernarlo en posiciones de la eeprom, pero eso es otra guerra.

Lo primero de todo es conseguir que me sume los kilometros recorridos en base a la velocidad marcada por el gps.

He modificado mi programa con esta parte de programa pero no me funciona, creo que algo me falta pero no se el que :-(.

#include <LiquidCrystal.h>
#include <TinyGPS++.h>

LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);

 int sensorPin = 1;
 int resistencia=0;
 int medio=0;
 int Temperatura=0;
 int val;
 int tempPin = A0;
 int speed1=0 ;
 int sat=0;
 int km=0;
 int kmtemp=0;
 int kmtemp2;
 
 TinyGPSPlus gps;
 
void setup() { 
  lcd.begin(16, 2);
  // Serial.begin(9600);
  Serial1.begin(9600);
  lcd.setCursor(0,0); // Vision de pantalla generico no cambiara
  lcd.print("Temp: ");
  lcd.setCursor(11,0);
  lcd.print("Sat:");
   
}

void loop()

{
 while (Serial1.available() > 0 )
 gps.encode(Serial1.read());

  medio=analogRead(sensorPin); // 
  speed1=gps.speed.kmph();
  val=analogRead(tempPin);
  int mv = (val/1024.0)*5000;
  int cel = mv/10;
  int sat =gps.satellites.value();
 [b] int kmtemp= speed1 * 0.277777778 ; // Velocidad a tiempo real pasada a metros
    if (gps.speed.isUpdated()) { // Si velocidad del gps cambia
    int kmtemp2 = speed1 * 0.277777778 ; // Nueva velocidad almacenada
    int km = (kmtemp + kmtemp2) / 0.277777778  ; // Velocidad total sumada ( velocidad antigua + nueva velocidad ) y pasada a km/h
   } [/b]
  
  
  
  /* Serial.print("Resistencia: "); // Serial print
  Serial.print(medio);
  Serial.print(" -- ") ;
  Serial.print(" Temperatura: ");
  Serial.print(cel);
  Serial.print(" -- Velocidad : ");
  Serial.print(gps.speed.kmph());
  Serial.print(" -- Sped : ");
  Serial.print(speed1);
  Serial.print(" km/h"); 
  Serial.print(" -- Satelites: ");
  Serial.print(sat); // Hasta aqui
  Serial.print(" -- Checksum : ");
  Serial.println(gps.failedChecksum()); */
    
  lcd.setCursor(6,0); // Print Celsius
  lcd.print(cel);
  lcd.print(" ");
  lcd.setCursor(15,0); // Print Satellites ok
  lcd.print(sat);
  lcd.setCursor(0,1); // Print speed
  lcd.print(speed1);
  lcd.print("  ");
  lcd.setCursor(4,1);
  lcd.print("km/h");
  lcd.setCursor(10,1);
  lcd.print(km);
 
  }

Como siempre gracias por vuestra ayuda.

Saludos
Jaime

No entiendo algunos conceptos de tu código, por ejemplo porque conviertes de km a metros multiplicando por: 0.277777778, pero independiente de eso, tu problema es que no defines ninguna variable para que acumule la cantidad de kilómetros, bueno, la defines pero no de manera correcta.

Supongo que es en esta variable donde quieres acumular ese dato:

int km = (kmtemp + kmtemp2) / 0.277777778;

para que se sume el dato anterior con la nueva lectura debes hacer esto

int km += (kmtemp + kmtemp2) / 0.277777778;

Agregando el operador + le dices a tu variable que sume el nuevo dato a lo que ya hay. Que sería lo mismo que hacer:

int km = km + (kmtemp + kmtemp2) / 0.277777778;

Haz la prueba y me cuentas.

Hola gepd

He cambiado el codigo por lo que dijiste, voy a probar a proba en un viaje real y a la vuelta te cuento. Me faltaba el dato acumulativo tienes razón. Lo multiplique por ese digito porque lo queria convertir a metros/segundos, creo que sera mas preciso que hacerlo en km/h.

Gracias

Bueno ahora me surge la duda a mi. Si en el loop defines una variable esta se pone a 0 cada vez que pasa por ahi. entonces poner int km por mas que uses luego int km = km + algo no va a acumular nada.

No estoy seguro ahora de estar en lo correcto. De lo que si estoy seguro es que si la defines como GLOBAL o sea antes del setup, y luego en el loop dices km = km + lo que sea; entonces va a acumular.

Otra cosa. 0.277777778 esto es para pasar km/hora a metros /seg? no se para que lo haces si luego crees presentar información en KM/hora kmh * 1000 mts / 3600 seg = valor * cte en m/seg queda claro?

surbyte: Bueno ahora me surge la duda a mi. Si en el loop defines una variable esta se pone a 0 cada vez que pasa por ahi. entonces poner int km por mas que uses luego int km = km + algo no va a acumular nada.

No estoy seguro ahora de estar en lo correcto. De lo que si estoy seguro es que si la defines como GLOBAL o sea antes del setup, y luego en el loop dices km = km + lo que sea; entonces va a acumular.

Otra cosa. 0.277777778 esto es para pasar km/hora a metros /seg? no se para que lo haces si luego crees presentar información en KM/hora kmh * 1000 mts / 3600 seg = valor * cte en m/seg queda claro?

Hola surbyte

Creó que la defini en el setup no en el loop. Igualmente, el problema radica en que es imposible hacerlo como yo hago, puesto que a la variable km ( la velocidad marcada en el gps ) le falta alguna otra variable de tiempo que cuente los millis que esta en esa velocidad,¿ no? Y después de eso hacer una fórmula tal como (distancia / tiempo del recorrido = distancia total )

¿ O me estoy complicando la vida?

Saludos Jaime

No sé los requerimientos de memoria y proceso que puede requerir (hay que tirar de math.h y cálculos más complejos en punto flotante), pero tal vez podías considerar también la posibilidad de ir calculando las distancias entre las posiciones gps. Requerirá más cálculos, pero menos frecuencia de cálculo; y tal vez sea más preciso que ir integrando velocidades. Googleando un poquito, he visto alguna cosilla. Echa un vistazo a esto, por ejemplo.

Lo hiciste en el loop. Mira tu propio código.

Para calcular la distancia, le pones un sensor a la rueda y medis su perímetro (ya se que puede estar mas o menos inflada pero tambien el velocímetro del auto puede fallar del mismo modo. Con esa lectua cada vez que cuentes un pulso tienes x metros recorridos. Mejor y mas facil imposible.

jlloret: Hola surbyte

Creó que la defini en el setup no en el loop. Igualmente, el problema radica en que es imposible hacerlo como yo hago, puesto que a la variable km ( la velocidad marcada en el gps ) le falta alguna otra variable de tiempo que cuente los millis que esta en esa velocidad,¿ no? Y después de eso hacer una fórmula tal como (distancia / tiempo del recorrido = distancia total )

¿ O me estoy complicando la vida?

Saludos Jaime

En efecto, Jaime.

Sin ponernos técnicos, la distancia recorrida es la integral de la velocidad. De poco te sirve ir sumando velocidades puntuales si lo que quieres sumar son distancias recorridas.

Simplificando y suponiendo que en todo el intervalo de tiempo de una iteración la velocidad es constante, tendrías la distancia recorrida como:

Distanciadeestaiteracion = Velocidad * tiempo

Obviamente, para que funcione, tienen que estar bien las unidades de tiempo y distancia. Con la velocidad en kilómetros/hora, tendrías que multiplicarlo por el tiempo en horas para que te devuelva el resultado en kilómetros (que es lo que te interesa, vas en moto no a pie!). Obviamente, a no ser que haya pérdidas por alguna cuestión del valor máximo que pillan las variables (imagino que puede pasar), no vas a tener mejor resultado por convertir o no a metros.

Si lo que quieres es integrar en tiempo real, para saber la distancia recorrida tendrías que hacer algo de ese estilo.

Como bien apuntas, puedes medir el tiempo de cada iteración del loop:

  timenow = millis();                            // tiempo desde que "encendiste" arduino (creo que se resetea cada 50 días, pero no te afectaría apenas)
  timeStep = (timenow - timeprevious)/3600000.; 
// timestep es el tiempo que ha tardado el ciclo, millis devuelve milisegundos, TE INTERESA EL RESULTADO EN KM, por lo que lo interesante parece pasarlo a horas. 
  timeprevious = timenow;  // guarda el tiempo actual, para poder restar de nuevo en el siguiente iteración y sacar el tiempo del loop

Obviamente, como ya has visto antes, el tiempo de cada iteración es muy constante, por lo que podrías medirlo y simplemente ponerlo hardcoded. Si tienes un dato cada 1.5 segundos:

timeStep /* = 1.5/3600000 */ = 0,000000417

Pero eso ya a tu elección.

No entiendo muy bien algunas partes de tu código, pero entiendo que simplemente tienes que hacer:

km += kmtemp * timeStep //donde kmtemp sería la velocidad en este ciclo

Eso sí, haya cambiado o sea igual la velocidad que en el ciclo anterior... tienes que sumar la nueva distancia que has recorrido.

No sé si me he explicado muy bien, espero que sea de ayuda y que no esté totalmente desencaminado

Nota adicional: si el tiempo de cada ciclo es siempre uniforme... sí que tiene sentido sumar velocidades a pelo tan y como haces, pues si te das cuenta, timeStep saldría fuera de la operación como factor común y podrías multiplicar la suma de velocidades por el valor de timeStep.

De todos modos, no sé como de preciso será integrar la velocidad para obtener la distancia recorrida... Será interesante verlo :)

arriazu: En efecto, Jaime.

Sin ponernos técnicos, la distancia recorrida es la integral de la velocidad. De poco te sirve ir sumando velocidades puntuales si lo que quieres sumar son distancias recorridas.

Simplificando y suponiendo que en todo el intervalo de tiempo de una iteración la velocidad es constante, tendrías la distancia recorrida como:

Distanciadeestaiteracion = Velocidad * tiempo

Obviamente, para que funcione, tienen que estar bien las unidades de tiempo y distancia. Con la velocidad en kilómetros/hora, tendrías que multiplicarlo por el tiempo en horas para que te devuelva el resultado en kilómetros (que es lo que te interesa, vas en moto no a pie!). Obviamente, a no ser que haya pérdidas por alguna cuestión del valor máximo que pillan las variables (imagino que puede pasar), no vas a tener mejor resultado por convertir o no a metros.

Si lo que quieres es integrar en tiempo real, para saber la distancia recorrida tendrías que hacer algo de ese estilo.

Como bien apuntas, puedes medir el tiempo de cada iteración del loop:

  timenow = millis();                            // tiempo desde que "encendiste" arduino (creo que se resetea cada 50 días, pero no te afectaría apenas)
  timeStep = (timenow - timeprevious)/3600000.; 
// timestep es el tiempo que ha tardado el ciclo, millis devuelve milisegundos, TE INTERESA EL RESULTADO EN KM, por lo que lo interesante parece pasarlo a horas. 
  timeprevious = timenow;  // guarda el tiempo actual, para poder restar de nuevo en el siguiente iteración y sacar el tiempo del loop

Obviamente, como ya has visto antes, el tiempo de cada iteración es muy constante, por lo que podrías medirlo y simplemente ponerlo hardcoded. Si tienes un dato cada 1.5 segundos:

timeStep /* = 1.5/3600000 */ = 0,000000417

Pero eso ya a tu elección.

No entiendo muy bien algunas partes de tu código, pero entiendo que simplemente tienes que hacer:

km += kmtemp * timeStep //donde kmtemp sería la velocidad en este ciclo

Eso sí, haya cambiado o sea igual la velocidad que en el ciclo anterior... tienes que sumar la nueva distancia que has recorrido.

No sé si me he explicado muy bien, espero que sea de ayuda y que no esté totalmente desencaminado

Nota adicional: si el tiempo de cada ciclo es siempre uniforme... sí que tiene sentido sumar velocidades a pelo tan y como haces, pues si te das cuenta, timeStep saldría fuera de la operación como factor común y podrías multiplicar la suma de velocidades por el valor de timeStep.

De todos modos, no sé como de preciso será integrar la velocidad para obtener la distancia recorrida... Será interesante verlo :)

Hola Arriazu te explicaste perfectamente.... algo parecido a esto :

  • Esto es el boceto del objetivo del programa : No es el codigo puesto que no lo tengo hecho, pero algo asi seria...

-Cuenta millis desde inicio del ARDUINO ( TIEMPO ) -Lee velocidad actual y almacenarla en metros segundo (por el motivo que asi puedo tener un odometro con todos los metros recorridos al momento.

-Si la velocidad cambia ( comando if ) - Compara el tiempo desde el inicio hasta que cambia la velocidad. - Cuenta el tiempo desde que ha cambiado la velocidad. - Hacer el calculo de vel. (m/s) * tiempo ( millis ) - Almacenar este calculo y sumarlo a la variable ( km ).

  • Si la velocidad no cambia ( cosa imposible )
  • Cuenta el tiempo que esta la velocidad constante.
  • Multiplica la velocidad por tel tiempo para saber la velocidad real en m/s ( VEL. * TIEMPO )
  • Almacenar este calculo y sumarlo a la variable ( km )

Creo que es lo mismo que tu dices pero de forma menos tecnica ( aqui uno sin estudios pero muy curioso ). Realmente os pregunto porque sois unos fenomenos con esta placa y sin darme la solucion podeis orientarme para que yo me coma la cabeza para resolverlo.

Ahora el tema es pasar esto a codigo. Te enseñare cuando funcione para que lo veas!!!!

Saludos Jaime

Hola Jaime,

¿Para qué necesitas saber si la velocidad ha cambiado o no? ¿para calcular la distancia cuando haya cambiado solamente?

Yo personalmente haría todos los ciclos una multiplicación de la velocidad en ese momento por el tiempo desde el ciclo anterior y no me complicaría mucho la vida. De esa forma, vas sumando cuánto se ha recorrido desde el ciclo anterior. Haya cambiado o no.

Ya se de un momento en el que tu velocidad no va a cambiar: cuando estés parado :P

Ah! y no te olvides de pasar el tiempo que te da millis a segundios (*1000), que si no te va a dar una cosa rara :)

Buenas, te funcionó el proyecto? Estoy diseñando uno pequeño pero que me guarde la distancia recorrida en una SD desde que se enciende el vehiculo hasta que se apaga. Podrian ayudarme con el tema? Saludos.