Forum: Mikrocontroller und Digitale Elektronik Analoges Signal einlesen


von Max (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

ich bin gerade dabei mit dem Atmega88 ein Analoges Signal einzulesen. 
Das Signal enthält einen konstanten Highpegel mit 17 Low-Pegel Impulsen. 
Dieses Signal wird alle paar Millisekunden wiederholt. Die letzten 
8-Impulse, also 9 bis 17 möchte ich auswerten und als 8-Bit Wert in 
einer Variablen speichern. Dabei soll der Impuls Nr.17 das 
höchstwertigste Bit sein.

Das Signal lese ich über einen externen Interrupt(INT0) ein. Dabei wird 
bei jedem Interrupt zwischen positiver und negativer Flanke gewechselt, 
und die Zeit dazwischen gemessen. Das funktioniert alles Prima.

Nun zu meinem Problem:

Der erste der Impuls enspricht einer Art Startbit. Dieser Impuls besitzt 
einen gemessenen Timerwert von 93. Meine Auswertung fängt nun an, sobald 
eine Impulsdauer einen Timerwert zwischen 91-95 besitzt. Die 
darauffolgenden Impulse werden überpruft, ob sie größer oder kleiner 
sind als das Starbit. Bei größer entspricht der Impuls einer logischen 
1, bei kleiner einer 0. Diese werden dann als 8-Bit in der Art des 
Zweierkomplement-Verfahrens ausgewertet, als Wert zwischen 0 und 255.

Wenn ich nun die ersten 9-Bit(Impulse) auswerte, also Starbit und 
Bit_2-9, klappt das auch ohne Probleme. Wenn ich aber nun Starbit, und 
Bit_10-17 auswerten will, kommt immer Murks raus.

Komisch dabei ist, das der Starimpuls, den ich mir noch mal als 
Hilfsvariable zur Überprüfung deklariert habe und im Watch Fenster 
betrachte, bei der Auswertung der ersten 9-Bit auch immer 93 beträgt. 
Sobald ich aber die Bits_10-17 auswerte, besitzt der Starimpuls auf 
einmal eine Länge von 72, obwohl ich in der Software festgelegt habe, 
das die Impulslänge nur in die Variable Starimpuls geschrieben wird, 
wenn der Wert zwischen 91-95 liegt.

Hab den Code mal mit angehangen, vielleicht hat einer ne Idee?


Danke und Gruß

Max


von antworter (Gast)


Lesenswert?

--- Glatteismodus ---

Du hast unten im Quelltext

      EICRA |= ((1 << ISC01) | (1 << ISC00));

sicher, daß beide Bits gesetzt werden sollen !?!



(Anm.: Habe mit den Triggern noch nicht gearbeitet, aber die anderen 
Abfragen kontrollieren nur jeweils 1 Bit... daher die Vermutung...)

von antworter (Gast)


Lesenswert?

P.S.:

Laut Deiner Aussage hat das "Analogsignal" nur zwei Spannungspegel... 
dies ist typischerweise Eigenschaft eines Digitalsignals.

von Max (Gast)


Lesenswert?

>> Du hast unten im Quelltext

>>      EICRA |= ((1 << ISC01) | (1 << ISC00));

>> sicher, daß beide Bits gesetzt werden sollen !?!

Ja, es müssen beide Bits gesetzt werden, um auf positive Flanke 
umzustellen.


Zwei kleine Fehler hab ich noch gefunden:

if((e >= 20) && (b <= 34) && (a == 1))

muss natürlich so heißen:

if((e >= 20) && (e <= 34) && (a == 1))

Und sobald das Starbit erkannt wurde, muss e natürlich auf 2 gesetzt 
werden.




von Max (Gast)


Lesenswert?

Klappt aber trotzdem nicht....;-)

von Rahul, der Trollige (Gast)


Lesenswert?

Hast du dir überlegt, vielleicht InputCature zu benutzen`? (Ich habe mir 
deinen Code noch nicht angeguckt).
Irgendwie klingt die Aufgabenstellung nach Auswertung eines 
Modellbau-Fernsteuersignals...

von antworter (Gast)


Lesenswert?

Also so ganz klar ist mir noch nicht, was für ein Signal das sein soll:

>konstanten Highpegel mit 17 Low-Pegel Impulsen.

Kann man davon ausgehen, daß jeder "Impuls" einem Bit entspricht, ohne 
weitere Kodierung ?

Wenn dem so ist, und das Signal immer eine feste Datenrate/Baudrate hat, 
solltest Du ohne permanente Zeitmessung auskommen:

Du stellst den Timer so ein, daß er jedesmal "feuert", wenn eine Bitzeit 
verstrichen ist.
Dabei startest Du den Timer sobald Du ein Startbit detektiert hast.

______      ________       ________
      |______|      |_______|

             ^
             |
      Startbit erkannt*

*hier den Timer mit Startwert!=0 loslaufen lassen, damit er "in der 
Mitte" des nächsten Bits "feuert"

Dann kannst Du im Interrupt einfach nachschauen, welchen Pegel Dein 
Signal hat.

von Sonic (Gast)


Lesenswert?

>if((e >= 20) && (e <= 34) && (a == 1))
Silche Abfrage kosten massig Zeit, wie schnell kommen die Bits denn 
hintereinander? Evtl. liegt hier das Problem!

von Falk (Gast)


Lesenswert?

@Sonic

>>if((e >= 20) && (e <= 34) && (a == 1))
>Silche Abfrage kosten massig Zeit, wie schnell kommen die Bits denn

Massig? Was ist bei dir massig? Das sind alles in allem vielleicht 
10..15 Assemblerbefehle, macht bei 16 MHz ~ 1us. Soviel Zeit muss sein 
;-)

MfG
Falk

von Max (Gast)


Angehängte Dateien:

Lesenswert?

> Hast du dir überlegt, vielleicht InputCature zu benutzen`?

Hatte ich vorher laufen, funktionierte aber nicht so gut.

> Irgendwie klingt die Aufgabenstellung nach Auswertung eines
> Modellbau-Fernsteuersignals...

Ist es auch fast, das Infrarotsignal einer Fernbedienung soll 
ausgewertet werden.


> Kann man davon ausgehen, daß jeder "Impuls" einem Bit entspricht, ohne
> weitere Kodierung ?

Ja, kann man. Jeder Impuls entspricht einem Bit.

> >if((e >= 20) && (e <= 34) && (a == 1))
> Silche Abfrage kosten massig Zeit, wie schnell kommen die Bits denn
> hintereinander?

Die Bits kommen ca. 80µs hintereinander. Die Impulslänge der Bits 
entspricht ca. 60µs.


Komisch ist halt, dass es mit den ersten 9-Bit wunderbar klappt. Doch 
wenn ich Bit 10-17 auswerten will, klappt es nicht.

Hab den Code für die Auswertung der ersten 9-Bit mal angehangen. Dieser 
funktioniert einwandfrei. Nun will ich dort ändern, das nicht Bit 1-9, 
sondern, Bit 1 und 10-70 ausgewertet werden.



von Max (Gast)


Lesenswert?

Oh, sorry. Bit 1 und 10-17.....

von Sonic (Gast)


Lesenswert?

>Die Bits kommen ca. 80µs hintereinander. Die Impulslänge der Bits
>entspricht ca. 60µs.

Ich hatte bei einem software-USART eine verknüpfte if-Abfrage drin, 
diese hat zu lange gedauert (2 verknüpfte Bedingungen), ein bit hatte 
21.5µs Länge. In Assembler ist das besser machbar, was der C-Compiler 
draus macht weiß ich nicht.

von Max (Gast)


Lesenswert?

Hab jetzt mal alle 17-Bits(16 + Starbit) kommplett ausgewertet und in 
einer 16 Bit Variablen gespeichert. Das klappt. Auch mit den Längen gibt 
es da keine Probleme.

Was ich nur nicht hinbekomme ist, die ersten 8-Bit nach dem Start Bit zu 
ingnorieren und nur die Bits 9-17 auszuwerten......

von Max (Gast)


Lesenswert?

Hey,

hab es hinbekommen!

Anstatt:

if( i == 1 && b > 0 && b < 8 )
    {
  wert = 1 << ( b - 1 );
    }

brauch ich doch einfach nur

if( i == 1 && b > 9 && b < 17 )
    {
  wert = 1 << ( b - 9 );
    }

zu schreiben. So werden nur die Bits 9-17 ausgewertet..... Man bin ich 
doof...;-)

Aber manchmal sieht man den Wald vor lauter Bäumen nicht.....


Danke und Gruß


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.