Spis treści
Ogólne
Schemat oraz płytka drukowana układu zostały zaprojektowane w programach ExpressSCH i ExpressPCB.
Główne elementy:
- Mikrokontroler AVR ATmega328P-PU taktowany rezonatorem kwarcowym 3.2768 MHz
- Moduł RTC DS3231 do precyzyjnego odmierzania czasu. Jest umieszczony na nim akumulator LIR2032 podtrzymujący odmierzanie czasu w razie zaniku zasilania.
- Wyświetlacz LCD 16x2 zgodny ze sterownikiem HD44780
- Odbiornik DCF77 oparty na układzie MAS6180B wraz z anteną ferrytową
- Moduł kart microSD z buforem LVC125A oraz stabilizatorem 3.3V
- Przekaźnik 5V typu NT73 do sterowania instalacją dzwonka w szkole
Układ jest zasilany napięciem 5V poprzez gniazdo USB (linie transmisyjne D+ i D- nie są nigdzie podłączone). Cały układ pobiera maksymalnie 100 mA prądu, przy wyłączonym przekaźniku około 50 mA.
Demontaż urządzenia
- Odkręcić 4 wkręty trzymających oba panele ze sobą. Znajdują się one w nóżkach na tylnim panelu w rogach obudowy.
- Podnieść lekko przedni panel do góry, a następnie usunąć prawy panel.
- Odłączyć wtyczkę diody (2 pin) oraz wyświetlacza (16 pin).
- Odkręcić nakrętki na przyciskach na przednim panelu a następnie wypchnąć je do środka.
- W tej chwili przedni panel wraz ze wszystkimi peryferiami jest oddzielony od tylnego.
- Aby wyjąć antenę, płytkę z układem lub wyświetlacz należy odkręcić odpowiednie śruby mocujące.
Oprogramowanie (firmware)
Struktura
Kod jest podzielony na oddzielne moduły które są odpowiedzialne za poszczególne funkcje dzwonka:
-
device - obsługa urządzeń
-
sdcard - obsługa karty pamięci
- hardwareConfig.h / asmfunc.S - programowa obsługa interfejsu SPI do komunikacji z kartą pamięci
- diskio.h / mmc.c - inicjalizacja, odczyt oraz zapis karty pamięci
- pff.h / pff.c / pffconf.h / integer.h - biblioteka Petit FatFs do obsługi systemu plików
- dcf77.h / dcf77.c - obsługa odbiornika DCF77 oraz dekodowanie danych
- ds3231.h / ds3231.c - obsługa modułu RTC DS3231
- hd44780.h / hd44780.c - obsługa wyświetlacza LCD HD44780
- i2c.h / i2c.c - sprzętowa obsługa protokołu I2C
- menu - katalog zawiera implementację poszczególnych menu
- clock.h / clock.c - odczytywanie czasu z modułu RTC DS3231, automatyczna zmiana czasu oraz synchronizacja z DCF77
- common.h / common.c - funkcje, które nie należą do żadnego modułu
- controller.h / controller.c - kontrolowanie przekaźnika dzwonka oraz pobieranie i zapisywanie ustawień głównych (settings_t)
- customChars.h / customChars.c - niestandardowe znaki wyświetlacza
- interface.h / interface.c - zarządzanie interfejsem użytkownika oraz obsługa menu
- internalStorage.h / internalStorage.c - odczyt i zapis do pamięci EEPROM, przywracanie domyślnych ustawień
- strings.c / strings.h - teksty
- main.c - inicjalizacja układu, pętla główna, główny licznik
Kompilacja
Wymagania:
Należy upewnić się, że wtyczka AVR plugin ma poprawnie skonfigurowane ścieżki, a następnie otworzyć workspace (z katalogu firmware) i zbudować projekt.
Fuse bity
- Low: 0xF7
- High: 0xD1
- Extended: 0x07
Aktualizacja
Aktualizację oprogramowania można dokonać używając programu avrdude oraz dowolnego programatora ISP (np. USBasp) poprzez gniazdo znajdujące się na płytce w środku obudowy.
W sekcji demontaż przedstawione jest w jaki sposób się do niego dostać.
Struktura pamięci EEPROM
Ogólne
Pamięć ma wielkość 1024 bajtów i jest w niej zawarta konfiguracja urządzenia. Wszystkie zmienne zajmujące więcej niż 1 bajt przechowywane są w formacie little-endian.
W opisie wykorzystane są definicje struktur w języku C oraz standardowe typy danych z nagłówka stdint.h. Jeżeli liczba jest poprzedzona przez 0x to oznacza, że jest zapisana w systemie heksadecymalnym.
Pamięć jest podzielona na następujące struktury:
- metadata_t - rozmiar 0x8 bajtów
- settings_t - rozmiar 0x40 bajtów
- profile_t - rozmiar 0x70 bajtów
- month_t - rozmiar 0x28 bajtów
Rozmieszczenie struktur w pamięci:
Adres |
0x0 |
0x8 |
0x48 |
0x48 + n * 0x70 |
0x198 |
0x208 |
0x208 + n * 0x28 |
0x3C0 |
0x3E8 |
0x400 |
Struktura |
metadata_t |
settings_t |
profile_t (0) |
profile_t (n) |
profle_t (3) |
month_t (0) |
month_t (n) |
month_t (11) |
nieużywane - pozostawić 0xFF (0x18 bajtów) |
Wpisanie nieprawidłowych wartości do jakiejkolwiek struktury może spowodować niezdefiniowane zachowanie układu dzwonka. System po otrzymaniu pliku z konfiguracją nie sprawdza jej i traktuje wszystkie dane jako poprawne.
W polach nieużywanych lub zarezerwowanych (reserved) należy pozostawić wartość 0xFF.
Lista profili:
- profile_t (0) - Normalne
- profile_t (1) - Skrócone
- profile_t (2) - Inne 1
- profile_t (3) - Inne 2
Lista miesięcy:
- month_t (0) - Styczeń
- month_t (1) - Luty
- month_t (2) - Marzec
- month_t (3) - Kwiecień
- month_t (4) - Maj
- month_t (5) - Czerwiec
- month_t (6) - Lipiec
- month_t (7) - Sierpień
- month_t (8) - Wrzesień
- month_t (9) - Październik
- month_t (10) - Listopad
- month_t (11) - Grudzień
Opisy struktur
typedef struct
{
uint16_t checksum;
uint8_t reserved[0x6]; // = 0xFF
} metadata_t;
- checksum - musi być równe 0x14D4 (wartość losowa), jeśli inne to urządzenie przywraca ustawienia fabryczne, a następnie ustawia tą wartość
settings_t
typedef struct
{
uint8_t bellLengthForLesson;
uint8_t bellLengthForBreak;
uint8_t schoolYear;
uint8_t autoTimeTransition;
uint16_t dcf77SynchronizationTime;
uint16_t dcf77SynchronizationMaxLength;
uint8_t reserved[0x38]; // = 0xFF
} settings_t;
- bellLengthForLesson - długość dzwonka na lekcję w sekundach
- bellLengthForBreak - długość dzwonka na przerwę w sekundach
- schoolYear - obecny rok szkolny, należy dodać 1900 aby otrzymać prawidłowy wynik. Np. dla roku szkolnego 2015/2016 wartość schoolYear powinna wynosić 115
- autoTimeTransition - automatyczna zmiana czasu z letniego na zimowy i na odwrót. 1 - włączone, 0 - wyłączone
- dcf77SynchronizationTime - <0; 1440) minuta doby w której rozpocząć synchronizację. 0xFFFF oznacza wyłączenie synchronizacji
- dcf77SynchronizationMaxLength - <1; 1440> maksymalna długość prób synchronizacji w minutach
profile_t
#define PROFILE_BELLS_COUNT 40
typedef struct
{
uint8_t count;
uint16_t bells[PROFILE_BELLS_COUNT];
uint64_t bellTypes; // bit mask, 0 - for lesson, 1 - for break
uint8_t reserved[0x17]; // = 0xFF
} profile_t;
- count - liczba aktywnych godzin dzwonienia
- bells[n] - 0 ≤ n < count oraz 0 ≤ bells[n] < 1440 - n-ta godzina dzwonienia. Wartość wskazuje na minutę doby w której powinien zadzwonić dzwonek (godzina * 60 + minuta). Wartości w tablicy muszą być uporządkowane rosnąco i nie mogą się powtarzać ani przekroczyć 1439 (23:59)
- bellTypes - maska bitowa dla rodzaju dzwonka dla poszczególnych godzin dzwonienia. n-ty bit oznacza rodzaj dzwonka dla n-tej godziny dzwonienia. 0 - dzwonek na lekcję, 1 - dzwonek na przerwę
month_t
typedef struct
{
uint8_t days[32];
uint8_t reserved[0x8]; // = 0xFF
} month_t;
- days[n] - n = dzień miesiąca - profil aktywny w n-ty dzień miesiąca. Wartość wskazuje który profil powinien być aktywny lub 0xFF jeżeli dzwonki mają być w ten dzień nieaktywne. Pierwszy element (0) nigdy nie jest używany (nie ma dnia numer 0, pozostawione w celu uproszczenia kodu oprogramowania dzwonka)
Przenoszenie pliku konfiguracyjnego na urządzenie
Poprzez kartę microSD
- Sformatuj kartę pamięci używając systemu plików FAT32 jeśli jest inny.
- Skopiuj plik konfiguracyjny do głównego katalogu na karcie pamięci i zmień jego nazwę i rozszerzenie na dzwonek.2lo.
- Włóż kartę pamięci do urządzenia i z menu głównego wybierz opcję "Zarządzaj ustawieniami" a następnie "Odczytaj z karty SD". Układ odczyta i zweryfikuje integralność danych, a następnie gdy wyświetli komunikat o pomyślnym załadowaniu konfiguracji wciśnij dowolny klawisz, aby go uruchomić ponownie.
Poprzez programator ISP
- Podłącz programator do komputera oraz układu za pomocą gniazda ISP znajdującego się na płytce.
- Za pomocą programu avrdude wgraj plik pamięci EEPROM następującym poleceniem (w miejsce programator wstaw swój model programatora, a w miejsce dane nazwę pliku z konfiguracją):
avrdude -p m328p -c programator -U eeprom:w:dane:r
np. dla programatora USBasp i pliku z danymi o nazwie dzwonek.2lo polecenie będzie wyglądało tak:
avrdude -p m328p -c usbasp -U eeprom:w:dzwonek.2lo:r