Speicher-Oszilloskop

Grundlagen

Das Mikrocontroller-Lab bietet mit der „Messwerterfassung“ eine einfache Methode an, um Daten grafisch in einem x-y-Raster darzustellen. Die Daten werden dazu einfach hintereinander über die serielle Schnittstelle geschickt; zulässig ist ein Wertebereich von 0.199, was in etwa der technisch darstellbaren Auflösung entspricht (plus-minus ein paar Pixel für Texte).

  Send_Command(MODE_QUIT);  // Aktuellen Modus verlassen, kommt immer als erstes
  Send_Command(MODE_MESSWERTE);   // Messwerterfassung wird aktiviert   
  Send_Command(MESSWERTE_WERTE);  // ist eigentlich überflüssig, weil das der Standardfall ist

  for (;;)
  {

  // Jetzt senden wir den Wert ganz einfach an die Grafikeinheit
      Send_Value(x);
  }

Der benötigte Code ist also sehr einfach. Allerdings ist die serielle Schnittstelle auf 19.200 Bit / Sekunde limitiert. Das sind maximal 2400 Werte pro Sekunde, bei 256 Zeichenpunkten (von links nach rechts) würde eine Zeile daher mit knapp 10Hz dargestellt werden. Dies würde bei einer Echtzeitdarstellung gerade einmal für Signale bis ca 100 Hz ausreichen – zu wenig für eine Oszilloskopanwendung.

Die eigentliche Erfassung eines analogen Messwerts geht jedoch weitaus schneller vonstatten. Sie benötigt zwar einige Takte, aber bei 16 MHz Taktfrequenz bleibt bei einer maximalen Samplingfrequenz von etwa 75 kHz genügend Zeit, auch Signale mit 10 kHz und mehr zu erfassen. Das ist immer noch nicht viel, aber es genügt für NF-Experimente – das EE2007-Oszilloskop wird in den meisten Tests auch nicht härter gefordert. Dieses Beispiel erreicht diese Werte allerdings nicht – es ist in C geschrieben und daher bei der Datenerfassung wegen der schlechteren Codeoptimierung langsamer.

Entkopplung

Um nun die relativ langsame Grafikausgabe zu umgehen, entkoppeln wir die Datenerfassung von der Ausgabe. Dazu werden die 256 Messwerte von links nach rechts in einem Rutsch gemessen und zwischengespeichert:

unsigned int value[256];	// 512 Bytes Datenspeicher
unsigned int delay=50;		// 100 µs Pause zwischen den Messungen als Voreinstellung
double Value; 

for (i=0; i<255; i++)	// Messen...
{
   Value = ADCW;       // A/D-Wandler auslesen, Wertebereich 0..1023 (10 Bit)
   Value = Value / 5.12 + 33;     // In Spannungswert umrechnen
   value[i] = round(Value);       // in Array einfügen
   _delay_us(delay);              // Verzögerung bis zur nächsten Messung (Zeitbasis)
}

Die Zeitbasis wird dabei durch eine Verzögerung in Mikrosekundengröße erreicht. Damit kann man das Signal beliebig dehnen bis zur maximalen Messfrequenz mit dem Wert 0 für „delay. Die Abtastung erfolgt mit einer Varianz von wenigen Taktzyklen weitgehend linear. Man hat dann 256 Messwerte, die das Signal in einem gewissen Zeitabschnitt repräsentieren. Wenn die Abtastfrequenz hoch genug war, ist das Signal deutlich zu erkennen. Da wir nur sich regelmäßig wiederholende Signale betrachten, ist es unerheblich, ob wie beim Röhren-Oszilloskop das gesamte Signal dargestellt wird oder nur ein Teil davon.

Oszi Signal Oszi Zeitfenster

Oszi Abtastwerte Oszi Abtastrate

Die Bilder zeigen das eingehende Signal, dessen Abtastung innerhalb eines Zeitfensters und die gemessenen Werte bei unterschiedlichen Abtastfrequenzen.

Synchronisation

Wie stellt man nun den Sync sicher? Dazu muss man sich einerseits vergegenwärtigen, dass wir es  mit einem periodischen Signal zu tun haben – das Signal wiederholt sich ständig in derselben Weise. Man kann also davon ausgehen, dass in jedem Satz von 256 Messwerten eine gewisse Ähnlichkeit zum vorhergehenden Satz Messwerte steckt – oder eben nicht, dann hat sich das Signal aber geändert und muss sowieso komplett neu dargestellt werden.

Zum anderen haben wir nach der Messung fast beliebig viel Zeit, das Signal auszugeben (von der Geschwindigkeit des Prozessors aus gesehen). Die Verarbeitung muss nicht in Echtzeit geschehen, und sie darf auch deutlich länger als die eigentliche Messung dauern. Eine Aktualisierung in jeder halben Sekunde genügt durchaus, um das Signal darzustellen – nur flackern bzw. sich verschieben sollte es eben nicht.

Um nun eine deckungsgleiche Darstellung zu erreichen, durchsuchen wir einfach das neue Signal nach dem ersten Maximum – das, nach dem es wieder abwärts geht. An dieser Stelle startet dann die Ausgabe auf dem Bildschirm. Auf diese Weise beginnen die Bilder grundsätzlich am Ende des ersten Maximums, und so können auch Rechtecksignale sauber dargestellt werden. Um nun sicherzustellen, dass auf jeden Fall der komplette Bildschirm von links nach rechts beschrieben werden kann, werden ein paar mehr Messungen durchgeführt als nötig, so dass man innerhalb der Messung den Startpunkt verschieben kann.

IMG_5446 IMG_5445

IMG_5447 IMG_5444

Die Bilder zeigen ein Sinus- und ein Dreiecksignal und mit einer Frequenz von 200 Hz, das von einem Funktionsgenerator auf XR2206-Basis erzeugt wurde. Das Sinussignal wurde mit unterschiedlichen Zeitablenkungen aufgenommen.

Speichern des Bildes

Eine dauerhafte Speicherung ist mit dem gewählten System nicht zu bauen, da man dazu auf den Speicher des Grafikcontrollers zugreifen müsste. Ein Einfrieren des Bildes ist aber problemlos möglich, indem einfach keine weiteren Messwerte gesandt werden. Der OK-Knopf ist dazu doppelt belegt. Ein einfacher Druck friert das Bild ein. Wenn man innerhalb einer Sekunde noch einmal drückt, wird das Oszi-Programm beendet, ansonsten startet eine neue Messung, das Einfrieren wird aufgehoben.

Zurück zur Hauptseite

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.