Forum: Mikrocontroller und Digitale Elektronik Drehzahlmessung per Lichtschranke


von Matthias (Gast)


Lesenswert?

Servus Leute,

ich bins mal wieder. Nachdem ich dachte entlich den Hardwareteil ferig 
zu haben, darf ich jetzt wieder basteln...

Folgendes Problem.
Ich soll die Drehzahl eines Motors ermitteln. Muss nicht 100 Pro genau 
sein, weils mir langsam auch wurscht ist. Aber sollte halt grob Stimmen, 
also eine Hausnummer halt.

So ich hab jetzt nen Motor samt geschlitzer Scheibe. Bei der Scheibe 
greift eine Lichtschranke.
Ist nun die Lichtschranke unterbrochen hab ich 5 V an einem Pin an 
meinem Mega 16. Läuft nun der Schlitz in der Scheibe an der Schranke 
vorbei, krieg ich 0 Volt an einem Pin.

Die Umdrehungen will ich dann rausrechnen indem ich die Zeit zwischen 
den beiden 0Volt messe. Aber wie fang ich das am besten an.
Ich dachte daran, einen Timer zu starten, wenn das erste mal 0 Volt 
anliegen. Dort eine Variable hochzählen, solange bis er das Zweite mal 
durchläuft.

Geh ich da Richtig in der Annahme, das ich einen Interrupt zwingen 
brauche, oder kann ich den auch "Emulieren" an einem X-Beliebigen Pin 
meines Mega16?
Denn der Controller soll/muss derweilen noch einiges anderes machen.

Vorallem hab ich noch nix mit Timer und Interrupt in C gemacht...

Für Antworten wäre ich sehr dankbar!

MfG
Matthias

von Michael Wilhelm (Gast)


Lesenswert?

Nimm die Funktionalität des Input Capture, wenn der Controller den hat.

MW

von Matthias (Gast)


Lesenswert?

Also ich hab etwas rumprobiert...

Timer krieg ich grob in den Griff...
Die Lichtschranke erkennt den Wechseln einwandfrei.

So jetzt brauch ich blos ne Möglichkeit auf einen X-Beliebigen Pin einen 
Interrupt auszulösen falls er von High auf Low geht.

@Michael Wilhelm
Input Capture
Kannst du mir vll in deinen eigenen Worten erklären was das ist? Weil 
das Internet macht nicht immer schlau. Und das was drinsteht ist 
irgendwie verworren bzw. unverständlich.

von Martin (Gast)


Lesenswert?

Input Capture heißt, dass der Timer auf einen Event seinen aktuellen 
Timerwert abspeichert in ein anderes Register. Dann wird meistens ein 
Interrupt ausgelöst. Du kannst den Wert speichern und auf den nächsten 
Event warten. Dann beide Werte voneinander abziehen, und du hast die 
Zeit.

von Thilo M. (Gast)


Lesenswert?

Ich poste dir hier mal meine ISR (ist schon älter, also bitte den alten 
Namen verzeihen):
1
SIGNAL (SIG_INPUT_CAPTURE1)  // Frequenzmessung
2
{
3
  if (!(Status &(1<<ST_ICP)))  //bei neuer Zählperiode:
4
    {
5
      starttime = ICR1;  // Startzeit zuweisen
6
      ICP_OVF = 0;       // Timer-überlaufzähler rücksetzen
7
      Status |= _BV(ST_ICP);  // Start neuer Zählperiode markieren
8
      return;
9
    }
10
  else
11
    {
12
       stoptime = ICR1;  // Stopzeit zuweisen
13
       Frequenz = (ICP_OVF * 65536) + stoptime - starttime; // Zählerstand ermitteln
14
       Frequenz = (16000000/Frequenz);  // Frequenz berechnen
15
       Status &= ~_BV(ST_ICP);  // Ende der Zählperiode markieren
16
       TIFR |= _BV(ICF1);  // Input-capture-Flag löschen, falls inzwischen ausgelöst
17
    }
18
}
19
20
21
SIGNAL (SIG_OVERFLOW1)  // ICP - Overflow-Zähler
22
{
23
  ICP_OVF++;
24
  if (ICP_OVF >5000)  // Timeout erkennen
25
    {
26
      Frequenz = 0;
27
    }
28
}
Oben die ICP-ISR, bei jeder (vorher festgelegten) Flanke wird ein 
'Zeitstempel' des Timer1 in den ICR-Registern abgelegt, dieser wird 
einer Variablen zugeiesen. Falls die Periodendauer nun länger als der 
Zählbereich des Timer1 ist, dann läuft dieser über und die 
Timer1-Overflow-ISR wird ausgelöst. In dieser werden die Überläufe 
gezählt und ein Fehlen der Flanken erkannt (z.B. Drahtbruch oder 
abgesteckter Geber). Kommt am ICP die nächste Flanke an (eine Periode 
durchlaufen), wird die Stopzeit einer Variable zugewiesen und 
anschließend die Frequenz berechnet.

das Ganze ist natürlich nur ein Codeschnipsel (Initialisierung der 
Interrupts usw. fehlen), dürfte aber zur verdeutlichung der 
Vorgehensweise dienen.

von Matthias (Gast)


Lesenswert?

Dank dir...

Auf gut Deutsch du lässt den Timer laufen. Du merkst dir dann Start und 
Stop und rechnest damit die Zeit dazwischen aus. Richtig verstanden?

Jetzt brauch ich blos noch ne Möglichkeit einen x-Beliebigen Pin als 
Interrupt zu nehmen, da die anderen schon belegt sind.

Er muss ja zwischen drin noch einiges erledigen, also der MC...

MfG
Matthias

von Thilo M. (Gast)


Lesenswert?

>Richtig verstanden?
Ja.

Ich habe dafür den Input-Capture-Pin benutzt, wenn möglich benutze den.
Mit beliebigen Anderen geht's nicht so komfortabel. Evtl noch ext. 
Interruptpins frei?

von Matthias (Gast)


Lesenswert?

Ok Danke...

Ich habs jetzt auf den Input-Capture-Pin umgelötet an meiner 
Testplatine. Wenn wirklich muss ich halt noch meine eigentlich schon als 
fertig betrachtete Platine umbaun.

Blos auf was reagiert der Input-Capture-Pin?
Fallende Flanke oder auf Steigende? Muss ich den noch konfigurieren?

Ich hab grad das große DB meines Controllers überfolgen. Da heissts er 
gehört zum Timer1. Das ist der 16 Bit Timer meiners Controllers. Also 
muss ich den verwenden oder?

SIGNAL (SIG_INPUT_CAPTURE1)

Ist dann das Event wo er reinspringt beim Input-Capture...

MfG
Matthias

von Thilo M. (Gast)


Lesenswert?

Das datenblatt würde ich zum Thea ICP genauer lesen, da steht eigentlich 
alles sauber drin. Der Interrupt wird bei einer von dir programmierbaren 
Flanke ausgelöst (steigend oder fallend).
Der Timer ist keinesfalls verschwendet, du kannst ihn gleichzeitig 
nutzen, vorausgesetzt der Vorteiler ist für Beides verwendbar. Ansonsten 
kannst du die Frequenzmessung ja abschalten, wenn sie nicht benutzt 
wird, dann steht der Timer1 wieder voll zur Verfügung.
Das 'SIGNAL (SIG_INPUT_CAPTURE1)' ist mittlerweile überholt im neuen 
WINAVR, da heißt's irgendwas mit 'ISR' (hab's grade nicht zur 
Verfügung).

Aber ja, das ist die ISR (das Event) die ausgeführt wird.

Meine Berechnung oben bezieht sich auf den Timer1 ohne Vorteiler, bei 
16MHz Taktfrequenz. Der Vorteiler (falls vorhanden) muss dann noch in 
die Berechnung 'rein.

>Muss ich den noch konfigurieren?
Ja. Ebenso muss Timer1 konfiguriert werden.
Die Variablen entsprechend groß (long int) wählen, da hier einiges 
zusammenkommt.

von Michael Wilhelm (Gast)


Lesenswert?

>Die Variablen entsprechend groß (long int) wählen, da hier einiges
>zusammenkommt.

Muss nicht sein. Einfach einen Int nehmen, Daten sichern und das 
Timerregister löschen. So hast du den Zeitstempel von 0 bis zum 
gemessenen (gesicherten) Wert, wobei 1 Tick halt 1/Timerfrequenz ist.

MW

von Matthias (Gast)


Lesenswert?

Jo danke Jungs für die Infos.

Werd mich mal schlau machen und rumbasteln...falls ichs net hinkrieg 
meld ich mich nochmals.

Also danke derweilen!

MfG
Matthias

von Matthias (Gast)


Lesenswert?

Servus nochmal...

kann ich den Input-Capture-Pin so umstellen, das er nicht die low high 
sondern die high low Flanken erkennt?

von Michael Wilhelm (Gast)


Lesenswert?

In TCCR1B das ICES1 bit. Der Name: Input Capture Edge Select

MW

von TOM (Gast)


Lesenswert?

Das ist doch im Datenblatt garnicht so missverständlich beschrieben, 
oder?

von Matthias (Gast)


Lesenswert?

Jo passt schon habs soweit.

Ärger mich blos momentan mit der Rechnung...
Timertakt...Compare...auf Umdrehungen.

Mist is das momentan keine feste def. Drehzahl hab da der Motor noch 
Antrieblos ist...fehtl die Richtige Stromquelle...also muss ichs 100 Pro 
richtig rechnen...kanns aber nicht überprüfen momentan.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.