Olaf Kaluza
Guest
Thu Dec 29, 2011 2:54 pm
Kennt sich hier einer mit Qt aus?
Der Grund warum ich mit dem HMO2022 reden wollte war ja im Prinzip das
ich etwas Qt lernen wollte. Der Hameg ist da nur das Opfer. :-)
Entweder aber ich habe einen dicken Fehler in meinem Programm, oder
aber ich habe einen weiteren fetten Fehler im Hameg entdeckt.
Aber zunaechst mal, Hameg hat sich mittleweile bei mir gemeldet. Sie
sagen man soll vor den Befehlen einen ':' schreiben. Deshalb mache ich
das jetzt auch mal. Allerdings aendert das nichts am Verhalten.
Ausserdem sagt Hameg der Grund warum sie bei den neuen HMOs die
Kommandos geaendert haben liegt darin das die jetzt kompatibel sind mit
den Kommando der neuen R&S Scopes. Sobald die alten HMOs (2524 3524
usw) anfang naechsten Jahre eine neue Firmware bekommen werden die
auch die neuen Kommandos unterstuetzen.
Werfen wir aber mal einen Blick auf diese Funktion. So soll
Informationen zur Channelwaveform auslesen:
void SCPI::WaveHeader(int Channel,QString *Wave)
{ QString SendString;
QString WorkString;
SendString = ":CHAN";
SendString += QString::number(Channel);
SendString += ":DATA:HEAD?\n";
//Offnet den Port und stellt die Schnittstellenparameter ein
MainInit::OsziDevice->OpenPort(RS232Parm->RS232_Settings);
//Sendet den String an den Hameg
MainInit::OsziDevice->SendQString(SendString);
//Wartet maximal 500ms, kommt aber eher zurueck wenn ein 0x0a von
//der RS232 reinkommt
Delay(500);
WorkString.clear();
while (MainInit::OsziDevice->ReadCount() >0)
{
printf("%c",MainInit::OsziDevice->ReadByte());
// WorkString += MainInit::OsziDevice->ReadByte();
}
//Schliesst den RS232 Port
MainInit::OsziDevice->ClosePort();
printf("\nReady\n");
}
Es ist wichtig folgendes zu verstehen:
1. Bei jedem Kommando an das Hameg oeffne ich die RS232 Schnittstelle
und schliesse sie hinterher wieder.
2. Es ist hier nicht direkt sichtbar, aber die RS232-Routinen
beinhalten zwei Fifos.
class QQueue<unsigned char> FIFO_Out;
class QQueue<unsigned char> FIFO_In;
3. Bei jedem offnen der Schnittstelle werden beide Fifos geloescht:
FIFO_In.clear();
FIFO_Out.clear();
Ich gehe also davon aus das mir jedes Kommando immer nur frische Daten
vom Oszi anzeigen kann.
Jetzt rufe ich in einer uebergeordneten Klasse folgendes auf:
//Einlesen des Waveheaders (Seite 44 im Handbuch)
MainInit::Hameg->WaveHeader(1,&Wave);
//Einlesen der Messdaten (Seite 43)
MainInit::Hameg->WaveData(1,&Wave);
//Normaliges einlesen des Waveheaders
MainInit::Hameg->WaveHeader(1,&Wave);
Wie man sehen kann verarbeite ich die Daten erstmal noch nicht weiter
sondern schreibe sie direkt auf die Konsole.
Ausserdem schreibt die Senderoutine das was sie an den Hameg sendet
ebenfalls auf die Konsole. Deshalb sieht man das Kommando nochmal.
Schauen wir uns mal die Antwort dieser drei Kommandos an:
:CHAN1:DATA:HEAD?
4.930010E-04,4.990000E-04,6000,1
Es kommen vier Zahlen zurueck. Das entspricht der Beschreibung von
Hameg und sieht okay aus.
:CHAN1:DATA?
ReadCount:5512
-4.000E-02,-2.000E-02,-2.000E-02,1.401E-07,2.000E-02,1.401E-07,
[..] einiges geloscht.
Der Hameg hat mir auf das WaveData Kommando insgesamt 5512 Bytes
geschickt. Das ist die Messkurve. Sieht auch gut aus.
Jetzt habe ich in meinem Source aber die Funktion zum auslesen
der Headerdaten nochmal aufgerufen. Und man wuerde erwarten das
dasselbe wie zuvor zurueckkommt.
Ergebniss ist aber:
:CHAN1:DATA:HEAD?
Dann einige vollkommen wirre Zeichen die ich hier nicht reinschreiben
kann und nach Muell aus unbenutztem Speicher aussieht.
Danach dann:
-2.000E-02,1.401E-07,1.401E-07,-2.000E-02,-4.000E-02,-4.000E-02,
-4.000E-02,-2.000E-02,-4.000E-02,1.401E-07,1.401E-07,1.401E-07,
1.401E-07,1.401E-07,-2.000E-02,-2.000E-02,1.401E-07,,07,2,
-2.000E-02,1.401E-07,1.401E-074.930010E-04,4.990000E-04,6000,1
Es sieht so aus als wenn dann wieder erst die Daten eines Kanals
kommen und danach dann die Headerdaten die man oben schon beim
erstenmal bekommen hat.
Entweder ich habe einen fetten Fehler in meinem Programm, vor dem
Hintergrund das man Fehler zuerst bei sich suchen sollte ja
naheliegend, oder aber die Senderoutine im Hameg hat eine dicke Macke.
Das Verhalten meines Programms ist reproduzierbar. Druecke ich also in
meinem Programm erneut den Startbutton ohne es neu gestartet zu haben
so sehe ich wieder dasselbe. Der erste Aufruf zum auslesen der
Headerdaten funktioniert, der zweite nach den Messdaten liefert wieder
Unsinn.
Jetzt habe ich mal mein Programm so abgeaendert:
MainInit::Hameg->WaveHeader(1,&Wave);
MainInit::Hameg->WaveData(1,&Wave);
MainInit::Hameg->WaveHeader(1,&Wave);
MainInit::Hameg->WaveHeader(1,&Wave);
MainInit::Hameg->WaveHeader(1,&Wave);
Das Ergebnis der ersten drei Kommandos entpricht dem obigen.
Also erster Aufruf von Waveheader geht, zweiter liefert erst Unsinn
und dann den Wheader. Die anderen beiden liefern keinerlei Daten!
[..]
2.000E-02,1.401E-07,1.4.930010E-04,4.990000E-04,6000,1
Ready
:CHAN1:DATA:HEAD?
HIER KOMMT NICHTS REIN
Ready
:CHAN1:DATA:HEAD?
UND HIER AUCH NICHT!
Ready
Jetzt aender ich mein Programm wieder ab:
MainInit::Hameg->WaveHeader(1,&Wave);
MainInit::Hameg->WaveData(1,&Wave);
MainInit::Hameg->WaveHeader(1,&Wave);
MainInit::Hameg->Identifikation(&DeviceType,&Seriennummer,&Firmware);
MainInit::Hameg->WaveHeader(1,&Wave);
Die Antwort der ersten drei Abfragen entsprechen wieder dem obigen.
Die Dritte liefert ebenfalls erst Muell und dann die richtigen Daten:
-2.000E-02,-2.000E-02,-2.000E-02,07,2,1.401E-07,1.401E-07,
1.401E-07,1.404.930010E-04,4.990000E-04,6000,1
Ready
Die Abfrage des Identifikationstrings scheint zu funktionieren
*IDN?
....und setzt irgendwas im Oszi zurueck, weil jetzt stimmt der Header
wider:
:CHAN1:DATA:HEAD?
4.930010E-04,4.990000E-04,6000,1
Ready
Interessant oder?
Olaf
Marc Santhoff
Guest
Thu Dec 29, 2011 4:38 pm
Am Thu, 29 Dec 2011 14:54:22 +0100 schrieb Olaf Kaluza:
Quote:
void SCPI::WaveHeader(int Channel,QString *Wave) { QString SendString;
QString WorkString;
SendString = ":CHAN";
SendString += QString::number(Channel); SendString += ":DATA:HEAD?\n";
//Offnet den Port und stellt die Schnittstellenparameter ein
MainInit::OsziDevice->OpenPort(RS232Parm->RS232_Settings);
//Sendet den String an den Hameg
MainInit::OsziDevice->SendQString(SendString);
//Wartet maximal 500ms, kommt aber eher zurueck wenn ein 0x0a von
//der RS232 reinkommt
Delay(500);
WorkString.clear();
while (MainInit::OsziDevice->ReadCount() >0)
{
printf("%c",MainInit::OsziDevice->ReadByte());
// WorkString += MainInit::OsziDevice->ReadByte();
}
//Schliesst den RS232 Port
MainInit::OsziDevice->ClosePort();
printf("\nReady\n");
}
Ich bin kein Qt-Spezi, aber erstmal würde ich zwei Dinge tun:
1.
Die Kommandosequenz von einem Terminal testen, und zwar eins, daß die
Schnittstelle explizit öffnen und schließen kann (oder ein Shellskript,
um es drei mal zu starten). Danach solltest Du wissen, ob's am Hameg
liegt.
2.
Sicherstellen, daß das String-Handling von Qt auch wirklich so arbeitet
wie Du meinst. Will sagen ob Workstring.clear() wirklich den String nicht
nur löscht, sondern ggf. auch Speicher alloziert oder ob das automatisch
passiert. Strings sind öfter für Überraschungen gut.
Und die geschichte mit dem Delay kommt mir irgendwie seltsam undefiniert
vor, lohnt aber erst daran zu fummeln, wenn das DSO wirklich die
Erwarteten Antworten gibt.
HTH,
Marc
Olaf Kaluza
Guest
Thu Dec 29, 2011 5:07 pm
Marc Santhoff <M.Santhoff_at_t-online.de> wrote:
Quote:
Die Kommandosequenz von einem Terminal testen, und zwar eins, daß die
Schnittstelle explizit öffnen und schließen kann (oder ein Shellskript,
um es drei mal zu starten). Danach solltest Du wissen, ob's am Hameg
liegt.
Davon halte nichts weil dies ja in das Timing eingreift. Allerdings
hab ich schon daruber nachgedacht mir einen Adapter zu loeten und mal
mit einem anderen Rechner mitzuschreiben was da wirklich ueber die
RS232 geht.
Quote:
2.
Sicherstellen, daß das String-Handling von Qt auch wirklich so arbeitet
wie Du meinst. Will sagen ob Workstring.clear() wirklich den String nicht
nur löscht, sondern ggf. auch Speicher alloziert oder ob das automatisch
passiert. Strings sind öfter für Überraschungen gut.
WorkString wird hier noch nicht benutzt.
Aber der grundsaetzliche Gedankengang ist ja nicht doof. Ich habe auch
gerade schon ueberlegt ob irgendwo in der ganzen
Puffer/Fifo-Verwaltung was schief laeuft, aber:
1. Habe ich gerade einiges an meinem Program geaendert ohne das das
Ergebnis beeintraechtigt.
2. Wenn ich irgendwo einen wilden Zeiger haette wuerde ich erwarten
das Linux entweder mein Programm beendet oder mein Programm Linux
beendet. Aber es laeuft alles stabil.
Was mich aber an Qt noch etwas erstaunt sind Sachen wie dies hier:
class QQueue<unsigned char> FIFO_Out;
QString Test123;
Test123="Hallo";
FIFO_Out.append('a');
Anders als man es in C fuer echte MaennerInnen gewohnt ist, scheint
man nirgendwo angeben zu muessen wie gross die Speicher sind die man
da so nutzen kann. Aber das scheint wohl so ueblich zu sein und die
Daten liegen einfach irgendwo...
Leider gibt es aber wohl auch keine Qt Newsgroup wo man mal fragen
koennte.
BTW: Wer sich schon immer gefragt hat wieso Computer heute so langsam
sind der sollte mal ueberlegen was alles hinter QString versteckt sein
muss. :-)
Quote:
Und die geschichte mit dem Delay kommt mir irgendwie seltsam undefiniert
vor, lohnt aber erst daran zu fummeln, wenn das DSO wirklich die
Erwarteten Antworten gibt.
Die Delayfunktion ist von mir. Letztlich wird dort nur darauf gewartet
das der Oszi irgendwann 0x0a sendet damit ich weiss das seine Daten
vollstaendig angekommen sind. Die Zeit ist sozusagen ein Timeout damit
bei einem Fehler nicht ewig gewartet wird.
Olaf
Olaf Kaluza
Guest
Thu Dec 29, 2011 5:36 pm
Marc Santhoff <M.Santhoff_at_t-online.de> wrote:
Ich habs! Der Fehler lag doch bei mir.
Quote:
Und die geschichte mit dem Delay kommt mir irgendwie seltsam undefiniert
vor, lohnt aber erst daran zu fummeln, wenn das DSO wirklich die
Erwarteten Antworten gibt.
Das Delay war schuld. Gut das wir mal drueber geredet haben. :-)
Ich muss es vergroessern:
Delay(10000);
Ein Delay(5000); reicht noch nicht! Es dauert also irgendwas zwischen 5
und 10s um den Speicher des Hamegs auszulesen. Das haette ich nicht
gedacht.
Wenn mein Timeout zu frueh kommt dann mache ich einfach die serielle
zu und macht man dann unmittelbar danach den Port wieder auf sind zwar
meine Buffer alle leer, aber der Hameg ist immer noch fleissig am
senden. ARGH!
Ausserdem braucht wohl die RS232 einen Moment bis sie sich richtig
aufsyncronisiert wenn man sie oeffnet waehrend gerade Bytes
reinkommen. Das finde ich auch erstaunlich.
Und es erklaert auch warum ich diesen Fehler vorgestern nicht hatte,
weil der Buffer des Hamegs je nach Messbereich verschieden gross ist.
Aber ganz schoen langsam! Vor allem weil es ja erstmal nur ein Kanal
ist. Ich hoffe wirklich das es ueber USB schneller geht.
Olaf