Mi trovo questo problema:
Il contaKM della moto è terribilmente impreciso, anche del 15%.
Il sensore non è sulla ruota, ma sul cambio, e legge un ingranaggio fisso da 18 denti (con un hall a 5 volts).
La teoria è semplice, prendo i segnali dal sensore, calcolo il tempo tra uno e l'altro, e ricreo gli stessi segnali con tempo corretto in piu o in meno (nel mio caso il contakm abbonda e devo 'allungare' i segnali).
Ho fatto varie prove, ma per ora senza successo; ho usato un interrupts per catturare i segnali, poi li sparo in uscita con frequenza variata tramite la lettura di un trimmer (moltiplico il tempo per 1+(lettura trimmer))
A 30kmh rilevati dal gps, lo strumento originale segna 36kmh.... col trimmer correggo finchè i segnali da me generati fanno rilevare allo strumento 30kmh. A 60kmh, con la stessa correzione, mi segna 54kmh, a 120kmh circa 98kmh..... a 10kmh(circa) varia tra 0 e 5kmh.
La correzione al tempo (frequenza) la applico in percentuale.
I tempi tra un impulso ed un'altro sono tra 450 e 4000uSec.
L'AVR usato non è fondamentale, con un 328 e un attiny85 ho lo stesso risultato.
Allego il codice (scusate il disordine)
/*
per attiny85
uscita:
int led = 4;
int inp=2; //int0 pin7
int srv=3; //di servizio */
/*
funziona loop - - durata letta bene
lettura potenz. ok - uscita ok, da circa -5% a 95% in piu
*/
#define led 4 //uscita verso strumento pin3
#define inp 2 //ingresso da sensore pin7
#define pot 3 //potenziometro pin2
unsigned long in1; //di servizio
unsigned long in2; //di servizio
//unsigned long ritardo=0;
unsigned long durata; //tempo tra una lettura e un'altra
unsigned long durata1;
unsigned long durata_new;
boolean vado=true;
boolean out_su=false;
//boolean leggo=false;
unsigned long quanto; //tempo impulso
double durr; // %tempo aggiunto all'uscita
unsigned long time1; // per lettura potenz. ogni xxx uSec
void setup() {
//Serial.begin(9600);
pinMode(led, OUTPUT);
pinMode(inp, INPUT);
pinMode(pot, INPUT);
in1=micros();
time1=micros();
//digitalWrite(led, HIGH);
attachInterrupt(0, verificaon, RISING);
durr=(analogRead(pot)*0.00095)+1;
//Serial.print(analogRead(A3));Serial.print(" - ");Serial.println(durr);
//delay(500);
}
void loop() {
if(digitalRead(inp)==LOW ){
//leggo=true;
attachInterrupt(0, verificaon, RISING);
}
if(durata>200 && durata <15000){
uscita();
}
if(micros()>in1+700000){vado=false;}
}
void verificaon(){
detachInterrupt(0);
in1=micros();
durata=micros()-in2; //***durata tra impulso e impulso************
quanto=durata/2; // rimane su per 1/2 di durata
//Serial.print("in : "); Serial.println(durata);
in2=in1;
vado=true;
}
void uscita(){ //output
if(!out_su && vado){
digitalWrite(led, HIGH); //su l'uscita
out_su=true;
durata_new=durata;
durata1=micros();
}
if(out_su && micros()>durata1+quanto){
digitalWrite(led, LOW); //giu l'uscita
if(micros()>time1+1000000){
durr=(analogRead(pot)*0.00095)+1; //lettura potenz. ogni sec circa
time1=micros();
}
}
if(micros()>(durata1+(durata_new*durr)) && out_su){
out_su=false; //riabilito l'uscita
//Serial.print("out : "); Serial.println(durr);
}
}
Qualche suggerimento??
Grazie!