AD9833 to popularny układ scalony DDS (Direct Digital Synthesis), który umożliwia generowanie przebiegów sinusoidalnych, prostokątnych i trójkątnych w zakresie do ok. 12.5 MHz przy 28-bitowej rozdzielczości. Dzięki niewielkiemu modułowi dostępnym w sprzedaży (z wbudowanym oscylatorem 25 MHz) można go szybko uruchomić z dowolnym mikrokontrolerem. W tym temacie pokażę, jak można to zrobić z ESP32 w środowisku PlatformIO w oparciu o gotową bibliotekę robtillaart AD9833.
Zacznijmy od samego modułu. Można go kupić za kilkanaście złotych w chińskim sklepie wysyłkowym. W naszym kraju jest niewiele drożej, bo cena wynosi nieco ponad 20 zł. Sam moduł dostajemy ze złączem szpilkowym, które musimy sami przylutować:
Z drugiej strony piny są opisane:
Nie ma tu problemu z zasilaniem, można uruchomić całość i na 5V, jak i na 3.3V. Dodatkowo nie trzeba konwertera napięć, w nocie katalogowej widzę że napięcie na pinach cyfrowych jest aż do VDD:
Do prezentacji użyję podstawowej płytki uruchomieniowej z ESP32 - też do kupienia za kilkanaście złotych.
Można ją wygodnie programować przez USB, a również przez WiFi (po odpowiednim skonfigurowaniu).
Od strony programowej użyję Visual Studio Code z rozszerzeniem PlatformIO. Zaczynamy od pustego projektu:
Potem wyszukujemy interesującą nas bibliotekę. Obiecująca wydaje się być praca robtillaart pod nazwą AD9833.
https://registry.platformio.org/libraries/robtillaart/AD9833
Można ją dodać w samym PlatformIO, albo dopisać ręcznie do platformio.ini.
Wychodzi wtedy:
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = robtillaart/AD9833@^0.4.3
Uruchomimy teraz najprostszy kod. Wymaga on jednak wykonania podstawowych podłączeń, czyli wspólna masa, zasilanie do 3.3V, oraz trzy sygnały SPI - tutaj zdecydowałem się użyć programowego, więc nadały się dowolne piny. Połączenie wykonałem na płytce prototypowej:
Kod dla mojego połączenia. Kolejno wpisałem indeksy pinów (15, 4, 2, tu nie ma mapowania):
Kod: C / C++
Wgrywamy i sukces:
Teraz zastanówmy się, co nasz kod robi:
- AD9833 AD(15, 4, 2) - ta linia inicjuje nowy obiekt klasy AD9833 i przekazuje indeksy pinów do jego konstruktora
- AD.begin() - ta linia uruchamia AD9833
- AD.setFrequency(1000, 0) - ta linia ustawia wybraną częstotliwość w Hz, drugi argument to kanał (dostępne są 2)
- AD.setWave(AD9833_SQUARE1) - tu z kolei ustawiany jest rodzaj generowanej funkcji. Dostępne jest też oczywiście AD9833_SINE i AD9833_TRIANGLE
Przetestujmy AD9833_SINE:
Przetestujmy AD9833_TRIANGLE:
Wersje 100Hz, 10kHz, 100kHz, 1MHz, 10MHz:
Układ pracuje do 12.5 MHz ale wraz ze wzrostem częstotliwości jakość przebiegów spada.
Biblioteka dodatkowo obsługuje kanały AD9833 - dostępne są dwa, pozwalają ustawić dwie funkcje i łatwo między nimi przełączać.
Kod: C / C++
Warto pamiętać, że biblioteka może też obsłużyć kilka AD9833 na jednej magistrali SPI - po prostu każdy ma osobny pin select.
Kod: C / C++
Podsumowując, pokazałem tu prosty w uruchomieniu moduł generatora sygnałowego DDS AD9833. Zademonstrowałem tu podstawy, czyli generowanie sygnałów sinusoidalnych, trójkątnych i prostokątnych w oparciu o programowe SPI, które może działać na dowolnych pinach. Wszystko opierało się o gotową bibliotekę i było możliwe do wyklikania nawet nie w jeden wieczór, lecz w pół godzinki czy tam kwadrans.
Nie jest to oczywiście jedyny generator DDS dostępny w formie prostego do uruchomienia modułu, mamy też chociażby AD9850 (50MHz) czy tam SI5351, który już kiedyś uruchamiałem:
Trzykanałowy generator zegera SI5351 i PIC32MX - pierwsze starcie
Teraz pojawia się tylko pytanie, co dalej z tym AD9833 zrobić - jakieś sugestie? Może zintegrować z odbiornikiem SSB? Kiedyś takie uruchamiałem, ale u mnie jest ciężka sytuacja antenowa i nie da się dużo posłuchać... może wobulator? Albo jeszcze jakieś bardziej egzotyczne zastosowanie? Pomyślę, mogłaby z tego wyjść ciekawa prezentacja.
Fajne? Ranking DIY Pomogłem? Kup mi kawę.