micro:bit:zegarek:binarny

micro:bit:zegarek:binarny

Świat nie kończy się na Arduino i Raspberry Pi. W sprzedaży znajdziecie wiele podobnych płytek. Fakt, chyba żadna z nich nie ma takiego wsparcia społeczności jak te dwie. Ale micro:bit zasługuje na szczególną uwagę. W ramach ogólnokrajowej akcji, każdy uczeń w Wielkiej Brytanii dostał za darmo zestaw z micro:bit. Idea była prosta: wzbudzić zainteresowanie nowymi technologiami. Jeżeli choć część z obdarowanych uczniów złapie „bakcyla” – biorąc pod uwagę rozmach akcji – istnieje całkiem realna szansa na pozyskanie w niedalekiej przyszłości całkiem pokaźniej kadry inżynierów… A tych każda współczesna gospodarka potrzebuje jak kredytów.

Od połowy 2016 roku moduł można również nabyć komercyjnie.

Wbrew “zabawkowemu” wyglądowi – micro:bit można wykorzystać na wiele sposobów. Tutaj pokażę, jak na jego podstawie zbudować zegarek. Więcej o micro:bit znajdziecie na moim blogu: “Elektronika bez Spięcia”.

Najlepiej zacząć od potrzeby. Po remoncie okazało się, że w pokoju… nie ma żadnego zegarka:) Pokój otrzymał dość nowoczesny wystrój.  Nic okrągłego czy tradycyjnego nie pasowało… micro:bit wyposażono w pole 5×5 diod – czy da radę na tym wyświetlić godziny, minuty?

Oczywiście można przewijać czas, ale to niezbyt czytelne. Analogowy zegar (ze wskazówkami) nie wyglądał zbytnio wyraźnie. Dlatego postanowiłem skonstruować… zegar binarny:) Ale po kolei.

Pomysł

Zbuduję zegar binarny. Zegar zasilę z baterii AA. Godzinę i minutę wyświetlę na polu LED micro:bit. Zegar będzie działał w oparciu o źródło odniesienia czasu. W tej roli użyję ds1307 (RTC: real-time clock, zegar czasu rzeczywistego). RTC będzie posiadał niezależne zasilanie tak, aby w razie rozładowania baterii – nie stracił ustawień.

Godzinę i minuty wyświetlę binarnie.

Na czym to polega? Każdą cyfrę możemy zapisać w systemie dwójkowym. Przyjmiemy 5 bitów – czyli tyle, ile w każdej kolumnie pola led mamy rzędów. Wtedy:

Liczba Zapisana
w systemie dziesiętnym
Liczba zapisana w
systemie binarnym
0  00000
1  00001
2  00010
3  00011
4  00100
5  00101
6  00110
7  00111
8  01000
9  01001

Jak widzicie, wystarczą nam 4 rzędy (4 bity) – piąty nie jest już potrzebny.

4 kolumny będą mi potrzebne, żeby pokazać godzinę (2 cyfry) i minuty (2 cyfry). Środkowa kolumna wyświetli migający dwukropek, co pomoże w oddzieleniu godzin i cyfr.

Dolny rząd użyję do pokazywania 10-tek sekund. 1 zapalona dioda – ponad 10 sekund, 4 zapalone – ponad 40 sekund. Łatwe? Już sprawdziłem – można się przyzwyczaić:)

Zegary RTC

Zegar czasu rzeczywistego (RTC – real time clock) dostarczy aktualną godzinę i minutę. O RTC takich jak ds1307 lub pcf8563 – pisałem ostatnio kilka razy. Warto przeczytać:

Zwłaszcza drugi tekst tu się przyda. Wiele mówi o i2c, która to wiedza będzie wykorzystywana poniżej.

ds1307 i pcf8563 komunikują się po szynie i2c. Obydwa wymagają podobnych peryferiów – kwarcu, kondensatora, rezystorów podciągających linie SDA i SCL. Obydwa mogą być wyposażone w dodatkowe baterie (lub kondensatory) podtrzymujące pracę, gdy wyłączone jest zasilanie. Łatwiejszy do aplikacji jest pcf8563. Działa on z napięciami od 1v. DS1307 wymaga napięcia 4.5 do 5.5v – czyli powyżej maksymalnego poziomu zasilania micro:bit. To pewna komplikacja, bo będę musiał znaleźć takie napięcie zasilania – oraz dopasować poziomy logiki między wszystkimi układami. Z pcf byłoby łatwiej bo może działać w takim samym zakresie napięć jak micro:bit.

Niestety po przeszukaniu sieci znalazłem przykładowy kod jedynie dla ds1307. I to w pythonie. Jest też specjalny bloczek ds1307 znalazłem też dla JavaScript, na razie w wersji beta – spróbuję go użyć następnym razem.

Zegar RTC DS1307

Więcej szczegółów na temat ds1307 znajdziecie w tekście: ds1307 – podłączenie do Arduino.

W skrócie:

  • GND podłączcie do masy,
  • Vcc podłączcie do zasilania – 4.5 do 5v,
  • Miedzy X1 i X2 podłączcie kwarc 32k,
  • Kwarc podłączacie do masy przez kondensator 22pF,
  • Linie SCL i SDA to część szyny i2c – podciągnijcie je przez rezystory 10kΩ do zasilania,
  • Vbat podłączacie do “+” baterii cr2032.

5v z baterii AA

Zegar planuję zasilić z dwóch baterii AA – zwykłych paluszków. Dwa paluszki to około 3v, co idealnie nadaje się do zasilania micro:bit. Niestety – ds1307 wymaga zasilania z zakresu 4.5…5.5v. Powstaje więc problem: jak ‘wydusić’ z paluszków 5v?

Układy konwertujące napięcie niższe na wyższe nazywane są popularnie przetwornicami step-up (w odróżnieniu do step-down, które zamieniają napięcie wyższe na niższe). Oczywiście nie ma nic za darmo. Przetworzenie kosztuje trochę mocy, co na pewno wpłynie na żywotność baterii.

W szufladzie znalazłem niewielką przetwornicę z portem USB. Dzięki niej można np. doładować telefon z bateryjki AA. Gniazdo USB nie było mi potrzebne – dodatkowo zajmowało trochę miejsca. Pozbyłem się go – a zamiast gniazda wlutowałem piny. W ten sposób będę mógł łatwo wpiąć przetwornicę do płytki.

Logika 5v, 3.3v (i i2c)?!

Normalnie łączenie układów posługujących się napięciem 5v (jak ds1307) i niższym (jak micro:bit) wymaga stosowania dodatkowych zabiegów dostosowujących poziomy logiki. Dla przykładu, port Raspberry Pi (3.3v) można łatwo uszkodzić, wysyłając do niego dane z Arduino – które jest 5v. Z drugiej strony – Arduino “powinno” zrozumieć impulsy z Raspberry – dlatego, że poziomy “1” z Raspberry i Arduino “zazębiają” się.

Jeżeli spojrzycie na dokumentację ds1307, zobaczycie, że dla niego logiczna “1” zaczyna się od 2.2v. Biorąc pod uwagę, że dwie AA, którymi chcę zasilić micro:bit, produkują 3v – margines wydaje się wystarczający. 2.2v na dwie AA daje po 1.1v na ogniwo – co może być uznane za prawie martwą baterię. Pamiętajcie, że w miarę wyczerpywania AA, ich napięcie niewiele spada – aż do “załamania” się przy pewnej wartości

Dodatkowo, micro:bit i ds1307 będą połączone poprzez szynę i2c. Linie SDA/SCl szyny i2s podciąga się do zasilania. Ale jeżeli macie układy zasilane z różnych napięć, można je podciągnąć do niższego z nich. O ile poziomy logiki będą się zazębiać, komunikacja powinna się udać. Oczywiście jest tu pewne ryzyko, mogą wystąpić błędy w komunikacji. Takie sytuacje powinno się rozwiązywać za pomocą konwerterów. Ale tutaj – “1” zazębiają się na tyle, że warto spróbować.

Przykładowy kod

Kod obsługi, który znalazłem w sieci, pokazuje jak komunikować się z ds1307, odczytać datę (rtc_gettime()) i ją zapisać (rtc_settime()). Stanowił on podstawę dla mojego oprogramowania.

Kod napisano w micro python’ie – kolejnym języku, który możecie użyć do programowania micro:bit. Dla tych, którzy nigdy nie mieli nic wspólnego z pythonem: cóż, uważajcie na wcięcia:) W pythonie zastępują one grupowanie komend za pomocą nawiasów. To znaczy, poniższe jest poprawne i wypisze w pętli wartość zmiennej ‘i’ (od 1 do 9) oraz jej kwadratu (od 1 do 81):

A to poniżej – skończy sie błędem, bo “i” nie jest znane w ostatniej linijce:

Reszta to już składnia języka i metody biblioteki micro:bit.

Jeżeli chodzi o komunikację po i2c:

Metoda i2c.write() zapisze na szynę wartość “0” w kierunku urządzenia pod adresem RTC_ADDR. Wartość “0” wybierze adres w pamięci ds1307 (0, czyli rejestr sekund). Metoda i2c.read() odczyta 7 bajtów z urządzenia RTC_ADDR – czyli wszystkie dane związane z czasem.

Zmiany w kodzie

Przedstawiony powyżej kod jest wystarczający, żeby przeprowadzić podstawowe operacje na ds1307. Postanowiłem trochę go rozszerzyć. Przede wszystkim stworzyłem funkcje, które zapisują/odczytują dane z linii:

  • safeWritei2c(): zapisuje dane do i2c
  • safeReadi2c(): odczytuje dane z

W odróżnieniu do oryginalnego kodu, moje funkcje “chronią” się przed wystąpieniem możliwych błędów. Jeżeli transmisja nie powiedzie się, próbują jeszcze raz – maksymalnie IO_RETRY razy. Jeżeli po tylu próbach dalej nie można uzyskać poprawnej wartości, funkcje zwracają błąd COMM_ERR – oznaczający błąd komunikacji.

Wyizolowanie kodu do wysyłania/odbierania wpłynie na funkcje rtc_settime() i rtc_gettime():

Pozostały kod rozszerzyłem o analizę wartości zwracanych przez te funkcje. Umożliwia to obsługę sytuacji związanych z niemożnością skontaktowania się z ds1307.

Kolejną modyfikacją było dodanie funkcji rtc_isrunning(). Znacie ją z implementacji biblioteki RTClib dla Arduino.

Mając taką funkcję, będę wiedział, czy przy starcie powinienem ustawić czas na nowszy – czy może czas zapamiętany w czipie była wcześniej ustawiony przez użytkownika.

Kolejne modyfikacje dotyczyły:

  • Klawisz A: wyświetla datę w formacie cyfrowym,
  • Klawisz B: wprowadza w tryb ustawiania czasu.

Ostatnie funkcja setTime() umożliwia ustawienie czasu na wyświetlaczu LED – co w oryginalnym kodzie było zaszyte na stałe. W trybie ustawiania daty:

  • Klawisz A: zmiana wartości o 1,
  • Klawisz B: przełączanie między godzinami (‘hh’), minutami (‘mm”) i przed południem/po południu (am/pm),
  • Godziny ustawiane są w zakresie 0…12,
  • Minuty ustawiane są w zakresie 0…59,
  • Przełączanie na pm zwiększa godziny o 12 (zegarek domyślnie wyświetla godziny w formacie 24 godzinnym),
  • Przytrzymaj B i przytrzymaj A żeby zapamiętać ustawioną datę i powrócić do trybu wyświetlania czasu.

Pełny kod:

Schemat

Nie ma co kombinować – typowa aplikacja z instrukcji do ds1307:

RPU to rezystory 10kΩ. Crystal to kwarc 32k. Dodatko podłączyłem go do masy przez kondensator 18pF. Zwróćcie uwagę na pin Vbat – tam podepnę baterię cr2032.

Budowa

Płytka

Złącza micro:bit wyprowadzono na krawędź płytki. Niestety nie przewidziano tu pinów, jedynie styki. SDA/SCL znajdują się miedzy masą GND i zasilaniem 3v (odpowiednio 20 i 19). Żeby dobrać się do nich, trzeba użyć specjalnego złącza krawedziowego:

Zauważcie, że tylko 2 rzędy niższych styków są podłączone. Styki rozmieszczone są co standardowe 2.54mm – ale rzędy przesunięto wzgledem siebie. Mimo to złącze dobrze pasuje do standardowej płytki 5×7.

Oczywiście mogłem użyć mniejszej płytki, ale potrzebuję miejsca dla dodatkowych eksperymentów.

Na płytce umieściłem kolejne elementy. Zacząłem od gniazda na wtyczkę baterii i wyłącznika:

Teraz wlutowałem złącze dla przetwornicy:

Układ ds1307 umieściłem na podstawce:

Na koniec dolutowałem baterię podtrzymująca zegar w wypadku braku zasilania. Niestety  nie miałem pod ręką podstawki, zrobiłem to trochę domowym sposobem – z resztek taśmy od gold pinów:

Obudowa

Zegarek potrzebował obudowy. Zrobiłem ją z odpadów sklejki 3mm. Część obudowy jest zdejmowana tak, żeby można było latwo wymienić baterie lub wyjąć całość i przerobić płytkę.

Do budowy wystarczy właściwie piłka reczna, kilka pilników i klej wikolowy. Oczywiście dużo łatwiej będzie, jeżeli dysponujecie piłą stołową, mini szlifierką itp. – ale przy odrobinie chęci można się bez nich obejść.

Podsumowanie

Jak widzicie, mimo ‘zabawkowego’ wyglądu, na podstawie micro:bit można budować nowe urządzenia nie gorzej niż w przypadku Arduino. Zamiast bloczków JavaScript można użyć pythona, który oferuje znacznie większe możliwości. Niestety wymaga też większej ‘biegłości’ w programowaniu.

Kolejną zaletą micro:bit jest niskie napięcie zasilania. Tu wystarczyły dwa paluszki AA. W urządzeniach wbudowanych, gdzie mamy zazwyczaj niewiele miejsca w obudowie, może być to dużą zaletą. Z drugiej strony – czasami do zintegrowania całości – konieczne są dodatkowe zabiegi (np. dopasowanie poziomów napięć logiki).

Zegarek działa już ponad tydzień. Prawie przyzwyczaiłem się do odczytywania z niego czasu. Chociaż niektórzy znajomi… wolą spojrzeć na komórkę…:)

Źródła

Ocena: 5/5 (głosów: 5)

Podobne posty

2 komentarzy do “micro:bit:zegarek:binarny

  • Tak. Fajne. Nawet bardzo.
    Ale dostałbym szału próbując ustalić godzinę w nocy po przebudzeniu. Albo po użyciu napojów rozweselających.
    Zajebistość 10, użyteczność 1.

    Odpowiedz
    • Pomyśl tak: odczytasz godzinę – możesz jechać, nie odczytasz – kluczyki zostają w domu:)
      Pozdrawiam,
      A
      PS. Warstwę prezentacji można łatwo zmienić:) Nawet zachęcam:) Mi chodziło o same możliwości zastosowania micro:bit:)

      Odpowiedz

Odpowiedz

anuluj

Masz uwagi?