[BASCOM DESIGN CONTEST] MIKA powie Ci…

Jak MIKA odtwarza więc dźwięki z karty SD?

Przed rozpoczęciem odtwarzania Timer2 jest przełączany na tryb Counter, a Timer1 na tryb PWM. W podświetlaniu to nie przeszkadza, bo wtedy ma świecić, więc po odłączeniu Timera2 od pinu kontrolę nad nim odzyskują rejestry DDR i PORT.

Po odtworzeniu sampla dźwiękowego przywracana jest poprzednia konfiguracja, czyli Timer1 pracuje w trybie Capture , ale wyzwalany za pomocą komparatora. Podczas różnych wersji testowałem też pin ICP, ale komparator może wyzwalać przy każdej zmianie stanu. Ta konfiguracja nie jest finalną, bo MIKA też finalnym sterownikiem nie jest. Opisuję jak jest zbudowana, ale jeszcze mogę podjąć kroki w innych kierunkach. Pomyślałem, że może przydać się informacja o ilości przejść przez zero.

Zmiany konfiguracji dokonuję poprzez wywołanie podprogramów.

Zatrzymam się na moment na ciekawym rozwiązaniu w BASCOM. Teraz można wybrać taki sposób załączania podprogramów, że nie trzeba ich deklarować. Muszą jednak być załączone zanim zostaną po raz pierwszy użyte w kodzie. Tak więc trzeba SUB umieścić zanim się do niego odwołamy. Wszelkie zmienne używane przez SUB też powinny być zadeklarowane zanim go użyjemy.

Wymaga to jedynie pewnej systematyczności. Nie można użyć w SUBie jakiejś zmiennej, która jeszcze nie została zadeklarowana. Tak samo nie możemy używać polecenia PRINT #x na kanale programowego UARTU, jeśli go jeszcze nie otworzyliśmy.

Poza wymienionymi sprawami, na które należy zwrócić uwagę, ten sposób dołączania podprogramów ma same plusy!

Możemy dołączyć całe biblioteki różnych gotowych instrukcji obsługujących jakiś układ zewnętrzny i tylko te, które użyjemy w kodzie wywołując je zostaną skompilowane. Mam na przykład wiele gotowych kodów, dołączam je w nagłówku, a wykorzystuję tylko kilka funkcji. Tak więc główny listing programu może wyglądać bardzo schludnie i nawet nie wymagać długiego przewijania w oknie edytora.

 

Program

Jeśli mamy opracowany jakiś kawałek kodu, w którym na razie nie planujemy zmian, to możemy go wyciąć, zapisać w osobnym pliku i dołączyć poprzez $include w miejscu skąd go wycięto. Wtedy zajmuje tylko jedną linijkę.

Zmiany konfiguracji Timerów dokonuję prostym z punktu widzenia użytkowania „Call Configure_for_commands” i „Call Configure_for_talking”

Subami zawartymi w pliku „config_timers.bas”.

Drugim moim ulubionym sposobem do poruszania się w kodzie jest przypisanie niektórym wartościom aliasów. Chodzi o to, że można w programie powołać nie tylko zmienne, ale i stałe. O tym pewnie wie wielu, ale program staje się przejrzystszy i łatwiejszy w zrozumieniu, jeśli na przykład dla kilku stanów programu normalnie określanymi wartościami powołamy stałe o tych wartościach. Stałe mają jednak nazwy.

Jeśli określę stałe  Const Waiting = 0 ,  Const Decoding = 1 i  Const Recording = 2…, to w całym programie mogę używać ich tak, że od razu wiadomo co się dzieje. Jeśli w kodzie napiszę, że Status = Decoding to wiem, że sterownik jest w stanie dekodowania słowa, ale mikrokontroler widzi to normalnie jako Status = 1

Tym sposobem w dowolnym miejscu mogę zmienić jakieś wartości nie sprawdzając co oznaczają, bo jest to jasno określone w ich nazwie.

Stałe przydają się też do często powtarzających się tekstów, które wyświetlamy. Po co kilka razy zapisywać te same słowo w pamięci programu, jeśli można je określić jako stałą i tak używać.

Jeśli napiszę Const Nagraj_ = „Nagraj ” to mogę tej stałej używać w wielu miejscach programu pisząc na przykład Lcd Nagraj_ lub umieszczając je w jakimś stringu. Piszesz raz, a używasz wszędzie.

Taki sposób ma jeszcze dodatkowy plus. Stałe tekstowe mogę umieścić w jednym miejscu i szybko przetłumaczyć na inny język. W całym programie pojawią się we właściwych miejscach bez szukania ich po całym kodzie.

Pisanie programów nie jest skomplikowane. Jeśli wiemy co chcemy osiągnąć, wystarczy się odpowiednio oczytać i jesteśmy w stanie napisać w każdym języku. W BASCOM jednak mamy możliwość ułatwionego testowania naszych pomysłów. Tutaj mam pomysł, piszę i się cieszę i jeszcze mam czas pomagać innym przy ich projektach.

W BASCOM na wyświetlaczach graficznych możemy łatwo wyświetlać fonty graficzne, czyli czcionki, jakie się nam tylko zamarzą. Stworzyłem nawet specjalny program tworzący plik fontów, który potem dołączamy do projektu. Program nazywa się Font Maker for Bascom by EDC. Mimo, iż jestem autorem takiego dzieła MIKA nie używa fontów graficznych. Takie fonty są dobre do wielkości 32 pikseli. Nawet wtedy są już bardzo pamięciożerne.

Jak więc MIKA wyświetla duże znaki i cyfry? Są to skompresowane obrazki znaków. Program wie, które obrazki pokazać.

Wrócę do kompresji obrazków. W BASCOM obrazki poddawane są kompresji. Jeśli bajty w danych obrazka powtarzają się, to zamieniane są na sekwencję „wartość bajtu i ile razy powtórzyć”. Jeśli więc obrazek ma kilka białych linii u góry (co się przekłada na 30 bajtów dla jednej linii), to zostanie to zamienione na sekwencje kilku bajtów, w której zostanie zapisane ile razy powtórzyć puste miejsce. Przekłada się to na dużą oszczędność. Font więc 15 dużych znaków o wielkości 56×64 px zajmuje tylko ok. 3 KB. W przypadku obrazków na cały ekran taka kompresja naprawdę nabiera znaczenia.

Pisałem o tym, że można szybko i łatwo przetestować swoje pomysły w BASCOM. Taki właśnie sposób wyświetlania dużych fontów przetestowałem i okazał się szybki i świetny.

Pliki o rozszerzeniu BGF podglądać można drugim moim programem ArrayEnigma. Nazwę wziął od tego jak rozszyfrowywałem sposób kodowania obrazków i tak zostało.

Kolejnym, myślę ładnym rozwiązaniem, które można podpatrzeć jest scrollowane menu sterownika. Nie jest specjalnie rozbudowane, bo nie było to potrzebne. Pozwala ustawić zegarek i nagrać komendy, które mają być rozpoznawane.

Ciekawy jest sposób prezentacji. Możliwy był między innymi dlatego, że wyświetlacz na sterowniku TC6369 ma jakby dwa ekrany nałożone jeden na drugi. Jeden należy traktować jako wyświetlacz alfanumeryczny, a drugi jako wyświetlacz graficzny. Znaki i obrazy mogą się na siebie nakładać, a tam gdzie na siebie nie nachodzą wyświetlane wspólnie, obok siebie.

Menu to statyczny obrazek z prostokątem w środku, a w polu prostokąta wyświetlane są dane alfanumeryczne. Są one specjalnie selekcjonowane i pozycjonowane przez program tak, że wyglądają jakby się w tym „oknie” przewijały. Dodatkowa strzałka pokazuje, którą pozycję możemy w tym momencie „kliknąć”

Menu można rozbudować. Przyznam się, że teraz nie jest ono zoptymalizowane, ponieważ ostatnio borykałem się z brakiem czasu. Tak więc jestem pewien, że potrafiłbym zaoszczędzić jeszcze dużo miejsca nie powtarzając niektórych linii kodu. Jestem ich świadom.

Tyczy się to także obsługi karty SD. Pierwotnie stworzyłem osobny moduł na ATmega8, z którym sterownik się komunikował. Stwierdziłem jednak, że kody można spróbować połączyć i zamknąć w jednym mikrokontrolerze. Zaadoptowałem więc kod jeszcze go nie optymalizując.

Obsługa karty SD i odtwarzanie dźwięków dokonywane jest za pośrednictwem przerobionej biblioteki KokkeKat autorstwa Niclasa Amdta. Biblioteka ta ma bardzo małe wymagania, jeśli chodzi stos. Nie używa takich SUBów, którym przekazywane są parametry lub wartości. Dzięki niej możliwe jest uruchomienie systemu FAT nawet na małej ATmega8.

Układ RTC obsługiwany jest za pomocą funkcji nie napisanych przeze mnie. Informacje odnośnie autora znajdują się w kodach źródłowych.

Pozostaje omówić pokrótce mechanizm rozpoznawania komend. Za każdym razem, gdy układ wykryje dźwięk ustanawia lub tez przedłuża Timeout oraz klasyfikuje częstotliwość pomiędzy jeden z 28 progów częstotliwości.

Co 5ms wartość Timeout jest zmniejszana, a aktualna wartość częstotliwości jest zapisywana do kolejnego bajtu bufora o rozmiarze 240 B. Próbki są zbierane tak długo, aż wartość Timeout spadnie do zera. Na przykład dlatego że już jest cisza. Mowa cechuje się tym, że to same słowo wypowiedziane kilka razy będzie miało za każdym razem inną długość, dlatego żeby móc porównywać próbki długość jest normalizowana.

Przy nagrywaniu komend do rozpoznania i wtedy kiedy nie uda się dopasować żadnej komendy, sterownik pokazuje za pomocą wykresu przebieg częstotliwości i przebieg znormalizowany. Pomaga to przy tworzeniu kodu, bo jak pisałem wcześniej procedury mogą być łatwo zmieniane i to też jest plus sterownika. Ma modułowy charakter i każdą z części kodu można modyfikować oddzielnie lub wymieniać.

Kiedy mamy znormalizowaną próbkę, to porównywana jest ona z zapisanymi wzorcami. Zliczane są różnice w poszczególnych odcinkach i wybierany wzór z najmniejszą i do tego nie przekraczającą maksymalną dopuszczalną ilością błędów.

W początkowej fazie należy wypowiedzieć komendę sterownika, czyli „Mikaaa”. Ma ona zawężoną ilość błędów, co ma stanowić pewne zabezpieczenie przed niepowołanymi uruchomieniami. Później sterownik czeka na drugie słowo.

Na chwilę obecną MIKA potrafi się przedstawić, powiedzieć jaka jest temperatura i godzina oraz sterować jednym pinem. Na przykład światłem.

Jest miejsce w pamięci na więcej słów. W celu poprawy rozpoznawalności słów można nagrać więcej komend z tym samym słowem. Nie jest to jeszcze zaimplementowane. Można dopisać jakiś program na PC albo dołożyć ekspander I2C i sterować czymś więcej. Nie było mi to na razie potrzebne.

Dźwięki wydawane przez MIKĘ to miły żeński głos z syntezatora. Dlatego że chciałem uniknąć składania wyrazów co mogłoby nie być „naturalne w odsłuchu” każdą godzinę i minutę nagrałem oddzielnie. Kosztowało mnie to trochę czasu, ale efekt chyba był tego wart. Są to pliki WAV 8Bit Mono tylko zapisane bez rozszerzenia.

Łączność za pośrednictwem Bluetooth pozwala na wymianę danych, jak i oprogramowania. Wystarczyło zainstalować w mikrokontrolerze bootloader, który znajdziemy w folderze Sample i od tej pory można wysyłać oprogramowanie do sterownika bezpośrednio z IDE Bascom. Bardzo to uprzyjemnia testowanie nowych linijek kodu. Wymiana oprogramowania „bez kabli” trwa około 15 sekund. Można sobie wyobrazić, jakie to może mieć znaczenie dla zainstalowanych już gdzieś sterowników, niekoniecznie MIKI.

Pisząc o Bluetooth, albo w ogóle o łączności poprzez port, nie sposób nie wspomnieć a wręcz opisać  nieocenioną instrukcję DEBUG. W dowolnym miejscu kodu możemy po wyrażeniu Debug umieścić nie dość że zmienną, to także od razu jej opis i podczas pracy programu zostanie ona do nas tak wysłana. Można dla przykładu napisać „Debug „Tutaj X wynosi=”;X” i w terminalu zobaczymy tak opisaną wartość X w danym momencie. Śmiem podejrzewać że bez Debug jeszcze byłbym „w lesie”.

Wszystkie „opisy dla zmiennych” zajmują jednak pamięć programu, bo muszą być przecież zapisane w pamięci Flash. Jedna instrukcja umieszczona w nagłówku kodu „Debug Off” powoduje, że kompilator sam usunie niepotrzebne już dane. Tym sposobem kod pozostaje mniejszy , ale w kluczowych dla programisty miejscach komendy do debugu pozostają w listingu i można je powtórnie uruchomić jedną tyko zmianą w nagłówku.

Hardware sterownika to karta SD podłączona pod sprzętowe SPI, podświetlanie podłączone jest przez MOSFET, który akurat miałem pod ręką. Sterownik obsługuje też pin wyciszający. Teraz ten pin odcina głośnik, ale przy innym wzmacniaczu podłączyłbym tam Mute. Jako wzmacniacz wykorzystałem LM386, a w układzie mikrofonu JRC4558D. Jeśli chodzi o układ mikrofonu należy wspomnieć o preemfazie w nim przeprowadzanej. Polega to na tym, że pomiędzy mikrofonem a wzmacniaczem operacyjnym znajduje się filtr górnoprzepustowy. Słowa zaczynające się od takich głosek jak S lub H są cichsze. Taki filtr tłumi niskie tony, a pozwala przejść wysokim. Powoduje to wzmocnienie tych cichych fragmentów słów. Układów mikrofonu testowałem kilka i jeszcze nie skończyłem. Najlepsze efekty daje jak dotychczas mikrofon z zestawu telefonu komórkowego i wspomniany układ  JRC4558D.

Układ prototypowy zbudowany jest na elementach przewlekanych, ale zamysłem jest zaprojektowanie płytki z elementami SMD.

Miałem taki wyświetlacz więc go użyłem. Dostosowanie kodu nawet do wyświetlacza alfanumerycznego i wyświetlanie dużych znaków na nim w Bascom to naprawdę moment.

Znajomość każdego innego języka zawsze jest plusem. Rozumiejąc kod napisany w innym środowisku jesteśmy w stanie napisać kod obsługujący jakiś układ i dalej pisać w Bascom. Ostatnio jednak widziałem, że to moje kody napisane w Bascom były tłumaczone na C.

Życzę wszystkim ciekawych pomysłów, ja mam jeszcze kilka 🙂

BARTek

 

Programy Font File Maker i ArrayEnigma można pobrać na stronie http://bart-projects.cba.pl/

Do pobrania

O autorze