Forum: Mikrocontroller und Digitale Elektronik Frequenz mittels ICP bestimmen und über UART ausgeben.wo steckt der Fehler?


von Cha_Ko (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich habe mir mittels Codesammlung und eigenen Überlegungen ein Programm 
zusammengeschreiben, was am ICP (PD6 vom Atmega32) eine Zeitspanne 
messen soll und diese dann in eine Frequenz umrechnen soll. Die Frequenz 
wird dann in ein char Array umgewandelt und mittels UART zum PC 
gesendet. Die Kommunikation zwischen AVR und PC klappte bis jetzt 
eigentlich immer und ich habe auch nichts verändert. Leider sendet mein 
Programm immer nur komische Zeichen und keine Zahl:( Könnte mal jemand 
meinen Code angucken? Vieleicht seht ihr ja auf Anhieb einen Fehler?

von Cha_Ko (Gast)


Lesenswert?

Hat keiner ne Idee?

von Cha_Ko (Gast)


Lesenswert?

Is denn soviel falsch, oder warum kann mir keiner helfen?

von David M. (md2k7)


Lesenswert?

Nein, aus dem, was du geschickt hast, ist (zumindest für mich) kein 
Fehler ersichtlich, der den UART versauen würde...

Vielleicht postest du noch ein bisschen mehr Code

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Wie wärs wenn du erstmal den gemssen Wert ohne umrechung an den PC 
sendest?
(und nicht 5x nachfragst ob dir jemand helfen kann...)

von Fred S. (Gast)


Lesenswert?

Hi,

> ..... Die Kommunikation zwischen AVR und PC klappte bis jetzt
> eigentlich immer und ich habe auch nichts verändert.
"Eigentlich" klingt nicht so gut...
Wenn Du nichts verändert hast, ist was kaputt oder hat sich spontan (?) 
verändert!

> Leider sendet mein
> Programm immer nur komische Zeichen und keine Zahl:
Reduziert sieht Dein Programm so aus:

int main()
{
   uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
   uart_puts("test");
}

Also sollte es auch keine Zahlen senden. Wenn mit der Hardware + 
Initialisierung beidseits alles stimmt, sollte es "test" senden, sonst 
nichts!

Die Overflows zu zählen, ist eine sehr grobe Methode, die allerdings für 
Deine Frequenzen durchaus adäquat sein kann.

Gruß

Fred

von 6640 (Gast)


Lesenswert?

Ich wuerde die float Umrechnung aufm PC machen. Das bringt wenig aufm 
Mega32.

von Cha_Ko (Gast)


Lesenswert?

Also, habe den fehler gefunden, hatte irgendwas mit den header files 
verpeilt. Nun funktioniert es und ich bekomme mittels uart wunderbar die 
werte ausgegeben. leider bekomme ich alle 5-10 Werte einen Wert, der 
nicht stimmen kann, es ist in etwas das doppelte der Werte von 
davor...wie kann so etwas passieren, oder wie kann ich es vermeiden?

von Karl H. (kbuchegg)


Lesenswert?

Lass dir doch mal die rohen Wert ausgeben.
Also NrOverflows, Starttime, Stoptime

Daraus kannst du dann deine Schlüsse ziehen.

von Werner (Gast)


Lesenswert?

Kann man aus einer InterruptRoutine eigentlich mit return wieder 
rausspringen?

von Karl H. (kbuchegg)


Lesenswert?

Werner wrote:
> Kann man aus einer InterruptRoutine eigentlich mit return wieder
> rausspringen?

Ja. Warum sollte das nicht gehen?

von Cha_Ko (Gast)


Lesenswert?

hmm, es sieht so aus, als würde teilweise eine Flanke übersprungen.Wo 
kann da der Fehler liegen?

von ulrich (Gast)


Lesenswert?

Die Overflows können Probleme machen. Die Zahl der Overflows sollte muss 
in der ICP routine gemerkt werden. Siehe auch:

Beitrag "sehr schnelle Signale messen"

von Cha_Ko (Gast)


Lesenswert?

Hmm, das Problem ist aber, dass der Feheler nur bei niedrigen Frequenzen 
auftriit, und zwar immer mehr, so tiefer die Frequenz:S

Wie meinst du das mit dem Overflow?

von ulrich (Gast)


Lesenswert?

In seltenen Fällen kann ein weiterer Timer-Overflow passieren zwischen 
dem 2 ten ICP und dem Ausgeben im Hauptprogramm.

Ebenfalls eher selten kann der Überlauf und ICP praktisch gleichzeitig 
auftreten. Dann wird erst der ISR mit höherer Priorität abgearbeite, 
obwohl der andere eventuell ein paar Zyklen vorher darn sein sollte. Das 
kann passieren, weil einige Befehle mehr als einen Zyklus brauchen. Für 
den Stopp-Fall wird dieser Fehler durch den oberen gerade wieder 
berichtigt, aber beim Start kann es da zu einem extra Overflow kommen, 
der eigentlich vor dem Start war.

Die oben beschrieben Fälle sind wirklich selten (ca. 1:10000) und 
sollten unabhängig von der Frequenz sein. Die Zeit kann dadurch gerade 
um jeweils einen Overflow zu lang sein.

Wenn der Fehler bei sehr niedrigen Frequenzen auftritt, wird das aber 
eher ein anders Problem sein.

von Cha_Ko (Gast)


Lesenswert?

hmmm, hat da jemand vieleicht noch ne Idee, warum gerade bei den 
niedrigen Frequenzen dieser Fehler auftritt, dass all 10 bis 20 
Messungen ein Wert dabei ist, der genau doppelt so hoch is wie die 
anderen?

von ulrich (Gast)


Lesenswert?

Bezieht sich das genau doppelt so hoch auf de Frequenz oder die Perioden 
Zeit ?
Das sollte dann eher ein Problem mit der Hardware sein:
Entweder reicht der Pegel nicht ganz aus, und nur Überschwinger triggern 
meistens den ICP oder es gibt bei der anderen Flanke noch ein paar 
Überschwinger die dann auch bei der falschen Flanke triggern.

von Cha_Ko (Gast)


Lesenswert?

hmm, naja an hardware gibts bei mir eigentlich nich viel;) ich habe 
einen Tachoausgang eines Lüfters und dieser hängt über einen Pull-up 
Widerstand (10kOhm) an Vcc...kann man das noch anders lösen?

von ulrich (Gast)


Lesenswert?

Man könnte versuchen im Controller den Noise Cnacler zu aktivieren. Dann 
werden ganz kurze Pulse Ignoriert. Da es für einen Lufter wohl nicht auf 
5 Stellen ankommt, könnte man auch den Przessortakt etwas runter setzen, 
der Noise Cancler wird dann effectiver. Eventuell könnte man auch in der 
ICP routine noch mal controllieren, ob wirklich der erwartete Pegel am 
ICP Pin anliegt und ggf. das Signal Ignorieren.

Wenn das Signal zu schwach ist, könnte man auch den analogen Komperator 
als Eingang nutzen.

Es ist immer noch nicht klar, ob die Frequenz gelegentlich zu hoch oder 
zu niedrig angezeigt wird ?

von Karl H. (kbuchegg)


Lesenswert?

Zeig doch endlich mal ein paar Messwerte her.
Also: Anzahl Overflows, Start ICP, End ICP

Ich wette fast, dass bei deinen falschen Werten immer
ein Overflow beteiligt ist.

von Cha_Ko (Gast)


Lesenswert?

Hallo, die Werte werde ich heute Abend mal reinstellen. Die Frequenz is 
immer fast genau doppelt so hoch, als wenn eine Flanke übersehen wird. 
Wie aktiviert man denn diesen Noise Canceler?

von ulrich (Gast)


Lesenswert?

Wenn die Frequenz doppelt so hoch ist, dann wird eine extra Flanke nach 
der halben Zeit erkannt. Abhilfe kömmte der noise Cancler bringen, oder 
auch ein kleiner Kondensator am Eingang.
Noise Cancler wird im TCCR1B Register eingeschaltet. Außer für sehr 
kurze Pulse (< 4 Zyklen) gibt der fast keinen Nachteile.

Auch die Software Lösung, den Zustand nach dem ICP abzufragen sollte 
helfen.

von Cha_Ko (Gast)


Lesenswert?

wo meinst du den kondensator am eingang? also wie soll ich ihn 
schaltungstechnisch einbauen? 100nF?

von Cha_Ko (Gast)


Lesenswert?

Hab das Problem jetzt gelöst, indem ich den aktuellen Wert immer mit dem 
vorherigen vergleiche und so keine groben Ausreißer zulasse. Nun habe 
ich aber noch eine Frage. Wenn keine Flanken mehr am ICP ankommen, 
wartet das Programm ja solange bis eine Flanke kommt. Wie kann ich es 
erreichen, dass nach einer gewissen Zeit, wo keine Flanke kommt ein 
bestimmtes Ereignis auslösen kann?

von STK500-Besitzer (Gast)


Lesenswert?

Die Überläufe des Timers zählen, und wenn diese Zahl groß genug ist, 
lässt du irgendwas passieren.
Natürlich mußt du die Überlaufzählvariable bei Flanken zurücksetzen...

von Cha_Ko (Gast)


Angehängte Dateien:

Lesenswert?

Hmm ok, das versteh ich schonmal, nur weiß ich nich ganz genau wie ich 
es im Code umsetzen soll. kannst du mir da nochmal nen Tip geben? Anbei 
nochmal mein aktueller Code

von Karl H. (kbuchegg)


Lesenswert?

Cha_Ko wrote:
> Hmm ok, das versteh ich schonmal, nur weiß ich nich ganz genau wie ich
> es im Code umsetzen soll.

Dann hast du es auch nicht verstanden.

> kannst du mir da nochmal nen Tip geben?

Was für einen Tip brauchst du noch?

> Die Überläufe des Timers zählen,

Das machst du ja schon. Genau das macht die Overflow ISR
indem sie die NrOverflows Variable hochzählt

> und wenn diese Zahl groß genug ist,

D.h. du legst eine Obergrenze fest.

> lässt du irgendwas passieren.

In der Hauptschleife in main() vergleichst du NrOverflows mit
deiner selbstgewählten Obergrenze und wenn beide gleich sind,
hast du dein Ereignis
1
#define MEINE_GRENZE 100
2
3
4
  ...
5
6
sei();
7
  while(1)
8
  {
9
    // zu viele Overflows ?
10
    if( NrOverflows > MEINE_GRENZE )
11
    {
12
       ....
13
    }
14
15
    //
16
    // liegt eine vollst�ndige Messung vor?
17
    //
18
    if( UpdateUart)
19
    {
20
      ...

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.