Anzeige:
Ergebnis 1 bis 8 von 8

Thema: zeitmessung

  1. #1
    Registrierter Benutzer
    Registriert seit
    15.08.2005
    Beiträge
    12

    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:

    Code:
    #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

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zeit auslesen
    man gettimeofday

    dann X messungen machen
    dann wieder Zeit auslesen
    dann X / vergangene Zeit

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    16.06.2003
    Beiträge
    73
    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

  4. #4
    Registrierter Benutzer
    Registriert seit
    15.08.2005
    Beiträge
    12
    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

  5. #5
    Registrierter Benutzer Avatar von sixfriends
    Registriert seit
    26.03.2003
    Ort
    /home/sixfriends
    Beiträge
    285
    rtfm

    sixfriends
    .
    Wenn die Sonne der Kultur niedrig steht, werfen selbst Zwerge einen Schatten.

  6. #6
    Registrierter Benutzer
    Registriert seit
    15.08.2005
    Beiträge
    12
    ich hab jetzt mal was zusammen gebastelt:

    Code:
    #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

  7. #7
    Registrierter Benutzer Avatar von 24dan
    Registriert seit
    07.07.2005
    Beiträge
    76
    Zeit:
    Code:
    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);
    }
    Geändert von 24dan (01-09-2005 um 13:06 Uhr)
    ...der erste Trunk aus dem Becher der Naturwissenschaften macht atheistisch, aber auf dem Grund des Bechers wartet Gott. (Werner Heisenberg 1901-1976, Nobelpreisträger für Physik)
    debian on acer travelmate c300: http://adweb.desy.de/~kaemtner/

  8. #8
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650
    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...95781.html#new
    Geändert von nobody0 (05-09-2005 um 19:58 Uhr)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •