Aplikację układu AS3935 wykonałem samodzielnie. Budując ją nie korzystałem z gotowych modułów, dostępnych w handlu.
Płytka musi być zaprojektowana zgodnie z zasadami obowiązującymi dla urządzeń radiowych. Pierwszy aspekt, na który chciałbym zwrócić uwagę, to projekt płytki, gdzie prowadząc poligon masy należy ominąć obwód antenowy, a więc cewkę i elementy RC wchodzące w skład obwodu rezonansowego anteny, jak pokazano na fotografii 1.
Układ nie dość, że ma obudowę trudną do przylutowania w warunkach domowego warsztatu (MLPQ16), to jeszcze na spodniej stronie znajduje się powierzchnia (exposed pad), która bezwzględnie musi być dołączona do masy. W swojej płytce pod układem zaprojektowałem metalizowaną przelotkę o średnicy 1,6 mm, dzięki czemu mogłem przylutować ten pad od spodu (fotografia 2). Oczywiście, jeżeli ktoś ma możliwość przylutowania układu za pomocą stacji lutowniczej hot air z użyciem pasty lutowniczej przelotka jest zbędna.
Z układem AS3935 można komunikować się za pomocą interfejsu SPI lub I2C. Wyboru trybu pracy dokonujemy dołączając napięcie lub masę do odpowiednich wyprowadzeń układu, co opisano w nocie aplikacyjnej. Układ można zasilać napięciem z zakresu 2,4…5,5 V, co pozwala na łatwe użycie w systemach zasilanych napięciem 3,3 V lub 5 V. W zależności od napięcia zasilania zmienia się schemat aplikacyjny, co również szczegółowo opisano nocie aplikacyjnej. Typowym napięciem zasilania układu jest 3,3 V. Jeśli takim samym napięciem zasilimy mikrokontroler komunikujący się z AS3935, to unikniemy konieczności stosowania translatorów poziomu napięcia.
W swojej aplikacji użyłem interfejsu I2C, co spowodowało konieczność ustawienia adresu układu na magistrali. Aby ustawić adres, dwa piny konfiguracyjne ADD0 i ADD1 należy dołączyć do masy lub Vcc, wybierając adres odpowiadający naszym potrzebom. Co typowe, logicznej „1” odpowiada przyłączenie wejścia adresowego do Vcc, natomiast logicznemu „0” przyłączenie go do masy. Wejście ADD0 odpowiada 21, natomiast ADD1 – 22. Ustawiane adresy są zgodne z kolejnymi liczbami binarnymi, a więc jeśli ADD1 = ADD0 = „0”, to układ zgłasza się pod adresem 0x00. Jeśli ADD1 = „0” i ADD0 = „1”, to 0x02 itd. Uwaga! Producent nie pisze tego w nocie, ale znalazłem taką informację w dodatkowych źródłach, że nie zaleca się wyboru adresu 0x00 ze względu na możliwe problemy z odczytem rejestru o tym samym indeksie.
Interfejs I2C zastosowany w układzie może pracować z maksymalną prędkością 400 kbit/s, ale jeżeli do magistrali dołączono inne, wolniejsze układy, to trzeba uwzględnić ten fakt i obniżyć prędkość transmisji np. do 100 kbit/s lub mniej.
Pierwszym krokiem podczas konfigurowania układu jest dostrojenie obwodu antenowego do częstotliwości rezonansowej jak najbliższej 500 kHz. Producent pisze o 3,5% tolerancji, ale im bliżej rzeczonych 500 kHz, tym lepsza czułość układu. W sieci jest dużo przykładów strojenia anteny za pomocą timera, zliczania impulsów i innych sposobów, prezentowanych szczególnie użytkownikom Arduino. Sposób, którego użyłem jest banalnie łatwy i jednocześnie zapewnia dużą skuteczność strojenia.
Po wpisaniu „1” do rejestru 0x08 na pozycję bitu nr 7, na wyprowadzeniu IRQ otrzymujemy przebieg o częstotliwości LCO (f rezonansowa anteny), domyślnie podzielonej przez 16. Jeżeli nie dysponujemy oscyloskopem, to można częstotliwość tego przebiegu mierzyć za pomocą multimetru, który ma tę funkcjonalność, a współcześnie nie jest to czymś niezwykłym. W następnym kroku dodajemy w rejestrze 0x08 na pozycjach bitów o numerach 3:0 wewnętrzne kondensatory, które mamy do dyspozycji w układzie scalonym. Są to pojemności z zakresu od 0 do 120 pF, z krokiem co 8 pF. Udało mi się osiągnąć wartość częstotliwości na pinie IRQ = 31,28 kHz, a więc łatwo obliczyć, że częstotliwość rezonansowa anteny to 500,48 kHz (31,28×16 → 500,48). W moim wypadku wystarczyło dodanie trzech kondensatorów, czyli zapisanie do rejestru 0x08 komendy 0x03. Oczywiście, może to być inna wartość z przedziału 0x01 do 0x0F w zależności od układu i wartości elementów RC w obwodzie anteny. Wartość dodanych kondensatorów zapamiętujemy – będzie nam ona potrzebna przy inicjalizacji układu.
Teraz przechodzimy do inicjalizacji układu. Według noty, na początku przywracamy ustawienia fabryczne, dodajemy kondensatory do obwodu anteny, kalibrujemy oscylatory, a następnie włączamy i wyłączamy generator TRCO. Dalsze ustawienia to już konfiguracja rejestrów czułości układu, progu zadziałania watchdoga, progu szumów i tym podobne. Gotową funkcję inicjalizacji, napisaną w języku C, którą zastosowałem w swojej aplikacji zamieszczono na listingu 1.
void AS3935_init(void)
{
uint8_t cd = 0x96;
uint8_t cap = 0x03;
uint8_t a;
TWI_write_buf(AS3935_ADRES, 0x3C, 1, &cd); // ustawienia fabryczne
_delay_ms(2);
TWI_write_buf(AS3935_ADRES, 0x08, 1, &cap); // dodanie kondensatorów wewnętrznych
_delay_ms(2);
TWI_write_buf(AS3935_ADRES, 0x3D, 1, &cd); // kalibracja oscylatorów
a = 0x23;
TWI_write_buf(AS3935_ADRES, 0x08, 1, &a); // włączenie generatora TRCO
_delay_ms(2);
TWI_write_buf(AS3935_ADRES, 0x08, 1, &cap); // wyłączenie generatora TRCO
a = 0x24;
TWI_write_buf(AS3935_ADRES, 0x00, 1, &a); // ustawienie wzmocnienia AFE
a = 0x24;
TWI_write_buf(AS3935_ADRES, 0x01, 1, &a); // ustawienie WDTH
}
Oczywiście, można modyfikować zawartość rejestrów umieszczonych pod adresami 0x00 i 0x01, a także dodać ustawienia w rejestrze 0x02 (bity 3:0 – rej. SREJ, wykres w nocie aplikacyjnej). Najważniejsze jest pięć pierwszych pozycji z funkcji – resztę można dowolnie modyfikować w celu uzyskania najlepszego efektu końcowego. Oczywiście, bezwzględnie należy sprawdzić w karcie katalogowej do czego służą poszczególne bity i nie wolno modyfikować ich na zasadzie chybił-trafił. Nie należy też przesadzać z ustawieniem zbyt wysokiego poziomu progu szumów i watchdoga, ponieważ ma to bezpośredni wpływ na odległość do wykrywanych wyładowań. A na koniec jeszcze jedna przestroga – jeżeli płytka odbiornika będzie umieszczona blisko komputera lub telefonu komórkowego, to układ będzie zgłaszał przerwania od szumów i zakłóceń.
Układ AS3935 po wykryciu pioruna generuje przerwanie, na które musimy zareagować. W swojej aplikacji, w procedurze obsługi przerwania ustawiam bit sygnalizujący odebrane wyładowanie, a w pętli głównej programu sprawdzam jego stan, jak na listingu 2.
ISR(INT2_vect)
{
FLAG = 1;
LED_ON;
}
void Storm(void)
{
_delay_ms(5);
uint8_t buf, buf1;
TWI_read_buf(AS3935_ADRES, 0x03, 1, &buf);
uart_puts("PRZERWANIE");
uart_puts("\r\n");
uart_puts("AS3935 rejestr INT = ");
uart_putint(buf,16);
uart_puts("\r\n");
if(buf == 8)
{
TWI_read_buf(AS3935_ADRES, 0x07, 1, &buf1);
uart_puts("AS3935 rejestr DISTANCE = ");
uart_putint(buf1,10);
uart_puts("km");
uart_puts("\r\n");
}
FLAG = 0;
LED_OFF;
}
while(1)
{
if(FLAG)Storm();
}
Za pomocą terminala np. Putty możemy podglądać zdarzenia. Ważne, aby po wejściu w funkcję odczytującą dane opóźnić działanie programu przed odczytem rejestru 0x03 (bity 3:0), czyli powodu przerwania (1 – szum, 4 – zakłócenie, 8 – wyładowanie atmosferyczne). W aplikacji reagujemy tylko na wartość „8” i odczytujemy rejestr 0x07, czyli odległość od wyładowania, a następnie wysyłamy do terminala. Jeżeli wszystko działa poprawne, to możemy w funkcji pominąć wysyłanie danych na terminal i napisać ją inaczej, na przykład tak, jak pokazano na listingu 3. Dane o odległości od wyładowania są wysyłane bo głównego procesora stacji pogodowej, w którym są parsowane i prezentowane na wyświetlaczu TFT.
void Storm(void)
{
_delay_ms(5);
uint8_t buf, buf1;
TWI_read_buf(AS3935_ADRES, 0x03, 1, &buf);
if(buf == 8)
{
TWI_read_buf(AS3935_ADRES, 0x07, 1, &buf1);
storm = buf1;
sprintf(bufor,("AT+storm %d"), storm);
uart_puts(bufor);
uart_puts("\r\n");
}
FLAG = 0;
}
Jeszcze jeden bardzo ważny aspekt. Układ po wykryciu wyładowania np. w odległości 10 kilometrów zapamiętuje tą wartość i jeżeli następne wyładowanie nastąpi w odległości większej, to niestety ponownie zostanie zgłoszone wcześniejsze 10 kilometrów. Jest to trochę uciążliwe, ponieważ jeżeli wyładowanie nastąpi naprawdę blisko, to stale jest pokazywana tą wartość aż do przepełnienia się rejestru, pomimo odsuwania się burzy. Można temu zaradzić manipulując bitem 6 w rejestrze 0x02. Na pozycję tego bitu wpisujemy kolejno „1” – „0” – „1” i dodajemy to do funkcji Storm. Od tej pory mamy zawsze aktualny odczyt odległości.
Układ AS3935 ma też rejestry, z których możemy odczytać energię, jaką wytworzył uderzający piorun. Są one umieszczone pod adresem 0x04, 0x05 i 0x06. Niestety, producent nie podaje, w jakich jednostkach jest kalkulowana ta energia i jak jest szacowana, więc myślę, że należy to potraktować jako ciekawostkę.
Generalnie, układ pracuje poprawnie od ponad 6 miesięcy w mojej stacji pogodowej. Zdarzało się, że sygnalizował wyładowanie, którego nawet nie było słychać. Największa do tej pory odległość, z jakiej wykrył piorun pracując na zewnątrz budynku to 33 kilometry.
Układ AS3935 można kupić poprzez stronę internetową firmy Austria Microsystems. Dostępne są również gotowe moduły ze wszystkimi elementami pod nazwą MOD-1016. Jeżeli podejmiemy decyzję o zakupie samego układu i zaprojektowanie własnej płytki, to trzeba jeszcze uwzględnić zakup cewki MA5532-AE firmy Coilcraft przeznaczonej do użycia z układem AS3935 w obwodzie antenowym. Trzeba również przewidzieć miejsce na dwa kondensatory w obwodzie anteny. Producent w nocie podaje wartość 1 nF, ale warto mieć alternatywę w postaci dwóch kondensatorów np. 680 pF + 270 pF, ponieważ może się okazać, że 1 nF to za dużo (szczególnie przy 10% tolerancji pojemności) i nie uda nam się precyzyjnie dostroić anteny.
Na fotografii 3 pokazano wyniki pomiarów przesyłane do terminala, natomiast na fotografii 4 sposób ich prezentacji na wyświetlaczu LCD stacji pogodowej.
Zachęcam do wykonania w programie oddzielnych plików bibliotecznych AS3935.c i AS3935.h mimo tego, że cała „biblioteka” to zaledwie dwie funkcje. Przykładowy plik nagłówkowy (.h) pokazano na listingu 4. Biblioteki do obsługi UART oraz I2C wykonano na podstawie książek Mirosława Kardasia „Mikrokontrolery AVR język C – podstawy programowania” oraz „Język C pasja programowania mikrokontrolerów 8-bitowych”. Nota aplikacyjna jest dostępna w Internecie, w tym na stronie producenta – firmy Austria Microsystems.
#ifndef AS3935_H_
#define AS3935_H_
#define AS3935_ADRES 0x06
volatile uint8_t FLAG;
uint8_t storm;
void AS3935_init(void);
void Storm(void);
#endif /* AS3935_H_ */
Powodzenia w pracy z układem i czekamy na wiosenną burzę!
Marek Rębecki