♬ ☘ Moja muzyka do kodowania ♬ ♬ ♬ ☘
♫ ♩ ♪ Voyager ⚡ ☘ ⚡ uniVers ♪ ♩ ♫
https://youtu.be/25xKTnGPJQ4
Ekraniki zgrywane z Rigola-Cukierka przez SCPI choć wyglądają estetycznie i naukowo to jednak posiadają kilka wad. Nie da się ich wstawić w rubryczki Excela, nie da się na ich podstawie wygenerować przebiegu w Analog Discovery 2, no i kolorowy obrazek cokolwiek trudno przeliczyć w Scilab czy Matlab. Zatem zrzutki ekranu to jedno, ale myślę, że warto umieć podebrać z urządzenia surowe, numeryczne dane. Gdy mamy je dostępne w formie płaskiego pliku na dysku lub choćby w buforze w pamięci komputera - otwierają się zupełnie nowe, ciekawe możliwości, przykład poniżej.
Wszelkie szczegółowe informacje wypisano bardzo przystępnie w sekcji `:WAVeformCommands` dokumentu `MSO1000Z/DS1000Z Programming Guide`, od strony 2-216, polecam lekturę w wolnej chwili, a tu garść zupełnie podstawowych detali. Do odczytu danych z urządzenia służy polecenie :waveform:data?. Oczywiście przed jego wydaniem należy wskazać kanał źródłowy (np. :waveform:source CHAN1), wybrać tryb pobierania danych (np. :waveform:mode NORMAL) oraz ich format (:waveform:form ASCII). Dwa słowa o trybie pobierania - teraz skupiamy się na NORMAL, co oznacza, że urządzenie odda nam zawartość bufora pamięci, z którego rysowany jest aktualny przebieg na wyświetlaczu. Czyli dostaniemy to co aktualnie widać, tylko w numerycznej postaci. Próbek będzie 1200 co wynika z faktu, że podziałka osi czasu ma sumarycznie 12 celek (centymetrów?), po sześć w prawo i lewo względem zera, a oscyloskop zbiera 100 próbek na jednostkę skali czasu. Format ustawimy sobie na ASCII aby było łatwiej obrabiać strumień danych pakietem matematycznym, przyjdą do nas tekstowo liczby w notacji naukowej (xE±y), taki zapis bez problemów przetłumaczymy sobie na float/double. W osi Y dane też są przeliczone na podstawowe jednostki z zapisie naukowym, w sumie to nie musimy nic tu robić.
Aby mieć pewność jaki jest kontekst nadesłanych przez Rigola danych dobrze jest pobrać sobie komplet aktualnych ustawień i współczynników - służy do tego jedna komenda: :waveform:preamble?, zwraca dane w postaci serii liczb, czyli dość wygodnie.
Spróbujmy teraz wykorzystać te informacje i wydobyć dane z oscyloskopu.
Aby nie rozpraszać niepotrzebnymi detalami, wysyłanie poleceń do urządzenia schowałam w małym przydasiu, będzie występował na dalszych etapach prac.
rigolCommand pisze:Kod: Zaznacz cały
echo $1 | netcat -w 20 cukierek 5555
Na początek napiszemy sobie skrypcik, który zwróci nam rzeczone współczynniki przebiegu:
waveformPreambleNormal pisze:Kod: Zaznacz cały
#!/bin/bash
# on-screen data
rigolCommand ':waveform:mode NORMAL'
# returns wave full info
rigolCommand ':waveform:preamble?' | tr "," "\n"
Efekt działania taki:
Naniosłam legendę-obrazek skubnięty z dokumentacji - widać wspomniane 1200 próbek/punktów oraz xincrement o wartości 2E-7. Zatem ile wynosi podstawa czasu? Ano 100*2E-7=20 us, co zaraz się okaże.
Teraz napiszmy skrypt wyciągający serię tych tysiąc dwustu liczb z Cukierka:
waveformPreambleNormal pisze:Kod: Zaznacz cały
#!/bin/bash
# set channel
rigolCommand ':waveform:source '$1
# on-screen data
rigolCommand ':waveform:mode NORMAL'
# gimme gimme ascii
rigolCommand ':waveform:form ASCII'
# get ascii stream, reject TMC header, replace colon by eol
rigolCommand ':waveform:data?' | tail -c +12 | tr "," "\n"
W międzyczasie z Analog Discovery 2 robimy sobie generator:
Dygresja niewielka - generator produkuje ładnego sinusa ale ze śmiećkiem, to zakłócenie będzie zaniedługo potrzebne do innych obserwacji, śmieciek powstaje skryptem dla AD2:
sin-intrusion.txt pisze:Kod: Zaznacz cały
if ( X > 0.5 && X < 0.52) {
sin(2*PI*X*50)/5;
}
else {
sin(2*PI*X*10);
}
Tak prezentują się przebiegi z AD2 na ekranie oscyloskopu:
A tak fragment strumienia liczb (przycięty dla prezentacji tail-em) zwracany przez Rigola:
Mamy zatem w garści informacje o ustawieniach przebiegu oraz sam przebieg, więc czas na Scilab, o którym już swego czasu wspominałam, taki darmowy jakby Matlab. Pośród dosłownie pierdyliarda różnych-różnistych funkcji są też takie, które potrafią wykonać zewnętrzne polecenie systemu operacyjnego i zebrać jego standardowe wyjście (stdout) do dalszego przetwarzania, w formie wektora. W wersji linuksowej to funkcja o nazwie unix_g(). Mając wektor napisów jednym ruchem konwertujemy je na wartości zmiennoprzecinkowe - strtod(), ta funkcja operuje i na skalarach i na wektorach. A mając tabelę tysiąca dwustu liczb oraz mniejszą, ze współczynnikami - nic tylko rysować sobie wykresiki przebiegów, o proszę:
Powyżej wystawka z kompletu okienek, pokazałam też zawartość zmiennej wave1, możliwy jest jak widać nie tylko podgląd ale i edycja (korekcja) wartości.
Oba przebiegi na jednym wykresie:
Okienko do rysowania przebiegów ma zoom, zatem można wnikać w czasem kłopotliwe detale tego co ekranik LCD Rigola już pokazać nie(umie|chce)
Oczywiście przebiegi można mieć i osobno, każdy dostanie swoją skale Y, przy zachowanej wspólnej skali czasu
Kompletny skrypcik dla Scilab wybierający świeże dane z Rigola i generujący owe wykresiki jest taki:
rigol-1.sce pisze:Kod: Zaznacz cały
clear; // wyzerowanie srodowiska
// pobranie ustawien oscyloskopu
settings=strtod( unix_g ( 'waveformPreambleNormal' ) );
// pobranie danych dla CH1 i CH2
wave1=strtod( unix_g ( 'waveformDataNormal CHAN1' ) );
wave2=strtod( unix_g ( 'waveformDataNormal CHAN2' ) );
n=settings(3); // ilość probek
dt=settings(5); // jednostek czasu/probke
t=[0:dt:n*dt-dt]; //dziedzina czasu
t=1000000*t; // na mikrosekundy!
clf();
xtitle('dwa kanały jednocześnie');
xgrid(5,1,7); xlabel('t [us]'); ylabel('u(t)');
plot( t, [wave1,wave2] );
scf();
subplot(211);
xtitle('kanały osobno');
xgrid(5,1,7); xlabel('t [us]'); ylabel('u(t)');
plot( t, wave1 );
subplot(212);
xgrid(5,1,7); xlabel('t [us]'); ylabel('u(t)');
plot( t, wave2 );
Na koniec odrobina relaksu, czyli - kółko! Na AD2 ustawiamy dwa sinusy pod kątem prostym:
Na oscyloskopie nie wygląda to jakoś specjalnie atrakcyjnie, ot - kolorowe przebiegi.
Ale jak sobie pobierzemy te dane z urządzenia i namalujemy skrypcikiem jako X-Y:
rigol-2.sce pisze:Kod: Zaznacz cały
clear; // wyzerowanie srodowiska
// pobranie danych dla CH1 i CH2
wave1=strtod( unix_g ( 'waveformDataNormal CHAN1' ) );
wave2=strtod( unix_g ( 'waveformDataNormal CHAN2' ) );
plot( wave1, wave2 );
To dostaniemy mechate kółko:
które w powiększeniu przypomina ślad mrówki wracającej nad ranem z imprezy do domu: