Oto kontynuacja tematu zapoczątkowanego w Cewki - pomiary indukcyjności oscyloskopem. Tym razem wprowadzimy kilka elementów automatyzujących cały proces pomiaru indukcyjności, korzystając z możliwości zdalnego sterowania cyfrowego oscyloskopu z użyciem interfejsu LAN.

Rozbudowujemy układ testowy

Tym razem zbliżymy się bardziej do układu zaprezentowanego w listopadowym numerze Elektroniki dla Wszystkich. Wyróżnimy 2 bloki funkcjonalne:

  • Układ wyzwalający z tranzystorem typu MOSFET, do generowania krótkich impulsów dla układu cewki.
  • Układ z poprzedniego artykułu, czyli badana cewka, dioda zabezpieczająca oraz rezystor pomiarowy.

Oba bloki zasilane będą osobnym źródłem zasilania. Ponadto, zarówno oscyloskop jak i układ generujący impulsy będą sterowane przez komputer za pomocą lokalnej domowej sieci.

Rysunek 1 - Schemat Blokowy

Do zadań PC'ta będzie należeć ustawienie parametrów oscyloskopu na dobrze nam znane wartości, które wiemy że są "dobre" dla pomiaru lub w przyszłości, na automatyczne dostosowanie parametrów dla jak najlepszej ekspozycji badanego sygnału.

Układ generatora

Układem generatora może być dowolne urządzenie, którym można sterować zdalnie. Najlepszymi kandydatami do tego celu będą oczywiście wszelkie mikrokomputery jak Arduino lub Raspberry Pi. A ponieważ jestem szczęśliwym posiadaczem tego drugiego w wersji 4 z 4Gb RAM na pokładzie, to właśnie nim posłużę się do sterowania sygnałami dla tranzystora/klucza S1 typu MOSFET z kanałem typu N.

Konfiguracja Raspberry Pi 4

Ściągnąłem zatem najnowszy obraz systemu operacyjnego dla Raspberry z oficjalnej strony i wgrałem na kartę SD. Domyślnie system operacyjnie nie ma uruchomionej usługi SSH Server, ani połączenia przez WiFi, więc nie będziemy mogli zdalnie łączyć się z powłoką systemu przez sieć. Konfigurację Raspberry można przeprowadzić na dwa sposoby:

  1. Pełny setup czyli podłączenie klawiatury, myszki, monitora i użycie GUI do wyklikania potrzebnych rzeczy.
  2. Utworzyć kilka plików konfiguracyjnych na karcie SD z użyciem innego komputera, które podczas uruchomienia systemu, skonfigurują automatycznie potrzebne usługi SSH i sieć bezprzewodową.

Ponieważ i tak miałem już kartę SD w komputerze po zafleshowaniu, szybciej mi było pójść ścieżką numer 2.

Konfiguracja sieci bezprzewodowej

Montujemy kartę SD, wchodzimy na partycję boot i tworzymy tam plik o nazwie wpa_supplicant.conf z poniższą zawartością:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=PL

network={
ssid="<Name of your wireless LAN>"
psk="<Password for your wireless LAN>"
}

Gdzie w polach ssid wpisujemy nazwę naszej domowej sieci bezprzewodowej a w miejsce psk wpisujemy hasło do sieci. Więcej informacji znajdziesz na oficjalnej stronie: Setting up a Raspberry Pi headless. Konfiguracja SSH

Aby usługa SSH była automatycznie uruchomiona po wystartowaniu systemu operacyjnego musimy utworzyć tylko jeden plik. Na tej samej partycji o nazwie boot należy utworzyć plik o nazwie ssh. Bez żadnego rozszerzenia i bez żadnej zawartości. I już.

Więcej informacji znajdziesz na oficjalnej stronie: SSH (Secure Shell), punkt 3.

Znajdowanie adresu sieciowego Raspberry

Zazwyczaj routery przypisują wartości adresów IP korzystając z protokołu DHCP oraz serwera DHCP działającego w routerze. Zakres puli adresów jest ustalany w zapleczu administratorskim samego routera. Jeżeli nie mamy ustawionego statycznego przypisania adresu IP do adresu MAC, wówczas przydzielany jest kolejny wolny adres z puli adresowej. Oznacza to, że urządzenie może przyjąć losowe adresy (w zakresie dopuszczalnych adresów ustalonych przez maskę podsieci).

Aby dowiedzieć się jaki adres IP został przydzielony dla Raspberry, możemy oczywiście podpiąć ekran po HDMI, myszkę i klawiaturę po USB i odczytać te wartości z ustawień systemowych. Ale oczywiście nie idziemy na łatwiznę! Zamiast tego, można to łatwo sprawdzić skanują sieć wewnętrzną poleceniem nmap, który jest dostępny we wszystkich szanujących się dystrybucjach linuksa.

Podpinamy zatem Raspberry Pi do zasilania, odczekujemy kilka chwil aby system operacyjny wstał i skanujemy sieć lokalną. W moim przypadku sieć lokalna jest skonfigurowana jako 192.168.2.* z maską podsieci 255.255.255.0. Zatem wywołujemy komendę:

$ nmap 192.168.2.*

W wyniku tej komendy otrzymałem taki oto raport:

Starting Nmap 7.80 ( https://nmap.org ) at 2020-11-26 19:39 CET
Nmap scan report for router.asus.com (192.168.2.1)
Host is up (0.0054s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http

Nmap scan report for raspberrypi (192.168.2.54)
Host is up (0.0049s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
22/tcp open ssh

Jak widać moje Raspberry otrzymało adres 192.168.2.54. Co więcej widzimy aktywny serwis SSH na porcie 22. Połączmy się zatem z nim, korzystając z domyślnego użytkownika pi, dla którego domyślne hasło to raspberry:

$ ssh pi@192.168.2.54

Zapewne za pierwszym razem będziemy musieli zgodzić na na połączenie do nieautoryzowanego urządzenia wpisując yes w odpowiednim miejscu.

W moim przypadku cały proces przebiegał jak poniżej:

The authenticity of host '192.168.2.54 (192.168.2.54)' can't be established.
ECDSA key fingerprint is SHA256:M/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.2.54' (ECDSA) to the list of known hosts.
pi@192.168.2.54's password:
Linux raspberrypi 5.4.51-v7l+ #1333 SMP Mon Aug 10 16:51:40 BST 2020 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Nov 26 18:31:06 2020

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

pi@raspberrypi:~ $

Od tego momentu możemy zdalnie sterować płytką Raspberry Pi.

Sterowanie GPIO

Raspberry Pi sławne jest z dużej ilości GPIO. Złącze GPIO to 40 pinowa, dwurzędowa listwa goldpin.

Funkcje tych portów IO są różne, w zależności od konfiguracji. Oprócz linii podłączonych do procesora, znajdziemy również linie zasilające +3.3V oraz +5V a także linie masy GND. Większość z pozostałych pinów mogą posłużyć jako port IO ogólnego przeznaczenia, ale czasami mogą również pełnić bardziej specyficzne funkcje jak zamienić się w interfejs I2C, SPI, sterowanie sygnałem PWM czy też serial port. Do naszego prostego układu, użyjemy tylko jednego wyprowadzenia GPIO oraz jednego pinu zasilającego +5V wraz z jedną linią masy. Z dokumentacji GPIO dla Raspberry Pi, możemy się dowiedzieć które piny odpowiadają za jakie funkcje:

Źródło: https://www.raspberrypi.org/documentation/usage/gpio/

Raspberry Pi posiada wiele narzędzi oraz bibliotek do sterowania GPIO. Dużą popularnością cieszy się biblioteka pythona RPi.GPIO. Dla przykładu tutaj znajdziecie opis jej wykorzystania. Ja natomiast zamiast skorzystać z gotowych bibliotek, będę korzystał ze sposobności sterowania "u źródła", czyli poprzez interfejs wystawiony w systemie plików sysfs, dostarczonego przez driver zaimplementowany w kernelu linuxa. Brzmi strasznie? A nie powinno bo używa się go przecudownie prosto.

W terminalu gdzie mamy połączenie SSH przechodzimy do folderu /sys/class/gpio/:

$ cd /sys/class/gpio/

Sprawdźmy co tam jest:

$ ls
export gpiochip0 gpiochip504 unexport

Będą nas interesowały pliki export oraz unexport. Pozostałymi nie będziemy się interesować.

Aby zacząć używać jakiegoś pinu GPIO, musimy go wyeksportować. Robimy to wpisując do pliku export numer pinu GPIO, który chcemy sterować. Ja sobie wymyśliłem, że chcę sterować pinem GPIO 23. Zatem robię:

$ echo 23 > export

Jeżeli ponownie sprawdzę zawartość folderu, to okaże się, że coś się zmieniło:

$ ls
export gpio23 gpiochip0 gpiochip504 unexport

Powstał folder o nazwie gpio23 wejdźmy zatem do niego i sprawdźmy co tam się znajduje:

$ cd gpio23
$ ls
active_low device direction edge power subsystem uevent value

Mamy tutaj kilka plików, parę linków symbolicznych ale tak naprawdę interesują nas dwa pliki:

  • direction - wskazujący czy jest to GPIO wejściowe czy też wyjściowe
  • value - wartość odczytana/wystawiona na pin GPIO

Aby sprawdzić bieżące ustawienia pinu możemy wyświetlić ich zawartość:

$ cat direction
in
$ cat value
0

Zatem w tym momencie pin GPIO 23 jest ustawiony jako pin wejścia i odczytujemy z niego, że w tym momencie na jego wejściu znajduje się logiczne 0.

To co potrzebujemy to przerobienie tego portu w port wyjścia tak abyśmy mogli nim generować sygnał dla klucza sterującego cewką. Robi się to za pomocą wpisania do pliku direction wartości out.

$ echo out > direction
$ cat direction
out

Kiedy mamy już ustawiony wybrany pin w trybie wyjścia, możemy sterować jego stanem wpisując 0 lub 1 do pliku value:

$ echo 1 > value
$ cat value
1
# lub
$ echo 0 > value
$ cat value
0

Po skończonej pracy, jeżeli przestaliśmy używać jakiegoś pinu, dobrym nawykiem jest jego usunięcie przez wpisanie do pliku unexport numeru pinu którego chcemy usunąć. Cofnijmy się zatem o poziom wyżej z powrotem do folderu /sys/class/gpio/ i wykonajmy polecenie:

$ echo 23 > unexport
$ ls
export gpiochip0 gpiochip504 unexport

Jak widać folder dla GPIO 23 zniknął.

Testowy skrypt BASH'owy do GPIO

Stworzyłem bardzo prosty skrypt BASH'owy, który będzie pełnił funkcję biblioteczną i zawierał funkcje sterujące GPIO za pomocą systemu plików sysfs. Zapisałem go w folderze domowym jako gpiolib.sh.

gpiolib.sh
#!/bin/bash

function gpio_export {
echo ${1} > /sys/class/gpio/export
}

function gpio_unexport {
echo ${1} > /sys/class/gpio/unexport
}

function gpio_direction {
echo ${2} > /sys/class/gpio/gpio${1}/direction
}

function gpio {
echo ${2} > /sys/class/gpio/gpio${1}/value
}

A następnie stworzyłem kolejny skrypt, który będzie wywoływał zdefiniowane wyżej funkcje. Zdecydowałem się nie rozdzielenie obu skryptów ze względu na to, że będę mógł ręcznie wywoływać funkcje z gpiolib.sh kiedy będę chciał coś na szybko sprawdzić.

gpio_pulse.sh
#!/bin/bash

# This can be override by running this script with GPIO_NR variable
# By default it's GPIO number 23
GPIO_NR=${GPIO_NR:-23}

if [ ! -x gpiolib.sh ]
then
echo "I cannot find my cool GPIO library here :("
echo "Or maybe it's not executable?"
exit 1
fi
# Import fancy GPIO functions
source gpiolib.sh

echo "Using GPIO No. ${GPIO_NR}"

echo "Exporting GPIO"
gpio_export ${GPIO_NR}

if [ ! -d /sys/class/gpio/gpio${GPIO_NR} ]
then
echo "Error: Failed to export GPIO ${GPIO_NR}"
exit 1
fi

if [ -w /sys/class/gpio/gpio${GPIO_NR}/value ]
then
echo "Set out direction"
gpio_direction ${GPIO_NR} out

echo "Fun time - generating pulse"
gpio ${GPIO_NR} 1
gpio ${GPIO_NR} 0
else
echo "Error: No permision to write to GPIO!"
echo "Error: Please run again with sudo!"
fi

echo "Unepxort GPIO"
gpio_unexport ${GPIO_NR}

Przed użyciem, ustawiłem prawa do wykonywania dla obu plików:

$ chmod a+x gpiolib.sh gpio_pulse.sh

Testowy układ

Zbudowałem prosty układ aby sprawdzić, czy bezpośrednie sterowanie kluczem tranzystorowym będzie wystarczające oraz sprawdzić, jakiej minimalnej długości impulsy będę w stanie generować (i jakie mam możliwości regulacji tej szerokości):

Rysunek 2 - Schemat ideowy testowego układu generatora na bazie płytki Raspberry Pi 4B

Do punktów OSC+ i OSC- podłączyłem sondy oscyloskopu.

Wyniki z testowego układu

Ustawiłem oscyloskop w pojedyńczy tryb wyzwalania i uruchomiłem skrypt gpio_pulse.sh. Jeżeli po uruchomieniu skryptu otrzymasz ostrzeżenie o braku uprawnień jak poniżej:

Error: No permision to write to GPIO!
Error: Please run again with sudo!

To wtedy należy uruchomić skrypt za pomocą sudo:

$ sudo gpio_pulse.sh

W wyniki działania skryptu otrzymałem na oscyloskopie przebieg:

Rysunek 3 - Przebieg na wyjściu GPIO 23 wygenerowany za pomocą skryptu

Szerokość impulsu to aż 213.90 us dla pojedynczego wyzwolenia, czas narastania 375nS a opadania 813ns. Bogatszy o doświadczenia z poprzedniego artykułu wiem, że to całkiem idealny czas dla sygnału, gdyż pierwsza cewka testowa potrzebowała właśnie 200uS aby zobrazować całkowity wzrost napięcia na rezystorze pomiarowym od 0V do VCC.

Ale ... Czy można ten czas skrócić? Spróbujmy zamiast wywołania funkcji wpisywać "z palca" wartości 0 i 1 do GPIO w systemie plików sysfs:

$ source gpiolib.sh
$ gpio_export 23
$ gpio_direction 23 out
$ GPIO=/sys/class/gpio/gpio23/value
$ echo 1 > $GPIO && echo 0 > $GPIO
$ gpio_unexport 23

Przy bezpośrednim wpisaniu wartości 0/1 do pliku value, czas impulsu drastycznie się zmniejszył:

Rysunek 4 - Przebieg na wyjściu GPIO 23 przy bezpośrednim wpisywaniu wartości

Jak widać czas impulsu teraz to już 151.25uS czyli o 60uS mniej!

Dlaczego obserwujemy takie wyniki? Otóż należy pamiętać, że skrypty BASH'owe są wolne ... Tzn. skrypty te nie są kompilowane a interpretowane w trakcie działania. Oznacza to, że jeżeli użyjemy w nich funkcji, zmiennych itp. to interpreter najpierw musi je rozwinąć (zinterpretować) do właściwej formy wykonywalnej a dopiero na końcu wywołać.

Czy można jeszcze bardziej skrócić czas trwania impulsu? Można, jeżeli użyjemy programu skompilowanego za pomocą niskopoziomowego języka np. C.

Zróbmy taki eksperyment i napiszmy prosty program, który będzie robił dokładnie to samo co skrypt ale tym razem napiszemy go w C:

gpio_pulse_native.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(void) {
int fd;

fd = open("/sys/class/gpio/gpio23/value", O_WRONLY);
if (fd == -1) {
fprintf(stderr, "Error: Cannot open GPIO 23\r\n");
return 1;
}

write(fd, "1", 1);
write(fd, "0", 1);
close(fd);
return 0;
}

Prosta kompilacja programu i ustawienie praw do wykonywania:

$ gcc gpio_pulse_native.c -o gpio_pulse_native
$ chmod a+x ./gpio_pulse_native

I uruchamiamy:

$ echo 23 > /sys/class/gpio/export
$ echo out > /sys/class/gpio/gpio23/direction
$ ./gpio_pulse_native
$ echo 23 > /sys/class/gpio/unexport

W wyniku tego otrzymałem impuls o szerokości tylko 2.72uS.

Rysunek 4 - Przebieg na wyjściu GPIO 23 przy sterowaniu natywnym

Z tego powodu warto wiedzieć, że:

Pamiętaj!

Wywoływanie funkcji systemowej z poziomu kodu wykonywalnego (np. skompilowanego z kodu źródłowego C) zawsze będzie wykonana szybciej od ekwiwalentnej komendy skryptowej tj. BASH. Skrypty świetnie radzą sobie w automatyzacji procesów, natomiast uzyskują słabe wyniki, jeżeli chodzi o szybkość działania.

Mimo to, szerokość impulsu 200uS z pierwszego uruchomienia skryptu jest wystarczająca do testów, więc będę dalej z niej korzystać. Można by zastanowić się nad sposobem sterowania szerokości impulsów ale to już inna sprawa :)

Zdalne Sterowanie oscyloskopem Siglent

Do zdalnej komunikacji z urządzeniami pomiarowymi, został opracowany standard SCPI, który należy poprawnie rozwinąć do postaci Standard Commands for Programmable Instruments. Sam standard definiuje jedynie składnię i strukturę komend natomiast nie definiuje interfejsu przez który dane urządzenie ma się po SCPI komunikować.

Mój oscyloskop cyfrowy Siglent SDS1202X-E posiada dwa interfejsy z implementacja standardu SCPI: USB oraz LAN. Przy czym za interfejsem LAN stoi jeszczce jeden skrót i jest to LXI, który rozwija się do Lan Extensions Basics for Instrumentation i jest w dużym uproszczeniu implementacją standardu dla interfejsu LAN umożliwiającą przesyłanie komend SCPI.

Dzięki wbudowanej implementacji standardu LXI w urządzenia pomiarowe, uzyskujemy możliwość bezpośredniej komunikacji peer-to-peer przez sieć internetową. Można za pomocą protokołu telnet połączyć się z urządzeniem i wydawać mu komendy SCPI oraz odbierać dane (np. wyniki pomiaru).

Konfiguracja oscyloskopu

Oscyloskop oraz komputer podłączyłem do tej samej lokalnej sieci domowej. Dzięki temu oba urządzenia będą mogły się bez problemu komunikować. Dokonałem konfiguracji oscyloskop tak aby użył serwera DHCP do uzyskania adresu IP z routera. Należy ten adres znaleźć w ustawieniach i zapisać gdzieś pod ręką, gdyż to właśnie on posłuży nam do nawiązania połączenia.

Ustawienia do interfejsu LAN były u mnie dostępne pod przyciskiem Utility -> I/O -> IP Set:

Fotografia 1 - Ustawienie IP Set

Testujemy podstawowe komendy

Są takie 2 komendy, które możemy z palca wykonać aby sprawdzić czy możemy poprawnie wykonywać komendy:

  • *IDN? - Identification Number
  • *RST - Reset

Spróbujemy połączyć się do urządzenia przez protokół Telnet i sprawdzić czy jesteśmy w stanie je wykonać. Otwórzmy program telnet i wykorzystajmy adres ip 192.168.2.2 oraz port 5025 do sprawdzenia połączenia.

$ telnet
telnet> open 192.168.2.2 5025
Trying 192.168.2.2...
Connected to 192.168.2.2.
Escape character is '^]'.
*IDN?
Siglent Technologies,SDS1202X-E,SDS1ECDX3R3476,8.1.1.3.23
*RST
^]
telnet> q
Connection closed.

Wskazówka

Aby wyjść z programu telnet, należy nacisnąć zdefiniowany escape character czyli ctrl + ], po czym wpisać q i nacisnąć enter.

Jak widać, na polecenie *IDN? oscyloskop ładnie się nam przedstawił, natomiast (czego tutaj nie widać), po wysłaniu polecenia *RST, oscyloskop zresetował się do stanu początkowego. Jest to równoważne z naciśnięciem przycisku Reset na panelu oscyloskopu.

Seth - Program do zdalnego sterowania oscyloskopami SIGLENT

Na potrzeby tego artykułu stworzyłem program, za pomocą którego, umożliwiamy sobie możliwość komunikacji z oscyloskopem bez użycia dodatkowych programów typu Telnet. Seth od Siglent Ethernet jest programem konsolowym, który używa gniazd sieciowych do komunikacji zdalnej z oscyloskopem po sieci internet. Program umożliwia wysłanie dowolnej komendy lub zapytania SCPI.

Różnica pomiędzy komendą a zapytaniem jest prosta: komenda wysyła dane do oscyloskopu ale nic nie zwraca, zapytanie za to zwraca dane z powrotem do komputera. Można wyspecyfikować podczas wysyłania SCPI czy jest to komenda czy zapytanie. Program również sam stara się odgadnąć, że dana komenda jest zapytaniem, jeżeli tylko w komendzie znajduje się znak zapytania.

Np.

$ seth -s 192.168.2.2 -x "*IDN?"
Siglent Technologies,SDS1202X-E,SDS1ECDX3R3476,8.1.1.3.23

Program na podstawie znaku ? domyśla się, że jest to zapytanie i odczytuje odpowiedź z DSO. Parametrem -s definiujemy adres IPv4 do urządzenia. Możliwe jest ustawienie również portu za pomocą -p (domyślnie jest to 5025).

Są też zapytania SCPI które nie zawierają znaku ? więc aby wymusić odczytanie odpowiedzi używamy parametru -q, np.:

$ seth -s 192.168.2.2 -q "SCDP" > SCREEN.bmp

Spowoduje wysłanie zapytania SCDP (utworzenie zrzutu ekranu) a dane odczytane z DSO zostaną zapisane do pliku SCREEN.bmp.

Zalety tego programu:

  • Nie potrzebuje dodatkowych bibliotek ani programów zewnętrznych;
  • Nie trzeba pamiętać wszystkich komend SCPI (wiele komend SCPI będzie zaimplementowana jako prosta komenda np. reset, id albo screendump);
  • Domyślnie wszystkie pobrane dane są drukowane na standardowym wyjściu, dzięki czemu można go używać do przetwarzania potokowego;
  • Można zautomatyzować wszystkie procesy komunikacji w połączeniu ze skryptami shellowymi;
  • Dzięki możliwości wysłania domyślnych komend, można go używać również do komunikacji z innymi urządzeniami pomiarowymi;
  • Prosta intuicyjna obsługa (podręczny --help).

Strona projektu GitHub: https://github.com/di0x7c5/seth.

Przydatne komendy

Skoro mamy już bezpośrednie połączenie z oscyloskopem, to potrzebujemy dowiedzieć się kilku przydatnych komend do sterowania. Nie zagłębiając się w szczegóły i podążając za dokumentacją do SCPI dla oscyloskopu siglent, poniżej udało mi się zebrać w jednym miejscu wszystkie potrzebne komendy wraz z opisami:

Komenda SCPI Opis
Reset *RST Przywrócenie ustawień początkowych
Horizontal Scale TDIV 20US Ustawienie 20uS na działkę
Vertical Scale C1:VDIV 3V Ustawienie 3V na działkę
Trigger Level C1:TRLV 6V Ustawienie poziomy wyzwalania na 6V
Trigger Mode TRMD SINGLE Ustawienie tryby wyzwalania na pojedyńczy
Channel Offset C1:OFST -6V Ustawienie offsetu dla kanału pierwszego na -6V
Attenuation C1:ATTN 1 Ustawienie współczynnika tłumienia sondy na 1
Waveform C1:WF? DAT2 Ściągnięcie próbek z oscyloskopu z kanału 1

Struktura danych Waveform

Z pobraniem wartości próbek zmierzonego przebiegu związane są dwie komendy:

  • WF? - zapytanie zwracające wartości próbek zmierzonego przebiegu. Ilość i jakie próbki zostaną przesłane definiuje druga komenda.
  • WFSU - określa jakie i ile próbek zostaną przesłane przy użyciu poprzedniego zapytania.

Komenda WFSU może być również użyte jako zapytanie. Zwraca ono 3 parametry definiujące sposób w jaki próbki aktualnie mierzonego przebiegu zostaną przesłane po wysłaniu zapytania WF?. Wyślijmy i sprawdźmy co takiego otrzymamy w wyniku wysłania zapytania WFSU?:

$ seth -s 192.168.2.2 -x "WFSU?"
WFSU SP,0,NP,0,FP,0

W wyniku otrzymaliśmy 3 pary wartości w postaci klucz/wartość oddzielone przecinkami:

  • SP (sparse point) definiuje interwał pomiędzy próbkami. Wartości 0 oraz 1 zwrócą nam wszystkie wartości próbek jakie oscyloskop posiada w pamięci. Wartość np 4 oznacza, że dostaniemy co czwartą próbkę zmierzonego sygnału.
  • NP (number of points) definiuje ile punktów pomiarowych zostanie przesłanych. Wartość 0 prześle wszystkie dostępne próbki.
  • FP (first point) definiuje pierwszy punkt pomiarowy, który zostanie przesłany. To coś w rodzaju offsetu, jeżeli przyjmie wartość 100 to oscyloskop zwraca nam jako pierwszą próbkę setną.

Możemy sami ustalać te wszystkie parametry. Domyślnie wielkość bufora z próbkami równy jest maksymalnej pojemności pamięci, co w moim przypadku jest to wartość 7.000.000. Jeżeli nie potrzebujemy za każdym razem transferować tak olbrzymiej ilości danych pomiarowych możemy np. ustawić sobie interwał na np. 1000.

Ustawienie parametrów SP, NP oraz FP dokonuje się za pomocą tej samej komendy tylko teraz zamiast zapytania, prześlemy nasze wartości parametrów. Robi się to w formacie klucz wartość i wszystko oddzielamy przecinkiem.

$ seth -s 192.168.2.2 -x "WFSU SP,1000,NP,0,FP,0"
$ seth -s 192.168.2.2 -x "WFSU?"
WFSU SP,1000,NP,0,FP,0

I tutaj mała uwaga. Wydawałoby się, że ustawienie parametru SP na wartość 1000 spowoduje, że oscyloskop zwróci nam wyłącznie co 1000 próbkę. Niestety tak nie jest i w wyniku zapytania oscyloskop i tak zwróci wszystkie próbki z pamięci. A to dlatego, że drugi parametr NP ciągle przyjmuje wartość 0 co oznacza, zwróć wszystkie wartości. Jeżeli chcemy aby z 7 mln. próbek oscyloskop zwrócił nam co tysięczną i tylko 7 tys. musimy ustawić parametr NP:

$ seth -s 192.168.2.2 -x "WFSU NP,7000"

Jak widać, każdy z trzech parametrów możemy ustawić oddzielnie. Docelowo zapytanie WFSU? powinno zwrócić następujące wartości:

$ seth -s 192.168.2.2 -x "WFSU?"
WFSU SP,1000,NP,7000,FP,0

Teraz możemy pobrać właściwe dane, służy do tego komenda WF?. Jego składnia wygląda następująco:

<trace>:WF? <section>

Gdzie <trace> definiuje kanał z którego pobierane będą dane lub wynik działania operacji matematycznej: C1, C2, C3, C4 lub MATH

Jeżeli zaś chodzi o wartości dla <section> to dokumentacja wspomina tylko o jednej sekcji DAT2.

Podłączmy sondę oscyloskopu do sygnału testowego 1kHz i spróbujmy za pomocą komendy WF? ściągnąć przebieg na komputer.

$ seth -s 192.168.2.2 -x "C1:WF? DAT2" > GEN1K_SP_1000_NP_7000_FP_0.bin
$ du -sh GEN1K_SP_1000_NP_7000_FP_0.bin
8,0K GEN1K_SP_1000_NP_7000_FP_0.bin

Zawartość utworzonego pliku wygląda tak:

$ hexdump -C GEN1K_SP_1000_NP_7000_FP_0.bin
00000000 43 31 3a 57 46 20 44 41 54 32 2c 23 39 30 30 30 |C1:WF DAT2,#9000|
00000010 30 30 37 30 30 30 2c 05 02 01 ff 00 00 00 00 00 |007000,.........|
00000020 00 00 00 00 00 01 00 02 00 00 00 01 00 01 01 01 |................|
00000030 00 00 00 01 00 00 02 00 00 01 02 00 00 00 00 01 |................|
...
00001b30 4b 4b 4c 4c 4b 4a 4b 4c 4b 4b 4b 4c 4c 4c 4b 4b |KKLLKJKLKKKLLLKK|
00001b40 4c 4c 4b 4a 4a 4b 4c 4b 4a 4b 4c 4b 4c 4a 4b 4b |LLKJJKLKJKLKLJKK|
00001b50 4b 4c 4a 4b 4c 4c 4b 4b 4a 4c 4c 4a 4b 4b 4c 4c |KLJKLLKKJLLJKKLL|
00001b60 4a 4b 4c 4b 4a 4b 4b 4b 4b 4c 4b 4b 4b 4c 0a 0a |JKLKJKKKKLKKKL..|

Wg. dokumentacji struktura odpowiedzi wygląda w następujący sposób:

C1:WF DAT2,#9<size><data> 0a 0a

Gdzie na początku znajduje się standardowy harcerski odzew na zadane zapytanie C1:WF DAT2, następnie po przecinku mamy wartość #9 która oznacza, że kolejne 9 znaków ASCII będzie reprezentowało ilość przesłanych próbek w tym przypadku jest to 000007000 czyli 7 tys. Następnie znajduje się obszar wartości próbek. Jedna próbka reprezentowana jest przez jeden bajt. Wszystko kończy się podwójnym kodem hex 0a, który sygnalizuje koniec danych.

Jak odczytujemy wartości próbek?

Otóż przesłane wartości nie reprezentują wartości napięcia próbki. Aby dowiedzieć się jaką dokładną wartość napięcia dana próbka reprezentuje, musimy wykonać pewną operację matematyczną na próbce. Robimy to w następujący sposób:

Voltage[V]={value(vdiv/25)voffsetif value127(value255)(vdiv/25)voffsetif value>127 Voltage[V] = \begin{cases} value * (vdiv/25) - voffset &\text{if } value \leqslant 127 \\ (value-255) * (vdiv/25) - voffset &\text{if } value > 127 \end{cases}

Gdzie vdiv to wartość napięcia na działkę, voffset to offset napięcie w pionie a value to przesłana wartość dziesiętna próbki. Jeżeli wartość ta jest większa od 127 to należy od niej najpierw odjąć 255 a potem dopiero podstawić do wzoru.

Zapytamy się naszego DSO jakie to są wartości:

$ seth -s 192.168.2.2 -x "C1:VDIV?"
C1:VDIV 1.00E-01V
$ seth -s 192.168.2.2 -x "C1:OFST?"
C1:OFST 0.00E+00V

A więc VDIV = 100mV a offset jest zerowy. Dla przykładu dla wartości próbki 4bh (75 dec) mamy:

V=75(0.1/25)0=750.004=0.3V V=75\cdot(0.1/25)-0=75\cdot0.004=0.3V

Ok, spróbujmy z tego coś namalować. Wyłuskam dane próbek z pobranego pliku pomijając nagłówek oraz ostatnie dwa bajty sygnalizujące koniec a przy okazji przekonwertujemy binarne wartości na dziesiętne do pliku CSV:

dd if=GEN1K_SP_1000_NP_7000_FP_0.bin bs=1 skip=22 count=7000 | hexdump -v -e '/1 "%u\n"' > GEN1K_SP_1000_NP_7000_FP_0.csv

Otwieram plik csv i w nim dodaję kilka nowych formuł. Najpierw dla wartości większych od 127 należy odjąć 255, zatem do kolumny B wprowadziłem formułę:

=IF(A1>127, A1-255, A1)

W kolumnie C wyliczyłem etykiety dla osi X, czyli osi czasu. Wiedząc, że podziałka czasu to 500uS na działkę a jest 14 działek w poziomie, mamy 7ms okna czasowego. Wiedząc, że mamy 7000 próbek możemy łatwo obliczyć punkt czasowy dla konkretnej próbki:

=(ROW()/7000)*7

A w kolumnie D chcę mieć już wyliczone wartości napięć dla próbek dlatego w wprowadziłem tam formułę:

=B1*(0.1/25)-0

Na podstawie wygenerowanych danych stworzyłem wykres:

Rysunek 5 - Wykres wygenerowany z danych przesłanych za pomocą zapytania WF?

I jeszcze szybkie porównanie z tym co się dzieje faktycznie na ekranie oscyloskopu. Wysyłam zapytanie SCDP i zapisuję dane do pluku BMP:

$ seth -s 192.168.2.2 -q "SCDP" > SCDP_GEN1K.bmp
Rysunek 6 - Faktyczny kształt przebiegu na ekranie oscyloskopu

Jak widać na załączonych obrazkach, wszystko do siebie pasuje i poprawnie zinterpretowaliśmy dane przesłane z oscyloskopu.

Rezystor pomiarowy

Tym razem w roli rezystora pomiarowego, zamiast równolegle połączonych rezystorów drutowych, wystąpi specjalnie do tego celu przeznaczony rezystor 0.02Ω w obudowie SMD typu 2512. Jest on na tyle duży, że wyszycie na niego odpowiedniego adaptera THT wcale nie będzie trudne. Wystarczy listwa goldpin o długości 3 pinów, z czego środkowy wyrzucamy i lutujemy układ bezpośrednio do dwóch pozostałych pinów:

Fotografia 2 - Prosty adapter SMD 2512 -> THT dla rezystora pomiarowego

Tak przygotowany rezystor znakomicie nada się do testów przeprowadzanych na płytce prototypowej.

Łączymy wszystkie elementy w całość

Teraz należy połączyć wszystkie opisane powyżej czynności w jedną aby automatycznie dokonywać pomiaru indukcyjności.

To Be Continued ...

Do ściągnięcia