mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zeitmessung funktioniert nur so halb :-/


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da bin ich wieder, ich und meine Schiene mit den 8 IR-Lichtschranken.

Waren letztens im 'Labor' und haben das Ding ausprobiert, funktioniert 
auch ganz gut, gibt schöne Kurven für lineare und beschleunigte 
Bewegungen (diese 'Bewegungen' durchbrechen auf ihrer Fahrt die 
Lichtschranken nacheinander).

Dann bin ich noch auf die glorreiche Idee gekommen, die Zeitmessung doch 
mal mit einem anderen Gerät zu vergleichen.

Also haben wir nach der lezten Lichtschranke noch eine zusätzliche 
Lichtschranke hingebaut, die dann an den Messverstärker angeschlossen 
wurde.

Nach den Messungen machte sich dann doch allgemeine Sprachlosigkeit 
breit, besonders bei mir, denn ich hatte das Ding ja gebaut.

Messergebnisse: Bei Zeiten von ca. 0,4 s gab es eine Abweichung von 20% 
zwischen den Ergebnissen. Diese Abweichung hat sich aber nicht auf 
längere Zeiten ausgewirkt. Als wir beide Schranken ca. 30 Sekunden lang 
unterbrochen haben, kan bei beiden so ziemlich das gleiche raus (30sek 
und 29,9 sek).

An was kann das also liegen?

Das Messprogramm vom ATmega8 hab ich mal veröffentlicht, falls jemand 
einen Fehler in der Software vermutet.

http://home.arcor.de/kreuzfeuer/fa1.html

Zum Programm: Nach der ganzen Initialisierung befindet sich das Programm 
solange in einer Endlosschleife (f_loop) bis, zum ersten mal eine 
Schranke unterbrochen wird, sich also das Ergebnis von GET_P_C ändert. 
Dann fragt das Programm in der Hauptschleife alle 96 Taktzyklen die 
Lichtschranken ab und speichert den Zustand und die Anzahl der 
Schleifendurchläufe im RAM aber, falls sich etwas geändert hat.

Autor: rene (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zuerst mal ein Pendel messen, das gibt gleichmaessige Werte und Zeiten. 
Dabei zuerst mal den Messausgang am Scope anschauen. Stimmt das Signal 
da noch ?

rene

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@rene

> Zuerst mal ein Pendel messen, das gibt gleichmaessige Werte und Zeiten.

Na, ich würde lieber nen (elektronischen) Taktgenerator nehmen.

MfG
Falk

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehe ich das richtig, dass du während der MessungÜbertragung auf der
seriellen macht, während gleichzeitig die Messung gemacht wird in
dem du die Anzahl der Schleifendurchläufe mitzählst.

Warum machst du es nicht einfach so:
Alle Lichtschranken hängst du zusätzlich an den Input Capture
Eingang vom Timer 1.
Messung startet: Timer auf 0 setzen, Input Capture freigeben.
Jetzt zählt der Timer klammheimlich vor sich hin. Sobald
am Input capture Eingang etwas vor sich geht, kopiert
der Timer seinen aktuellen Wert in ein spezielles Register
und benachrichtigt dich mit einem Interrupt. Im Interrupt
hast du alle Zeit der Welt, den Wert aus dem speziellen
Register zu holen und zu speichern (oder per RS232 zu
verschicken). Auf die Art misst dir der Timer ganz von
alleine die verstrichene Zeit zwischen 2 Ereignissen.
Du brauchst keine Takte zählen, es ist einfacher, in
der Zwischenzeit hast du genügend Zeit was anderes zu tun,
du kriegst die Zeit in Quarzauflösung (dividiert durch den
Prescaler) und nicht zuletzt: Du kannst das bequem in
C programmieren.

Autor: rene (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Zuerst mal ein Pendel messen, das gibt gleichmaessige Werte und Zeiten.

Na, ich würde lieber nen (elektronischen) Taktgenerator nehmen.

Falk

@Falk
Du traust der Lichtschranke ? Ich nicht.

rene

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich bin auch ganz start geneigt zu Sagen das das Problem am 
Programm liegt!
Wie Karl Heinz shcon sagte..

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Du traust der Lichtschranke ? Ich nicht.

Was soll die Hardware schon falsch machen?
Noch eine Stimme für ein Softwareproblem!

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Zuerst mal ein Pendel messen, das gibt gleichmaessige Werte und Zeiten.

Danke das ist eine Gute Idee

> Dabei zuerst mal den Messausgang am Scope anschauen. Stimmt das Signal
> da noch ?

Da siehst zur Zeit schlecht aus, da müsste ich wieder ins 'Labor' (was 
eigentlich kein Labor ist, sondern der Nebenraum vom Physiksaal :-) )

> Na, ich würde lieber nen (elektronischen) Taktgenerator nehmen.

Den ich zufällig in der Hosentasche hab ;-)

> Sehe ich das richtig, dass du während der MessungÜbertragung auf der
> seriellen macht, während gleichzeitig die Messung gemacht wird in
> dem du die Anzahl der Schleifendurchläufe mitzählst.

?? MessungÜbertragung auf der seriellen ??

Zu der anderen Messmöglichekeit von Karl Heinz:

Ich denke, dass das daran scheitern wird, dass die gemessenen Zeiten 
sehr unterschiedlich sein können, also von 10 s bis 0,001 s und dann 
entweder der Timer überläuft oder die Messung auf Grund des Prescalers 
zu ungenau wird (wahrscheinlich eher ersteres da mit Prescaler 1024 und 
einem Takt von 14MHz Timer1 nach 4,5 sek voll ist)

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich denke, dass das daran scheitern wird, dass die gemessenen
> Zeiten sehr unterschiedlich sein können, also von 10 s bis 0,001 s
> und dann entweder der Timer überläuft

Und wozu denkst du gibt es den Overflow Interrupt?

Deine gemessene Zeit ist dann halt:
  Input Capture Wert  + Anzahl der Overflows * 65536

Bei 32 Bit Arithemtik, dauert es dann bei einem
Prescaler von 1 und 14 Mhz immerhin 5 Minuten bis
das überlauft. Bei einer Auflösung von 7 * 10^-8 Sekunden
(theoretisch).

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> > Na, ich würde lieber nen (elektronischen) Taktgenerator nehmen.

> Den ich zufällig in der Hosentasche hab ;-)

74HC14 + Widerstand + Kondensator.

MfG
Falk



Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab grad eine Messung mit einem Pendel gemacht (ca. 1,5m Faden, schwarze 
Glaskugel unten dran, Amplitude 5 - 10cm)

Der Durchschnittswert der Zeiten ist 0,09804 s
Die maximal Abweichung der Meswerte vom Durchschnitt ist 6%
Die Abweichung vom minimalen zu maximalem Messwert ist 10%.

Ist das jetzt gut oder schlecht? :-?


nochmal @ karl heinz

Jetzt ist mir noch was eingefallen, warum ich nicht deine Methode 
verwenden kann: Es können auch zwei Bewegungen gleichzeitig auf der 
Schranke ablaufen. D.h. dass unter Umständen eine Schranke unterbrochen 
wird, wenn woanders schon länger eine Schranke unterbrochen ist. Das 
würde ja dann vom Interrupt nicht erfasst werden und somit würde diesem 
Ergebnis auch kein Messwert zugeordnet werden, oder?

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Den ich zufällig in der Hosentasche hab ;-)

>74HC14 + Widerstand + Kondensator.

Sowas hast du in der Tasche?
Das würde mir zu doll pieksen...


>D.h. dass unter Umständen eine Schranke unterbrochen
>wird, wenn woanders schon länger eine Schranke unterbrochen ist. Das
>würde ja dann vom Interrupt nicht erfasst werden und somit würde diesem
>Ergebnis auch kein Messwert zugeordnet werden, oder?

Dafür haben diverse Controller Pinchange-Interrupts. Da wäre es dann 
egal, ob ein Eingang ein statisches Signal liefert.
Da könnte man dann nämlich den ganzen Spass so realsieren:
Timer starten, bei Überlauf wird eine weitere Variable (16Bit) 
inkrmentiert.
Sobald ein Pinchange-Interrupt auftritt, wird der Timer und die 
Überlaufvariable ausgelesen (Da muß man dann den Übertragsmoment noch 
beachten) und der Zustand der Eingänge.
Dann guckt man sich den letzten Zustand an, stellt fest, welcher Eingang 
sich verändert hat und berechnet für diesen die Differenzzeit (Man muß 
sich also den Zeitpunkt jedes Eingangs in einem Feld merken.).

Oder man fragt die Lichtschranken in einem regelmässig auftretenden 
Timer-Interrupt ab, der mindestens zweimal so häufig auftritt, wie die 
höchste Geschwindigkeit ist (Shannon-Theorem).

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dafür haben diverse Controller Pinchange-Interrupts.

Meiner aber nicht :-) (ATmega8)

Mir wäre es viel lieber, wenn jemand den Fehler in meinem Programm 
finden würde oder eine Idee für eine anderes Programm (das aber mit dem 
gleichen Controllerbeschaltung läuft, die ja jetzt wirklich nicht 
speziell ist) hätte.
Das mit den anderen Lösungen ist zwar auch interessant, aber bringt 
micht jetzt nicht wirklich weiter, da ich nicht mehr die Zeit habe einen 
ganz neuen Aufbau anzufangen.

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wenn jemand den Fehler in meinem Programm finden würde

Hat Karl Heinz doch schon gemacht: Dir kommt das USART in die Quere.
Du kannst die Abfrage der Lichtschranken auch in der Hauptschleife 
machen und da dann die "Uhrablesen".
Ich habe mir dein Programm (noch) nicht weiter angeguckt.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes

> Hab grad eine Messung mit einem Pendel gemacht (ca. 1,5m Faden, schwarze
> Glaskugel unten dran, Amplitude 5 - 10cm)

> Der Durchschnittswert der Zeiten ist 0,09804 s
> Die maximal Abweichung der Meswerte vom Durchschnitt ist 6%
> Die Abweichung vom minimalen zu maximalem Messwert ist 10%.

> Ist das jetzt gut oder schlecht? :-?

Für ne Zeitmessung ist das grotenschlecht.

@fieser Rahul

> >74HC14 + Widerstand + Kondensator.

> Sowas hast du in der Tasche?
> Das würde mir zu doll pieksen...

Wieso? Hast du keine Haare am Sack? ;-)

> Oder man fragt die Lichtschranken in einem regelmässig auftretenden
> Timer-Interrupt ab, der mindestens zweimal so häufig auftritt, wie die
> höchste Geschwindigkeit ist (Shannon-Theorem).

Shannon ist hier vollkommen deplaziert.

MfG
Falk

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Shannon ist hier vollkommen deplaziert.

Nö, finde ich nicht.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ oskar

> Dir kommt das USART in die Quere.

Inwiefern?

> Du kannst die Abfrage der Lichtschranken auch in der Hauptschleife
> machen und da dann die "Uhrablesen".

Mache ich doch, oder? In der Hauptschleife (main) wird das Macro GET_P_C 
doch aufgerufen.

> Ich habe mir dein Programm (noch) nicht weiter angeguckt.

Wäre nett, wenn du das machen würdest. Ich wollte es nicht kürzen, weil 
ich sonst sicher die Fehler weg editiert hätte.


@ karl heinz:

Würdest du mir das bitte nochmal genauer erklären: An was denkst du 
scheitert die Messung?

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Zeitmessung hat doch höchste Priorität, oder? Dann den INT mit der 
höchsten Priorität zum Messen benutzen: INT0. Wie ein Zähler >16 bit zu 
realisieren ist sollte wohl kein Problem sein. Alle anderen Vorgänge 
(USART usw.) sind Nebensache und können ausgeführt werden wenn Zeit ist. 
Ich würde das Programm zuerst auf Papier strukturieren und dann neu 
aufbauen. 75% der Programmierarbeit erfolgt bei mir auf dem 
Konzeptblock, wegen der Übersichtlichkeit.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Jetzt ist mir noch was eingefallen, warum ich nicht deine Methode
> verwenden kann: Es können auch zwei Bewegungen gleichzeitig auf der
> Schranke ablaufen. D.h. dass unter Umständen eine Schranke unterbrochen
> wird, wenn woanders schon länger eine Schranke unterbrochen ist. Das
> würde ja dann vom Interrupt nicht erfasst werden und somit würde diesem
> Ergebnis auch kein Messwert zugeordnet werden, oder?

Monoflops hinter die Lichtschranken.


> Hab grad eine Messung mit einem Pendel gemacht (ca. 1,5m Faden,
> schwarze Glaskugel unten dran, Amplitude 5 - 10cm)
>
> Der Durchschnittswert der Zeiten ist 0,09804 s

Das ist schlecht.
Ein Pendel von 1m Länge hat eine Schwingungsdauer von
ca. 1 Sekunde. Bei 1m Länge wird die Schwingungsdauer
größer. Wenn deine 1.5 Meter als eine knappe 10-tel
Sekunde dauern, ist was oberfaul.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das ist schlecht.
> Ein Pendel von 1m Länge hat eine Schwingungsdauer von
> ca. 1 Sekunde. Bei 1m Länge wird die Schwingungsdauer
> größer. Wenn deine 1.5 Meter als eine knappe 10-tel
> Sekunde dauern, ist was oberfaul.

Nein, ich hatte die Unterbrechungsdauer der Lichtschranken betrachtet. 
(Das das nicht allzu sinnvoll ist, ist mir auch gerade aufgefallen)

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich würde das Programm zuerst auf Papier strukturieren und dann neu
> aufbauen. 75% der Programmierarbeit erfolgt bei mir auf dem
> Konzeptblock, wegen der Übersichtlichkeit.

Das habe ich auch gemacht und rausgekommen ist das obige.

> Monoflops hinter die Lichtschranken.

Mir ist auch klar, dass man es anders auch lösen kann. Aber wenn ihr 
hier so viele Lösungen findet, wie man es anders machen kann, dann 
sollte es doch kein Problem sein, eine Lösung für meinen Aufbau zu 
finden.


Kann mir denn niemand mal den konkreten Fehler im obigen Programm sagen? 
Also was wo nicht stehen darf/soll und wo es dann hinkommt.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, steht doch in meinem Beitrag, andere haben's auch schon geschrieben:
Zeitmessung Interruptgesteuert machen. Alles Andere produziert Fehler im 
unteren Zeitbereich.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Na, steht doch in meinem Beitrag, andere haben's auch schon geschrieben:
> Zeitmessung Interruptgesteuert machen.

Aber wie soll ich das machen, wenn ich 2 Bewegungen erfassen will aber 
keine Zeit / Platz für Monoflops habe?

Autor: rene (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Du traust der Lichtschranke ? Ich nicht.

Rahul:
Was soll die Hardware schon falsch machen?
Noch eine Stimme für ein Softwareproblem!

Nun, ein analoges Signal von einem Photosensor geht auf einen 
Komparator. Da kann vieles Schiefgehen. Das Umgebungslicht kann den 
Level verschieben, usw. Daher zuerst den Sensor ueberpruefen. Der muss 
am Scope bockstabil sein. Ein Pendel sollte auf mikrosekunden 
reproduzierbar sein.

Aber zuerst sollte die Zeit mit Hardware, dh dem Capture interrupt 
gemessenn werden.

rene

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mehrere Eingänge (Lichtschranken) diodenentkoppelt auf einen INT-Pin und 
auf einzelne Portpins legen, die INT-Routine so kurz wie möglich halten 
und in dieser abfragen welcher Pin den INT ausgelöst hat. Das geht im 
µs-Bereich, ich denke nicht dass die Lichtschranken gleichzeitig 
auslösen (< 5µs z.B.).

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und selbst wenn, wenn man den Interupt ausreichend kurz macht
und den Wert nur speichert (z.b. nen buffer von 100bytes/Lichtschranke 
im RAM) dann ist die Reaktionszeit der Lichtschranke warscheinlich um 
ein vielfaches größer als die Interuptlaufzeit.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Nun, ein analoges Signal von einem Photosensor geht auf einen
> Komparator. Da kann vieles Schiefgehen. Das Umgebungslicht kann den
> Level verschieben, usw.

Nun, den hab nicht ich gebaut, daher kann da nicht viel schiefgehen.

> Mehrere Eingänge (Lichtschranken) diodenentkoppelt auf einen INT-Pin und
> auf einzelne Portpins legen.

Wie meinst du das mit den Dioden?

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wie meinst du das mit den Dioden?

Na, eine ODER-Verknüpfung der einzelnen Lichtschranken, deren Ausgang 
einen Interrupt auslösen soll. Soll heißen: jede Lichtschranke löst den 
selben INT aus, in dessen Routine wird festgestellt welche Lichtschranke 
wann (Zeitstempel) den INT ausgelöst hat. Das Ganze, wie Läubi 
gschrieben hat, in einen Buffer, dann haste nach den INTs Zeit das Ganze 
auszuwerten.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, auch auf die Gefahr hin mich hier unbeliebt zu machen, möchte ich es 
nochmal sagen:

Es muss doch eine Möglichkeit geben das Programm zu verbessern ohne dass 
ich den Aufbau verändern muss.

Grund:
1. Die Platine ist eh schon voll
2. Wenn ich da jetzt wieder mit meinem Halbwissen anfange rumzubauen, 
könnte es sein, dass ich in einem Monat mit gar nichts dastehe und das 
wäre schlecht ... sehr schlecht

Gibt es denn keine Lösung die ohne zusätliche Interrups mit einfachem 
Eingänge-Pollen annehembare Ergebnisse bringt?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Gibt es denn keine Lösung die ohne zusätliche Interrups mit einfachem
> Eingänge-Pollen annehembare Ergebnisse bringt?

Nur dann, wenn deine Pollroutine
 * möglichst kurz ist
 * und nur das tut, was unbedingt notwendig ist.
   Sprich: Die Eingänge überwachen, bei einem Ereignis
   den Timerwert wegspeichern.  Und sonst nichts 

In dem Moment, indem deine Funktion mehr tut, zb zwischendurch
Messwerte verschicken etc. -> Ask for troubles.

Das einfachste ist aber sicherlich: Das ganze Zeitmessgefrickel
dem Timer, sprich der Hardware, überlassen. Denn: Der Timer
macht das auch wenn dein Programm anderweitig beschäftigt ist.

Und um ehrlich zu sein: Dein Assemblerprogramm will ich mir
nicht antun.


Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie schon gesagt: Polling produziert IMMER Fehler im Timing!
Wenn du noch einen Monat Zeit hast, entwickle lieber eine neue Platine. 
Neu aufbauen geht oft schneller als was vorhandenes umzustricken. Ich 
kenne deinen Termindruck nicht, aber so würde ich es machen.

Autor: balu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja absolut definierte verhältnisse

ich hab deim prog nur überfolgen  aber du springst wild rum. du rufst 
immer mal deine kommunikation auf  in dieser wir auf einen zustand 
gewarte wenn das kein grund für ungenauigkeit is naja.

also

0. das bisherige prog und dessen bestandteile nichtmehr anguggen  am 
besten vergessen

1. zettel nehmen PAP oder sonstwas mahlen was einenm schema gleichkommt
2. das programmtechnisch umsetzen


noch was


initialisieren

messen

wenn messen bendet kommunizieren  und schluss


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  * möglichst kurz ist

Also im Normalfall passt das meine Pollroutine auch locker in die 96 
Zyklen.

>  * und nur das tut, was unbedingt notwendig ist.
>  Sprich: Die Eingänge überwachen, bei einem Ereignis
>  den Timerwert wegspeichern. * Und sonst nichts *

Dann gibt es natürlich eine Problem: Wie kann ich der Schranke dann 
sagen, dass sie mir die Messwerte schicken soll, wenn sie auf nichts 
reagiert?

> In dem Moment, indem deine Funktion mehr tut, zb zwischendurch
> Messwerte verschicken etc.

Tut mein Programm das? Wenn der µC während der Messung nichts übers UART 
empfängt, dann macht er das auch nicht (Er springt ja nur in den 
Kommunikationsteil, wenn er vorher ein Byte empfangen hat). Und wenn er 
schließlich das Byte zum Übertragen der Messwerte empfängt, dann ist es 
egal ob das dann noch die Messwerte dich noch aufgezeichnet werden 
würden verfälscht, denn dann ist die Messung für den Benutzer eh 
beendet.

Ich sehe immer noch nicht das Problem mit meinem Programm (es sei denn, 
der Computer schickt dem µC ständig irgendwas).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn dir eine Genauigkeit von 1 tausendstel Sekunde reicht,
sehe ich eigentlich keinen Grund, das Ganze nicht in C
zu schreiben. Das sollte eigentlich auch mit Pollen
ausreichend schnell sein.
In der Warteschleife nur auf die Lichtschranke warten, sonst
nichts! Das Zeitzählen kannst du wieder einem Timer überlassen,
das ist sein Spezialgebiet.


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> du rufst immer mal deine kommunikation auf in dieser wir auf einen zustand
gewarte wenn das kein grund für ungenauigkeit is naja.

könntest du das mal am code belegen, dass ich z.b. immer wieder die 
Kommunikation aufrufe? Ich rufe die Kommunikation nur, dann auf, wenn 
was empfangen wurde, und das passiert nicht so oft.

> initialisieren - messen - wenn messen bendet kommunizieren - schluss

Leider weiß der µC nicht wann Schluss, das wird vom Benutzer erst 
während der Laufzeit festgelegt.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie oft denn noch?
Miss die Zeiten INT-gesteuert!
Mach' doch einfach einen Versuchsaufbau auf'm Steckbrett und probier's 
aus, dauert auch nicht länger als hier auf eine Antwort zu warten, die 
dir gefällt. Nix für ungut, aber ein bischen experimentieren ist nie ein 
Fehler.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes wrote:
>> In dem Moment, indem deine Funktion mehr tut, zb zwischendurch
>> Messwerte verschicken etc.
>
> Tut mein Programm das? Wenn der µC während der Messung nichts übers UART
> empfängt, dann macht er das auch nicht (Er springt ja nur in den
> Kommunikationsteil, wenn er vorher ein Byte empfangen hat). Und wenn er
> schließlich das Byte zum Übertragen der Messwerte empfängt, dann ist es
> egal ob das dann noch die Messwerte dich noch aufgezeichnet werden
> würden verfälscht, denn dann ist die Messung für den Benutzer eh
> beendet.
>
> Ich sehe immer noch nicht das Problem mit meinem Programm (es sei denn,
> der Computer schickt dem µC ständig irgendwas).

Wo hast du eigentlich die 96 Takte her?

Im Grunde ist dein Pgm ja clever aufgebaut.
Du benutzt den CTC Mode im Timer um alle 96 Takte
einen Interrupt zu provozieren. Am Ende der Messschleife
wartest du auf das Auftreten des Interrupts und weist
somit, dass 96 Takte vergangen sind (mal einer mehr, mal
einer weniger, weil du ja den Interrupt nicht exakt im
Moment des Auftretens erwischt).
Aber: Ist sichergestellt, dass ein Durchgang durch die
Schleife nie länger als 96 Takte dauert? Ich hab jetzt
keine Takte gezählt.


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ sonic:

um mal dabei zu bleiben:

Wie oft denn noch? Ich möchte nichts am Aufbau verändern. Und ich weiß, 
dass es Leute gibt die so eine Platine in einer Woche nachbauen. Ich 
zähle nicht dazu weil ich halt nicht im Keller ätzen kann und ich nicht 
alle Teile doppelt dahab'.

Grund:
1. Die Platine ist eh schon voll
2. Wenn ich da jetzt wieder mit meinem Halbwissen anfange rumzubauen,
könnte es sein, dass ich in einem Monat mit gar nichts dastehe und das
wäre schlecht ... sehr schlecht

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, kenne deinen Kenntnisstand natürlich nicht. Ich mache in so einem 
Fall eine neue Platine (EAGLE) und lasse sie mir bei PCBPool o.Ä. 
fertigen. Kostet ein paar € aber das Resultat ist erstklassig.
In deinem Fall kann ich dann leider nicht weiterhelfen.

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich würde es so machen:
- Interupts AUS!
- Counter starten
- Die Lichtschranken pollen, wenn sich was ändert Timerwert (natürlich 
mit überlaufzähler) Speichern+Pollresult
(also z.B. einfach den Port kontinuierlich mit "in temp, PORT" einlesen, 
vergleichen ob sich was geändert hat. (cp last, temp).
Wenn ja, Timerwert einlesen+speichern+den eingeselen PORT wert.
- Auf tastendruck endet die Messung und alle gespeicherten werte werden 
an den PC gesendet, erneuter Tastendruck starte alles wieder von vorne.

Sollte einfach funktionieren (auch mit deiner bestehenden Hardware) und 
ausreichend genau sein.
- Du kannst dann etwa mit einem 10tel des Taktes pollen
(in 1 takt, cp 1 takt, branch+ggf speicher naja so etwa halt) was 
ausreichend genau sein müßte.
- Du mußt nicht mitzählen
- dir kann eigentlich nix dazwischen kommen
- die Messung kann zu einer beliebigen Zeit ausgelesen werden und am PC 
dann die Meßwerte den Lichtschranken zugeordnet werden.

mit 24 Zeitstempel und 8 bit Port kannst du dann (rechne rechne)  32 
Zustandsänderungen im Internem SRAM speichern.

Hilft dir der Ansatz?

Autor: unbeschreiblicher Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Nun, ein analoges Signal von einem Photosensor geht auf einen
>Komparator.

Wie sieht denn eigentlich die Hardware aus? Gibt es dazu einen Link?

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Im Grunde ist dein Pgm ja clever aufgebaut.

Danke :-)

> Ich hab jetzt keine Takte gezählt.

Ich aber grad. Hab jetzt mal den worst case während einer Messung 
angenommen. Also die Messwerte haben sich verändert und das Programm hat 
ein unbekanntes Zeichen erhalten (eins, für das keine Antwort in der 
Kommunikation vorgesehen ist). Rausgekommen sind 54 Zyklen, also da wäre 
theor. noch Luft.

Eine Frage hätte ich dann noch.
Wenn ich jetzt das Programm neu entwerfe, wie soll ich das dann mit der 
Kommunikation machen? Denn auch wenn das Programm misst, dann muss der 
µC ja noch ansprechbar sein, ich also die Messung beenden können. Hast 
du da eine Idee, meine Lösung scheint ja nicht so 'prickelnd' zu sein.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Läubi

> - Interupts AUS!
> - Counter starten
> - Die Lichtschranken pollen, wenn sich was ändert Timerwert (natürlich
> mit überlaufzähler) Speichern+Pollresult
> (also z.B. einfach den Port kontinuierlich mit "in temp, PORT" einlesen,
> vergleichen ob sich was geändert hat. (cp last, temp).
> Wenn ja, Timerwert einlesen+speichern+den eingeselen PORT wert.
> - Auf tastendruck endet die Messung und alle gespeicherten werte werden
> an den PC gesendet, erneuter Tastendruck starte alles wieder von vorne.

Danke für deine Hilfe. Mit Tastendruck meinst du eine echte Taste am µC, 
oder? Kann man das auch mit einem Zeichen per UART realisieren?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Eine Frage hätte ich dann noch.
> Wenn ich jetzt das Programm neu entwerfe, wie soll ich das dann mit der
> Kommunikation machen? Denn auch wenn das Programm misst, dann muss der
> µC ja noch ansprechbar sein, ich also die Messung beenden können. Hast
> du da eine Idee, meine Lösung scheint ja nicht so 'prickelnd' zu sein.

Ich würde es so machen

Bevor noch irgendwas gemessen wird:
Vom PC (oder der Gegenstelle) muss ein Kommando kommen, dass
ab jetzt gemessen werden kann und zwar n Messwerte.
Eventuell würde ich noch die Maximalzeit dafür bekanntgeben.

Danach wartet das Pgm darauf, dass die Lichtschranken n
mal unterbrochen werden und speichert die Zeitstempel
dafür weg. Während der Messzeit gibt es keine Unterbrechung,
durch nichts und niemanden. Der µC ist nur damit beschäftigt
die Zeit weiterzuzählen, die Lichtschranken zu überwachen
und bei Bedarf den Zeitstempel zu speichern. Ach ja: Wenn
eine maximale Messzeit bekannt ist, dann beendet der µC
auch noch vorzeitig die Messung. Aber ansonsten gibt es
nichts in der Schleife was mich noch  interessieren könnte.
(Ev. vielleicht noch ein 'Reset' Taster, falls eine Messung
durch Hardwareprobleme in die Hose geht und die maximale
Messzeit auf 0.5 Stunden eingestellt ist).

Autor: Johannes (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Wen die Hardware interessiert -> Anhang
Das links unten ist die Schaltung für den Reset-Taster

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes wrote:
> @ Läubi
>
>> - Interupts AUS!
>> - Counter starten
>> - Die Lichtschranken pollen, wenn sich was ändert Timerwert (natürlich
>> mit überlaufzähler) Speichern+Pollresult
>> (also z.B. einfach den Port kontinuierlich mit "in temp, PORT" einlesen,
>> vergleichen ob sich was geändert hat. (cp last, temp).
>> Wenn ja, Timerwert einlesen+speichern+den eingeselen PORT wert.
>> - Auf tastendruck endet die Messung und alle gespeicherten werte werden
>> an den PC gesendet, erneuter Tastendruck starte alles wieder von vorne.
>
> Danke für deine Hilfe. Mit Tastendruck meinst du eine echte Taste am µC,
> oder? Kann man das auch mit einem Zeichen per UART realisieren?

Lass blos die UART raus!

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Vom PC (oder der Gegenstelle) muss ein Kommando kommen, dass
> ab jetzt gemessen werden kann und zwar n Messwerte.
> Eventuell würde ich noch die Maximalzeit dafür bekanntgeben.

Das ist eben beides nicht bekannt.

Autor: unbeschreiblicher Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wen die Hardware interessiert -> Anhang
Wie ein Mikrocontroller beschaltet wird, weiß ich selbst.
Ich meinte eher die Messapparatur.

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst prüfen ob ein Zeichen am UART empfangen wurde, ja.
Das würde ja reichen das du die Meßdaten rausgibst sobald irgeneien 
Zeichen vom UART empfangen wurde.

Ansonsten, miß auf jedenfall mal nach was die Lichtschranken so bringen!
Ich weiß das einige Infarotsensoren eine ReaktionsZeit von 20(!!!)ms 
haben.
Wenn vom Sensor schon so eine lahme Reaktionszeit kommt wirds mit der 
Zeitmessung halt recht schwer.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes wrote:
>> Vom PC (oder der Gegenstelle) muss ein Kommando kommen, dass
>> ab jetzt gemessen werden kann und zwar n Messwerte.
>> Eventuell würde ich noch die Maximalzeit dafür bekanntgeben.
>
> Das ist eben beides nicht bekannt.


Ach komm, du wirst doch eine ungefähre Abschätzung haben?
Sind das 10 Sekunden oder 2 Minuten.
Es geht lediglich darum, dass sich die Messaperatur selbstständig
wieder abschaltet, wenn mal nicht alle Lichtschranken
ausgelöst wurden, weil dein zb. deine Kugel aus der Rille
gefallen ist. Ansonsten hängt der µC und wartet bis auch tatsächlich
alle 5 Lichtschranken durchgeschaltet haben.


Autor: Johannes (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
> Ich meinte eher die Messapparatur.

Sags halt gleich :-)

> Das würde ja reichen das du die Meßdaten rausgibst sobald irgeneien
> Zeichen vom UART empfangen wurde.

Dann müsste ich aber auf einige mehr oder weniger wichtige Funtkionen, 
wie z.b. die automatische Erkennung des verwendeten COM-Ports oder eine 
Funktion zur sofortigen Status-Übermittelung an den PC (ist für das 
PC-Programm wichtig) verzichten.

> Ansonsten, miß auf jedenfall mal nach was die Lichtschranken so bringen!

Kein Scope in der Hosentasche :-)

> Ich weiß das einige Infarotsensoren eine ReaktionsZeit von 20(!!!)ms
> haben. Wenn vom Sensor schon so eine lahme Reaktionszeit kommt wirds mit
> der Zeitmessung halt recht schwer.

Es werden Phototransistioren eines Typs verwendet, der heute anscheinend 
nicht mehr existiert. Kannst ja mal schaun, was du auf dem Bild erkennen 
kannst. Ich lese BPA01II, finde aber dazu nichts.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ach komm, du wirst doch eine ungefähre Abschätzung haben?

Ja ca. 10 sek.

> Es geht lediglich darum, dass sich die Messaperatur selbstständig
> wieder abschaltet, wenn mal nicht alle Lichtschranken ausgelöst wurden

Es kann aber auch vorkommen, dass einigen Lichtschranken öfters 
durchbrochen werden. Das ist für den Benutzer vorher nicht vorhersagbar.

> tatsächlich alle 5 Lichtschranken durchgeschaltet haben

es waren 8 ;-)

Autor: balu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was ist denn nun deine kürzesteze gewünschte zeiteinheit ?

meine aus der hüfte geschossene variante.

unter folgenden vorrausetzungen:
- der interrupt für den timer überlauf ist höher priorisiert als die 
uart
- und der timer interrupt unterbricht den uart interrupt.
- der inhalt des timer interrupts is kürzer al ser selbst (logischer 
weise)

dann kannst du im Timer pollen, auf veränderung prüfen
sowie speichern bei bedarf

die uart kann alles übertragen und auf "posteingang warten"

in der hauptschleife wird dann der restliche mist gemacht  zb den 
posteingang auswerten und ggf aktionen vormerken ....

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>- und der timer interrupt unterbricht den uart interrupt.

Niemals! Außer du gibst am Anfang der Timer-INT-Routine den globalen INT 
frei.

Autor: balu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also gehts doch oder

ich  hab eben schon länger nicht mehr so  defizile sachen gemacht
in c gabs doch den unterschied zwischen

signal ()

und

interrupt()

gelle der eine war zu unterbrechen und der andere nicht  aber aus gutem 
grund habe ich das bisher immer gemieden einen solchen konstruckt zu 
friemeln damit macht man sich wenn nicht alles 100% bekannt is schnell 
ein loch ins knie solle aber bei den paar zeilen hier gehen

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vergleich C und ASM:
C: SIGNAL verlässt die INT-Routine mit 'reti'
   INTERRUPT verlässt die INT-Routine mit 'ret'
Dann muss der globale INT 'von Hand' freigegeben werden.

Autor: balu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ehm meinst du nicht

außer man gibt am anfang der uart routine den globalen INT wieder frei?

und meien asm zeiten liegen 5 j zurück  also ret und reti sind für mich 
rücksprünge naja
egal mal sehen was wird

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
probier's mal mit Gemütlichkeit ...
waren wohl ein paar 'Erfrischungen' zuviel heute ???

Autor: Dieter Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Es werden Phototransistioren eines Typs verwendet, der heute anscheinend
> nicht mehr existiert. Kannst ja mal schaun, was du auf dem Bild erkennen
> kannst. Ich lese BPA01II, finde aber dazu nichts.

Ich lese da BPX81IX (römisch 9)

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Dieter Werner

Danke, dann wissen wir ja endlich mit was wir es zu tun haben.
Anstiegs-/Abfallzeit: 5.5 - 8 µs

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes:

Vielleicht ist Dir folgender Pseudocode für ein paar Anregungen 
dienlich.

t und _Time_[] verstehen sich darin als 24 Bit-Variablen.  Damit 
kannst Du Dich dann über eine maximale Messzeit von 0.1 ms * 2^24 = 
1677721 ms = 1677 s = 28 min bei einer Messauflösung von 0.1 ms freuen.
// Interrupt-Tabelle
// ...
// ...


//=============================================

// Da "TimerOverflow" sehr zeitkritisch ist,
// darf es "USARTInput" unterbrechen;
// deshalb hier ein "sei" am Anfang!


USARTInput:
  {
  sei

  // Eingetroffenes Byte aus Hardware abholen und
  // in Ringpuffer abspeichern
  }

  reti


//=============================================

// Interrupt-Routine

// Geschätzte Anzahl Instruktionen für den Fall dass jede
// Zeile abgearbeitet wird: ca. 100 (siehe Tabelle)
// ATmega8 @ 8 MHz schafft innerhalb 0.1 ms ca. 500
// Instruktionen
// --> zu erwartende relative Prozessorlast durch diese
// Interruptroutine beträgt ca. 20 % --> OK!
//
// --------------------------------------------------
// Aktion                           # Instruktionen
// --------------------------------------------------
// IF TimeMeasRunning               3
// Inc _t_                          4
// IF (_t_<_Grenzwert_)             6
// PortState = PORTXXX              4
// FOR (i = 0...8-1)                6
// IF (Bit i in PortState gesetzt)  4*8
// _Time_[i] = _t_                  4*8
//
// MainFlag = 0                     1
// inc k                            1
// IF (k=200)                       4
// k = 0                            1
// MainFlag = 1                     1
//                                 -----
//                           total: 95
// --------------------------------------------------


TimerOverflow:
  {
  // Passiert alle 0.1 ms

  IF TimeMeasRunning
    {
    Inc _t_

    IF (_t_<_Grenzwert_)
      {
      PortState = PORTX

      FOR (i = 0...8-1)       // 8 = Anzahl der Lichtschranken
        {
        IF (Bit i in PortState gesetzt)
          {
          _Time_[i] = _t_     // Auslösezeit protokollieren
          }
        }
      }
    }

  //-----------------------

  MainFlag = 0

  inc k

  IF (k=200)
    {
    // Passiert alle 20 ms

    k = 0

    MainFlag = 1
    }
  }

  reti

  
//=============================================

ResetTimer:
  {
  _t_ = 0

  FOR (i = 0...8-1)       // 8 = Anzahl der Lichtschranken
    {
    _Time_[i] = -1
    }
  }


//=============================================

Init:
  // Um Initialisierungskram kümmern
  // ...
  // ...


Main:
  IF (MainFlag=1)
    {
    // Passiert alle 20 ms

    // Alles Zeitunkritische erledigen was zu erledigen ist
    //
    // - Benutzertasten-Abfragen
    //
    // - entsprechend Zeitmessung enablen/disablen
    //   durch Setzen/Löschen von TimeMeasRunning
    //
    // - Wenn Zeitmessungslauf gestoppt, _Time_-Werte
    //   für alle ausgelösten Lichtschranken verrechnen
    //
    // - Prüfen, ob UART-Ringpuffer voll ist,
    //   gegebenenfalls auswerten
    //
    // - Falls nötig Daten über UART an PC senden
    //
    // - irgendwelche Kontroll- und Status-LEDs schalten
    //
    // - ...
    }

  sleep

  rjmp Main

Autor: Johannes (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich hab mir auch nochmal was überlegt ... und zwar auf einem Blatt 
Papier

bitte auseinandernehmen :-)

Schönen Abend noch. Ich bin jetzt Fernsehen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, nu sach ich auch mal wat:

Du mußt die Lichtschranken im Timerinterrupt pollen.
D.h. der Pollzyklus muß kürzer als die kürzeste Unterbrechungszeit sein, 
sonst geht sie Dir duch die Lappen.

Oder Du nimmst nen ATmega168, ist pinkompatibel, aber mit 
Pin-Change-Interrupt.

Die UART darf dann auch kein Interrupt sein, da die AVRs leider keine 
Prioritäten haben.
Also die UART im Main pollen, 3 Bytes werden ja gepuffert.
Notfalls die Baudrate runter setzen.

Dann müßte es gehen, Layoutänderung ist unnötig.


Peter


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Peter Dannegger

Verstehe ich das richtig, dass deine Anmerkungen sich nicht auf das 
Programm beziehe, das ich im Beitrag über dir vorgeschlagen habe.

Du meinst das also so:

Ich stelle einen Timer so ein, das er z.b. alle 64 (oder auch mehr oder 
weniger) Taktzyklen überläuft und mir einen Interrupt gibt. In der 
Interruptroutine frage ich dann 1mal die Lichtschranken ab und spiechere 
den Zustand (wenn sich etwas geändert hat) mit der Anzahl der Überläufen 
seit Messungsbeginn (die ich irgendwo anders speichere und bei jedem 
Interrupt des Timers erhöhe).

Dann habe ich noch eine Hauptschleife in der so Sachen wie die 
Kommunikation mit dem PC erledigt wird (ohne Interrupt).

Alles richtig wiedergegeben?

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem Atmega168 ist natürlich die eleganteste Lösung, die machen 
ich/wir wenn das nächste Programm auch keine guten Ergebnisse liefert.

Aber eigentlich müsste es der Atmega88 [sic] doch auch tun, 
unterscheiden sich dann ja nur noch in der Größe des Flash-Speichers.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber eigentlich müsste es der Atmega88 [sic] doch auch tun,

Da hast du recht.
Was mich allerdings noch etwas stutzig macht sind deine
Abweichungen beim Pendelexperiment. 20% ist schon ne
Menge Holz.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ peter D.:
>da die AVRs leider keine Prioritäten haben.

Doch! Bitte nochmal ins Dateblatt gucken.

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Doch! Bitte nochmal ins Dateblatt gucken.

Nicht in der Art, wie die 8051er sie haben:
Da kann ein Interrupt höherer Priorität einen mit niedrigerer 
unterbrechen.
Beim AVR sind grundsätzlich alle anderen Interrupts während einer 
ISR-Bearbeitung gesperrt.
Bei solchen zeitkritischen Sachen muß man ISR extrem kurz halten.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@fieser Rahul

> > Doch! Bitte nochmal ins Dateblatt gucken.

> Nicht in der Art, wie die 8051er sie haben:
> Da kann ein Interrupt höherer Priorität einen mit niedrigerer
> unterbrechen.
> Beim AVR sind grundsätzlich alle anderen Interrupts während einer
> ISR-Bearbeitung gesperrt.

Nööö, man kann einfach in niederpriorisierten Interrupts ein SEI zu 
Begin ausführen. Dadurch ist dieser Interrupt durch andere 
unterbrechbar.
OK, eine richtige Interuptpriorität wie sie andere uC oder CPUs haben 
ist das nicht ganz.

MfG
Falk

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>OK, eine richtige Interuptpriorität wie sie andere uC oder CPUs haben
>ist das nicht ganz.

Genau das meinte ich. (Und wusste auch, dass das kommt.)

>Nööö, man kann einfach in niederpriorisierten Interrupts ein SEI zu
>Begin ausführen

"Gebastel".
Da könnte man in C-Programmen auch ein "goto" verwenden...

Zum Thema:
Im Prinzip ist es doch nichts anderes als ein Frequenzmesser.
Da kann man entweder abfragen, ob sich etwas am Eingang gändert hat und 
die Zeit zwischen zwei Änderungen messen, oder innerhalb einer 
bestimmten Torzeit die Anzahl der Ereignisse feststellen.

Kann es sein, dass man diese (Schul-)Versuche früher mit nur einer 
Lichtschranke gemacht hat, die in der Höhe variable war?
(Oder habe ich den praktischen Anwedungszweck immer noch nicht 
verstanden?)

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>"Gebastel".
>Da könnte man in C-Programmen auch ein "goto" verwenden...

Falsch! Die Prioritäten wurden von Atmel absichtlich so aufgebaut, um 
einen versehentliche Stacküberlauf zu vermeiden, was bei den 8051ern 
öfter mal vorkommen kann. Das mit dem SEI ist schon richtig und gängige 
Praxis, nur sollte man dann wissen was man tut! Das Ergebnis ist das 
gleiche wie bei den 8051ern.

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>nur sollte man dann wissen was man tut!
Ja, sollte man. Man sollte das Programm so auslegen, dass man ohne das 
SEI auskommt...

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimme ich zu!

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der von Johannes oben gepostete Programmablaufplan sieht das ja 
eigentlich so auch vor...

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kann es sein, dass man diese (Schul-)Versuche früher mit nur einer
> Lichtschranke gemacht hat, die in der Höhe variable war?
> (Oder habe ich den praktischen Anwedungszweck immer noch nicht
> verstanden?)

Jetzt noch mal genau:
Man stelle sich eine Schwebebahn vor, auf der sich bis zu 2 Gleiter 
befinden können. Diese Gleiter haben obendruaf ein kleines Fähnchen mit 
dem sie die Lichtschranken durchbrechen die entlang der Bahn aufgebaut 
sind.

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte mir vielleicht noch mal jemand die Aufgabenstellung ansich 
verklickern?
Soweit ich das bis jetzt verstanden habe, bezieht sich das o.g. Problem 
auf einen älteren Thread (den ich nicht finde / nach dem ich nicht 
weiter suchen will...).
Die Aufgabe scheint eine Stoppuhr für einen Versuchsaufbau für den 
Physik-Unterricht zu sein, bei dem es um Pendel geht.
Richtig?

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahaj, es dämmert wieder.
Das haben wir damals mit einem Hochspannungsnetzteil gemacht, das mit 
einer bestimmten Frequenz gepulst wurde. Die Impulse sorgten für Löcher 
in einer Folie. Die Abstände der Impulse waren dann ein Maß für die 
Geschwindigkeit...(t = const, s = variable => v = variable).

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sonic wrote:

> Falsch! Die Prioritäten wurden von Atmel absichtlich so aufgebaut, um
> einen versehentliche Stacküberlauf zu vermeiden, was bei den 8051ern
> öfter mal vorkommen kann. Das mit dem SEI ist schon richtig und gängige
> Praxis, nur sollte man dann wissen was man tut! Das Ergebnis ist das
> gleiche wie bei den 8051ern.


Nein, da ist ein grundsätzlicher Unterschied !

Bei den 8051 kann es zu keinem Stacküberlauf kommen, da die Prioritäten 
in Hardware gemacht werden. Es können also immer nur soviel Instanzen an 
Interrupts gleichzeitig auftreten, wie verschiedene Prioritäten 
zugewiesen wurden. Ein gleiche Interruptpriorität kann sich daher nie 
selber unterbrechen.


Wenn Du dagegen beim AVR im UART-Interrupt ein sei() machst, um den 
Timerinterupt wieder zu erlauben, läuft sofort der Stack über, da ja das 
Pending-Flag beim Eintritt nicht gelöscht wird.

Das hat mich bei den AVRs auch schon oft geärgert, daß ausgerechnet die 
zeitunkritischen Interrupts (UART, EEPROM, I2C usw.) ihre Flags nicht 
löschen und daher Priorität in Software äußerst kompliziert wird.


Peter

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter Dannegger

> Nein, da ist ein grundsätzlicher Unterschied !

Ja.

> Wenn Du dagegen beim AVR im UART-Interrupt ein sei() machst, um den
> Timerinterupt wieder zu erlauben, läuft sofort der Stack über, da ja das
> Pending-Flag beim Eintritt nicht gelöscht wird.

Kommt auf den Interrupt an. Einige löschen per Hardware automatisch die 
Bits, andere müssen "per Hand" gelöscht werden. Es sollte klar sein, 
dass bei diesen erstmal das Löschen angesagt ist, bevor man SEI 
ausführt.

> Das hat mich bei den AVRs auch schon oft geärgert, daß ausgerechnet die
> zeitunkritischen Interrupts (UART, EEPROM, I2C usw.) ihre Flags nicht
> löschen und daher Priorität in Software äußerst kompliziert wird.

Naja, als "äußerst kompliziert" würde ich das nicht bezeichnen.

MfG
Falk

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn Du dagegen beim AVR im UART-Interrupt ein sei() machst, um den
> Timerinterupt wieder zu erlauben, läuft sofort der Stack über, da ja das
> Pending-Flag beim Eintritt nicht gelöscht wird.

Bei denen wo's automatisch gelöscht wird geschieht dies beim Aufruf der 
INT-Routine, er kann sich also nicht selbt wieder aufrufen wenn in der 
ISR das SEI ausgeführt wird.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, habs mir nochmal durchgelesen. Ich rekapituliere mal.

Die Zustandsänderung eines 8 Bit Ports soll mit einer Auflösung von 5us 
protokolliert werden. Innerhalb einer maximalen Messzeit von 20s können 
maximal 40 Zustandswechsel auftreten. Die Liste der Zustandswechsel soll 
am Ende der Messzeit zum PC per UART übertragen werden.

Richtig?

OK, hier mein Vorschlag.

theoretisch bräuchte man 8 Capture-Compare-Eingänge. Da wir die im AVR 
nciht haben, muss es eben per Polling gemacht werden.

Kleiner Pseudocode.

Warte aus Startsignal für Messung
  Schleifenanfang:
Port einlesen
Vergleich mit vorherigem Wert
Wenn verschieden, aktuellen Zeitstempel und Portwert per Z-pointer in 
SRAM schreiben
Zeitstempel hochzählen
Wenn Schleifenzähler ungleich null, Sprung zum Schleifenanfang

Messwerte zum PC schieben

Der Trick dabei ist, dass die beiden Zweige (Vergleich positiv oder 
negativ) mittels NOP auf gleich lange Ausführungszeiten getrimmt werden 
müssen(Takte), um eine konstante Zykluszeit zu erreichen. Logo, dass man 
hier Assembler braucht. Man kann den Zeitstempel und Schleifenzähler 
kombinieren und muss nur eine Variable bearbeiten. Spart ein paar Takte.

20s / 5us = 4000000, wir brauchen also einen 3 Byte Zeitstempel
+ 1 Byte für den Portwert, macht 4 Byte/Eintrag
Macht bei 1k RAM max. 256 Einträge
Das sollte passen.

MfG
Falk


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, hab mich heute früh hingesetzt und die 'Version 2' des Programms 
geschrieben (bitte ab jetzt immer dazuschreiben, auf was man sich 
bezieht).

Ablauf:

nach der ganze Initialisierung läuft das Programm in einer Hauptschleife 
in der die Kommunikation abgearbeitet wird.
Ein Interrupt tritt alle 96 Zyklen auf und unterbricht diese 
Hauptschleife. In der Interruptroutine werden die LS abgefragt und wenn 
nötig mit dem Überlaufzähler gespeichert.

http://home.arcor.de/kreuzfeuer/fa2.html

Bitte wieder bewerten. Eine Messung habe ich noch nicht durchgeführt, 
möchte erst noch erste Rückmeldungen abwarten.


@ fieser Rahul

Ja, ich glaube das war der erste Beitrag den ich hier zur Zeitmessung 
gemacht habe. Du bekommst nochmal 100 extra Punkte, wenn du mir den 
Beitrag aus dem Usenet ausgräbst, in dem mir die Leute die ersten 
Hinweise für mein Vorhaben gegeben haben :-)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sonic wrote:

>> Wenn Du dagegen beim AVR im UART-Interrupt ein sei() machst ...

> Bei denen wo's automatisch gelöscht wird ...

Der UART-Interrupt wird bei keinem AVR automatisch gelöscht !

Das ist es ja. Wenn wenigstens dann das Enable-Flag gelöscht würde.
So aber braucht man unter AVR-GCC immer noch etwa weitere 20 Zyklen, ehe 
man andere Interrupts wieder erlauben kann.
Und naked Interrupts sind wirklich ne Krücke.

Ich habs dann daher mit nem 2.Timer gemacht, ist aber auch irgendwie 
"von hinten durch die Brust ins Auge".


Peter

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes

> So, hab mich heute früh hingesetzt und die 'Version 2' des Programms
> geschrieben (bitte ab jetzt immer dazuschreiben, auf was man sich
> bezieht).

Naja, sieht erstmal brauchbar aus. ABER!

Warum mit Interrupt?
Das kostet dich 4+4+2 Takte jedesmal für Interrupt aufrufen, SREG 
sichern und Interuptverlassen. Ich würde ne normale Poll-Schleife 
machen.

Zweitens, das mit der Endlosschleife forever find ich hier unbrauchbar. 
Ich würde in einer Schleife auf ein Zeichen waren (Start der Messung), 
dann die Pollschleife anspringen. Innerhalb der der Poll-Schleife kannst 
du dann per Polling prüfen ob ein weiteres Zeichen empfangen wurde (Ende 
der Messung, Wert ist egal). Das alles ohne Interrupts. Dann ist das 
Timing auch absolut deterministisch und überschaubar.

MfG
Falk

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Warum mit Interrupt?

Weil ich mir dann sicher sein kann, dass das Abfragen der Lichtschranken 
immer im gleichen (zeitl.) Abstand geschieht.

> Ich würde ne normale Poll-Schleife machen.

Dann hab ich wieder das Problem, dass ich das Pollen der Lichtschranken 
und das Abfragen ob ein Byte empfangen wurdeunter einen Hut zu bekommen, 
ohne dass das UART die Messung blockiert.

> Zweitens, das mit der Endlosschleife forever find ich hier unbrauchbar.
> Ich würde in einer Schleife auf ein Zeichen waren (Start der Messung),
> dann die Pollschleife anspringen. Innerhalb der der Poll-Schleife kannst
> du dann per Polling prüfen ob ein weiteres Zeichen empfangen wurde (Ende
> der Messung, Wert ist egal). Das alles ohne Interrupts. Dann ist das
> Timing auch absolut deterministisch und überschaubar.

Mach ich auch gleich mal ein Programm dazu, wird dann Version 3 :-)

Autor: Falk (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes

> > Warum mit Interrupt?

> Weil ich mir dann sicher sein kann, dass das Abfragen der Lichtschranken
> immer im gleichen (zeitl.) Abstand geschieht.

Geht wunderbar mit ner Schleife.

> > Ich würde ne normale Poll-Schleife machen.

> Dann hab ich wieder das Problem, dass ich das Pollen der Lichtschranken
> und das Abfragen ob ein Byte empfangen wurdeunter einen Hut zu bekommen,
> ohne dass das UART die Messung blockiert.

nein, weil die Messwertübertragung nach der MEssung statt findet.

> > Timing auch absolut deterministisch und überschaubar.

> Mach ich auch gleich mal ein Programm dazu, wird dann Version 3 :-)

Hier mal mein Versuch. Ist nicht durch den Assembler gejagt, hat sicher 
noch Tippfehler.

MfG
Falk

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes:

Du wünschst eine Zeitauflösung von 5 µs?  Hast Du mal ausgerechnet, wie 
genau Du die Lichtschranken für eine gegebene Maximalgeschwindigkeit 
(wie groß ist die bei Deinem Projekt?) räumlich positionieren müsstest, 
damit diese Auflösung Sinn macht?

Außerdem gebe ich zu bedenken, dass ein ATmega8 @ 8 MHz während 5 µs 
lediglich noch ca. 30 Instruktionen abarbeiten kann.  Meinst Du, das 
reicht für die Durchführung aller erforderlichen Aktionen (Port 
einlesen, auf Änderung überprüfen, Lichtschrankenzustände an richtigem 
Platz im SRAM abspeichern, evtl. noch "Messung abbrechen"-Taster 
abfragen...)?


@Peter Dannegger:

Dein Einwand mit dem "sei", das man nicht so wie von mir in dem 
Pseudocode dargestellt ohne weitere Maßnahmen am Anfang einfügen darf, 
weil das Interruptflag beim UART-Interrupt nicht automatisch gelöscht 
wird, ist berechtigt.  Daran hab ich nicht gedacht. Danke für den 
Hinweis!

Autor: Johannes (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Falk:

ich habe deinen Logger mal angepasst und die Durchlaufzeiten in den 3 
Pfaden (keine Änderung, Änderung mit Speichern, Änderung ohne Speichern, 
weil schon 150 Messwerte gespeichert wurden) auf immer 19 Zyklen 
gebracht.

Außerdem habe ich wieder auf einen 4 Byte Zeitstempel umgestellt, da mit 
3 Byte und 17 Zyklen nur ca 17 Sekunden drin gewesen wären und das wäre 
mir etwas zu knapp geworden.

Bitte drüberschauen.

DANKE AN ALLE DIE MIR BISHER GEHOLFEN HABEN

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>und die Durchlaufzeiten in den 3 Pfaden (...) auf immer 19 Zyklen
>gebracht.

Na dann funzt es ja bestens.  Wenn Du die Schleifendurchläufe durch 
weitere "nop"s auf exakt 40 Zyklen justierst, kannst Du bei 8 MHz 
Systemtakt ein Messintervall von quarzgenauen 5 µs erreichen. Damit 
bleibst Du zwar etwas unterhalb der maximal möglichen Auflösung, hast es 
dafür aber bei der späteren Auswertung sicher bequemer als mit einem 
"krummen" Wert.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ avr fan:

Aber mit genau 8mhz habe ich dann weider ein Problem mit dem UART ;-)
Also lassen wird das so ;-)

Autor: Falk (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes

> ich habe deinen Logger mal angepasst und die Durchlaufzeiten in den 3
> Außerdem habe ich wieder auf einen 4 Byte Zeitstempel umgestellt, da mit
> Bitte drüberschauen.

Sieht gut aus. Du magst wohl meine r_ Notation nicht? ;-)
Aber cnt3 würde ich noch definieren, um konsequent zu bleiben. Das fällt 
einem sonst beim nächsten, grösseren Projekt auf die Füsse.

> Aber mit genau 8mhz habe ich dann weider ein Problem mit dem UART ;-)
> Also lassen wird das so ;-)

Wieso?

Mit 8 MHz kann ich alle normalen Baudraten ausser 28k8, 57k6, 76k8 und 
115k2. Reicht das nicht?

@AVRFan

> Du wünschst eine Zeitauflösung von 5 µs?  Hast Du mal ausgerechnet, wie
> genau Du die Lichtschranken für eine gegebene Maximalgeschwindigkeit
> (wie groß ist die bei Deinem Projekt?) räumlich positionieren müsstest,
> damit diese Auflösung Sinn macht?

Keine Ahnung wie die Anforderungen sind, aber mal mal als Orientierung.

1 m/s = 1mm / 1ms  (das metrische System ist schon was feines ;-)
      = 5um / 5us

So breit ist wahrscheinlich der Bonddraht ;-)

Wenn sich die Objekte schneller bewegen siehts natürlich anders aus.
Aber unabhängig davon ist die Zeitmessung korrekt. Nur sollte man sich 
bei der Umrechnung von Zeit in Geschwindigkeit in Acht nehmen, da der 
Weg (Abstand der Lichtschranken, bzw. des effektiven Lichtstrahls) nicht 
so genau ist ;-)

MfG
Falk


Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Aber mit genau 8mhz habe ich dann weider ein Problem mit dem UART ;-)

Überhaupt nicht ;-).  Bei den Baudraten 2400, 4800 und 9600 beträgt die 
relative Abweichung der UART-Frequenz nur 0.2 % und das ist völlig 
belanglos.  Siehe Data Sheet zum ATmega8 [*], Seite 159 ff.  Dort stehen 
auch die passenden UBRR-Werte.

[*] http://www.atmel.com/dyn/resources/prod_documents/...

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
38400 Baud bei 8MHz gehen völlig problemlos.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber cnt3 würde ich noch definieren, um konsequent zu bleiben. Das fällt
> einem sonst beim nächsten, grösseren Projekt auf die Füsse.

Naja, gibt halt eine Warnung, weil XL schon als r26 definiert ist.

> Mit 8 MHz kann ich alle normalen Baudraten ausser 28k8, 57k6, 76k8 und
> 115k2.

Datenblatt Atmega8, Seite 158
Da steht, dass man mit 8Mhz schon bis 0M5 hochkommt, aber dann hat man 
Fehlerwahrscheinlichkeiten von 0.2 - 8.5 %

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach, ist ja alles egal, wenns mit 14,7456 MHz auch funktioniert (das 
wird jetzt dann getestet :-)

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, hab gerade wieder eine Pendelmessung mit Version 3 gemacht, die alle 
34 Zyklen die Schranken abfragt. Die Ergebnisse sind überzeugend :-)

Alle Werte beziehen sich jetzt auf T (Periodendauer), es wurden 7 
Unterbrechungen gemessen, woraus sich 5 Periodendauern berechnen lassen:

Abweichung größter - kleinster gemessener Wert: 3 Promille
Größte Abweichung zum theoretischen Wert: 2 Promille

Ich denke, das ist ziemlich gut :-)

NOCHMAL DANKE AN ALLE DIE MIR GEHOLFEN HABEN

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Johannes

> So, hab gerade wieder eine Pendelmessung mit Version 3 gemacht, die alle
> 34 Zyklen die Schranken abfragt. Die Ergebnisse sind überzeugend :-)

Warum nun wieder 34 Takte?

MfG
Falk

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die 19 die ich oben gezählt habe waren nur der 'variable' Teil. Bei den 
34 Takten ist dann auch das dabei, was in allen 3 Zweigen gleich gemacht 
wird.

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes:

Noch Lust auf ne knifflige Rätselfrage? Bitteschön:

Wenn Du alle acht Lichtschranken durch einen Taster ersetzt, der alle 
Lichtschranken-Signalleitungen parallel bedient, wirst Du nicht immer 
für alle Leitungen die genau gleichen Zeiten protokolliert finden, 
sondern...

Wie ist der Satz fortzusetzen und warum? Na? ;-)

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes:

Wenn du für jede Lichtschranke eine genaue Zeitmessung haben willst geht 
das nur über einen anderen µC.

Du musst dann für jede Lichtschranke einen extern getriggerten 
Hardwaretimer haben, der einen Zeitstempel der Flanke speichert. Diese 
Zeitstempel kannst du dann zeitunkritisch Auswerten.

Darüber kannst du dann eine Auflösung im unteren µs eventuell ns Bereich 
erzielen.

Solange du nicht jedem Eingang einen eigenen Zeitstempel zuordnen 
kannst, egal ob getriggerter Timer oder Interrupt, wirst du immer mehr 
oder weniger große Abweichungen erhalten.
Und du kannst auch nie ausschließen das Impulse der Lichtschranken 
"übersehen" werden.


Ein möglicher µC für dein Problem wäre der TMS 470 vom TI.
Das ist ein AMR 7 Controller der zusätzlich einen HighEndTimer Modul mit 
bis zu 32 einzel triggerbare IO Leitungen hat.


Ralph

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Darüber kannst du dann eine Auflösung im unteren µs eventuell ns Bereich
>erzielen.

Wozu?

>Ein möglicher µC für dein Problem wäre der TMS 470 vom TI.
>Das ist ein AMR 7 Controller der zusätzlich einen HighEndTimer Modul mit
>bis zu 32 einzel triggerbare IO Leitungen hat.

Klingt nach großkalibrigen Waffen und kleinen Vögeln...

Wie Falk oben schon schrieb: 5µs ergeben eine Auflösung von 5µm. So 
ganau wird man die Lichtschranken nicht mal positionieren können...

Autor: fieser Rahul (auch Oskar genannt) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ein möglicher µC für dein Problem wäre der TMS 470 vom TI.
>Das ist ein AMR 7 Controller der zusätzlich einen HighEndTimer Modul mit
>bis zu 32 einzel triggerbare IO Leitungen hat.

Johannes hatte ein Modifikation der Platine schon abgelehnt...

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ralph

> Du musst dann für jede Lichtschranke einen extern getriggerten
> Hardwaretimer haben, der einen Zeitstempel der Flanke speichert. Diese
> Zeitstempel kannst du dann zeitunkritisch Auswerten.

Soweit waren wir alle schon lange. Und wenn schon richtig, dann gleich 
FPGA.

> Solange du nicht jedem Eingang einen eigenen Zeitstempel zuordnen
> kannst, egal ob getriggerter Timer oder Interrupt, wirst du immer mehr

Kann er doch. Nur eben mit einer maximalen Auflösung von 5us.

> oder weniger große Abweichungen erhalten.

> Und du kannst auch nie ausschließen das Impulse der Lichtschranken
> "übersehen" werden.

Ach, und wie macht das ein schnellerer Prozessor? Der ist auch nur 
schneller, und auch den kann man dann pratisch mit noch kürzeren 
Impulsen aus dem Konzept bringen.

Wenn wirklich mehr Auflösung nötig ist, würde ich erstmal die 
Lichtschranken untersuchen.

MFG
Falk

P.S. @Johannes: Bei deinen letzten Messungen sprachst du von 2 Promille 
Abweichung. Bei welchen Zählerdifferenzen?



Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn Du alle acht Lichtschranken durch einen Taster ersetzt, der alle
> Lichtschranken-Signalleitungen parallel bedient, wirst Du nicht immer
> für alle Leitungen die genau gleichen Zeiten protokolliert finden,
> sondern...

Ja ... keine Ahnung :-)

> Und du kannst auch nie ausschließen das Impulse der Lichtschranken
> "übersehen" werden.

Alles was in Meiner Anordnung eine Lichtschranke kürzer als mein 
Abtastintervall unterbricht kann ich als Störung auffassen. (Da hätte 
der Schlitten schon Überschallgeschwindikeit :-)

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn Du alle acht Lichtschranken durch einen Taster ersetzt, der alle
> Lichtschranken-Signalleitungen parallel bedient, wirst Du nicht immer
> für alle Leitungen die genau gleichen Zeiten protokolliert finden,
> sondern...

Noch ein Versuch: Da ich ja die Schranken an unterschiedlichen Ports 
hängen habe, kann es sein, dass ich zuerst den ersten Port abfrage, da 
ist noch alles 0, dann drückt jemand den Schalter, dann frage ich den 
zweiten Port ab, da ist dann alles 1. So habe ich dann als Status 0011 
1111 oder so. (Aber das macht nichts, weil ich ja die anderen zwei im 
nächsetn Druchlauf erkenne, die 34/14745600 Sek. kann ich verkraften)

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Da ich ja die Schranken an unterschiedlichen Ports
>hängen habe, kann es sein, dass [...]

So ist es.  Und man kann sogar den zu erwartenden statistischen Anteil 
der "inkonsistenten" Protokolle bei diesem Versuch angeben: 1/34.

>[...] weil ich ja die anderen zwei im nächsetn Druchlauf erkenne,

Selbstverständlich.

Um das Sampling korrekt zu bewerkstelligen, müsstest Du alle acht 
Lichtschranken an einen einzigen Port hängen.  Leider ist das bei Deinem 
ATmega8 nicht ohne weiteres möglich, weil Du ja noch den Hardware-UART 
nutzen willst, der die Pins 0 und 1 von Port D belegt.  Damit bliebe Dir 
als Möglichkeit, um den (kleinen) Makel zu beheben, ein externes 
8-fach-Latch zur Zwischenspeicherung der Lichtschrankenzustände "an 
einem Stück" einzusetzen.

Autor: Johannes (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
> P.S. @Johannes: Bei deinen letzten Messungen sprachst du von 2 Promille
> Abweichung. Bei welchen Zählerdifferenzen?

Ih hab mal die ganze Messauswertung angehängt (weil ich nicht genau 
weiß, nach was du genau suchst)

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wenn du für jede Lichtschranke eine genaue Zeitmessung haben willst geht
>das nur über einen anderen µC.

Kannst Du mir genauer erklären, warum?

>Du musst dann für jede Lichtschranke einen extern getriggerten
>Hardwaretimer haben, der einen Zeitstempel der Flanke speichert.

Wieso muss man das so machen, und warum sollte es so wie es jetzt 
realisiert wurde, nicht einwandfrei funktionieren?

>Diese Zeitstempel kannst du dann zeitunkritisch Auswerten.

Eben dies geschieht doch bei Johannes' Lösung!?

>Darüber kannst du dann eine Auflösung im unteren µs eventuell ns Bereich
>erzielen.

Na prima.  Und wenn eine solche Auflösung gar keinen Sinn gibt?  Ist für 
Dich ein Routenplaner wertlos, wenn er Dir die Entfernung 
München-Hamburg nicht auf den Meter, sondern nur auf den Kilometer genau 
ausgibt?

>Solange du nicht jedem Eingang einen eigenen Zeitstempel zuordnen
>kannst, egal ob getriggerter Timer oder Interrupt, wirst du immer mehr
>oder weniger große Abweichungen erhalten.

Was bitte soll diese Abweichungen verursachen?

>Und du kannst auch nie ausschließen das Impulse der Lichtschranken
>"übersehen" werden.

Siehe die Bemerkung von Johannes dazu.

>Ein möglicher µC für dein Problem wäre der TMS 470 vom TI.
>Das ist ein AMR 7 Controller der zusätzlich einen HighEndTimer Modul mit
>bis zu 32 einzel triggerbare IO Leitungen hat.

Manchmal sinnvoll - manchmal aber vielleicht auch schlicht oversized.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@AVRFan

> >Da ich ja die Schranken an unterschiedlichen Ports
> >hängen habe, kann es sein, dass [...]

> So ist es.  Und man kann sogar den zu erwartenden statistischen Anteil
> der "inkonsistenten" Protokolle bei diesem Versuch angeben: 1/34.

Naja, aber was bedeutet das real? Praktisch nix, denn das fällt unter 
die Zeitauflösungsgrenze. Wenn die Schranke irgendwo anders innerhalb 
der 34 Takte schaltet ist der Effekt der gleiche, auch wenn alle Pins an 
einem Port hängen.

-> passt schon.

@Johannes

Die Differenz zwischen kleinster und grösster Periodendauer T beträgt in 
deiner Tabelle 3967. Das ist auf jeden Fall ein Effekt der 
Lichtschranken bzw. deren Auslösung.

MfG
Falk


Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Naja, aber was bedeutet das real? Praktisch nix

zustimm Die praktische Relevanz für Johannes ist gleich Null :-)  Aber 
ich wollte auch nicht sagen, dass da was ernsthaft im Argen liegt, 
sondern nur darauf denkanstoßen, dass und wie man das 
Auf-zwei-Porte-Aufgeteiltsein der Lichtschrankenabfrage in den 
Protokollen "sichtbar" machen kann, wenn man es - 
forschunginteressehalber - will.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.