Archiv verlassen und diese Seite im Standarddesign anzeigen : zeitmessung
hi,
ich hab mir ein kleines Windrad gebaut und an den Parallelport angeschlossen.
An dem Windrad ist ein Reed-Kontakt. Bei jeder umdrehung werden zwei Pins am Port geschlossen. Jetzt wollte ich den Parallelport auslesen und messen wieviele Kontakte pro Sekunde zustande kommen.
Das Auslesen des Parallelports ist kein Problem:
#include <stdio.h>
#include <asm/io.h>
int main(int argc, char *argv[])
{
int wdat;
int halten;
if(iopl(3) !=0)
{
perror("Can't set I/O permissions");
return(1);
}
wdat=0;
outb(255,0x378);
while(1)
{
if((inb(0x379) & 64)==0)
{
if(halten==0)
{
printf("piep\n");
wdat++;
}
halten=1;
}
if((inb(0x379) & 64)!=0) halten=0;
}
outb(0,0x378);
return(0);
}
aber wie kann ich nun messen wieviele Kontakte pro Sekunde zustande kommen?
Damit ich dann die Windgeschwindigkeit ausrechnen kann.
Gruß kurm_de
anda_skoa
25-08-2005, 13:21
Zeit auslesen
man gettimeofday
dann X messungen machen
dann wieder Zeit auslesen
dann X / vergangene Zeit
Ciao,
_
Hi,
ich würde das mit einem Timer und dem SIGALRM lösen. Dazu benötigt man dann noch zwei globale Variablen in denen der aktuelle Counter deines Reed Kontaktes und die aktuelle Geschwindigkeit abgelegt wird.
Der Signalhandler macht folgendes:
Er berechnet die Geschwindigkeit und speichert sie in der globalen Variable. Danach setzt er den Counter für den Reed Kontakt wieder auf 0.
Das Hauptprogramm:
Mit der Funktion sigaction definiert man einen Signalhandler für das Signal SIGALARM.
Mit Funktion setitimer zieht man den timer auf. Dazu die den Struktureintrag it_intervall.tv_sec auf 1 setzen, damit es ein alle 1s wiederkehrender Timer wird.
Danach kommt deine normale Hauptschlife die den Zähler deines Reed-Kontktes hochzählt.
Sollte Das Programm einen sauberen Weg zum Verlassen bekommen, so mußt du den Timer mit setitimer wieder auf auf 0 Sekunden setzen und damit entschärfen.
Damit erhälst du einen sauberen Weg alle Sekunde die Geschwindigkeit zu berechnen.
Bei der lösung von anda_skoa wird das Messintervall bei langsamen Geschwindigkeiten länger, weil du auf eine feste Anzahl X an Messwerten wartest die bei langsamer Geschwingigkeit natürlich auch länger brauchen. Du bekommst dann auch nur ein Mittel der Geschwindigkeit über diesen langen Zeitraum.
Hoffe das war nicht zu verwirrend und hilft dir weiter.
Gruß
almoeli
ich glaub ich komm da nicht ganz mit :)
ich brauche doch eigentlich nur in eine Variable(zeit1) die Zeit zu schreiben.
dann mach ich eine Schleife:
in der Schleife wird dann die aktuelle Zeit in eine andere Variable(zeit2) geschrieben und die anzahl Kontakte hochgezählt z.b. über die Variable count.
Die Schleife verlasse ich, wenn zeit2 +1 >zeit1 ist.
Nun hab ich doch die Anzahl Kontakte pro Sekunde und kann die Geschwindigkeit ausrechnen.
ich glaub mein Problem ist das ich nicht weis wie man die Zeit in eine Variable bekommt.
gruß kurm_de
sixfriends
30-08-2005, 14:42
rtfm (http://mirbsd.mirsolutions.de/cman/man2/gettimeofday.htm)
sixfriends
ich hab jetzt mal was zusammen gebastelt:
#include <stdio.h>
#include <asm/io.h>
#include <sys/perm.h>
#include <sys/time.h>
int main()
{
struct timeval start,end;
int halten,wdat,difftime;
ioperm(0x378,3,1); //Port(LPT1) öffnen
gettimeofday(&start,NULL); //Anfangszeit in 'start' speichern
difftime=0;
wdat=0;
outb(255,0x378); //Strom an allen Pins an
while(1)
{
gettimeofday(&end,NULL); //Endzeit in 'end' speichern
if((inb(0x379) & 64)==0) //wenn zwichen Pin 10 und Masse->Kontakt wdat->hochzählen
{
if(halten==0)
{
wdat++;
}
halten=1;
}
if((inb(0x379) & 64)!=0) halten=0; //wenn zwichen Pin 10 und Masse-> kein Kontakt mehr dann nächsten Kontakt registrieren
difftime = end.tv_sec - start.tv_sec; //Differenz zwichen Anfangszeit und Endzeit ausrechenen
if(difftime>=1) //nach einer 1er Sek. ...
{
system("clear"); //Bildschirm löschen:)
printf("wdat: %i\n",wdat); //wdat auf Bildschirm schreiben
gettimeofday( &start,NULL); //Anfangszeit erneut in 'start' speichern
wdat=0; //wdat leer machen für neue messung
}
}
outb(0,0x378); //Strom an allen Pins aus
ioperm(0x378,3,0); //Port(LPT1) schliessen
}
soweit funktioniert alles, ihr könnt ja mal schreiben was ihr davon haltet.
gruß kurm_de
Zeit:
typedef struct
{
int d;
int mo;
int y;
int h;
int mi;
int s;
}TIME;
int inVariablenSchreiben(TIME *active)
{
struct timeval wt;
struct tm gtime;
// int stime;
gettimeofday (&wt,NULL);
gtime = *gmtime (&(wt.tv_sec));
active->d = gtime.tm_mday;
active->mo = ++gtime.tm_mon;
active->y = 1900+gtime.tm_year;
active->h = gtime.tm_hour;
active->mi= gtime.tm_min;
active->s = gtime.tm_sec;
return(0);
}
:D
Zuverlässig funktionieren kann sowas nur bei niedrigen Frequenzen und nicht allzu hoher Rechner-Auslastung.
Zuverlässiger ist es einen Interrupt-Handler dafür zu nehmen und besser noch harte Echtzeit wie z. B. den RTAI-Patch, www.rtai.org .
Hier mal ein Programm dazu:
http://www.mikrocontroller.net/forum/read-4-195781.html#new
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.