

Tiny Gad A- żegnajcie nudne wyświetlacze

Prawie luxomierz na ATTINY13
Nie da się ukryć, że z pewnych kontrowersyjnych

Tym razem postanowiłem odpowiedzieć na pytanie, czy można na 1kB pamięci programu zbudować jakikolwiek system umożliwiający podawanie zmierzonej wartości w sposób „audio słowny”.
Ponieważ w tym samym czasie kończę projekt odtwarzacza plików wave na MEGA88, postanowiłem, że dla relaksu spróbuję przenieść część kodu na tego malucha. Ponieważ debugging ATTINY13, bez DW jest nieco utrudniony, dobrze się złożyło, że najbardziej czasochłonne fragmenty obsługi SD były już gotowe, i nie trzeba było go tracić na pisanie niezawodnych procedur obsługi protokołu SD spi do którego nawiasem mówiąc dokumentacja dostępna w internecie wydaje mi się lekko „upośledzona” zapewne z powodu 'simplified' . Bo jak wyjaśnić, że kartę SD w tryb SPI można zainicjować bez zmian stanu CS, i może on spokojnie przez cały czas pracy karty pozostać połączony do masy nawet podczas startu? W dokumentacji nic nie pisze żeby było to możliwe, a jednak. Wracając do mini systemu syntezy mowy

W tym miejscu wspomnę, iż najpierw próbowałem połączyć przetwornik z wejściem CLK karty, lecz okazało się, że to wyprowadzenie dalekie jest od stanu wysokiej impedancji. Na szczęście wyprowadzenie DI nie ma takiego problemu, i można prawie bezkarnie podawać na ten port napięcie do zmierzenia (0-1V). Wyprowadzenie CLK natomiast oprócz komunikacji z kartą posłużyło również, do sterowania tranzystorem załączającym zasilanie. Ponieważ z gadających mierników, za najbardziej przydatny uznałem światłomierz, na płytce znajduje się specjalizowany układ przetwornik natężenia światła na napięcie z logarytmiczną zależnością na wyjściu. Jeżeli uda mi się pożyczyć luxomierz, to uzupełnię program o przeliczanie surowego napięcia na luxy, oraz wykonam kalibrację dzielnika napięcia/prądu z czujnika światła (czynność niezbędna również ze względu na rozrzut parametrów napięcia odniesienia attiny13). W tym momencie urządzenie podaje słownie wartość zmierzoną przez ADC (wartość podawana jest w miliwoltach), która teoretycznie wynosi w przybliżeniu 220 miliwoltów dla 10lux, 1100mV - 100klux. Oczywiście zamiast czujnika oświetlenia, po małym przystosowaniu można mierzyć doprowadzone napięcie i cieszyć się gadającym woltomierzem, amperomierzem itp.

Słów parę o programie:
Starałem się by był jak najmniejszy, jednak jestem pewien, że to nie szczyt możliwości minimalizacji rozmiaru kodu. Na ten moment pozostaje ponad 200B wolnego miejsca, co powinno zupełności wystarczyć do dopisania w przyszłości dodatkowych funkcjonalności. Po rozpoczęciu programu procesor mierzy najpierw napięcie przez ADC, następnie wykonywana jest inicjalizacja karty, na koniec wykonywany jest program zamieniający liczbę word na słowo mówione. Tutaj przybliżę nieco jak to jest rozwiązane i jakie mamy do dyspozycji próbki w pamięci flash karty.
Posiadając teoretycznie nieograniczoną pamięć danych, zależy na jak najmniejszym obciążeniu pamięci rom procesora. Najkorzystniej było by umieścić wszystkie wartości słów odpowiadające liczbą, jako pojedyncze frazy tekstu. Niewątpliwą zaletą takiego rozwiązania była by prostota programu procesora oraz perfekcyjnie naturalna dykcja komunikatów wynikająca z braku składania pojedynczych słów- liczb z mniejszych części. Wiąże się to jednak z niedogodności w postaci dużej ilości zajętej pamięci na karcie (zakładając 128kB na komunikat 65535x128kB = ponad 8GB ! Danych dla 16bitowych sampli w SR 32kHz). Należało więc pójść na kompromis, więc użyłem 100 komunikatów o wartościach 0-99, 9 komunikatów o setkach (100-900), oraz 10 o tysiącach (1000-10000). Program w obecnej postaci nie może generować komunikatów >1023. Na przygotowanym obrazie karty SD ostatni komunikat to 10000 (obraz zostanie uzupełniony do 100000 jeśli luxomierz będzie miał taki zakres). Tak przygotowane etykiety nie zajmą więcej niż 32MB.
O formacie i odtwarzaniu danych:
Program odtwarzający dźwięk mimo deficytu zasobów posiada 32 bajtowy bufor próbek, który umożliwia poprawę jakości dźwięku (jak wynika z badań najbardziej jest to uciążliwe dla powolnych kart gdzie każde zaadresowanie kolejnego bloku danych wiąże się z opóźnieniem). Program zawsze najpierw buforuje dane, dopiero po zapełnieniu bufora jest uruchamiana procedura zamieniająca bajty na sample wysyłane do pwm-a. Format danych jak dla normalnych plików WAVE czyli intel najpierw LSB. Na zegarze procesora 16MHz można odtwarzać 16 bitowe sample o SR max 64kHz. Jednak ze względów praktycznych program używa samplowania 32kHz ( w takim formacie są zapisane próbki na karcie SD)
Słów parę o zamianie słowo na słowo:
Program bierze liczbę word i sprawdza czy jest ona większa od 1000, jeśli tak to odejmuje od niej ten tysiąc równocześnie zwiększając licznik, który wskaże miejsce sampla do odtworzenia z pamięci karty. Następnie sprawdza czy liczba tysięcy osiągnęła zero, jeśli nie odejmuje znowu 1000 i tak w kółko. (jeśli na starcie brak tysięcy licznik=0, program nie odtwarza żadnego słowa tysięcy). Następnie w ten sam sposób jest wskazywana etykieta z setkami. Liczby 0-99 są przeliczane nieco prościej, od razu mnożony jest offset komunikatu przez pozostałą wartość liczbowa 0-99. Oczywiście we wszystkich przypadkach ważny jest początkowy adres bloku karty dla danego zestawu etykiet. Taki sposób wydał mi się najbardziej efektywny jeśli zależy nam na rozmiarze kodu (jeśli ktoś zna lepszy proszę podać). Program rozpoznaje koniec komunikatu sprawdzając ilość próbek o wartości zerowej. Zwalnia to nas z zaopatrywania każdej etykiety słownej na końcu o specjalny znacznik końca. (W źródle programu znajduje się dokładniejsza mapa adresów gdzie jakie sample powinny się znajdować). Po odtworzeniu 1 2 lub 3 etykiet (jeśli liczba >999) program zatrzymuje się i zasilanie systemu zostaje odłączone. Następuje oczekiwanie na kolejne „wybudzenie”, co praktycznie oznacza podanie napięcia zasilania za pomocą włącznika.
Na zakończenie wspomnę, iż szczególną uwagę położyłem na niezawodność działania i takie napisanie kodu, aby niemożliwe było zawieszenie jego działania bez względu na okoliczności. Oczywiście bez watchdoga i BOD nic by nie dały najwymyślniejsze zabiegi programowe.
W praktyce można balansować napięciem zasilania, wyjmować i wkładać kartę, i nic niekorzystnego nie powinno nastąpić (mnie się nie udało powiesić procesora w ten sposób /nawet jeśli karta SD ulegnie zawieszeniu, to procesor po prostu po kilku nieudanych próbach inicjalizacji odłączy zasilanie/).
Możliwości modyfikacji:
Jak widać na schemacie lubię eksperymenty i niekonwencjonalne rozwiązania. Stąd min zastosowanie wzmacniacza słuchawkowego w klasie AB jako bufora kluczowanego sygnałem PWM o częstotliwości 64kHz pracujący w klasie D, było to również wynikiem braku komplementarnych mosfetów o niskim rdson, bo w taki sposób (4 tranzystory w mostek) należałoby to rozwiązać bardziej elegancko

Jeśli ktoś chciałby skorzystać z 16 bitowej rozdzielczości i lepszej jakości odtwarzania, to należy podać zewnętrzny sygnał zegara (20-25MHz), zrezygnować ze wzmacniacza w cyfrowej klasie i użyć każdego pwma osobno dla LSB oraz MSB (wymagana niewielka zmiana w programie+ wykorzystanie dodatkowego portu). Więcej na ten temat w następnym odcinku.
Sample do „syntezera” wyeksportowałem z expressivo. (Gdybym miał lepszy głos nagrałbym swoje o wiele lepszej jakości – na samplach z expressivo słychać różne śmieci np. klikanie klawiatury – patrz sampel liczby „24,50” ).
A może jesteś chętny do użyczenia swojego głosu (głos kobiecy byłby bardziej pożądany ze względu na zakres pracy miniaturowego głośnika)? Jeśli ktoś chce mieć inny głos, nic nie stoi na przeszkodzie. Rozlokowanie ponad 100 sampli na karcie SD zajmuje ponad godzinę, nagranie ich pewnie drugą. Jeszcze nawiązując do obrazu karty. Program nie obsługuje żadnego systemu plików i dane są zapisane „na surowo” w odpowiednich sektorach. Nie należy się przejmować, że karta po zapisaniu obrazu na komputerze będzie „pusta” bez żadnego pliku, po prostu domyślnie jest sformatowana w fat16 w trybie dysku FDD (popularne programy do edycji sektorów wyświetlają taką partycję w całości od bloku zerowego).
Mimo iż ATTINY nie jest zasilany napięciem stabilizowanym, jego napięcie odniesienia jest wystarczająco stabilne do poprawnego działania ADC z 10 bitową rozdzielczością. Również SFH5711 nie przeszkadzają zmiany napięcia zasilania- na wyjściu daje stabilny prąd, który odkłada się w postaci napięcia na rezystorze. Napięcie zasilania układów powinno wynosić ~3V. Poniżej 2.5V układ zaczyna mieć problemy z działaniem, przekraczanie 4V nie jest zalecane ze względu na możliwość uszkodzenia karty SD. Układ można z powodzeniem zasilać z akumulatora li-io. (jeśli ktoś nie lęka się o kartę przy pełnym ogniwie). Średni pobór prądu w stanie aktywnym 30 – 100mA zależnie od amplitudy dźwięku. Wyłączony <100nA (prąd upływu mosfeta).
W załącznikach znajdują się schemat .sch oraz płytka .brd (eagle), źródło programu w asemblerze .asm, oraz obraz .img, który trzeba zapisać na kartę od sektora 0 dowolnym programem umożliwiającym zapis obrazu bloków na dysk. Przed zapisem obrazu może być konieczne wcześniejsze sformatowanie karty w formacie 'USB-FDD mode', stąd dołączony bootice.exe
Życzę wszystkim zainteresowanym przyjemnego i udanego budowania miniaturowych gadających mierników, pozytywek dzwonków drzwiowych i innych zabawek.
Boberov 2013
Przepraszam za słabą jakość audio
Cool? Ranking DIY