Forum: Mikrocontroller und Digitale Elektronik AM Demodulation


von JAyThaRevo (Gast)


Angehängte Dateien:

Lesenswert?

Grüß euch,

wie bereits der Titel sagt möchte ich ein amplitudenmoduliertes Signal 
demodulieren. Im Anhang befindet sich ein Bild vom Signal.

Das untere Signal werte ich mit dem INT1 Interrupt aus. Das funktioniert 
auch ganz gut. Das obere möchte ich gern mit dem PCINT20 auswerten. Das 
funktioniert leider gar nicht so wie ich mir das vorstelle...

Hier ist der Codeteil mit dem ich es Decodieren möchte:
1
ISR(INT1_vect)    // ISR for Pulse counting
2
{
3
  Tick_P_el++;
4
   if(!Lock1) 
5
   {
6
     if(Lock2)
7
     {
8
       Tick_P_th++;
9
       Lock2 = False;
10
       PORTB ^= (1<<PB3);    // LED!!!
11
     }
12
     Lock1 = True;
13
   }
14
   else Lock2 = True;
15
}
16
17
ISR(PCINT2_vect)
18
{
19
  Lock1=False;
20
}
Meine Logik ist folgende:
Wenn INT1 kommt wird "Tick_P_el" hochgezählt. Lock1 und Lock2 ist false, 
kommt also nicht in die Zweite if. Dann kommt PCINT2 und setz Lock1 
wieder false. Wenn dann INT1 wieder kommt wird nun "Tick_P_th" 
hochgezählt und Lock1 wieder true. Da PCINT2 Pegel abhängig ist kommt er 
bei fallender Flanke wieder und setzt Lock1 wieder um zu verhindern, 
dass im INT1 in der if Abfrage in den else Zweig gesprungen wird. Dass 
passiert so lange bis kein Signal an PCINT20 mehr ankommt. Kommt dann 
wieder eines wird der Zähler wieder um eines hochgezählt, usw...

Ist meine Logik so weit in Ordnung?
Die LED an PB3 blinkt leider nicht wie sie sollte^^.

Im Anhang auch das komplette Programm + Header file.

Controller: ATMega88PA

Was wären bessere Varianten?

MfG, Julian

von Nn N. (jaytharevo)


Lesenswert?

:(?

photo.JPG
620,1 KB, 41 Downloads

von chris (Gast)


Lesenswert?

Hallo,

hä? Wo ändert sich denn die Amplitude ?

Ist das nicht eher FM?

von Karl H. (kbuchegg)


Lesenswert?

Ich versteh eines noch nicht.

Wie hängen dein Signal_1 bzw. Signal_2 zusammen?

Hast du durch Signal2 praktisch gesehen so etwas wie einen Basistakt?

von Karl H. (kbuchegg)


Lesenswert?

Ich denke, ich würde das anders angehen.

Ich würde mir mit einem Timer so etwas wie ein retriggerbares Monoflop 
machen. D.h. der Timer muss regelmässig wieder zurückgesetzt werden. 
Wird er nicht zurückgesetzt, dann setzt er meine Wertvariable auf 0.
Mit dem Eintreffen einer steigenden Flanke (meinetwegen mit Interrupt) 
wird die Signalvariable auf 1 gesetzt und der Timer (das Monoflop) 
getriggert (zurückgesetzt). D.h. die eintreffenden Pulse sorgen dafür, 
dass die Variable auf 1 gehalten wird, indem sie den Timer daran hindern 
auszulaufen und die Variable auf 0 zu setzen.
-> Die Variable ist die Hüllkurve des Signals.


Auf der anderen Seite hab ich mir nicht genau angesehen, ob die Pulse 
deines Signals 1 und des Signals 2 in der Phasenlage gleiche sind. Wenn 
sie das sind (und ich denke mal davon kann man ausgehen, weil du 
abscheinend beides von einer externen Schaltung bekommst), dann bedeutet 
das doch nur: Wenn im unteren Signal eine steigende Flanke kommt, siehst 
du am Eingang an dem Signal 1 reinkommt nach, ob dort eine 0 oder eine 1 
anliegt.

von Stupido (Gast)


Lesenswert?

Das erste Signal kann man denke ich ohne weiteres als ASK bezeichnen. 
Aber das zweite... Da seh ich auch nicht so recht ne Amplitudenänderung.


Aber zur Lösung des Problems:
Hast du mal probiert deine Signale abzukoppeln und die Interrupts per 
Hand auszulösen?

von Nn N. (jaytharevo)


Lesenswert?

Ok, sry da hab ich wohl doch noch zu wenig beschrieben.

Also eigentlich kommt das Signal so über die Leitung:
1
    _   _   _   _                   _   _   _   _  
2
   | | | | | | | |                 | | | | | | | |
3
   | | | | | | | |  _   _   _   _  | | | | | | | |
4
   | | | | | | | | | | | | | | | | | | | | | | | |
5
___| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |__

Die Hardware macht es dann so, dass bei dem anderen Port (PCINT20) quasi 
nur die Signale ankommen die über einer gewissen Schwelle liegen. 
Dadurch kommen dann die beiden Signal zustande wie sie auf dem Oszi- 
Bild zu sehen sind. Die untere Kurve wurde dann so verstärkt, dass das 
Signal 5Vs hat.
Das klingt jetzt blöd, aber ist es nun klar wie ich es meine?


Karl Heinz Buchegger schrieb:
> Ich würde mir mit einem Timer so etwas wie ein retriggerbares Monoflop
> machen. D.h. der Timer muss regelmässig wieder zurückgesetzt werden.
> Wird er nicht zurückgesetzt, dann setzt er meine Wertvariable auf 0.

Was ich vielleicht auch noch sagen sollte ist, dass die Frequenz sich 
verändern kann. Die Frequenz beider Kurven.


Karl Heinz Buchegger schrieb:
> Auf der anderen Seite hab ich mir nicht genau angesehen, ob die Pulse
> deines Signals 1 und des Signals 2 in der Phasenlage gleiche sind.

Das ist eben schwer zu sagen. Ich glaub man kann nicht zu 100% sagen, 
dass der PCINT immer vor INT1 kommt. Aber eig ist es gar kein 
schlechter Einfall. Denn im Prinzip sind sie ja "synchron". Auch wenn es 
jetzt nicht elegant ist, aber man könnte im INT1 ein paar µs warten und 
dann checken ob es high ist oder nicht.

Stupido schrieb:
> Aber zur Lösung des Problems:
> Hast du mal probiert deine Signale abzukoppeln und die Interrupts per
> Hand auszulösen?

Was meinst du mit abkoppeln?

Vielen Dank für eure Hilfe :)!

MfG

von Nn N. (jaytharevo)


Angehängte Dateien:

Lesenswert?

So, hab nun KHB's Vorschlag realisiert (einfach anderen Pin abfragen).
In der Main() kam dadurch ein neuer State dazu. Dafür wurde INT0 stark 
verkürzt/vereinfacht.
PCINT20 wurde ganz gelöscht... Zusätzlich wurden die ganzen hardcoded 
Values durch #defines ersetzt.


Vielleicht findet sich jemand der sich die Mühe macht :D!

Einzige Sorge sind die weiten Frequenzbereiche in denen es arbeiten 
muss!
Weiß zufällig jemand wie lang der Pin High sein muss, damit er als High 
erkannt wird? Weiß leider nicht den Fachausdruck und bin deswegen im 
Manual nur bedingt fündig geworden.

MfG

von Nn N. (jaytharevo)


Angehängte Dateien:

Lesenswert?

Leider scheint mein Problem ziemlich uninteressant zu sein :(?!


Ich probiers noch mal...

Hab jetzt wieder ein wenig überarbeitet:
1
        case Count: // Is used to determine the number of el and th pulses
2
3
          Tick_P_el++;
4
          Pin_Buffer = PIND;    // Make sure the Port State is for both if's the same
5
          if((Pin_Buffer & (1<<PD4)) && !(Lock) )
6
          {
7
            Tick_P_th++;
8
            Lock = True;
9
          }
10
          // Once PD4 is low again Lock can be set back to false so once it is high again Tick_P_th will be increased
11
          if( !(Pin_Buffer & (1<<PD4)) ) Lock = False;
12
13
          State = State_Buffer;
14
        break;

Ich hab mir gedacht, ich speicher einfach den Port Zustand in 
"Pin_Buffer".
Dadurch hab ich für beide if's das selbe und ist ev. auch noch ein 
bisschen schneller?

Wie immer volles Proggi und Header im Anhang.

MfG :)

EDIT: Hab grad gesehen, dass ich ganz am Anfang noch vergessen hab den 
Pull up für PD4 zu aktivieren. Wurde ausgebessert.

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.