Skocz do zawartości

Tablica liderów


Popularna zawartość

Pokazuje zawartość z najwyższą reputacją od 26.10.2019 we wszystkich miejscach

  1. 15 punktów
    Witam Elektroniką zajmuję się od dwóch miesięcy, kiedy to po raz pierwszy zaświeciłem diodą z kursu: FORBOT - podstawy elektroniki - zestaw elementów + kurs ON-LINE. Kurs tak mi się spodobał że ukończyłem go w dwa dni i kupiłem 4 kolejne: FORBOT - podstawy elektroniki 2 - zestaw elementów + kurs ON-LINE, FORBOT - technika cyfrowa - zestaw elementów + kurs ON-LINE, FORBOT - zestaw do nauki lutowania elementów THT oraz FORBOT - zestaw do kursu podstaw Arduino + gadżety i Box (wersja PLUS). Jak tylko je połknąłem pojawił mi się w głowie pomysł na pierwszy projekt którym chciałbym się Wami podzielić. Projekt został oparty o Arduino Pro Mini i jest to Szachownica która gra za mną w szachy Bardzo zależało mi żeby była to tradycyjna duża drewniana szachownica, którą będę się mógł cieszyć przez lata. Całość prezentuje się tak: Najpierw należało zacząć od wykrywania pozycji bierek. Do tego zdecydowałem się (być może nieco pochopnie) na użycie małego ładnego zgrabnego komponentu o nazwie sg-2bc. SG-2BC to nic innego jak dioda IR i fototranzystor w jednej małej (4mm średnicy) ceramicznej obudowie. Ma jednak jedną wadę w zastosowaniu do którego go potrzebowałem - jego fototranzystor jest bardzo wrażliwy na światło słoneczne. Musiałem więc odróżnić jakoś światło słoneczne od światła odbitego diody IR. Zaprojektowałem w tym celu prosty obwód oparty o ne555, który generuje sygnał PWM o częstotliwości około 32kHz i wypełnieniu 33%. Układ ten daje sygnał na diodę IR oraz sprawdza za pomocą 3 komparatorów (dwa lm393 - 2 komparatory na układ) i filtra RC czy odebrał sygnał o odpowiedniej charakterystyce po stronie fototranzystora (czyli na polu stoi bierka). Na wyjściu wystawia stan wysoki jeśli to mu się udało. W ten sposób powstał mój pierwszy w życiu projekt płytki drukowanej Oczywiście zdarzyło mi się wlutować jeden z komparatorów odwrotnie a potem to poprawiać. I tu uwaga do Forbota: w kursie lutowania brakuje informacji i praktyki w wylutowywaniu układów scalonych - na prawdę by się przydało! Jakoś to jednak poszło i efekt był taki: Z racji uśredniania na filtrze RC który jest częścią obwodu czas odpowiedzi na sygnał to 3ms. Oczywiście nie chciałem takiego obwodu powtarzać dla każdego testowanego pola szachownicy, zastosowałem więc multipleksowanie - obwód załączany jest tranzystorami kolejno do wszystkich czujników, co jak łatwo policzyć daje <200ms na zeskanowanie stanu szachownicy (uwzględniając szybkość I2C i czasy przełączania w praktyce są to 3 pełne skany na sekundę - wystarcza). Skoro już umiałem testować pojedyncze pole, nadszedł czas na zaprojektowanie płytek do samej szachownicy. Tu użyłem ekspandera wyprowadzeń MCP23017 oraz demultiplexera MC74HC154. Skoro i tak nie mogę testować więcej niż jednego pola na raz, demultiplexer zapewnił mi rozsądne wykorzystanie wyprowadzeń MCP23017 - dzięki temu wystarczył jeden ekspander na 16 pól szachownicy (każde ma jedną diodę świecącą i jeden czujnik wspomniany wczesniej SG-2BC). Prototyp tego rozwiązania wyglądał następująco: Projekt płytki pokrywającej 16 pól (przed ułożeniem ścieżek, wizualizacja ze ścieżkami, gotowe płytki): Na całą szachownicę użyłem 4 takich samych równolegle połączonych płytek: Czemu nie dwóch - po jednej na stronę szachownicy? Z tej oto przyczyny że darmowa licencja DIPTrace pozwala na 300 padów na płytkę Po polutowaniu i zmontowaniu całości otrzymałem taki oto efekt: W montażu najtrudniejsze okazało się jednoczesne wcelowanie 32-ma okrągłymi elementami w wywiercone otwory: Aby tego dokonać ułatwić płytki umieściłem na mosiężnych dystansach 1cm przyklejonych klejem na ciepło do wewnętrznej strony szachownicy, przewlokłem diody i czujniki przez płytkę, zakleilłem otwory w szachownicy od jej frontowej strony przezroczystą taśmą klejącą i manewrowałem cierpliwie elementami oraz samą płytkę aż wskoczyły na swoje miejsce. Dopiero wtedy płytkę przykręcałem a nóżki elementów lutowałem. Pozostało to oprogramować Jako że programuję od ponad 20 lat i do tej pory nie pisałem jeszcze enginu szachów, postanowiłem nie używać „cudzego” i napisać własny. Biorąc pod uwagę ograniczenia Arduino było to naprawdę fajnym wyzwaniem i zajęło mi około 2 tygodnie. Zaimplementowałem mini-max z przycinaniem alpha-beta i iteracyjnym pogłębianiem. Engine nie alokuje żadnej pamięci dynamicznie, a ze stosu bierze nie więcej niż 600B, co uważam za swój sukces. Ostatecznie wygrywa nie tylko ze mną (żaden ze mnie wybitny szachista), ale i z Stockfishem na poziomie 3, z czego jestem dumny Ostateczny kształt szachownicy w działaniu wygląda tak: Szachownica rozpoznaje ustawienie początkowe i sygnalizuje to spiralnym zaświeceniem wszystkich diod. Grę rozpoczynamy białymi lub sygnalizujemy szachownicy ze chcemy grać czarnymi poprzez podniesienie na chwile czarnego króla. Po podniesieniu bierki gracza, szachownica pokazuje dostępne pola na które figura ta może się ruszyć umieszczonymi w ich rogach diodami (mój niespełna 6-cio letni syn bardzo to docenia). Ruch szachownicy również sygnalizowany jest diodami i szachownica czeka aż zostanie wykonany. Dodatkowe dwie małe diody na krawędzi szachownicy sygnalizują po czyjej stronie jest ruch. Zdjęcie dwóch własnych bierek z szachownicy jest dla niej gestem do zapisania stanu gry do EEPROMU. Po tym można ją wyłączyć i wznowić grę np. za tydzień. Po włączeniu szachownica czyta stan z EEPROMU i czeka aż jeden ze stanów (początkowy lub zapisany) zostanie ustawiony na szachownicy. Jeśli nie była w tym czasie składana, a bierki nie były ściągane - grę można kontynuować natychmiast po włączeniu. Szachownicę można normalnie składać, niestety nie mieszczą się już do niej szachy Mam nadzieje mój pierwszy projekt się Wam spodobał, ja jeszcze wciąż się nim cieszę jak dziecko. Chciałbym przy tym podziękować Forbotowi za naprawdę świetne kursy które nie tylko dały mi niezbędną w realizacji wiedzę, ale też zainspirowały to zrobienia tejże zabawki. Pozdrawiam, Okjak
  2. 15 punktów
    Sprzedaż samodzielnie zbudowanego urządzenia może być kuszącą wizją dla wielu początkujących elektroników. Czy jeśli układ działa, to można go od razu zacząć sprzedawać, np. na Allegro? W tym miejscu warto jednak uświadomić sobie, że każdy producent elektroniki jest zobowiązany do przestrzegania różnych przepisów. [blog]https://forbot.pl/blog/skonstruowalem-sobie-budzik-z-wifi-a-co-z-ce-id41631[/blog]
  3. 13 punktów
    Witam chce wam przedstawić mojego pierwszego robota o nazwie LEM Od dłuższego czasu w moim domu leżały nieużywane moduły zdalnego sterowania do bram wjazdowych. Stwierdziłem, że jest to marnowanie ich potencjału, w mojej szkole miał odbyć się cykliczny konkurs mam talent gdzie uczniowie z całej szkoły pokazywali co potrafią. Ten projekt był pierwszym tego typu ''talentem'' w mojej szkole i wywołał nie małe zainteresowanie. Więc tak jak napisałem wyżej za rozum robota odpowiadał moduł 12 kanałowy z wbudowanymi przekaźnikami. Nie było to najlepsze rozwiązanie, ale chciałem wykorzystać to co mam. Planując możliwości robota uparłem się na gąsienice, nie chciałem montować kół, bardziej fascynowały mnie właśnie gąsienice. Te napędzane były przez dwie niezależne głowice od wkrętarek 12v dzięki czemu lem miał możliwość skręcania. Głowice zakończone zębatkami od przerzutek rowerowych zdawały się nie najlepiej ale wystarczająco dobrze dużo lepiej zdałyby egzamin np. takie silniki z przekładnią. Ramię robota zginane jest też za pomocą silników od wkrętarek z zamontowaną śrubą trapezową. Tak działały dwa zgięcia ''ręki'' natomiast sam chwytak działał przy pomocy osi z napędu dvd. Napęd ten był nietypowy ponieważ wykorzystywał silnik dc a nie silnik krokowy jak można to spotkać w większości napędów. Nie ukrywam, ułatwiło mi to zadanie. Najwięcej czasu zajęło mi zrobienie gąsienic skradają się one z 5 łańcuchów rowerowych. co drugi nit w łańcuchu musiałem wybić i zastąpić prętem m3 ręcznie dociętym na 6cm łącząc tym samym dwa łańcuchy równolegle. Pomiędzy nimi wsunąłem dystanse zrobione z rurek od namiotu, nadały się idealne! Następnie ze starej opony rowerowej powycinałem małe elementy które zostały przewiercone i przyczepione na trytytki. Pod spód mojej maszyny doczepiłem ledy wydobyte kosztem lampki nocnej ale można je kupić również oddzielnie w formie pasków LED. Jednak to nie jedyne oświetlenie lema z przodu posiada on dwa reflektory 10W. Są to nieco zmodyfikowane lampki rowerowe, rozebrałem obudowę lampki i włożyłem tam własne ogniwo led. Te grzało się tak bardzo, że niezbędne okazało się zamontowanie z tyłu radiatory chłodzące. na powyższym zdjęciu można zaobserwować rurę u dołu robota jest to niedopracowany odkurzacz działający na wentylatorze komputerowym, jednakże działało to dość słabo dlatego traktuje to bardziej jako ciekawostkę. Ciekawy może też być tył robota. Lem nosi na swoich barkach odznakę ZSRR i znak wysokiego napięcia. Kontroler to przerobiony pad do gier z wymienionymi przyciskami i doklejonym pilotem do ledów. Robot działał na 9 akumulatorach 18650 które działały znakomicie. Jeszcze parę bajeranckich przełączników dźwigniowych tego typu lub takich i robot gotowy! film z działania okazał się zbyt duży i nie mogłem go tutaj przesłać wiec wrzuciłem na yt i proszę bardzo wszystko działa! Dziękuje wszystkim za uwagę i chcę was zachęcić tym samym do budowy odważniejszych projektów. Ten robot był prosty w podłączaniu teraz uczę się języka Arduino mam nadzieję że przeczytacie tu jeszcze nie jeden artykuł mojego autorstwa!
  4. 12 punktów
    Trochę gorącego kleju i jazda! Takim stwierdzeniem kierowałem się podczas budowy tej drukarki. Pewnie sporo drukarzy 3D zbije mnie za to, ale już lecę z wyjaśnieniem . Od paru lat marzyła mi się drukarka 3D, chociażby do drukowania obudów do przyszłych projektów, ale również jako produkcja użytecznych rzeczy "na już" - no prawie, ponieważ drukowanie nie jest natychmiastowe. Niestety ze względu na to, że mam dość mały budżet i rodzice niezbyt byli przychylni do kolejnego sprzętu w domu oraz wierzyli w moją "twórczość", nie mogłem kupić firmowej sztuki. Dopiero jak po kilku miesiącach na discordzie znalazłem grupkę osób zajmująca się właśnie drukiem jak i samą elektroniką, postanowiłem się zabrać do roboty. Po kilku dniach przemyślania i projektowania wziąłem trzy napędy DVD i za pomocą kleju na gorąco złożyłem "coś co wytłaczało plastik i wiecznie się psuło". Szczątkowe zdjęcie "tego czegoś" wygrzebane z odmętów mojego dysku twardego. Jak w końcu się zepsuło w taki sposób, że straciłem chęci do dalszych zabaw w tym kierunku, dałem sobie spokój, ale nie na długo. Po dwóch tygodniach znowu zajrzałem i natknąłem się na technologię RepRap. Dla nie wiedzących polega to na tym, że części do nowej drukarki drukuje się na pierwotnej. Poszedłem więc do lokalnego sklepu budowlanego kupić części do budowy ramy. Dokładnie to: 3 Profile aluminiowe o przekroju kwadratowym 15mm dużo kątowników (sam już nie wiem ile ich nakupiłem) 3 profile aluminiowe o przekroju okrągłym 10mm (jako prowadnice) WIEM, WIEM budowanie drukarki na takich profilach i prowadnicach to grzech, ale DZIAŁA! Nie mając warsztatu, udałem się do dziadka, z pomocą którego udało mi się złożyć dolną część ramy. Naprawdę PRZEPRASZAM, ale to są zdjęcia archiwalne, więc stąd taka jakość. Przez całą budowę drukarki posługiwałem się tylko brzeszczotem, wiertarką no i gwintownikiem, choć tego ostatniego odradzam przy profilach aluminiowych, bo sam się na tym przejechałem i zerwałem dwa gwinty. Tak czy siak z pomocą kleju na gorąco i taśmy klejącej jakoś się udało. Tydzień później znowu przyszedłem do dziadka dokończyć budowę. Po kilku godzinach składania wyszła rama, która wymagała tylko zamontowania elementów i powinno działać. Silniki kupiłem na na popularnym serwisie aukcyjnym za skromne 8zł za sztukę. Działają, nie mam zarzutów, poza tym, że musiałem zdjąć oryginalne koła zębate i zeszlifować wał, aby zamontować koła GT2. Gdy tylko przyniosłem ramę do domu, zabrałem się za dalszą część montażu. Zamontowałem hotend, ekstruder, paski i wiele innych mniej lub bardziej przydatnych elementów. Gotowy sprzęt, który już działał i wymagał tylko kalibracji Na płytę główną Creality3D v1.1.4 (dokładnie ta co występuje w Enderze 3 lub CR-10) wgrałem oprogramowanie marlin, które wspiera dowolną zmianę sprzętową m.in. Serwomechanizmy, czujniki i wiele więcej. Niestety nie zamontowałem wyświetlacza ze względu na problemy sprzętowe, lecz jak będę wymieniać płytę główną zapewne go zamontuję, bo go posiadam. Po istotnych kalibracjach ze względu na kończące się próbki filamentu zakupione do starej drukarki, zakupiłem jednokilogramową szpulę filamentu. Parę dni później, gdy paczka do mnie dotarła, zacząłem drukować części, które zastąpią gorący klej. Były to głównie mocowania na łożyska, nowa karetka oraz nóżki. Zauważyłem dość sporą różnicę w jakości wydruków, co mnie jeszcze bardziej zmotywowało do dalszych ulepszeń. Po lewej spoiwo z kleju/Po prawej jego wydrukowany odpowiednik Na dzień dzisiejszy drukarka pracuje, postawiłem serwer druku na Raspberry Pi, nadal trwają nad nią prace, głównie konserwacyjne i drobne ulepszenia, lecz projekt uważam za zakończony. Bez problemu można drukować obudowy do projektów, ale też jakieś figurki. Obudowa do wzmacniacza gitarowego (nie będę opisywać, bo uważam go za zbyt niski poziom) Jak na powyższym zdjęciu widać, jedna szpula poszła na zepsute wydruki, wydruki kalibracyjne oraz jakieś zabawki. Dlatego warto zaopatrzyć się w 1kg filamentu jak buduje się tego typu drukarkę. W przyszłości mam zamiar zmienić malinkę prawdopodobnie na ESP8266. Zauważyłem też, że dzięki zbudowaniu takiego sprzętu nauczyłem się baardzo dużo w tym temacie. Morał z tego projektu jest taki: Staraj się nie robić gwintów w profilach aluminiowych - są mało wytrzymałe. jak kupujesz rurki aluminiowe na prowadnice w sklepie budowlanym to idź z suwmiarką, bo u mnie powodem luzów na karetce była zbyt mała średnica jednej z prowadnic. Nie kupuj najtańszej głowicy, bo jej jakość może być bardzo dyskusyjna. Gorący klej nie nadaje się do wszystkiego Warto robić projekty DIY Specjalne podziękowania kieruję do: Staszka, matika i wiele innych osób z discorda :3 Dziadka, który mi pomógł od strony planowania Leoneq'a, który mnie namówił, aby wstawić tu ten projekt ;3 Tak to wygląda na chwilę obecną Z góry przepraszam za ewentualne błędy językowe czy literówki, ale orłem z Polskiego nie jestem, więc proszę o wybaczenie. Naturalnie zapraszam do dyskusji w komentarzach pod postem. Pozdrawiam.
  5. 12 punktów
    Zabierając się za rozbudowane projekty, jest szansa że zabraknie nam pamięci. Jeżeli potrzebujemy przechować np. dużą tablicę zmiennych, możemy ją załadować do zewnętrznej pamięci RAM. Co jednak, gdy potrzebujemy przechować duże dane, ale stałe? Najlepiej podpiąć zewnętrzną kość pamięci. Co prawda, nie będzie możliwości zapisu danych (a przynajmniej tak łatwo) ale nasz mikrokontroler uzyska nawet kilka megabitów (!) dodatkowej pamięci. Może to być program, tekst, a nawet obrazek. Programując mikrokontroler najprawdopodobniej wgrywasz program do pamięci FLASH. Do dyspozycji możesz mieć także małą, dodatkową pamięć EEPROM. Czym się one różnią? Pamięć FLASH to ewolucja pamięci EEPROM. Same pamięci PROM są dość stare, mają ok. 50 lat. Są one jednorazowe - można je zaprogramować tylko raz. Ich nowocześniejszą wersją jest pamięć UVEPROM - które łatwo rozpoznać po okienku, które pozwala światłu ultrafioletowemu kasować całą pamięć. Pamięć EEPROM można skasować i zaprogramować elektrycznie, lecz zwykle z pomocą 12V. Z racji tego że te pamięci są stare jak komputery, interfejs jest równoległy; do podłączenia mamy, zwykle ośmiobitową, szynę danych, oraz szynę adresów - jej długość będzie zależeć od pojemności kości. Rozwój elektroniki sprawił, że powstał kolejny rodzaj pamięci: FLASH. Do programowania nie wymagają wysokiego napięcia, a do kasowania światła UV. Aby je zaprogramować, muszą być najpierw wyczyszczone, co można robić co najmniej stronami (nie pozwalają czyścić pojedynczych bajtów). Pamięci te zaczęto masowo stosować jeszcze pod koniec XX wieku. Kości pamięci. Od lewej: PROM, UV EPROM, FLASH (w dwóch obudowach), EEPROM (po I2C) Do podstawowych rozwiązań powinny wystarczyć małe pamięci EEPROM, które podłączymy po I2C. Trochę większe pamięci można podłączyć przez SPI. Lecz do niektórych rozwiązań najlepiej wykorzystać właśnie te starsze kości. I właśnie do nich zrobiłem programator, który dedykuję kościom FLASH (ponieważ tych mam najwięcej... ) przeróbka na EPROM/EEPROM jest możliwa oczywiście, należy zaopatrzyć płytkę w wyższe napięcie i odpowiedni MOSFET. Następnie najlepiej zapoznać się z notą katalogową wybranej pamięci, i przerobić program. Wracając do pamięci FLASH - zajrzyjmy do noty katalogowej wybranej kości - tutaj 29F002, w której był przechowywany BIOS komputera PC. Wiemy zatem, że jest to kostka o pojemności dwóch megabitów, wyprodukowana w technologii CMOS (jest wrażliwa na ładunek elektrostatyczny). Posiada dość niski czas odczytu (120ns), pobiera mało prądu, i co najważniejsze - nie wymaga wysokiego napięcia do programowania/kasowania. Ilość pinów może przerażać, lecz nie ma się czego bać. VCC i GND to zasilanie, na które podajemy 5V. Pin CE (Chip Enable) uaktywnia kość. Jeżeli z szyn korzysta więcej urządzeń niż jedno, to nasza kość pamięci nie będzie im przeszkadzać. Kreska nad nim oznacza, że jest on aktywny w stanie niskim - czyli żeby włączyć czip, musimy podciągnąć ten sygnał do masy. W programatorze będzie on zwarty do masy, jako że to jedyny układ korzystający z szyn. Pin OE (Output Enable) pozwoli na odczyt danych. W chwili podpięcia tego sygnału do masy, na szynę danych ustawiany jest bajt z podanego adresu. Pin WE (Write Enable) pozwala na zapis. Bajt który w chwili zapisu będzie na szynie danych, zostanie zapisany do podanego adresu. Pozostałe piny (D0..D7) to szyna danych, a A0..A17 to szyna adresu. Liczby na tych szynach są zapisywane w systemie binarnym - co oznacza że możemy operować na 262 144 (2^18) liczbach, a każda liczba może mieć wartość z zakresu 0-255. Jeżeli wiemy jak podłączyć naszą kość, możemy to już zrobić: przygotowałem także schemat układu. Sercem programatora jest Atmega 8, z racji tego że 328 nie miałem żadnej wolnej (nie ma powodu żeby jej nie stosować). Wokół niej powinien się znajdować przycisk reset z rezystorem podciągającym, kondensator do filtrowania zasilania. Przejdźmy do połączenia pamięci z atmegą - dlaczego między nimi są 2 układy? Są to dwa rejestry przesuwne, 74HC595. Dzięki trzem pinom z mikrokontrolera możemy obsłużyć aż 16 (a nawet więcej, bo rejestry można łączyć) pinów. Jeżeli dana pamięć ma szerszą szynę adresów, nieużyte piny powinniśmy połączyć z masą. Co do szyny danych, tą podłączyłem bezpośrednio do Atmegi. Piny RX i TX są zarezerwowane dla konwertera USB-UART, w celu komunikacji z komputerem. Tak wygląda układ zmontowany przeze mnie: Niebieski, podłużny element to drabinka rezystorowa, zastępująca 8 rezystorów podciągających szynę danych do masy. Dałem na wszelki wypadek. Teraz należy odpowiednio zaprogramować mikrokontroler. Obecnie dane do wgrania są przechowywane w pamięci mikrokontrolera, co będzie działać dopóki chcemy wgrywać małe dane. Pracuję nad programem w VS, który będzie przekazywał dane z komputera do Atmegi - w razie czego zaktualizuję post. Gotowa paczka z kodem i generatorem są na dole do pobrania. Kod napisałem w VS Code, z wtyczką Platformio (kod powinien być w 100% kompatybilny z Arduino IDE). Zacznijmy od zdefiniowania pinów: #include <Arduino.h> #define SHIFT_DATA 2 #define SHIFT_CLK 3 #define SHIFT_LATCH 4 #define D0 5 #define D7 12 #define WRITE_EN 13 #define OUTPUT_EN A0 Pierwsze 3 piny są dla rejestru przesuwnego. Podaliśmy także Pierwszy i ostatni pin szyny danych - będziemy operować na pętlach for(), więc nie musimy podawać wszystkich pinów (ważne żeby były podłączone po kolei). Kolejne dwa piny to WE i OE (CE jest zwarty do masy). Przejdźmy do właściwego kodu. Zaczniemy od napisania funkcji niezbędnych do działania urządzenia: void setAddress(int address) { shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address >> 8); shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address); digitalWrite(SHIFT_LATCH, LOW); digitalWrite(SHIFT_LATCH, HIGH); digitalWrite(SHIFT_LATCH, LOW); } Funkcja ta ustawi wybrany adres na szynie adresów. Najpierw wysyłamy do rejestrów pierwsze 8 bitów zmiennej. potem 8 kolejnych, ponieważ funkcja shiftOut() może wysłać tylko ośmiobitowy bajt. Po wysłaniu bitów zatwierdzamy je, ustawiając na chwilę latch w stan wysoki. void setDataBusOut() { for(int i = D0; i <= D7; i++) pinMode(i, OUTPUT); } void setDataBusIn() { for(int i = D0; i <= D7; i++) pinMode(i, INPUT); } Z racji tego, że na szynie danych będziemy zapisywać i odczytywać dane, te funkcje umożliwią ustawić szynę jako wejście lub wyjście. void setByte(byte out) { for(int i = D0; i <= D7; i++) digitalWrite(i, bitRead(out, i - D0)); } byte readByte() { byte bajt = 0; for(int i = D0; i <= D7; i++) if(digitalRead(i)) bitSet(bajt, i - D0); return bajt; } Funkcja setByte() ustawi dany bajt na szynie danych. Z kolei readByte() zwróci bajt, który jest obecnie na szynie danych. Wykorzystałem tutaj funkcje bitSet i bitRead, które pozwalają na operacje na bitach (odsyłam do dokumentacji Arduino). Jeżeli chodzi o podstawowe funkcje - to tyle. Teraz przeanalizujmy poszczególne arkusze noty katalogowej: Wygląda skomplikowanie, ale nie ma się czego bać. W celu odczytania bajtu z pamięci, musimy ustawić docelowy adres. Pin CE musi być zwarty do masy (u nas jest), a pin WE do dodatniej szyny zasilania. Następnie krótko po podpięciu OE do masy, dostajemy dane na szynie danych. Zróbmy zatem funkcję, która zwróci odczytany bajt: byte readData(int adr) { byte bajt = 0; setDataBusIn(); digitalWrite(WRITE_EN, HIGH); digitalWrite(OUTPUT_EN, HIGH); setAddress(adr); digitalWrite(OUTPUT_EN, LOW); delayMicroseconds(1); bajt = readByte(); digitalWrite(OUTPUT_EN, HIGH); return bajt; } Najpierw ustawiamy szynę danych jako wejście. Upewniamy się, że WE i OE są w stanie wysokim. Wysyłamy docelowy adres, ustawiamy OE na stan niski, czekamy chwilę, odczytujemy bajt, i ustawiamy OE z powrotem na stan wysoki. Zwracamy odczytany bajt. Teraz czas na prawdziwą zabawę. Dlaczego nagle jakieś komendy mamy wysyłać? Otóż jest to zabezpieczenie przed przypadkowym skasowaniem/zapisaniem danych. Wysłanie komend polega na wysłaniu 3 odpowiednich danych w odpowiednie adresy. Kolejno AA do adresu 555, 55 do adresu 2AA, i A0 do 555. Literka 'H' oznacza że liczby te są zapisane w systemie heksadecymalnym - tutaj mocno polecam pobawić się kalkulatorem w trybie programisty: Tak więc operacja zapisu sprowadza się do zapisania 4 bajtów. Zapiszmy funkcję zapisującą jeden bajt: void writeByte(byte bajt, int adr) { digitalWrite(OUTPUT_EN, HIGH); digitalWrite(WRITE_EN, HIGH); setAddress(adr); setByte(bajt); digitalWrite(WRITE_EN, LOW); digitalWrite(WRITE_EN, HIGH); } Myślę że objaśniać nie trzeba. Teraz zapiszmy funkcję zapisującą jeden bajt w pamięci: void programData(byte bajt, int adr) { setDataBusOut(); writeByte(0xAA, 0x555); writeByte(0x55, 0x2AA); writeByte(0xA0, 0x555); writeByte(bajt, adr); delayMicroseconds(1); } Na końcu dodałem mały odstęp czasowy, ponieważ czip po zapisie przez chwilę jeszcze prowadzi wewnętrzne operacje. Do zrobienia została jeszcze jedna rzecz - nie można zapisywać zapisanej już pamięci. Dlatego patrzymy w notę jak wyczyścić kość: Całość się sprowadza do wysłania 6 bajtów. void chipErase() { setDataBusOut(); writeByte(0xAA, 0x555); writeByte(0x55, 0x2AA); writeByte(0x80, 0x555); writeByte(0xAA, 0x555); writeByte(0x55, 0x2AA); writeByte(0x10, 0x555); delayMicroseconds(1); } I jeżeli chodzi o kwestię techniczną - to tyle. Przejdźmy zatem do setup(): void setup() { pinMode(SHIFT_DATA, OUTPUT); pinMode(SHIFT_CLK, OUTPUT); pinMode(SHIFT_LATCH, OUTPUT); pinMode(WRITE_EN, OUTPUT); pinMode(OUTPUT_EN, OUTPUT); digitalWrite(OUTPUT_EN, HIGH); digitalWrite(WRITE_EN, HIGH); writeByte(0xf0, 0x0000); //reset Serial.begin(115200); delay(3000); Serial.println("programator FLASH v1.0 - gotowy."); } Piny sterujące ustawiamy jako wyjście (i od razu jako stan wysoki), oraz resetujemy czip. Do tego wystarczy jedna komenda jak widać. W loopie zaś sprawdzamy jedynie czy z serialu przyszły nowe dane: void loop() { if(Serial.available()) readSerial(Serial.read()); } Jeżeli tak, wykonujemy dużego switcha: void readSerial(byte bajt) { switch(bajt) { case 'E': Serial.println("Czyszcze pamiec FLASH..."); chipErase(); delay(200); Serial.println("Wyczyszczono!"); break; case 'W': Serial.println("Wgrywam przykladowy program..."); for(int i = 0; i < sizeof(data); i++) programData(data[i], i); Serial.println("Wgrano pomyslnie!"); break; case 'R': Serial.println("Odczytuje dane od adresu 0x0000..."); for(int y = 0; y <= 249; y+=5) { for(int x = 0; x <= 4; x++) { Serial.print(readData(x+y), HEX); Serial.print(" "); } for(int x = 0; x <= 4; x++) Serial.print(char(readData(x+y))); Serial.println(""); } break; case 'T': Serial.println("Resetuje pamiec..."); setDataBusOut(); writeByte(0xF0, 0x0000); setDataBusIn(); break; default: Serial.println("Programator FLASH v1.0 - by Leoneq ;3"); Serial.println("-------------------------------------------"); Serial.println("E - Wyczysc pamiec"); Serial.println("R - Odczytaj zawartosc pamieci"); Serial.println("W - Wgraj przykladowy program"); Serial.println("T - Zresetuj pamiec FLASH"); break; } } Oczywiście te funkcje są przykładowe, zachęcam do samodzielnej zabawy z programem. Zostaje teraz kwestia samych danych do zapisu. Jak napisałem, docelowo mają one być nadawane z komputera PC, a obecnie są one przechowywane w pamięci uC: //generated data const byte data[11] = {B00100001, B11111111, B00000001, B11111001, B00111110, B00000001, B11010011, B00000000, B11000011, B00000100, B00000000}; Specjalnie do tego zadania napisałem generator w C++. Tworzy on z plików .bin (kod maszynowy) tablicę zmiennych. #include <iostream> #include <fstream> #include <bitset> using namespace std; ifstream source; fstream output; //0x21 0xFF 0x01 0xF9 0x3E 0x01 0xD3 0x00 0xC3 0x04 0x00 int main() { cout << "FLASH code generator v1.0\nby Leoneq ;3\n" ; source.open("ROM.bin", ios::binary | ios::ate); if(source.good()) cout << "Successfully opened the file.\n"; else cout << "Couldn't open the file. Put 'ROM.bin' in the same directory where .exe is."; int size = source.tellg(); source.close(); source.open("ROM.bin", ios::binary); char buffer[size]; source.read (buffer, size); source.close(); output.open("array.txt", ios::out); output << "//generated data\nconst byte data[" << size << "] = {"; for(int i = 0; i < (size-1); i++) output << "B" << bitset<8> (buffer[i]) << ", "; output <<"B" << bitset<8> (buffer[size]) << "};"; cout << "The array is in 'array.txt'. Exit..."; return 0; } Program wczytuje plik ROM.bin, który powinien znajdować się w tym samym miejscu co .exe, a wygenerowaną tablicę zapisze w array.txt. Tą tablicę należy skopiować do kodu Atmegi, wgrać i... cieszyć się programatorem. Linki: dokumentacja kości FLASH nota katalogowa rejestrów przesuwnych datasheet mikrokontrolera opis funkcji shiftOut(); bitSet(); bitRead(); ------------------ W planach mam więcej poradników tego typu, dlatego prosiłbym o komentarze co jest dobrze napisane, a co źle. Dzięki ^^ box.zip
  6. 12 punktów
    RoChN 4 to robot typu linefollower, kolejny z serii Robotów o Chwytliwych Nazwach. Jest to konstrukcja w dużej mierze eksperymentalna, stworzona w celu przetestowania nowych pomysłów i komponentów. Wyniki nie były priorytetem, ale robot radzi sobie całkiem nieźle. Prawdopodobnie należy do kilku najlepszych, startujących na zawodach, linefollowerów w Polsce. Rozwijamy go razem z Pojemnikiem od ponad roku, w czasie wolnym między "przygotowaniami" do matury i jesteśmy zadowoleni z osiągniętych efektów. Historia powstania: Po zajęciu kolejnego czwartego miejsca RoChNem 3 uznaliśmy, że osiągnął on już szczyt swoich możliwości i trzeba zbudować coś nowego, aby wreszcie wskoczyć na podium. Początkowa “lista życzeń” wyglądała następująco: STM32 enkodery IMU Chcieliśmy też lepiej zaprojektować sekcję zasilania, żeby uniknąć losowych resetów procesora które zdarzały się poprzednikowi. W ciągu kilku tygodni stworzyliśmy projekt mocno inspirowany Fuzzym. Już wysyłaliśmy zamówienie, gdy odkryliśmy w projekcie poważny błąd. Jego naprawienie wymagałoby zaprojektowania całej płytki od nowa, więc schemat poszedł do kosza. W tym samym czasie na forum pojawił się opis Cukiereczka, który okazał się kopalnią wiedzy o linefollowerach. Uznaliśmy wtedy, że trzeba się inspirować najlepszymi i od tego czasu pomysł na RoChNa 4 był już inny. Postanowiliśmy w jednym robocie zamontować możliwie dużo “wodotrysków” i sprawdzić, które z nich dają tak dużą przewagę podczas zawodów. Dla upamiętnienia niedokończonego poprzednika oficjalny numer umieszczony na płytce ukończonego robota to 4.1. Jako, że jest to konstrukcja eksperymentalna, postawiliśmy na modułowość. Sterowniki silników, enkodery i moduł bluetooth umieszczone zostały na dodatkowych płytkach przylutowanych w pionie do głównego PCB. Dzięki temu rozwiązaniu byliśmy w stanie wygodnie wymieniać i przeprojektowywać peryferia, co bardzo się przydało podczas usuwania błędów konstrukcyjnych. MECHANIKA Kolory: Jak wiadomo ładne roboty szybciej jeżdżą[potrzebny przypis]. Dlatego od początku planowaliśmy jak będzie wyglądał nasz linefollower. Postanowiliśmy wzorować się na bolidach Formuły 1, w końcu są one dosyć szybkie. Mieliśmy już zamówione pionowe płytki w zielonym kolorze, więc ilość bolidów zawęziła się do malowania Force India z 2011 roku. Zdjęcie Cukiereczka jako robota, na którym się wzorowaliśmy, przemalowaliśmy w Paint-cie, żeby zobaczyć, jak będzie wyglądać. Na (nie)szczęście zielone płytki okazały się grubości 2mm, co dyskwalifikowało je z wykorzystania w robocie, więc mając wolny wybór zdecydowaliśmy się na żółto-czarną kolorystykę Renault. Ostatecznie jesteśmy całkiem zadowoleni z tego jak prezentuje się nasz robot. Podwozie: Robot składa się z dwóch płytek PCB połączonych taśmą FFC (raster 0,5mm, 24 piny) oraz dwiema listewkami. Próbowaliśmy je zrobić z włókna węglowego, ale okazało się, że nie umiemy wywiercić w nim otworów domowymi sposobami. Zamówiliśmy też listewki plastikowe, ale były tak miękkie, że na zakręcie przednia płytka mogłaby uderzać o tylną. Gdybyśmy kupili je z twardszego materiału, może zaoszczędzilibyśmy kilka gram na masie robota, ale aktualnie jesteśmy zadowoleni z aluminiowych. Z tyłu nie mogło zabraknąć listewki ochraniającej robota przed obróceniem podczas ruszania. Całkowita masa wynosi 62 gramy (73 z akumulatorem). Taśma FFC poza obsługą 14 czujników koloru i 3 żył z zasilaniem, posiada 7 żył, na których zależnie od użytych czujników odległości można wyprowadzić 2xI2C, SPI, jeden pin ADC, lub po prostu użyć ich jako GPIO. Napęd: Dwa standardowe silniki Pololu 10:1 z obustronnym wałem i węglowymi szczotkami jak zawsze spisują się bardzo dobrze, choć słychać już powoli ich zużycie (to już drugi komplet). Powoli osiągamy koniec ich możliwości, więc kolejna konstrukcja będzie pewnie używać czegoś innego. Zastosowaliśmy przedłużone mocowania, aby szerokość płytki nie przekraczała 10 cm i zamontowaliśmy od dołu zaślepki osłaniające przekładnie przed kurzem, który czasem w nie wpadał. Koła i opony: Początkowo robot jeździł na felgach toczonych w aluminium. Teraz ma dwa razy lżejsze wydrukowane na drukarce 3D, ale za to lekko bijące (musieliśmy rozwiercić otwór na wał, co nie wyszło idealnie). Kiedyś próbowaliśmy odlewania oponek z silikonu - miały podobną przyczepność, ale zużywały się dużo szybciej od Mini-Z, więc używamy tych drugich. ELEKTRONIKA PCB: Zdecydowaliśmy się na czterowarstwową płytkę, bo już podczas projektowania poprzedniego linefollowera mieliśmy problemy z optymalnym doprowadzeniem zasilania. Na głównej płytce jedna warstwa to wyłącznie masa, jedna zajmuje się zasilaniem, a dwie zewnętrzne wszystkimi sygnałami. Przednia płytka z czujnikami również jest czterowarstwowa, tam sygnały schowaliśmy do środka, aby zmniejszyć szumy na sygnałach analogowych. Mniejsze, żółte płytki są dwuwarstwowe. Zdecydowaliśmy się na elementy pasywne w obudowach 0402 - najmniejszych, które można wygodnie ręcznie polutować. W poprzedniej konstrukcji elementy w 0805 zajmowały dużo miejsca dlatego wybraliśmy mniejszy standard. Mikrokontroler: Pierwsza, porzucona wersja RoChNa 4 wykorzystywała STM32F1. Ostatecznie po przeanalizowaniu opisu Cukiereczka zdecydowaliśmy się na serię F7. W robocie zastosowaliśmy STM32F745VET6 w obudowie LQFP-100. Stu-pinowa obudowa okazała się niezbędna przy tylu elementach zastosowanych w robocie - tylko 5 pinów pozostało wolnych. Układ taktowany jest rezonatorem kwarcowym 8MHz, którego sygnał umożliwia stabilną pracę procesora na 216 MHz. Do programowania korzystamy z interfejsu SWD i odłamanego programatora ST-LINK z płytki Nucleo. Nie planowaliśmy programowania przez USB, choć gdyby udało się je uruchomić, to prawdopodobnie byśmy spróbowali. Zapas mocy obliczeniowej okazał się bardzo przydatny przy testowaniu najdziwniejszych rozwiązań. Czujniki linii: Użyliśmy standardowych elementów KTIR0711S. Rozmieszczone są w dość wąski (8,5 cm szerokości) łuk. Ponieważ nasz STM miał 16 pinów z ADC, a chcieliśmy także mierzyć stan baterii i mieć możliwość zamontowania analogowego czujnika odległości do wykrywania przeszkód, zdecydowaliśmy się na 14 sztuk. Odpowiedni dystans od podłoża zapewniają cztery rezystory w obudowach ¼ watta. Sterowniki silników: Po rozmowach z autorem Cukiereczka doszliśmy do wniosku, że sterowniki TB6612 mogą nie wytrzymać nagłych szarpnięć silnikami, więc wybraliśmy mostek H VNH7013 (40A prądu stałego) oraz układ DRV8703 sterujący takim mostkiem. Zestaw mógł sterować tylko jednym silnikiem, więc musieliśmy zamontować takie dwa w robocie. Jednak intuicja podpowiedziała nam, że coś może nie zadziałać, więc zamontowaliśmy je na osobnych, żółtych, pionowych płytkach, abyśmy mogli ewentualnie wymienić je na TB6612. Podczas testów udało nam się raz zakręcić silnikiem i dwa razy spalić mostek, więc ostatecznie robot jeździ na 4 starych sterownikach. Daje to 4,8A ciągłego poboru prądu przez silnik (12,8 w piku (♠)). Nie stosujemy żadnych opóźnień w celu oszczędzania tych układów i nie zostały one jeszcze uszkodzone (a przeżyły już wiele dziwnych manewrów), więc rozwiązanie choć mało profesjonalne okazało się skuteczne. Enkodery: Wybraliśmy enkodery magnetyczne AS5134 z uwagi na dużą szybkość kolejnych odczytów położenia magnesu, możliwość komunikacji po SPI do 6MHz i łatwą dostępność. Początkowo błędnie zasilaliśmy je napięciem 3,3V (układ potrzebuje co najmniej 4,5V), więc musieliśmy przeprojektować ich płytki (tu znowu pomogła nam modułowość projektu). Na prawej płytce umieściliśmy jedyny w robocie stabilizator na 5V i przewodem doprowadziliśmy zasilanie do lewej. Napięcia sygnałów z enkodera do STM-a (5V->3,3V) są dzielone dwoma rezystorami, a w drugą stronę (3,3V->5V) wzmacniane układem MOSFET-a i dwóch rezystorów. Chcieliśmy zastosować 6-biegunowe magnesy firmy Pololu, jednak enkoder zadziałał dopiero gdy użyliśmy pierścieniowe magnesy neodymowe namagnesowane po średnicy. Ustawienie magnesu i czujnika Halla w idealnej osi znacznie zwiększyło dokładność odczytów. Pomiary wykonujemy z częstotliwością 2 kHz. Zmiana kąta między odczytami wynosi zwykle 20-80 stopni, więc niedokładność pomiarów ±2 stopnie nie wpływa za bardzo na stabilność algorytmu sterującego silnikami. Bluetooth: Tu bez żadnych szaleństw. HC-05 spełnia swoją funkcję zadowalająco. Rozglądaliśmy się za czymś innym, ale nie znaleźliśmy rozsądnej alternatywy. Brakowało nam miejsca na głównej płytce robota, dlatego został on umieszczony na osobnej pionowej. Planowaliśmy wpinanie go na złączach goldpin, aby była możliwość wyjmowania go na przejazdy finałowe (mniejsza masa itd). Mieliśmy problemy z tym złączem. Wstrząsy podczas jazdy powodowały krótkie utraty zasilania podczas jazdy, co skutkowało zerwaniem połączenia i uniemożliwiało zatrzymania robota. Przylutowanie dwóch przewodów rozwiązało problem. Zasilanie: Dalej stosujemy akumulatory li-po Dualsky 2S, 150-250 mAh, te same co w Rochnie 3. Montujemy je do robota na rzep i przytrzymujemy kawałkiem drutu, aby się nie kołysały na boki. Mamy 7 akumulatorów oraz jedną ładowarkę na dwa linefollowery, więc podczas zawodów ledwo nadążamy z ich ładowaniem. Robot pożera naprawdę dużo prądu, dlatego wiele układów usypiamy lub odłączamy od zasilania (usypiając stabilizatory) kiedy robot akurat nie jedzie (patrz tabelka, nie uwzględniono prądu pobieranego przez silniki). IMU: Czujnik przestrzeni miał docelowo pomagać w zapamiętywaniu trasy i niwelowaniu poślizgu podczas pokonywaniu zakrętów. Użyliśmy układu LSM6DSM i przylutowaliśmy go bezpośrednio do głównej płytki. Pomimo tego, że podczas testów statycznych układ działa bez zarzutu (1g pojawia się w odpowiednim kierunku), to podczas jazdy wyłapywane są wszystkie wstrząsy i drgania, co uniemożliwia wykorzystanie danych w jakimkolwiek celu nawet po przefiltrowaniu. Czyszczenie kółek podczas jazdy: Przetestowaliśmy system umożliwiający czyszczenie kółek w trakcie przejazdu w celu minimalizacji wpływu przyklejającego się brudu. Rolkę do zbierania kurzu przymocowaliśmy do stelarzu wydrukowanego na drukarce 3D. System działał, ale stawiał bardzo duży opór, co znacząco zmniejszało osiągi robota, utrudniając nawet ruszenie z miejsca. Niewykorzystane bajery: Karta SD - Docelowo miała być użyta jako magazyn danych na temat trasy oraz aktualnej konfiguracji robota. Niestety nie udało nam się jej uruchomić poza odczytaniem informacji o danej karcie. Ostatecznie jako magazyn danych użyta została część niewykorzystanej pamięci FLASH. USB - Miało służyć do szybkiego wymieniania dużych ilości informacji pomiędzy robotem, a komputerem. Z nieznanych nam przyczyn nie udało nam się skłonić go do działania. Dane z robota wysyłamy albo przez Bluetooth albo zczytujemy całą pamięć FLASH programatorem. EEPROM - Został dodany na osobnej płytce, aby łatwiej zapisywać dane konfiguracyjne. Okazał się jednak nie być niezbędny, i zapisujemy te dane na kilku ostatnich bajtach pamięci. SOFTWARE Program został napisany w C z użyciem bibliotek HAL. Nigdy nie robiliśmy żadnego większego projektu na STM32, więc trzeba było nauczyć się wielu rzeczy. Algorytm podążania za linią składa się z głównego regulatora, który na podstawie odczytów z czujników linii zadaje prędkość obrotową dwóm regulatorom PD, które sterują prędkością kół. Dużą część programu zajmuje kod obsługujący komunikację przez bluetooth. Praktycznie wszystkie istotne zmienne można zmieniać zdalnie, istnieje także możliwość podglądu odczytów z czujników linii i innych danych w czasie rzeczywistym. Robot zapamiętuje cześć swojej konfiguracji w pamięci FLASH. Na potrzeby kalibracji i sprawdzania różnych rzeczy powstało kilka mniejszych programów na komputer. Głównie generują wykresy na podstawie danych z robota. Zapamiętywanie trasy: Od początku planowaliśmy zapamiętywać trasę przejazdu. Po kilku tygodniach prób i błędów udało się zrobić program, który działał na krótkich trasach. Niestety na długich się gubił. Uznaliśmy, że bez doświadczenia, wiedzy teoretycznej i pewnie dokładniejszych czujników nie będziemy w stanie zrobić lepszego algorytmu. Poniżej screenshot z programu wizualizującego zapamiętaną trasę. Usprawnienia sterowania: Robot ma kilka różnych sposobów aktywacji dodatkowego hamowania na zakrętach aby z nich nie wypadać. Uwzględnia też podczas pokonywania trasy różnego rodzaju przypadki szczególne np. kąty ostre ("teoretycznie" niemożliwe) i skrzyżowania. Na każdych zawodach sprawdzamy, jaka kombinacja ustawień zadziała najlepiej, choć mamy kilka optymalnych ustawień. PODSUMOWANIE Robot w pełni spełnił swoje zadanie, czyli przetestowanie nowej rodziny procesorów, enkoderów, IMU i zapamiętywania trasy, a wyniki są lepsze niż się spodziewaliśmy. Niestety z powodu epidemii ilość zawodów, w których mógł wystartować została mocno ograniczona. Projekt dalej jest rozwijany i wdrażamy kolejne ciekawe rozwiązania, które opiszemy, jeżeli sprawdzą się na zawodach. Osiągnięcia: III miejsce Robocomp 2019 IV miejsce Sumo Challenge 2019 II miejsce Robotic Arena 2020 Filmy z zawodów:
  7. 12 punktów
    Po kursie Arduino chcesz nauczyć się czegoś jeszcze? Albo chcesz zrobić inteligenty dom? A może Arduino po prostu ci nie wystarcza - na to wszystko jest rozwiązanie! ESP8266 to wydajny i tani mikrokontroler. Znajdziemy go na wielu płytkach, od małego 01 na NodeMCU kończąc. Dzisiaj zobaczymy jakie są rodzaje płytek, co w sobie ukrywa kostka mikrokontrolera, oraz spróbujemy przygotować środowisko i wgrać Blinka. Niestety, tak nie robimy - tylko zewrzemy piny. Spis treści serii artykułów: 1. Omówienie, i przygotowanie środowiska 2. Zapoznanie z nowym środowiskiem, praca jako Arduino, prosty serwer WWW 3. Przyspieszony kurs na webmastera 4. Wykresy, zapis do SPIFFS, mini smart-dom 5. Odbiór danych z przeglądarki, stałe IP, łączenie modułów ESP Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. Możliwości ESP8266 Uznałem, że najlepiej będzie zestawić NodeMCU v3 z Arduino UNO. Najważniejsze informacje podałem w tabeli. Pamiętamy, że ESP pracuje na napięciu 3.3v. Kiedy podłączałem do 5V (nie róbcie tego w domu) się tylko grzał, ale lepiej tego nie róbcie. ESP ma także pamięć FLASH w oddzielnej kostce - co pozwala na dużą jej pojemność (zależy to od wersji modułu). Co więcej, interfejsy możemy zdefiniować na (prawie) każdym pinie. ESP pracuje o wiele szybciej od Arduino - bo aż na 80MHz (z możliwością do 160!), i przede wszystkim ESP jest 32 bitowe. No, i ESP się lekko grzeje, ale to nic złego. Warianty ESP8266 Ten mały mikrokontroler możemy znaleźć na równie małych płytkach, lub znacznie większych i rozbudowanych modułach. Jednym z mniejszych, samodzielnych modułów jest ESP12. Posiada wiele wyprowadzeń, lecz nie jest (nawet z przejściówką) zbyt przyjazny dla płytki stykowej. Posiada natomiast aż 4MB pamięci FLASH (wersja ESP12F). Będzie to optymalny wybór dla rozwiązań wbudowanych (np. własnych płytek). ESP12 Jeżeli natomiast szukamy czegoś równie małego, ale bardziej przyjaznego dla nas, tutaj nadchodzi ESP01. Ten mały modulik ma niestety mniej pamięci (niebieska wersja 512kB, czarna 1MB), oraz tylko 8 wyprowadzonych pinów - lecz do konkretnego zastosowania, np. gniazdka z przekaźnikiem, wystarczy. ESP01 (niebieski) ESP03 i ESP07 to uboższe wersje ESP12, ale posiadają ceramiczną antenę - a ESP07 nawet złącze do zewnętrznej anteny. ESP07 Pozostałe moduły rzadko się spotyka, różnią się jedynie ilością wyprowadzeń, rozmiarem, i sposobem montażu. Przygotowanie ESP do programowania W zależności od tego, jaki moduł wybrałeś, będziesz musiał albo przylutować przewody do jego wyprowadzeń, lub podłączyć się przewodami do płytki stykowej. Dlatego na początek nauki, najlepiej zakupić NodeMCU (płytkę deweloperską z ESP12 na pokładzie), Wemos (troszkę mniejsze płytki z ESP12) - mają wszystko wbudowane. Jeżeli taką płytkę wybrałeś, możesz pominąć ten krok. Mając "surowe" ESP12 lub 01, musisz je odpowiednio podłączyć. Połączenie ESP01 z konwerterem USB ↔ UART. Rozpiska pinów dla ESP01. Do tego będziemy potrzebować dwóch przycisków tact switch, kondensatora elektrolitycznego (z zakresu 100-1000µF), dwóch rezystorów 10kΩ, przewodów, oraz oczywiście ESP i konwertera. Pokazałem to na przykładzie ESP01, ale każdy ESP też ma takie wyprowadzenia: pin CH_PD łączymy na stałe do napięcia zasilania przez rezystor 10kΩ pin RST podciągamy do VCC rezystorem 10kΩ, oraz podpinamy przycisk zwierający do masy pin GPIO0 podpinamy do przycisku zwierającego z masą między VCC a GND dajemy kondensator pin RX konwertera łączymy z pinem TX ESP, a pin TX konwertera z pinem RX ESP piny VCC i GND ESP łączymy z pinami VCC i GND konwertera napięcie na konwerterze ustawiamy na 3.3V! Na NodeMCU także znajdziemy dwa przyciski. Przycisk RST odpowiada ze reset mikrokontrolera - tak samo jak w Arduino. Ale co robi przycisk PRG? Otóż, jeżeli na pin GPIO0 podamy logiczne 0 podczas startu mikrokontrolera, wprowadzimy go w tryb programowania. Dzięki temu będziemy mogli wgrać do niego nasz kod. Jeżeli nie mamy zainstalowanych sterowników dla konwertera (np. CH340), powinniśmy je pobrać i zainstalować. Przygotowanie środowiska ESP możemy programować na dwa sposoby, w języku lua - oraz klasycznie, jak arduino, w c++. Opiszę wam sposób jak programować ESP jako Arduino - a do tego potrzebne będzie Arduino IDE. Jeżeli jeszcze takowego nie mamy, pobieramy najnowszą wersję stąd, po czym instalujemy. Dokładny proces instalacji został opisany na kursie Arduino - jeżeli mamy już zainstalowane środowisko, uruchamiamy je, a następnie przechodzimy do zakładki Plik → Preferencje. Powinno nam się otworzyć nowe okno. Szukamy okienka "Dodatkowe adresy URL do menedżera płytek", i wklejamy ten adres: https://arduino.esp8266.com/stable/package_esp8266com_index.json Całość powinna teraz wyglądać tak: Klikamy OK - następnie przechodzimy do zakładki Narzędzia → Płytka → Menedżer płytek Szukamy "esp8266", i klikamy Instaluj. Pobrane zostanie ok. 100MB danych. Od teraz możemy wybrać płytkę ESP jak zwykłą płytkę Arduino. ALE! Jeżeli już kiedyś programowałeś, w innym IDE, zapewne wiesz, że Arduino IDE jest troszkę przestarzałe. Brak autouzupełniania, podpowiedzi, rozbudowanego systemu plików, GIT, i innych funkcji. Jest na to sposób! Dlatego w tym poradniku także opiszę instalację i konfigurację Microsoft Visual Studio Code do pracy z Arduino. Dzięki temu będzie o wiele prościej i wygodniej pisać programy. Pobieramy zatem najnowsze VS Studio Code z tej strony. Jak widać jest ono dostępne na Windowsa, Linuxa, i MacOS. Po pobraniu i zainstalowaniu, powinniśmy zobaczyć taki widok: Jeżeli ciemny motyw nam nie odpowiada, możemy to zmienić naciskając koło zębate (lewy, dolny róg) i "Color Theme" - jasny motyw to Light+. Problemem dla niektórych może być język angielski - lecz w informatyce jest on niezbędny do funkcjonowania. Nie ma problemu aby wrócić do spolszczonego Arduino IDE. Jeżeli jednak chcesz zostać przy VS Code, musimy zainstalować rozszerzenie Platform.io. Dokładniej masz to opisane w tym forbotowym artykule. Po zainstalowaniu Platformio, klikamy magiczny przycisk F1 (musimy go zapamiętać!), i ukazuje nam się to okno: Znajdziemy tam wszystkie funkcje znane z Arduino IDE! Teraz możemy podpiąć nasz konwerter lub NodeMCU do komputera. Tworzymy nowy projekt, i szukamy po lewej pliku platformio.ini. Tam możemy wybrać inną płytkę niż ta, którą wybraliśmy podczas tworzenia projektu. Możemy także ustalić inne rzeczy - więcej w dokumentacji. Otwieramy podfolder src, i szukamy pliku main.cpp. Otworzyło nam się nowe okno - pierwsze co widzimy, to biblioteka Arduino. Dołączy ona wszystkie funkcje z starego IDE. Wklejamy poniższy kod. Największą różnicą ESP w stosunku do Arduino, jest tutaj zapalenie poprzez ustawienie LOW na pinie. #include <Arduino.h> void setup() { pinMode(LED_BUILTIN, OUTPUT); //pin drugi jako wyjście } void loop() { digitalWrite(LED_BUILTIN, LOW); //zapalamy diodę delay(1000); //czekamy sekundę digitalWrite(LED_BUILTIN, HIGH); //gasimy diodę delay(1000); //czekamy sekundę } Teraz przyszedł moment na wgranie szkicu. Klikamy przycisk PRG (gdzieniegdzie opisywany jako FLASH), trzymamy, a następnie RESET, i puszczamy. Dioda powinna raz mrugnąć - oznacza to, że ESP jest gotowe do zaprogramowania. Klikamy zatem znowu F1, a następnie "Platformio: Upload". Cierpliwie czekamy, aż program się wgra. Kiedy zobaczymy ten komunikat: Przyciskamy przycisk reset na naszej płytce - i dioda powinna zacząć mrugać. Na dole, po lewej, na niebieskim pasku są także małe ikonki pozwalające wgrać szkic. Gratulacje, udało Ci się zaprogramować ESP! Możesz je teraz wykorzystać jako moduł Wifi, samodzielne urządzenie, zastosowań jest tyle ile dla Arduino, a nawet i więcej. Udało Ci się także skonfigurować poprawnie VS Code do pracy z płytkami Arduino (i nie tylko!). W następnym odcinku zobaczymy co tak naprawdę oferuje przesiadka na VS Code, oraz spróbujemy połączyć się przez Wifi. Liźniemy nawet trochę HTMLa z CSSem, aby postawić stronę WWW! W przypadku jakichkolwiek problemów, nie bójcie się pisać komentarzy. Spis treści serii artykułów: 1. Omówienie, i przygotowanie środowiska 2. Zapoznanie z nowym środowiskiem, praca jako Arduino, prosty serwer WWW 3. Przyspieszony kurs na webmastera 4. Wykresy, zapis do SPIFFS, mini smart-dom 5. Odbiór danych z przeglądarki, stałe IP, łączenie modułów ESP
  8. 12 punktów
    Ech, prezenty, prezenty... Taki byłem zadowolony, że prezent dla synka skończę przez święta i będę mógł zająć się swoimi robocikami. A tu guzik: okazało się, że siostra weszła w posiadanie kota (czy odwrotnie, z kotami to różnie bywa) i jakiś prezent trzeba zrobić. Wyszło mi na to, że najszybciej będzie zrobić taką laserową latawicę za którą lata kot - bo i na instructables są kompletne projekty, i na thingiverse gotowe STL-e, a i na naszym Forbocie ktoś coś ostatnio publikował... niewiele myśląc obiecałem, że taką zabawkę zrobię i kończąc świąteczną wizytę udałem się do domu (drugi koniec Polski). Po przyjeździe okazało się, że: Forbotowy projekt (LaserCat) jest mi absolutnie do niczego nie przydatny - zero konkretów, nawet kawałka kodu nie ma żeby sobie zerżnąć Projekty z instructables są jakieś takie uproszczone i nie pasują mi do niczego (oprócz podpatrzenia na filmikach na YT jak lata mucha) Jedyne na czym mogę się wzorować (ale tylko wzorować) to zawieszenie lasera z thingiverse. Postanowiłem więc opracować sobie jakieś wstępne założenia (jak zwykle w maksymalnym stopniu używając części z szuflady). Wyszło mi coś takiego: Mikrokontroler - moduł Arduino Pro Mini; Sterowanie - żadnych błękitnych ząbków, super wypasionych aplikacji na komórkę, serwerów http i wifi, ma być najprostszy pilot na podczerwień plus klawisz START na obudowie; Zasilanie z akumulatora; Dwa tanie serwa SG90 jako napęd; Możliwość łatwego zaprogramowania obszaru, po którym ma latać mucha. Obudowę chciałem początkowo wydrukować w całości, ale okazało się, że leży mi i zawala miejsce nówka Kradex Z-5 - oczywiste było więc jej wykorzystanie. Zacząłem od mechanizmu pan-tilt. Ten z thingiverse nie podobał mi się z dwóch powodów: po pierwsze oba serwa były w nim ruchome, podczas gdy wystarczałoby tylko jedno, po drugie wydruk wymagał za dużo wysokich podpór. Ponieważ i tak musiałem czekać na zamówione kilka części (nie miałem np. diody laserowej ani niepotrzebnego pilota), postanowiłem przeznaczyć ten czas na zaprojektowanie i sprawdzenie mechanizmu. Przede wszystkim postanowiłem wydrukować oddzielnie obejmę diody i mocowanie do serwa. Pozwoliło mi to na pozbycie się niepotrzebnych podpór przy druku, a jednocześnie dało większą możliwość jakichś manipulacji przy ewentualnym błędzie (jak się okazało - sprawdziło się to, ale o tym później). Dodatkowo chciałem tam zrobić jakieś miejsce na przewody (do diody i serwa), a przy okazji zrobić ten element nieco bardziej uniwersalnym - czyli z możliwością poprowadzenia przewodów z jednej lub drugiej strony. Dodatkowo niepotrzebny okazał się główny element mocujący - ponieważ serwo poziomu jest nieruchome, przymocowane zostało bezpośrednio do obudowy. Tak więc mechanizm działa w ten sposób: Oto zestaw elementów potrzebnych do złożenia całości (bez wkrętów i serw) oraz zmontowany mechanizm: Jak widać, orczyk musiał być przycięty tak, aby zmieścił się w przygotowanym rowku w uchwycie. Jeden z wkrętów mocujących orczyk do uchwytu (użyłem oryginalnych wkrętów dołączonych do serwa) - ten na krótszym ramieniu - musiał być również lekko przycięty, inaczej zawadzałby o obudowę serwa. Najlepiej po prostu skrócić oba wkręty i wkręcić je od wewnątrz (od strony orczyka) tak, aby nie wystawały poza obejmę. Oczywiście otwory w orczyku należy rozwiercić tak, aby wkręt się zmieścił! W załączniku STL-e i plik OpenSCAD-a: LaserFly.zip UWAGA! Co prawda oficjalna stabilna wersja OpenSCAD-a wystarcza do otwarcia pliku i wygenerowania STL-i, ale do działania customizera wymagana jest wersja co najmniej 2019.05! Teraz przyszła kolej na stworzenie schematu zabawki (co w rzeczywistości sprowdzało się do rozstrzygnięcia, które biblioteki gryzą się ze sobą i co podłączyć do którego pinu). Jako że biblioteki Servo i IRremote używają timerów (uniemożliwiając działanie PWM na niektórych pinach) a chciałem jednak mieć możliwość regulacji świecenia diody - wyszło mi coś takiego: I tu od razu uwaga: kondensator C1 został dodany w czasie eksperymentów z ustaleniem przyczyny niedziałania serwa. Najprawdopodobniej nie jest potrzebny - ale nie chciało mi się go już wyciągać Jako że w międzyczasie doszły zamówione brakujące części, mogłem zabrać się za zmontowanie całego urządzenia i pisanie programu. Przede wszystkim stwierdziłem, że obudowa Z-5 to jakiś wynalazek diabła; sterczący pośrodku jakiś szpindel ze śrubką wielce skutecznie blokuje możliwość zamontowania tam czegokolwiek, co jest większe od pudełka po zapałkach i nie ma dziury w środku. Na szczęście największy element (koszyk na akumulator) udało mi się tam upchnąć, reszta była już prosta. Dwa uchwyty mocowane do spodu obudowy śrubami od nóżek służą do utrzymania przetwornicy oraz modułu ładowarki (trzeci element niewidoczny na zdjęciu to podkładka pod ładowarkę, utrzymująca ją na właściwej wysokości koniecznej dla prawidłowego dostępu do gniazda USB): I tu kolejna uwaga: Moduły ładowarki różnych producentów mają różne wymiary (a nawet kształty płytki) - warto to sprawdzić i ew. poprawić moduł rholder w pliku OpenSCAD-a! Arduino i gniazda połączeniowe umieściłem po prostu na kawałku płytki uniwersalnej przykręconej do jednego z uchwytów. Koszyk akumulatora jest przykręcony do podstawki tak, aby możliwe było przeprowadzenie przewodów między koszykiem a podstawką, a ta z kolei skręcona jest z uchwytami. Zmontowana całość wygląda tak: Jak widać, mikroswitche są przylutowane znów do kawałka płytki uniwersalnej a ta przykręcona do ściany obudowy - to chyba najszybszy, a jednocześnie niezawodny sposób na w miarę estetyczne klawisze... Po złożeniu wszystkiego całość przedstawia się następująco: Jak widać, akumulator zamocowany jest dodatkowo opaską zaciskową. Nie jest to absolutnie niezbędne (koszyk tego typu z blaszkami zapewnia zarówno niezły styk, jak i pewne zamocowanie akumulatora) ale urządzenie miało przed sobą podróż w paczce - a wolałem nie sprawdzać, czy akumulator przypadkiem nie wypadnie w transporcie (czort jeden wie co oni tam z tymi paczkami robią, na pewno nic przyjemnego). W międzyczasie oczywiście powstawał program (w załączniku). W tym przypadku jest on dość prosty - pozwala na zaprogramowanie za pomocą pilota obszaru ruchu "muchy", punktu zerowego oraz regulację sygnału PWM diody laserowej. Jedna tylko uwaga: kod funkcji getKey dostosowany jest do konkretnego pilota z kodowaniem NEC, w razie użycia innego fragment funkcji odpowiedzialny za odczyt pilota musi byc przerobiony! Na tylnej ścianie urządzenia umieszczone są kolejno: dioda sygnalizująca i przycisk AUTO (włączający program ruchu) dioda sygnalizująca i przycisk PROG (włączający tryb programowania) dioda kontrolna, wyłącznik urządzenia oraz gniazdo USB ładowarki Odbiornik IR umieściłem w czymś w rodzaju obrotowej wieżyczki - nie wiedziałem w jakiej pozycji będzie używana zabawka a znając prawa Murphy'ego gdzie bym go nie umieścił to by akurat patrzył w odwrotną stronę Jako że nie mam możliwości umieszczenia filmiku z interakcją z kotem: krótka demonstracja działania urządzenia (ruch muchy po podłodze) oraz zapewnienie siostry, że kotu się spodobało - muszą wystarczyć I to by było na tyle. Tym razem nie liczę na mnóstwo komentarzy, ale byłoby mi miło, gdyby ktoś wykorzystał mój projekt choćby częściowo.
  9. 12 punktów
    W poprzednich odcinkach zobaczyliśmy jak działa program, który przesyła do wyświetlacza dane dla każdego piksela osobno, następnie przetestowaliśmy wersję z buforem dla całej pamięci obrazu. Pierwsza wersja działała bardzo wolno, ale zużywała mało pamięci RAM. Druga działała bardzo szybko, ale bufor zajmował ogromną jak na mikrokontroler ilość pamięci. Teraz spróbujemy przygotować wersję pośrednią - tym razem użyjemy mniej pamięci, ale więcej czasu procesora. Spis treści: Sterowanie wyświetlaczem TFT - część 1 - wstęp, podstawowe informacje Sterowanie wyświetlaczem TFT - część 2 - analiza problemu Sterowanie wyświetlaczem TFT - część 3 - testy prędkości na STM32 Sterowanie wyświetlaczem TFT - część 4 - własny program Sterowanie wyświetlaczem TFT - część 5 - optymalizacja programu Obliczanie danych obrazu Pełny bufor obrazu jak pamiętamy zajmuje 160 x 128 x 2 = 40960 bajtów pamięci. Takie rozwiązanie zapewniło nam możliwość szybkiego tworzenia grafiki w pełnej rozdzielczości oraz 65 tysiącach kolorów. Jednak w wielu zastosowaniach wystarczyłaby nieco mniejsze możliwości, przykładowo gdybyśmy zamiast 16-bitów zastosowali 8, uzyskalibyśmy 256 kolorów, a jednocześnie zmniejszyli zużycie pamięci o połowę. W wielu przypadkach nawet 16 kolorów, czyli 4 bity mogłyby wystarczyć, a jak łatwo policzyć bufor zajmowałby wówczas 10240 bajtów. Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. Podobnie z rozdzielczością, jeśli tworzymy np. mini konsolę do grania, tryb 80x64 mógłby nam wystarczyć, nadałby nawet nieco stylu "retro". Ogólna idea jest więc taka, że spróbujemy przechowywać mniejszą ilość danych, a następnie przeliczać je na reprezentację oczekiwaną przez wyświetlacz dopiero przed wysłaniem. Tryb z paletą kolorów Metod generowania obrazu jest mnóstwo, ja spróbuję przedstawić bardzo prosty, czyli użycie 8-bitowej palety. Bufor obrazu będzie wyglądał podobnie jak wcześniej, ale zamiast typu uint16_t użyjemy uint8_t: uint8_t lcd_framebuffer[LCD_WIDTH * LCD_HEIGHT]; Jak łatwo policzyć zajmuje on teraz 160 x 128 = 20480 bajtów, czyli nadal sporo, ale zawsze można zastosować kolejne optymalizacje. Wyświetlacz oczekuje danych w postaci RGB565, czyli 16-bitowych wartości gdzie 5-bitów określa składową czerwoną, 6-zieloną, a 5-niebieską. Paleta to po prostu 256-elementowa tablica, która zawiera wartości opisujące dany kolor: uint16_t palette[256]; W docelowym programie moglibyśmy dobrać idealną paletę do naszego zastosowania i zapisać ją w pamięci flash (albo w samym programie). Jak wspomniałem tutaj prezentuję jedynie demo, więc paletę będę obliczać: Prawdę mówiąc takie rozwiązanie nie wyglądało najładniej, bo nie można w nim reprezentować bieli, więc zamiast uzupełniać zerami, uzupełniłem jedynkami - jak napisałem, to tylko demo. Bardzo prosty kod przeliczający 8-bitową paletę, na 16-bitowy kolor dla wyświetlacza wygląda następująco: static inline uint16_t palette2rgb(uint8_t color) { uint16_t r = ((uint16_t)color & 0xe0) << 8; uint16_t g = ((uint16_t)color & 0x1c) << 6; uint16_t b = ((uint16_t)color & 0x03) << 3; return __REV16(0x18e7 | r | g | b); } Ta magiczna wartość 0x18e7 to właśnie uzupełnienie jedynkami - wiem że to brzydki kod, z góry za niego przepraszam, ale to mało istotny fragment, zachęcam oczywiście do zastosowania o wiele lepszych rozwiązań. Teraz przechodzimy do najważniejszego, czyli przeliczania 8-bitowych danych w buforze, na docelowe 16-bitowe przeznaczone dla wyświetlacza. Przesyłanie po jednym bajcie nie działa wydajnie, więc utworzymy nieduży bufor tymczasowy, ja ustaliłem jego wielkość na 512 pikseli: #define TX_BUF_SIZE 512 static uint16_t tx_buf[TX_BUF_SIZE]; Skoro wyświetlacz ma rozdzielczość 160 x 128, więc jak łatwo policzyć będziemy ten bufor wypełniać i wysyłać 40 razy, aby przesłać cały obraz. Funkcja do wypełniania bufora wygląda następująco: static void fill_tx_buf(uint32_t part) { uint16_t *dest = tx_buf; uint8_t *src = lcd_framebuffer + part * TX_BUF_SIZE; for (uint32_t i = 0; i < TX_BUF_SIZE; i++) *dest++ = palette2rgb(*src++); } Jako parametr podajemy indeks bufora, czyli wartość 0..39, po jej wykonaniu bufor tx_buf będzie zawierał dane do przesłania. Teraz możemy napisać funkcję rysującą zawartość naszego ekranu: void lcd_copy(void) { lcd_cmd(ST7735S_RAMWR); HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET); for (uint32_t i = 0; i < LCD_WIDTH * LCD_HEIGHT / TX_BUF_SIZE; i++) { fill_tx_buf(i); HAL_SPI_Transmit(&hspi2, (uint8_t*)tx_buf, 2 * TX_BUF_SIZE, HAL_MAX_DELAY); } HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET); } Musimy jeszcze zmodyfikować naszą bibliotekę graficzną, tak żeby pracowała z 8-bitowymi kolorami, ale to właściwie kosmetyczna zmiana. Czas skompilować program: Zgodnie z oczekiwaniami zużycie pamięci RAM znacznie spadło i wynosi niecałe 23KB. Przetestujmy wydajność naszego programu: Jak widzimy rysowanie w lokalnym buforze zajmuje tyle samo czasu, czyli 7ms, natomiast kopiowanie trochę więcej niż poprzednio, bo 37ms zamiast 33ms. Warto przy okazji przetestować wydajność funkcji wypełniającej bufor, czyli fill_tx_buf: void lcd_test(void) { uint32_t start = HAL_GetTick(); for (uint32_t i = 0; i < 1000; i++) fill_tx_buf(i % (LCD_WIDTH * LCD_HEIGHT / TX_BUF_SIZE)); uint32_t end = HAL_GetTick(); printf("lcd_test: %ld us\r\n", end - start); } Wywołanie 1000 razy fill_tx_buf zajmuje 110ms, czyli jedno jej wywołanie ok. 110us. Jak pamiętamy używamy jej 40 razy, co zgadza się z pozostałymi pomiarami - trochę ponad 4ms zużyliśmy na obliczenia, ale zaoszczędziliśmy prawie 20KB pamięci. Użycie tablicy zamiast obliczeń pewnie pozwoliłoby skrócić ten czas, ale jak wspominałem, to tylko przykład. Nie będę wstawiał kolejnego filmu, bo już tyle razy widzieliśmy ekran testowy, że chyba każdy ma go dosyć. Czas udoskonalić nasz program. Użycie DMA W poprzedniej części korzystaliśmy z DMA, więc nowy program jest pod wieloma względami "gorszy". Użyjmy więc HAL_SPI_Transmit_DMA zamiast, HAL_SPI_Transmit. Procedura wysyłania będzie wyglądała następująco: void lcd_copy(void) { lcd_wait_ready(); lcd_busy = true; lcd_cmd(ST7735S_RAMWR); HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET); tx_part = 0; fill_tx_buf(tx_part++); HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)tx_buf, 2 * TX_BUF_SIZE); } Wypełniamy w niej bufor pierwszym fragmentem obrazu i rozpoczynamy wysyłanie. W zmiennej tx_part przechowujemy informację o numerze kolejnego fragmentu do wysłania. Musimy teraz obsłużyć przerwanie informujące o zakończeniu transmisji i w nim przygotować dane dla następnego fragmentu, albo zakończyć całą operację: void lcd_copy_done(void) { if (tx_part < LCD_WIDTH * LCD_HEIGHT / TX_BUF_SIZE) { fill_tx_buf(tx_part++); HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)tx_buf, 2 * TX_BUF_SIZE); } else { HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET); lcd_busy = false; } } Po uruchomieniu zobaczymy, że program działa tak samo jak poprzednio. Różnica jest jednak taka, że podczas transmisji przez DMA procesor może wykonywać inne zadania. Jednak czas kopiowania obrazu nadal wynosi 37ms. Jeszcze jedna ważna uwaga - w przerwaniu generujemy dane dla kolejnego bufora, więc na 110us blokujemy przerwanie. Długie procedury obsługi przerwań to nic dobrego, ale STM32 pozwala na szczęście na ustawienie priorytetów przerwań. Możemy więc przerwaniu od DMA nadać niski priorytet i dzięki temu nasze obliczenia nie będą opóźniały innych, pilniejszych zadań: Użycie podwójnego bufora Jeśli podłączymy analizator logiczny to zobaczymy, że komunikacja z wyświetlaczem ma "przerwy". Wynika to stąd, że gdy obliczamy dane dla kolejnego fragmentu ekranu komunikacja jest zatrzymywana. Możemy trochę skomplikować nasz program, ale jednocześnie przyspieszyć działanie. Tym razem użyjemy dwóch buforów, albo raczej jednego większego. Gdy DMA będzie wysyłało jedną część danych, będziemy mieli czas na przygotowanie następnej. Deklarujemy więc większy bufor: #define TX_BUF_SIZE 512 static uint16_t tx_buf[TX_BUF_SIZE * 2]; Funkcja wypełniania bufora będzie teraz zapisywać parzyste fragmenty w pierwszej części tx_buf, a nie nieparzyste w drugiej: static void fill_tx_buf(uint32_t part) { uint16_t *dest = (part % 2 == 0) ? tx_buf : tx_buf + TX_BUF_SIZE; uint8_t *src = lcd_framebuffer + part * TX_BUF_SIZE; for (uint32_t i = 0; i < TX_BUF_SIZE; i++) *dest++ = palette2rgb(*src++); } Przed rozpoczęciem transmisji wypełnimy nie jeden, ale dwa bufory: void lcd_copy(void) { lcd_wait_ready(); lcd_busy = true; lcd_cmd(ST7735S_RAMWR); HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET); tx_part = 0; fill_tx_buf(tx_part++); fill_tx_buf(tx_part++); HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)tx_buf, 4 * TX_BUF_SIZE); } Ostatnia zmiana to obsługa nowego przerwania, które będzie wywoływane po przesłaniu połowy danych: void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) { lcd_copy_halfdone(); } Gdy otrzymamy to przerwanie, będziemy po prostu wypełniać następny bufor: void lcd_copy_halfdone(void) { fill_tx_buf(tx_part++); } Natomiast procedura obsługi końca transmisji prawie się nie zmieniła, jedyna różnica to wielkość bufora: void lcd_copy_done(void) { if (tx_part < LCD_WIDTH * LCD_HEIGHT / TX_BUF_SIZE) { HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)tx_buf, 4 * TX_BUF_SIZE); fill_tx_buf(tx_part++); } else { HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET); lcd_busy = false; } } Program jest nieco bardziej skomplikowany, ale w nagrodę otrzymaliśmy czas kopiowania identyczny jak w wersji z poprzedniego odcinka, ale zużyliśmy mniej pamięci: Na zakończenie jeszcze mały przykład wykorzystania naszego nowego programu. Program demonstracyjny Jakiś czas temu na forum pojawił się wątek z pytaniem o sposób wyświetlania kołowego progres baru. Pytanie sprowokowało ciekawą dyskusję na temat możliwości wydajnej realizacji takiego zadania. Skoro mamy opanowane sterowanie wyświetlacza TFT, możemy spróbować narysować nieco podobny element, a przy okazji sprawdzić jak nasza "biblioteka" sprawdzi się w realnym przykładzie. Zacznijmy od małej powtórki z matematyki oraz pewnego uproszczenia. Dla ułatwienia rysujmy tylko połowę progres-bara, zawsze możemy później rozbudować program. Rysowanie pionowych linii jest na ogół dość szybką operacją, więc zastanówmy się jak narysować wykres pionowymi (albo poziomymi) liniami. Kąt alfa oraz promienie r1 i r2 to nasze dane. Ja wybrałem rysowanie pionowych linii, więc x będzie zmienną. Wszyscy pamiętamy z matematyki wzór okręgu: x2 + y2 = r2. Po karkołomnych przejściach matematycznych uzyskujemy więc: y1 = sqrt(r1 - x2) y3 = sqrt(r2 - x2) Funkcja sqrt to pierwiastek. Jeśli ktoś jest miłośnikiem optymalizacji to wartości y1 i y2 może raz policzyć i trzymać w tablicy (najlepiej w pamięci Flash). Jak wspominałem program to demo, więc na razie nie będzie aż tak optymalny. Zostaje jeszcze obliczenie y2. Jest to odrobinę trudniejsze, może wymagać szybkiej powtórki z trygonometrii, a jak pamiętamy tg(alpha) = y/x, więc: y2 = x * tg(alpha) Tutaj znowu możemy tablicować wartości, ale na początek zostawmy prostą wersję. Mamy więc dla każdego x obliczone y1, y2 i y3. Teraz wystarczy sprawdzić jak y2 ma się do pozostałych i są możliwe 3 przypadki: jeśli y2 <= y1 to nic nie rysujemy jeśli y2 >= y3 to rysujemy "pełną" linię od y1 do y3 a jeśli y1 < y2 < y3 to linię od y1 do y2 Rysowanie możemy więc wykonać następującym programem: void draw_bar(uint32_t r1, uint32_t r2, uint32_t alpha) { float t = tan(alpha * M_PI / 180.0); bar_circle(0, 0, r1, WHITE); bar_circle(0, 0, r2, WHITE); bar_line(0, 0, r1 * cos(alpha * M_PI / 180.0) * 0.8f, r1 * sin(alpha * M_PI / 180.0) * 0.8f, WHITE); for (uint32_t x = 0; x <= r2; x++) { uint32_t y1 = (x < r1) ? sqrt(r1 * r1 - x * x) : 0; uint32_t y2 = sqrt(r2 * r2 - x * x); uint32_t y3 = x * t; if (y3 > y2) bar_line(x, y1, x, y2, WHITE); else if (y3 > y1) bar_line(x, y1, x, y3, WHITE); } } Funkcje bar_circle i bar_line są dodane aby "przenieść" nasz początek współrzędnych w odpowiednie miejsce: static void bar_circle(uint32_t x, uint32_t y, uint16_t r, uint8_t color) { lcd_circle(LCD_WIDTH - 1 - x, LCD_HEIGHT - 1 - y, r, color); } static void bar_line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint8_t color) { lcd_line(LCD_WIDTH - 1 - x1, LCD_HEIGHT - 1 - y1, LCD_WIDTH - 1 - x2, LCD_HEIGHT - 1 - y2, color); } Dodajmy jeszcze "wskazówkę", pomiar czasu działania oraz wyświetlanie wartości: void draw_test_screen(uint32_t value) { char buf[32]; uint32_t start = HAL_GetTick(); lcd_clear(BLUE); draw_bar(117, 127, value); sprintf(buf, "%ld", value); lcd_fill_rect(110, 90, 150, 120, BLACK); lcd_draw_string(120, 100, buf, &Font16, WHITE, BLACK); lcd_copy(); uint32_t time = HAL_GetTick() - start; printf("drawing: %lu ms\r\n", time); } Teraz program jest gotowy: Nawet bez tablicowania wartości i z arytmetyką zmiennopozycyjną rysowanie zajmuje ok 22ms. Kopiowanie to 33ms, mamy więc prawie 20 klatek na sekundę, ale pewnie dałoby się więcej. Podsumowanie Początkowo planowałem napisanie jednego, może dwóch artykułów odnośnie sterowania wyświetlaczem TFT. Okazało się jednak, że temat jest o wiele obszerniejszy i ciekawszy, a 5 części to właściwie dopiero wstęp. Mam nadzieję, że udało mi się pokazać jak można sterować wyświetlaczem kolorowym oraz zachęcić do własnych eksperymentów i udoskonalania zaprezentowanych rozwiązań. Spis treści: Sterowanie wyświetlaczem TFT - część 1 - wstęp, podstawowe informacje Sterowanie wyświetlaczem TFT - część 2 - analiza problemu Sterowanie wyświetlaczem TFT - część 3 - testy prędkości na STM32 Sterowanie wyświetlaczem TFT - część 4 - własny program Sterowanie wyświetlaczem TFT - część 5 - optymalizacja programu
  10. 11 punktów
    To będzie zbiór kilku projektów, które zrobiłem przez ostatnie kilka lat, związanych z klawiaturami. Zorientowałem się, że nie pisałem o tym tutaj jeszcze nigdy (poza krótką wzmianką w "nad czym teraz pracujesz"), a temat jest bardzo głęboki i potencjalnie ciekawy dla wszystkich użytkowników komputerów, szczególnie gdy spędzają przy nich dużo czasu. Z góry ostrzegam o dwóch sprawach: po pierwsze, klawiatury mechaniczne (a tylko takie moim zdaniem jest sens samemu budować) są dość drogą zabawą, ze względu na wysoki koszt mechanicznych przełączników no i ich dość dużą liczbę w takim projekcie. Owszem, w minimalnych klawiaturach możemy się obyć 40-klawiszami, ale i tak wychodzi to drogo. Na pewno nie ma co liczyć na zrobienie klawiatury taniej niż sklepowa, chyba, że przerabiamy klawiaturę znalezioną na złomowisku (co tak naprawdę jest doskonałym pomysłem, bo drzewiej klawiatury były znacznie wyższej jakości niż dziś). Po drugie, osobiście skupiać się będę na klawiaturach do pracy, czyli do pisania dużych ilości tekstu. Nie interesują mnie klawiatury zaprojektowane do jak najszybszego wykonywania combosów albo oddawania jak największej liczby strzałów, czy też najskuteczniejszego oślepiania użytkownika migającymi animacjami we wszystkich kolorach tęczy. To są osobne nisze, które nieco się pokrywają, ale mają odmienne wymagania niż moje. No więc zacznijmy może od najbardziej oczywistego pytania: po co robić własną klawiaturę, skoro te ze sklepu będą tańsze, w ładnej obudowie i od razu działające. Normalnie w takim przypadku odpowiedź brzmi "żeby się nauczyć i wiedzieć jak działa", ale akurat w tym przypadku mamy znacznie lepsze powody: ergonomia, wybór i jakość. Zacznijmy od ergonomii. Każdy, kto czytał o alternatywnych układach klawiatury, takich jak Dvorak czy Colemak, na pewno wie, że tradycyjny układ QWERTY nie został jakoś specjalnie zaprojektowany dla optymalności. Krążą nawet legendy, jakoby niektóre klawisze zostały poprzestawiane specjalnie, żeby maszynistki spowolnić, bo w przeciwnym razie mechanizm maszyny nie nadążał i zacinał się. Legendy te są nieprawdziwe. Owszem, poprzestawiano klawisze, ale nie w celu spowolnienia, tylko w celu oddalenia od siebie młoteczków tych liter, które często występują obok siebie, żeby właśnie zmniejszyć szansę zacięcia. Ale nie miało to na celu spowolnienia piszących i nie da się takiego efektu zauważyć. Drugą legendą jest większa "prędkość" pisania na nowych, zoptymalizowanych układach — niestety ten efekt jest zauważalny wyłącznie w badaniach przeprowadzonych przez proponentów tych układów i jak dotychczas nie udało się go powtórzyć w niezależnych badaniach. Zatem standardowy układ klawiatury jest jednak optymalny? Niekoniecznie, szczególnie gdy będzie nam wolno zrobić więcej niż tylko pozamieniać klawisze miejscami. Klawiatura w tej formie, którą znamy, powstała niemalże 150 lat temu, gdy ustandaryzowały się maszyny do pisania i od tamtego czasu prawie się nie zmieniła, poza dodaniem kilku klawiszy tu i ówdzie, no i oczywiście zmianach w technice produkcji. Na pewno zauważyliście, na przykład, że klawisze nie są ustawione w równych kolumnach, tylko w każdym rzędzie przesunięte są o ¼ albo ½ szerokości. Dlaczego tak? Bo w maszynach do pisania klawisze zamontowane były na metalowych dźwigniach i trzeba było na te dźwignie mieć miejsce. Inna rzecz, że nie wszystkie klawisze są tej samej wielkości. Oczywiście częściowo związanie jest to ze wspomnianym już ich poprzesuwaniem, żeby całość jednak mieściła się w prostokącie, ale częściowo związanie jest to z tym, że taka maszyna do pisania jest w zasadzie napędzana siłą ludzkich mięśni, i o ile taki zwykły młoteczek z literką da się poruszyć jednym palcem (choć kto próbował kiedyś mechanicznej maszyny ten wie, że żeby się dobrze odbiło, a jeszcze w kilku kopiach przez kalkę, to nieraz trzeba nieźle w taki klawisz przyłożyć), o tyle klawisz "shift" na przykład podnosi praktycznie cały mechanizm do góry, a do tego trzeba go przytrzymać — łatwiej to zrobić gdy klawisz jest większy. Podobnie inne "specjalne" klawisze są zazwyczaj traktowane specjalnie, do tego stopnia, że "enter" oryginalnie nawet nie był klawiszem, tylko dźwignią umieszczoną przy wałku. Wszystkie te kompletnie nieistotne dziś detale zachowały się w tradycyjnym układzie i utrudniają nam życie. Budując własną klawiaturę możemy je zignorować i zaprojektować ją od początku dobrze. Drugi powód to wybór. Oczywiście można dzisiaj znaleźć w sklepach szeroki wybór klawiatur w różnych kolorach, z touchpadem, z migającymi światełkami, bezprzewodowych, do tabletów, z kucykami, etc. Ale nawet jeśli sięgniemy po te z wyższej półki, to nie mamy za bardzo wyboru w kwestiach, które się liczą dla wygody pracy. Klawiatury niskoprofilowe wyglądają jak skopiowane z kalkulatorków, klawiatury mechaniczne są tak wysokie, że można dostać lęku wysokości patrząc między klawisze, producenci często wykazują się fantazją przestawiając niektóre klawisze albo zastępując klawisze funkcyjne klawiszami do zmiany głośności albo uruchamiania kalkulatorka. Pewien producent urządzeń domowych udających komputery nawet stwierdził, że klawisz Esc w zasadzie nikomu do niczego nie jest potrzebny (lata wcześniej usunęli klawisze Ins i Del i też było dobrze). Zatem w praktyce wybór rozsądnych klawiatur do pracy jest zatrważająco mały. Nie pomaga przy tym fakt, że producenci wprowadzając nowe udziwnione produkty lubią usuwać z oferty te dobre i sprawdzone, więc jeśli zepsuje się wam dobra klawiatura, której używaliście przez lata, to zapomnijcie o kupieniu takiej samej. No i wreszcie jakość. Trochę to dziwne, że coś, co możemy zbudować domowym sumptem będzie mieć wyższą jakość niż zaprojektowane przez profesjonalistów i wyprodukowane w fabrykach towary, ale tak jest — głównie dlatego, że większość ludzi kupując komputer nie myśli o jakości klawiatury, tylko o tym, żeby jakaś była, i być może, jeśli to do gier, to żeby migała. Istnieje kilka firm specjalizujących się w rzeczywiście dobrych klawiaturach, ale ponieważ nie sprzedają ich dużo, a celują głównie w profesjonalistów, to ich ceny są naprawdę wygórowane. Jeśli chcemy coś dobrej jakości, ale tańsze od używanego samochodu, to pozostaje nam polować na klawiatury gamerowe, którym przypadkiem trafiły się akurat lepsze części. Wymaga to cierpliwości i dobrego oka. No albo uda się nam zdobyć "starą" klawiaturę, która okaże się dla nas skarbem. Alpen Clack Moja przygoda z klawiaturami rozpoczęła się właśnie od takiego przypadku — dostałem "ze złomu" starą klawiaturę, która przeleżała u mnie kilka lat, aż któregoś dnia postanowiłem przerobić ją na klawiaturę USB (oryginalnie była oczywiście PS/2, i to ze starą, dużą wtyczką DIN). Słyszałem co prawda o rozwiązaniach polegających na zrobieniu adaptera, a stwierdziłem, że będę ambitny i wymienię w niej całą elektronikę. W tym samym czasie zaczęły też pojawiać się klawiatury bez numpada (tak zwane "tenkeyless") i spodobał mi się pomysł zostawienia więcej miejsca na myszkę, szczególnie, że komputera nauczyłem się używać na klonie IBM XT, który nie miał osobnych strzałek, więc NumLock musiał być zawsze wyłączony by był dostęp do strzałek, więc nigdy nie nauczyłem się używać numpada. Z usuniętych klawiszy postanowiłem zrobić brakujące klawisze "super". Klawiatura przed operacją wyglądała tak: Wtedy o tym nie widziałem, ale okazało się, że trafił mi się nie mała rarytas: klawiatura z mechanicznymi przełącznikami firmy ALPS. Dzisiaj takie są bardzo poszukiwane. Ale nie wiedząc o tym z zadowoleniem zabrałem się za jej masakrowanie. Trzeba było ją rozmontować, wylutować wszystkie przełączniki, umyć klawisze no i obciąć ten nieszczęsny numpad: Oraz wyciąć dziury na dodatkowe klawisze: Następnie powtykałem wszystkie przełączniki na miejsca, przylutowałem do nich wylutowane z płytki klawiatury diody, i połączyłem wszystko mniej więcej w matrycę, podłączając do nóżek płytki prototypowej Pro Micro. Niestety nóżek nie starczyło, więc musiałem też wylutować z Pro Micro jedną z diod świecących i użyć jej jako dodatkowej nóżki. Tutaj wypada się zatrzymać na chwilkę, żeby wyjaśnić po co te diody i jakim cudem da się podłączyć niemalże 100 przełączników do mikrokontrolera, który ma tylko jakieś 20 nóżek. Odpowiedzią jest wspomniana wcześniej matryca. Przełączników nie podłączamy tak jak się to zazwyczaj robi, pomiędzy nóżkę a masę, tylko pomiędzy dwie nóżki. A dokładniej, pomiędzy nóżki podłączone do kolumn, a nóżki podłączone do rzędów. No i teraz ustawiamy masę tylko na jednym z rzędów (lub kolumn), pozostałe zostawiając w trybie wejścia, a na kolumnach (lub rzędach, odpowiednio) ustawiamy rezystory podciągające i odczytujemy wartości. W ten sposób sczytamy stan klawiszy z jednego rzędu (lub kolumny) i operację powtarzamy dla innego. Robimy to bardzo szybko, więc opóźnienie jest niezauważalne dla człowieka. Ale po co te diody? No bo niestety może się zdarzyć, że wciśnięte zostaną dwa (lub więcej) klawisze, wówczas rząd na którym ustawiliśmy masę będzie połączony przez przełącznik jednego z tych klawiszy z kolumną, a ta z kolei będzie połączona z innym rzędem przez przełącznik innego wciśniętego klawisza — w rezultacie masę będziemy mieć na dwóch (lub więcej) rzędach jednocześnie i nie będziemy mieć sposobu na zgadnięcie które dokładnie klawisze są wciśnięte. Tanie klawiatury radzą sobie z tym prosto: po prostu uznają, że wciśnięte są wszystkie, przez co uzyskujemy zaskakujący wynik: tak zwany "ghosting". My chcemy porządną klawiaturę, więc na każdym przełączniku jest dioda zapobiegająca połączeniu rzędów. Dalej poszło już z górki: użyłem gotowego oprogramowania z projektu TMK (https://github.com/tmk/tmk_keyboard), więc jedyne, co trzeba było napisać, to dwie funkcje: jedna do ustawiania odpowiedniego rzędu i jedna do sczytywania jego stanu. Skopiowałem i przerobiłem po prostu przykłady. Do tego definicją który klawisz ma wysyłać jaki kod (lub modyfikator) i gotowe. Na koniec dołożyłem ładny kabel USB w otulinie z plecionki i dorobiłem obudowę z arkuszy tworzywa sztucznego: Troszkę ta obudowa wyszła niechlujnie, ale klawiatura działa i jest nawet wygodna — byłem z projektu zadowolony. Tylko pojawił się jeden mały problem: pracując nad tym projektem odkryłem bardzo dużo narzędzi i informacji o robieniu klawiatur. W tym między innymi oprogramowanie do projektowania własnych układów klawiszy i do generowania z nich plików do wycięcia laserem własnej obudowy. Znalazłem też gdzie można kupić mechaniczne przełączniki i same klawisze okazyjnie, postanowiłem więc zbudować kolejną klawiaturę od zera. Alpen Clack 2 Stanąłem przed kilkoma ważnymi wyborami. Po pierwsze, chciałem standardowy układ amerykański (ANSI), ale bez numpada (tenkeyless). Użyłem zatem jednego z presetów na http://www.keyboard-layout-editor.com/ i usunąłem numpad. Przy okazji przesunąłem nieco też klawisze funkcyjne i zrobiłem tam miejsce na dodatkowy klawisz. Następnie skopiowałem json-a z definicją klawiatury i wkleiłem do http://builder.swillkb.com/ aby wygenerować pliki do wycięcia laserem. Lokalny FabLab wyciął mi je bez problemu. Wybór przełączników miałem ograniczony budżetem, ale zdecydowałem się na brązowe Gaterony. Czemu brązowe i czym się one różnią od niebieskich albo czerwonych? Albo innych jeszcze kolorów? Długo by tłumaczyć, ale w dużym skrócie różne "kolory" przełączników mają różnie ustawione mechaniczne elementy tak, aby dawać odpowiednie wrażenie przy ich wciskaniu. Niebieskie przełączniki to te najbardziej znane z klawiatur mechanicznych, wydają przy wciśnięciu charakterystyczne głośnie kliknięcie, które odczuwane jest też w bardzo satysfakcjonujący sposób dotykiem. Czerwone przełączniki natomiast nazywane są "liniowymi" bo nie wydają odgłosu ani nie mają żadnego dotykowego powiadomienia o tym, że się włączyły. Przełączniki brązowe są pewnym kompromisem — wyczuć można w nich przełączenie, ale nie hałasują tak głośno, jak niebieskie. Nie mając doświadczenia postanowiłem pójść na ten kompromis. Klawisze wybrałem z tego co akurat było w danym momencie dostępne za rozsądne pieniądze i w ładnym kolorze. Nie widziałem wtedy jeszcze nic o profilach, różnych wysokościach klawiszy i różnych sposobach ich wykonania. Oprócz tego kupić trzeba było też tak zwane "stabilizatory", czyli kawałki drutu i plastikowe uchwyty do nich, które montuje się pod wszystkimi dłuższymi klawiszami po to, aby wciskały się zawsze całe naraz, bez względu na to w którym miejscu je naciśniemy. Jako mózgu użyłem tym razem płytki Pololu A-Star 32U4 Mini ULV — bo ma ten sam mikrokontroler ATmega32u4 co Pro Micro, ale z wyprowadzonymi wszystkimi nóżkami. Spodobała mi się tez biała płytka PCB, która w tamtych czasach była jeszcze rzadkością, Diody musiałem kupić tym razem własne, podszedłem też nieco bardziej profesjonalnie do połączeń: Przezroczysta obudowa w końcu trochę zobowiązuje. Oprogramowanie w zasadzie jest takie samo, musiałem tylko zmodyfikować definicje który klawisz jest który. Gotowa klawiatura wygląda tak: Niestety, pomimo faktu, że jest to dobra klawiatura, jakoś nie nauczyłem się jej używać. Znacznie później uświadomiłem sobie dlaczego, kiedy wypróbowałem kilka innych mechanicznych klawiatur: standardowe mechaniczne klawiatury, z pełnowymiarowymi przełącznikami są dla mnie za wysokie. Zazwyczaj rozwiązuje się ten problem stosując podkładki pod nadgarstki, ale dla mnie to nigdy nie działało, tym bardziej, że droga klawisza jest dla mnie zbyt wielka, nawet po dodaniu do nich "uszczelek" aby ją zmniejszyć. Wciskając klawisz mam wrażenie, że za chwilę wpadnę do środka klawiatury. Kiedy sobie to uświadomiłem, dałem sobie spokój z klawiaturami mechanicznymi ma ładnych kilka lat. 5plit Któregoś dnia dowiedziałem się, że w moim mieście odbywa się spotkanie miłośników klawiatur. Postanowiłem na nie pójść nie tyle z miłości do klawiatur, co z chęci pochwalenia się moimi dwoma projektami. Okazało się, że spotkanie było bardzo ciekawe i dowiedziałem się na nim o wielu rzeczach, między innymi o planowanych przez firmę Kailh przełącznikach o niskim profilu, zwanych "czekoladowymi" (choc switches). Sprawdzałem od tego czasu stronę tej firmy regularnie, niestety najmniejsze zamówienie jakie można było zrobić to 800 sztuk, więc pozostawały poza moim zasięgiem. Zastanawiałem się czy nie złożyć się może w kilka osób, ale jakoś nigdy z tego nic nie wyszło i o sprawie zapomniałem. Rok później spotkanie odbyło się ponownie i tym razem pojechałem bardziej żeby pooglądać ciekawe klawiatury i dowiedzieć się nowinek. No i dowiedziałem się, że Kailh sprzedaje swoje przełączniki na sztuki na Aliexpressie, razem z pasującymi klawiszami, a do tego kupiłem od jednego z uczestników płytki do dwuczęściowej klawiatury jego projektu używającej tych przełączników: Klawiatura nazywa się 5plit is jest minimalistyczna, ale jak tylko jej spróbowałem, to wiedziałem, że to są przełączniki, na które czekałem całe życie. Po zmontowaniu jej własnej wersji i zabawie z różnymi układami klawiszy odkryłem też uroki minimalistycznych klawiatur z "warstwami" — czyli różnymi funkcjami poszczególnych klawiszy przełączanymi za pomocą dodatkowego klawisza. Niestety na tym etapie nie potrafiłem jeszcze pisać poprawie wszystkimi palcami, głównie używając trzech palców u każdej ręki i czasem wciskając klawisze z lewej strony klawiatury prawą ręką, więc taka dwuczęściowa klawiatura nie była dla mnie łatwa w użyciu. Starałem się na niej ćwiczyć, ale do codziennego korzystania z komputera preferowałem jednak klawiaturę kupną (udało mi się w końcu znaleźć kupną klawiaturę używającą tych samych przełączników i jest to najlepsza kupna klawiatura jaką kiedykolwiek miałem, choć nadal jest dość wysoka). Flounder Na tym etapie postanowiłem, że skoro w sklepach nie ma takich płaskich klawiatur jak ja bym chciał, to sam sobie taką zrobię. Postanowiłem, że posunę się tak daleko jak to tylko możliwe używając nawet niższych przełączników niż te w 5plit — wpuszczanych w płytkę drukowaną. Chciałem też, żeby klawiatura miała tradycyjny układ, ale była minimalistyczna, więc tym razem zdecydowałem się na układ 65%. Zamówiłem na Aliekspresie przełączniki i zestaw klawiszy i zabrałem się do projektowania płytki. Tak naprawdę to ten projekt stał się możliwy tylko dlatego, że mniej więcej w tym czasie płytki drukowane większe niż 10x10cm stały się dostępne cenowo dla hobbysty, choć nadal była to inwestycja. Zaprojektowanie płytki wymagało trochę pracy, bo trzeba było zrobić wycięcia na każdy klawisz, a następnie poprowadzić ścieżki pomiędzy nimi. Udało mi się to z tylko dwoma małymi błędami, które poprawiłem drucikami. Pożegnałem się także z wysłużoną Atmegą32u4 i użyłem SAMD21, który stał się na tym etapie moim ulubionym mikrokontrolerem. Dodanie do CircuitPythona obsługi USB pozwoliło mi napisać kod kontrolujący klawiaturę w tym języku, co też było miłą odmianą. Z fizycznych problemów najgorsze okazały się stabilizatory. Kailh oferuje specjalne stabilizatory dla tych klawiszy, ale montowane są one po drugiej stronie PCB, co w moim przypadku jest niedopuszczalne, bo płytka ma leżeć płasko na stole. W ostateczności zbudowałem własne stabilizatory ze spinaczy do papieru: Generalnie rzecz biorąc projekt okazał się przełomowy, bo nauczyłem się na nim bardzo dużo. Niestety, ostateczny jego wynik, czyli sama klawiatura, okazała się nieużywalna z trzech powodów. Po pierwsze, postanowiłem ją zrobić tak małą jak się da, więc popełniłem kardynalny błąd eksperymentując z odstępami klawiszy i zamiast użyć standardowego 1U (czyli 0.75" albo 19.05mm) upchnąłem je tak gęsto, jak na to pozwoliła wielkość klawiszy. Okazuje się, że to źle współpracuje z ludzką pamięcią mięśniową i po prostu nie trafiam w klawisze. Po drugie, przełączniki wpuszczane w płytkę okazują się być znacznie gorszej jakości niż zwykłe choc switches i po prostu nie są tak przyjemne. Po trzecie, nie udało mi się zrobić tak, żeby płytka była całkowicie płaska z tyłu, a przy tej wielkości niestety lekko się ona wygina. Można zatem powiedzieć, że operacja się udała, ale pacjent zmarł. Klawiatura jest i wygląda i działa dobrze, ale nie da się jej używać. Dorsch 40k i 48k Minął rok. Spotkanie klawiaturowe nie odbyło się z powodu plagi, ale naszła mnie ochota ponownego eksperymentowania z klawiaturami. Zniechęcony flądrą postanowiłem jednak ograniczyć ryzyko i zrobić małą klawiaturę — mając mniejszą płytkę i mało przełączników będzie tańsza. Pogodziłem się już z używaniem kupnej klawiatury na co dzień i to miał być bardziej eksperyment. Chciałem mianowicie zobaczyć jak wygodna będzie klawiatura z zaledwie 40-ma klawiszami, ale używająca niektórych klawiszy w podwójnych rolach. Pomysł był taki, żeby na przykład przy naciśnięciu i puszczeniu klawisza wysyłać Esc, ale przy przytrzymaniu i naciśnięciu jednocześnie innego klawisza traktować to jak Ctrl... Klawiaturę nazwałem Dorsch kontynuując nazewnictwo płasko-rybne. Zacząłem oczywiście od zaprojektowania układu klawiszy. Zmienił się on potem kilka razy w miarę jak używałem klawiatury, więc zamieszczę tutaj wersję ostateczną: Dolne legendy mówią jak klawisz działa gdy się go przytrzyma, górne co gdy się go wciśnie normalnie, a te po prawej co jak z klawiszem Fn. Zamówiłem 40 przełączników i zestaw klawiszy, zaprojektowałem i zamówiłem płytkę — ponownie użyłem SAMD21. Wszystko przyszło po dwóch tygodniach, więc zmontowałem i zacząłem testować: Pierwsze zdziwienie: tego się nawet da używać! Ręce trochę uciekają do backspace-a w złym miejscu i do esc, ale po jednym dniu udało się pokonać odruchy. Drugie zdziwienie — ja piszę poprawnie wszystkimi palcami! Jak to, przecież nigdy się tego nie mogłem nauczyć! Czyżby fakt, że klawisze są w prostych kolumnach i nie ma gdzie przesuwać rąk to spowodował? Po używaniu tej klawiatury jako głównej przez tydzień stwierdziłem, że jest bliska ideału, ale jednak to jeszcze nie to. W międzyczasie ktoś na Twitterze zauważył, że taka klawiatura, ale z efektami świetlnymi programowalnymi w CircuitPythonie byłaby fajna. Zaprojektowałem i zamówiłem zatem jeszcze dwie płytki (i jeszcze jeden zestaw przełączników): Pierwsza to to samo, tylko z LED-ami RGB pod każdym klawiszem. W zasadzie nuda, tylko strasznie ciężko było polutować APA102 w opakowaniach QFN, dużo poprawiania zanim wszystkie zaświeciły. Biblioteki do animacji Adafruit ma gotowe, więc nawet mi się po zmontowaniu nie chciało tego programować. Jest ten sam kod co na oryginalnej klawiaturze, z której zresztą przełożyłem przełączniki. Druga natomiast to jest to, na czym piszę ten artykuł. Z ilości tekstu możecie się zapewne domyślić, że bardzo mi pasuje. Dwie dodatkowe kolumny pozwoliły umieścić backspace, tab, enter i esc na ich prawowitych miejscach, a drugi klawisz przełączający warstwy zapewnia dużo wygodniejszy dostęp do symboli. Stabilizator pod spacją sobie odpuściłem, choć może kiedyś zrobię jakiś ze spinacza znowu i przylutuję go na górze płytki tym razem, ale klawisz jest na tyle mały, że nie jest to konieczne. Turbot Pomyślelibyście, że po tym wszystkim będę wreszcie zaspokojony klawiaturowo. Ale okazuje się, że sukces zachęca do dalszego działania i eksperymentów. Nie chcąc chwilowo wydawać więcej pieniędzy na kolejne przełączniki postanowiłem, że skoro flądra nie działa jak należy, to szkoda trochę żeby tak leżała — wylutuję z niej te nieszczęsne przełączniki i spróbuję zbudować coś ciekawszego. Usiadłem do tego na poważnie, konsultując się na klawiaturowych forach z ludźmi z doświadczeniem i popełniłem taki projekt: Tym razem mamy do czynienia z klawiaturą w pełni ergonomiczną, złamaną na środku, ale nadal z 65% klawiszy, bez warstw (no, chyba, że do F1-F12). Klawisze w kolumnach, kolumny poprzesuwane zgodnie z długością i zasięgiem palców. Zrobiłem do tego płytkę: Tym razem od razu zakładam stabilizatory ze spinaczy, ale na górze płytki, więc dół ma być płaski. Odstępy między klawiszami takie jak mają być. Płytka powinna przyjść za tydzień, to napiszę co wyszło...
  11. 11 punktów
    Autonomiczny robot mobilny z nawigacją GSP W życiu każdego studenta przychodzi monet, kiedy musi się spiąć i zrobić pracę inżynierską. Jako, że większość proponowanych tematów przez uczelnię nie wpadło w obszar moich zainteresowań, a już od jakiegoś czasu chciałem „pobawić się” w budowę robota z GPS to właśnie taki temat zaproponowałem promotorowi i bez problemów został zaakceptowany (kierunek – AiR). Potem jak się okazało nie był to do końca dobry pomysł z uwagi na problemu w testowaniu GPS – testy przypadły głównie na styczeń – a więc w tym roku deszcze itp. a nawigację trzeba jednak testować na dworze. To tyle tytułem wstępu a teraz do bardziej praktycznych zagadnień. Robot z założenie miał być 2 kołowy + jedno koło wleczone, posiadać moduł bluetooth do wstępnej kalibracji i wpisywaniu współrzędnych, sterowany za pomocą Arduino Nano (w tym przypadku klon), a jego zmysłami poznawania świata miał być: moduł GPS Neo-6m, magnetometr oraz 3 czujniki ultradźwiekowe z przodu do wykrywania przeszkód. Przeszukałem pełno gotowych platform mobilnych ale żadna mi do końca nie pasowała, a że od niedawna byłem właścicielem drukarki 3D to postanowiłem zaprojektować własną i wydrukować z PLA. Projekt owej platformy zrobiłem w środowisku CAD w programie Solid Edge i wyglądał tak jak poniżej. Składa się z 2 platform oraz miejsca na czujniki ultradźwiękowe: dolna na arduino, sterownik i akumulator, a górna na pozostałe podzespoły. Jak widać pokusiłem się o zamodelowanie również felg do już gotowych kół – okazało się że mają efekt „ósemkowania” co uniemożliwiało prostą jazdę. Koło wleczone zastąpiłem jednak Ball Caster'em, ponieważ te które użyłem miało straszne luzy i również powodowało samoczynną jazdę po łuku. A tak prezentuje się już wydrukowana i złożona platforma: Jako że wszystko było zamodelowane w CAD’zie to mogłem porobić rysunki złożeniowe rodem jak z sklepów meblowych (może projektowanie mechaniczne to dobry pomysł na artykuł ) Kolejnym krokiem było zrobienie elektroniki. Aby wyglądało to w miarę estetyczniej to pokusiłem się o zrobienie płytki PCB – projekt w KiCad'zie a potem termotransferem na laminat (tam gdzie Arduino to płytka dwustronna, a tam gdzie moduły jedno) Jeszcze tylko zasilanie – Li-Pol 2s firmy Redox (pomocny w ogarnięciu tego tematu był artykuł na Forbocie – wielkie dzięki za kompendium wiedzy w pigułce) i możemy zaczynać programować – a to dla mnie było największym wyzwaniem. Wrzuciłbym kod ale to jest 700 linijek napisanych raczej łopatologicznie więc tylko ja się w nim odnajduję Jak byście mieli jakieś pytania odnośnie działania jakiejś części to podrzucę i postaram się wyjaśnić. Jako, że byłem na AiR no to fajnie by było wrzucić jakiś nawet prosty regulator – zdecydowałem się na Proporcjonalny a układ regulacji wygląda następująco: (KSN – kompensacja strefy nieczułości) Działał on dosyć dobrze, im robot "był dalej" od zadanego kontu tym szybciej obracał się a im bliżej tym zwalniał, zaś przeregulowanie było znikome. Gotowy robot prezentuje się tak: Niestety wszystko nie było takie piękne i proste, a to niektóre napotkane problemy Magnetometr praktycznie nie działał. Wskazywał azymut w przedziale może z 0-15o. Powodem było pole magnetyczne wytwarzane przez magnesy silników. Google jednak nie znały odpowiedzi co zrobić z tym faktem więc testowałem po kolei różne warianty i tak o to idealnym rozwiązaniem okazało się umieszczenie silników w stalowe rurki. Z powody złych warunków na dworze testowanie robota nie było zawsze możliwe. Arduino też nie wyrabiał jak dostawał tyle danych (GPS okazał się bardzo obciążający – w momencie kiedy dostawał pakiet danych to Ardu zaczęło wariować). GPS i bluetooth nie mogły działać w tym samym momencie więc nie miałem możliwości zdalnie dowiedzenia się co robot w danej chwili „miał na myśli”. Generalnie to wszystko działało ale osobno: jak testowałem unikanie przeszkód i ustawianie się na dany kąt to była gitara. Dołożyłem do tego GPS to raz działało a raz nie – jak wspomniałem po dostaniu pakietu danych zaczynał wariować przez chwilę. W planach mam zamianę Ardu na STM32 i spróbowanie ponownie ruszyć temat. Dodatkowo napisałem prostą aplikację w C#, która komunikowała się z robotem przez bluetooth i można było łatwiej testować podzespoły i wprowadzać współrzędne. Praca została obroniona na 5 więc było warto poświęcić nad tym dużo czasu. Zapraszam do komentowania
  12. 11 punktów
    Czasem gdy zaprojektujemy jakiś szczególnie udany projekt, chcielibyśmy wyprodukować więcej niż tę jedną czy dwie sztuki — żeby sprzedać, rozdać, użyć w warsztatach czy jakiekolwiek inne zastosowanie wymyślimy. No i pojawia się problem, bo co innego zmontować jeden prototyp, a co innego ślęczeć codziennie i składać ten sam projekt od nowa kilkadziesiąt razy. Oczywiście możemy sobie życie ułatwić stosując bardziej zaawansowane narzędzia, ale o ile jeszcze przerobienie opiekacza na piecyk do wypalania płytek ma sens, o tyle kupowanie maszyny pick-and-place dla jednego projektu ma sens mniejszy. Na szczęście istnieją fabryki, które z dziką rozkoszą dla nas taki projekt wyprodukują. Jak to wygląda w praktyce? Usługa, której szukamy nazywa się po angielsku "PCB assembly" i zazwyczaj firmy, które robią płytki drukowane także oferują ich montaż. Aby skorzystać z takiej usługi, musimy mieć trochę więcej dokumentacji do naszego projektu: pliki gerber z projektem płytki — panelizację chyba w tym wypadku lepiej zostawić fabryce, wtedy zrobią to tak, żeby im jak najlepiej pasowało do reszty procesu, plik pick-and-place zawierający pozycje wszystkich komponentów — zazwyczaj program generujący gerbery także generuje ten plik, lista komponentów — wraz z nazwami na płytce, wielkością i wartością, oraz najlepiej z linkami do przykładowych podzespołów w sklepach, parametry płytki — kolor, grubość, wykończenie, dodatkowe wymagania, liczba sztuk, jaką zamawiamy, jeśli nasz projekt wymaga programowania, to wysyłamy firmware do wgrania i instrukcje jak to zrobić, opcjonalnie, instrukcja testowania, uwagi na temat montażu i/lub pakowania. Kiedy już skompletujemy powyższe informacje, załączamy je wszystkie do e-maila, w którym prosimy fabrykę o wycenę. Zazwyczaj po jednym lub dwóch dniach dostaniemy informację na temat tego ile to będzie kosztować i ile potrwa. Możemy w tym momencie dopytać o szczegóły, zmienić pewne rzeczy, etc. — kiedy będziemy zadowoleni z oferty, płacimy i fabryka produkuje i wysyła nasze urządzenia. Kilka uwag praktycznych: Warto wysłać zapytania do kilku fabryk, żeby mieć rozeznanie na temat tego ile to powinno kosztować, ale też dlatego, że różne fabryki będą wyceniać stosując różne reguły i nasz specyficzny projekt może wychodzić drogo w jednej, ale dużo taniej w innej. Rozmawiamy z żywymi ludźmi, więc choć zazwyczaj nie mają oni za dużych marginesów żeby móc się z nami targować, przynajmniej mogą nam doradzić co zmienić żeby było taniej/łatwiej/bardziej niezawodnie. Kiedy już wysyłamy zapytanie, to warto zapytać od razu o różne ilości. Na przykład jeśli chcemy zrobić czegoś 40 sztuk, to można zapytać o 20, 40 i 100. Nieraz jest tak, że 100 sztuk będzie kosztować tyle samo co 40, bo będą robione na linii produkcyjnej zamiast ręcznie, a części będą zamawiana hurtowo. W liście komponentów warto podać które komponenty chcemy oryginalne, a które fabryka może wymienić na równoważne zamienniki — szczególnie jeśli chodzi o oporniki, kondensatory, etc. zazwyczaj mają w magazynach części tańsze i gotowe do użytku od razu. Nie musimy się obawiać, że fabryka ukradnie nasz projekt i zacznie go sprzedawać. Zazwyczaj nie interesuje ich zupełnie co to jest i do czego ma służyć, ani nie chce im się dochodzić jak się tego używa i pisać własnej dokumentacji. Klonowane są projekty, które już są popularne. Na koniec jeszcze kilka rad dotyczących samego projektu. Kiedy robimy coś dla siebie, to nie obchodzi nas za bardzo optymalizacja kosztów i łatwości montażu — w końcu zrobimy to tylko raz. Kiedy projektujemy dla fabryki, to każda oszczędność zostanie pomnożona przez liczbę zamawianych sztuk, więc gra może być warta świeczki. Zatem: Unikamy elementów przewlekanych i "łatwych do lutowanie" opakowań — na przykład zamiast TQFP lepiej użyć QFN, bo jest tańszy, mniejszy i łatwiej go masowo montować. Minimalizujemy liczbę komponentów — mamy 4 takie same oporniki? Czemu nie użyć komponentu, który ma je w jednym opakowaniu ("resistor array"). Czy naprawdę potrzebujemy do wszystkiego pin headery, czy niektóre z nich mogłyby być po prostu test padami? Ułatwiamy programowanie i testowanie. Nikt nie będzie dolutowywał drucików do nóżek naszego mikrokontrolera żeby go zaprogramować — powinniśmy wyprowadzić odpowiednie połączenia. Mniejsze płytki nie tylko są tańsze, ale też mniej ważą (także cieńsze płytki), więc mniej zapłacimy za wysyłkę. Czy na pewno wszystko musi robić fabryka? Jeśli sprzedajemy moduł, to nóżki do niego użytkownik sobie może sam dolutować (szczególnie, jeśli będzie chciał inne niż nasze). Zanim zamówimy czegoś 100 sztuk, warto zrobić jeden prototyp dokładnie taki, jak będziemy zamawiać, żeby upewnić się, że na pewno wszystko jest dobrze. Poprawianie 100 płytek nie jest przyjemne. Jeśli udokumentujemy procedurę testowania, to nam w fabryce mogą płytki przetestować. Zazwyczaj i tak będziemy musieli za te zepsute zapłacić, przynajmniej złapiemy problem wcześniej, zanim cała paczka dojdzie do nas. Jeśli nasz projekt wymaga dodatkowo obudowy czy innych elementów mechanicznych, warto o to także zapytać w fabryce — bardzo często mają zaprzyjaźnione serwisy, które będą w stanie to dla nas zrobić, mimo, że sami nic takiego oficjalnie nie oferują. To samo jeśli chodzi o opakowania (standardowo po prostu włożą każdą sztukę do woreczka antystatycznego i całość w karton).
  13. 11 punktów
    Jakoś tak przed dwoma miesiącami mój kochany synuś przy okazji wizyty w domu stwierdził, że jest mu niesłychanie potrzebny theremin i to szybko. Jako że oryginalne instrumenty są conieco przydrogie postanowiłem po konsultacji zrobić odpowiednik instrumentu samodzielnie. Początkowo myślałem, że mam czas do Gwiazdki - okazało się że zamiast dwóch miesięcy mam na zrobienie wszystkiego dwa tygodnie. W tej sytuacji nie było szans na jakąś bardziej skomplikowaną konstrukcję - postanowiłem jak zwykle wykorzystać w większości elementy które miałem w domu i postawić na czysto cyfrową wersję. Z uwagi na krótki termin musiałem pracować praktycznie bez planu, metodą "kolejnych przybliżeń", stąd trochę nietypowa kolejność prac. Jako "serce" instrumentu postanowiłem wykorzystać ESP32 (płytka DevKit miała zawiadywać konstruowanym właśnie robotem, który na razie został odłożony na półkę). DAC ze wzmacniaczem został na razie wyjęty z "Ciapka". Przede wszystkim musiałem sprawdzić, jaki dźwięk mogę uzyskać z tego zestawu. Po prowizorycznym podłączeniu okazało sie, że mój pecet na gnieździe USB ma ok. 4.3 V, a po podłączeniu ośmioomowego głośniczka próba wyemitowania jakiegokolwiek sensownego dźwięku kończy się brownoutem ESP. Cóż - lutownica w dłoń, znalazłem jakieś luźne gniazdko 5.5/2.5, porządny zasilaczyk 5V, diodę dla bezpieczeństwa... no i zagrało. Nawet całkiem nieźle. Teraz przyszła kolej na sensory. Wypróbowałem kilka różnych, począwszy od zwykłego zestawu dioda/fototranzystor, poprzez HC-SR04, laserowe TOF aż po czujniki odległości Sharpa. O ile lasery sprawdziłyby się pewnie bardzo dobrze - o tyle ESP ma poważne problemy z jednoczesnym generowaniem dźwięku i gadaniem po I2C (niestety, nie doszedłem do tego skąd się tak naprawdę biorą ale nie miałem czasu sprawdzać), pozostałem więc przy Sharpach. W tym momencie mogłem już założyć, że coś mi wyjdzie. Jeszcze nie bardzo wiedziałem co, ale ważne, aby wyszło - mogłem się więc zająć czymś, co szumnie nazwałem "projektowaniem". Przede wszystkim, po policzeniu nóżek w ESP32 oraz przejrzeniu zawartości szuflad doszedłem do wniosku, że instrument będzie miał: klawiaturę matrycową 4x4 (do czego miałaby służyć miałem wymyślić pisząc program) cztery potencjometry regulujące różne ciekawe rzeczy (jakie - to miałem rozstrzygnąć później) cztery dodatkowe klawisze (dwa do przełączania oktaw i po jednym do zakresu sensora PITCH i trybu DUAL) pięć diod LED sygnalizujących różne mądre rzeczy mały wyświetlacz OLED 128 x 64 Dodatkowo docelowo miałem wykorzystać inny przetwornik DAC, ale to już musiałem dodatkowo zamówić; ponieważ ten przetwornik już znałem i miałem go w radyjku internetowym postanowiłem, że zamówię go później (być może coś jeszcze będzie potrzebne), a w razie konieczności (np. skończą sie w magazynie w Botlandzie) jakoś przeżyję jakiś czas bez radyjka. Na szczęście nic to na tym etapie nie zmieniało, więc pozostałem na razie przy podłączonym moim przetworniko-wzmacniaczykiem od Ciapka i głośnikiem (chyba) od jakiegoś taniego gramofonu. Tak więc pod względem elektroniki całość przedstawiałaby się następująco: A więc Eagle, projekt, laminat, termotransfer... i tu zonk: moja nowiutka drukarka nie nadaje się do tych celów, a wysłużona Kyocera właśnie się wyprowadziła do nowego właściciela Nie ma problemu. Telefon do kumpla od frezarki, zrobisz mi... A tak, zrobi. Za dwa tygodnie bo akurat swoją frezarkę przerabia (co u niego jest normalne). Dlatego właśnie na zdjęciu widzimy płytkę uniwersalną. Wyprzedzę trochę bieg wydarzeń: co prawda sprawę zasilania rozwiązałem na samym końcu (chciałem koniecznie mieć akumulator ale gdyby mi nie starczyło czasu podłączyłbym zwykły zasilacz), ale jako że pokazuję urządzenie praktycznie przed ostatnim zamknięciem obudowy - pokażę również jak mam to zrobione: Ponieważ zarówno przetwornicę, jak i ładowarkę miałem nie było sensu wysilać się na jakieś poważniejsze rozwiązania. Jeśli ktoś mi podpowie jak to zrobić lepiej (najchętniej bez przełącznika zasilacz/akumulator) będę bardzo wdzięczny. Skoro sprawę kabelków miałem już rozwiązaną, przyszedł czas na zaprojektowanie jakiejś obudowy. Oczywiście mógłbym całą obudowę wydrukować, ale z uwagi na termin i na to, że pewnie będzie fafnaście poprawek postanowiłem zrobić to inaczej: dolna i górna płyta wycięte ze spienionego PCW 4mm,a wydrukowane tylko ramka i boki. Ponieważ obróbka PCW jest prosta i zajmuje niewiele czasu (w sumie kwestia przycięcia ostrym nożem) mogłem pozwolić sobie na wydrukowanie jedynie szkieletu, mocując doń obie płyty. Powiem szczerze że był to dobry pomysł; co prawda górna płyta wyszła "nieco" krzywo (tak to jest, jak się tnie i wierci w ręku), ale nie traciłem czasu na wielokrotne próby. Dzięki temu jedyne co mnie ograniczało to wielkość stołu mojej Anetki (ramka musiała być wydrukowana w całości). Co prawda ktoś może twierdzić że mógłbym wydrukować jakąś wersję finalną - ale na to naprawdę nie było już czasu (całość skończyłem na kilka godzin przed oddaniem maszynki w ręce użytkownika, w związku z tym nawet drukarka by się nie wyrobiła w czasie). Wyszło jak wyszło - wygląda to tak: Z przodu instrument nie wygląda za ciekawie, ale chciałem pozostawić dostęp do przycisków RESET i BOOT na płytce. I mała dygresja: program pisałem na komputerze z zainstalowanym Ubuntu 18.04, od paru dni robiłem ostatnie poprawki używając lapka z Debianem Stretch. Ta sama wersja Arduino IDE, ta sama wersja definicji ESP32. Na Ubuntu wymagane było wciśnięcie BOOT do zaprogramowania płytki - na Debianie nie trzeba. Ktoś wie może o co chodzi? Bo chciałbym, aby moje Ubuntu zachowywało sie tak samo I to by było na tyle jeśli chodzi o kabelki, śrubki i plastiki - warto sobie przypomnieć, że cały czas równolegle powstawała część najważniejsza, czyli PROGRAM. Ponieważ napisanie w ciągu dwóch tygodni od zera programu na płytkę, którą pierwszy raz trzymam w ręku i to z dziedziny, w której akurat mistrzem wcale nie jestem to bardzo ryzykowny pomysł - postanowiłem nie wygłupiać się i użyć sprawdzonych rozwiązań. Jako że grałem kiedyś na małym Moogu (Rouge) naturalne dla mnie było zasymulowanie właśnie analogowego syntezatora. Program symuluje działanie dwóch generatorów (VCO), z których jeden może być lekko odstrojony. Do wyboru są: sinus, prostokąt, piła oraz sześć dodatkowych fal składanych z 32 harmonicznych oraz szumu. Szum przepuszczany jest przez filtr o częstotliwości środkowej odpowiadającej wysokości dźwięku generatora A. Oba generatory mogą pracować z różnymi kształtami fal, dodatkowo zamiast filtrów VCF zastosowałem podwójne fale: fala pomocnicza miksowana jest z podstawową, a stosunek amplitudy obu fal regulowany jest albo poprzez sensor PITCH (najniższy dźwięk to fala podstawowa, najwyższy to pomocnicza, pośrednie wysokości to odpowiednio zmieszane obie fale) albo przez sensor VOLUME (wtedy do połowy odległości od sensora głosność wzrasta do 100%, w miarę dalszego zbliżania się następuje przejście z fali podstawowej na pomocniczą). Daje to dużo większe możliwości niż klasyczne filtry. Oczywiście - ten tryb (czyli Dual Mode) można wyłączyć - wtedy oba generatory pracują z falą podstawową. Generatory zrealizowane są poprzez przemiatanie z odpowiednim krokiem tablic fal. Każda z 4 tablic składa się z 4096 próbek float. Początkowo zastosowałem typ double do obliczeń - niestety okazało się, że ESP32 po prostu się nie wyrabia w czasie. Szkoda, bo różnica jest w niektórych przypadkach wyraźnie słyszalna; przy pewnych kształtach fal (szczególnie zawierających wysokie harmoniczne) przy odstrojeniu generatorów powstają artefakty, których nie było w wersji double (prawdopodobnie były, ale poniżej granicy słyszalności). Zakres instrumentu to 7 oktaw, przy czym sensor PITCH reguluje wysokość w zakresie max. dwóch oktaw, przełącznik OCTAVE UP/DOWN zmienia ton podstawowy. Dodatkowo przełącznik transpozycji pozwala na podniesienie skali od zera do 11 półtonów, a precyzer płynnie dostraja skalę o +/- jeden półton z rozdzielczością 5 centów. Najwięcej kłopotu sprawiły mi te nieszczęsne Sharpy. Generatory są skonstruowane tak, że wysokość dźwięku jest proporcjonalna do wartości sterującej (korzystam z wstępnie przeliczonych tablic dla interwału 5 centów, czyli praktycznie poza zakresem czułości ludzkiego ucha). Niestety - poziom napięcia na wyjściu czujnika jest proporcjonalny do odwrotności odległości (w pewnych granicach), do tego sygnał jest dość mocno zaszumiony. Okazało się jednak, że zastosowanie filtrów Kalmana poskutkowało praktycznie całkowitym usunięciem szumów, a 12-bitowe przetworniki wejściowe ESP32 pozwoliły mi uzyskać na wejściu wystarczającą rozdzielczość. Ponieważ zabawa z 32 harmonicznymi przy pomocy 16-klawiszowej klawiatury i zabawkowego OLED-a to absolutnie chybiony pomysł - do ustalania fal służy dość prosta aplikacja napisana w Pythonie. Aplikacja łączy się poprzez port Serial z instrumentem oraz uruchamia serwer HTTP na adresie localhosta. Działa bez problemu na Linuksie (Firefox, Chrome, Chromium), na Windows mogłem sprawdzić tylko Chrome i Edge. O dziwo - Edge poradził sobie prawie bez problemu (prawie robi wielką różnicę - okazało się że do odczytu wartości selecta musiałem użyć jQuery zamiat po prostu selectedIndex), natomiast Chrome nie potrafił nawet wyświetlić prawidłowo interfejsu... który wygląda mniej więcej tak: Oczywiście - konieczność zastosowania tej aplikacji nie oznacza konieczności ciągania za sobą komputera. Ponieważ użytkownik ma do dyspozycji 9 zestawów po 6 fal w każdym i może zapisać je w pamięci Flash urządzenia - powinno wystarczyć na koncert Minęło kilka dni... jako że w międzyczasie przyszedł z Botlandu DAC mogłem już zabrać Ciapkowy wzmacniaczyk. Ponieważ ta wersja nie posiada własnego wzmacniacza, a podłączenie jakiegoś prostego odsłuchu bywa konieczne - po prostu podłączyłem tam mały moduł wzmacniacza PAM8403 z potencjometrem (widać go na zdjęciu wnętrza urządzenia). W efekcie tylna ściana instrumentu wygląda tak: I to by było na tyle... A nie, wyjaśniam, że: Klawiatura służy do obsługi generatorów (przyciski A i B), zmiany transpozycji (przycisk C) i presetu/zestawu fal (przycisk D) LED-y sygnalizują tryb działania klawiatury (A, B, C i D) oraz włączenie stroju temperowanego Potencjometry regulują odstrojenie generatora B, balans generatorów, precyzyjne strojenie oraz czas portamento Wyświetlacz pokazuje: Fale generatora A (podstawowa 1, pomocnicza 2), tryb synchronizacji (LFO), fale generatora B (1 i 2), strój generatora B (Prima) Transpozycja (tonacja C, oktawa 2) tryb Double Mode (Vl - volume) Zakres sensora PITCH (1 oktawa) Numer presetu (Pg - zero) Numer zestawu fal (W - zero) Numer pasma głównego filtra dolnoprzepustowego (F - 8 ) A skąd nazwa InfraWave? Bo theremin (na falach eteru) produkcji Mooga nazywa się Etherwave, a mój jest a podczerwień Mam nadzieję że Moog nie opatentował jeszcze słowa Wave... I kilka słów o możliwej przyszłości. O ile powstanie następna wersja instrumentu (zależnie od zamówienia i widzimisię synka) należałoby poprawić kilka rzeczy. Przede wszystkim - trzeba by było zająć się generatorami. Może udałoby się zmusić je do pracy w arytmetyce double (potrzebne cztery mnożenia i trzy dodawania), a resztę (filtry, szumy itp.) robić na floatach. Prawdopodobnie jest to możliwe - ale na razie nie miałem czasu a eksperymenty. Ilość przeróżnych manipuladeł jest stanowczo za mała. Bezwzględnie konieczne są potencjometry do regulacji częstotliwości LFO, głośności ogólnej oraz dobroci głównego filtra szumów. Licząc potrzebne klawisze na razie wychodzi mi 22 (mam cztery) i 26 sztuk LED (mam pięć)... Warto by było pozbyć się pecetowej aplikacji - do tego potrzebny jest co najmniej enkoder obrotowy z przyciskiem i większy ekran (jakiś TFT, przynajmniej 320x240 albo i więcej). O ile czujnik Sharpa bardzo dobrze nadaje się na sensor VOLUME, o tyle sensor PITCH mógłby być nieco lepszy. Wymaga trochę eksperymentowania... Ogólnie jestem otwarty na propozycje - może ktoś ma jakieś lepsze pomysły Natomiast świetnie się sprawdza DAC od Adafruit, a więcej czasu pomogłoby mi w lepszym opanowaniu ESP32 (to on ma słuchać mnie, a nie ja jego!) Kody programów w załączniku: infrawave.zip. Nie jest potrzebna żadna dodatkowa biblioteka (drivery wyświetlacza i audio są zawarte w programie). Jak zwykle pozostaję do dyspozycji w razie pytań.
  14. 11 punktów
    Wyświetlacze stosowane w urządzeniach elektronicznych przeszły ogromną ewolucję. Można ją łatwo prześledzić chociażby na przykładzie telefonów komórkowych. Pierwsze modele miały monochromatyczne, często tekstowe wyświetlacze. W latach 90. ubiegłego wieku popularne były już wyświetlacze graficzne (oraz gra w węża). W kolejnych latach wyświetlacze monochromatyczne zostały prawie zupełnie wyparte przez modele z kolorową, aktywną matrycą, czyli popularne TFT. Spis treści: Sterowanie wyświetlaczem TFT - część 1 - wstęp, podstawowe informacje Sterowanie wyświetlaczem TFT - część 2 - analiza problemu Sterowanie wyświetlaczem TFT - część 3 - testy prędkości na STM32 Sterowanie wyświetlaczem TFT - część 4 - własny program Sterowanie wyświetlaczem TFT - część 5 - optymalizacja programu W przypadku urządzeń wbudowanych, wiele nowości dociera ze znacznym opóźnieniem. Podczas kursu Arduino wykorzystany został alfanumeryczny wyświetlacz 2x16 znaków, kursy STM32 F1 oraz STM32 F4 wykorzystywały graficzne, ale nadal monochromatyczne wyświetlacze (chociaż F4 o wiele nowocześniejszy OLED). Celem niniejszego artykułu jest pokazanie jak można we własnym projekcie wykorzystać kolorowy wyświetlacz TFT. Będzie to okazja do pokazania zarówno wad, jaki i zalet tego typu wyświetlaczy oraz podstawowych technik optymalizacji. Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. Wybór wyświetlacza Jednym z dość istotnych powodów powolnego wzrostu zainteresowania wyświetlaczami TFT była ich dość wysoka cena (w szczególności w porównaniu ze starszymi modelami monochromatycznymi). Obecnie ceny wyświetlaczy TFT bardzo spadły i model o niewielkiej przekątnej można kupić za podobną cenę do starszych urządzeń. Jako przykład użyję wyświetlacza o przekątnej 1.8 cala i rozdzielczości 160 na 128 pikseli firmy WaveShare. Dokumentację wyświetlacza, użytego sterownika oraz przykładowe programy znajdziemy na stronie producenta: https://www.waveshare.com/wiki/1.8inch_LCD_Module Również z tej strony pochodzi zdjęcie modułu wyświetlacza: Jak widzimy na zdjęciu jest to kompletny moduł. Na stronie producenta znajdziemy zarówno instrukcję obsługi, jak i schemat, jednak jest on tak prosty, że raczej niezbyt interesujący. To na co powinniśmy zwrócić uwagę to opis wyprowadzeń: Kolejny ważny parametr to model kontrolera, czyli ST7735S oraz jego dokumentacja. Wszystkie wspomniane dokumenty warto oczywiście przeczytać. Ale jeśli nie mamy akurat czasu na czytanie nieco ponad 200 stron, powinniśmy chociaż pamiętać gdzie szukać informacji. Podłączenie wyświetlacza Czas wybrać mikrokontroler i podłączyć do niego wyświetlacz. Przykłady dostarczone przez WaveShare są przeznaczone dla Arduino UNO, STM32F103, Raspberry Pi oraz Jetson Nano. Sensowność podłączania tak małego wyświetlacza do potężnego komputera jakim jest Raspberry Pi (o Jetson Nano nawet nie wspominając) jest mocno dyskusyjna więc ograniczę się do Arduino oraz STM32. Na początek Arduino UNO, bo to chyba najlepiej znana wszystkim platforma. Oczywiście wiele osób pewnie stwierdzi, że układ atmega328 jest o wiele za słaby na sterowanie kolorowych wyświetlaczem, ale skoro producent dostarczył gotowe przykłady warto chociaż spróbować. Sam interfejs jest opisywany jako SPI, ale szybkie spojrzenie na listę wyprowadzeń może nieco zaskoczyć. Po pierwsze używane są nieco inne nazwy, po drugie komunikacja jest jednokierunkowa (można tylko wysyłać dane do wyświetlacza), a po trzecie wreszcie jest sporo linii, które nie są obecne w standardowym interfejsie SPI. Musimy również zadbać o zasilanie układu z napięcia 3.3V oraz konwersję napięć sterujących - Arduino UNO używa sygnałów o napięciu 5V, co może uszkodzić wyświetlacz TFT. Do podłączenia użyłem modułu opartego o układ 74LVC245, można to zrobić taniej, lepiej itd. ale akurat miałem taki moduł pod ręką. Krótki opis wyprowadzeń wyświetlacza: 3V3, GND - zasilanie DIN - linia danych, podłączamy do MOSI interfejsu SPI CLK - zegar interfejsu SPI CS - odpowiada linii CS interfejsu SPI DC - informuje o rodzaju przesyłanych danych, stan niski oznacza komendę sterującą, a wysoki dane RST - stan niski resetuje sterownik wyświetlacza BL - sterowanie podświetlaniem Podłączenie do Arduino UNO jest dość proste, linie interfejsu SPI, czyli DIN i CLK należy podłączyć do pinów zapewniających dostęp do sprzętowego modułu SPI, pozostałe linie są sterowane programowo (chociaż BL można podłączyć do wyjścia PWM, aby uzyskać sterowanie jasnością podświetlenia). W programie przykładowym użyte wyprowadzenia są zdefiniowane w pliku o nazwie DEV_config.h, powinniśmy więc ustawić je odpowiednio do wybranego sposobu podłączenia. U mnie ten kod wygląda następująco: //GPIO config //LCD #define LCD_CS 7 #define LCD_CS_0 digitalWrite(LCD_CS, LOW) #define LCD_CS_1 digitalWrite(LCD_CS, HIGH) #define LCD_RST 5 #define LCD_RST_0 digitalWrite(LCD_RST, LOW) #define LCD_RST_1 digitalWrite(LCD_RST, HIGH) #define LCD_DC 6 #define LCD_DC_0 digitalWrite(LCD_DC, LOW) #define LCD_DC_1 digitalWrite(LCD_DC, HIGH) #define LCD_BL 4 #define LCD_BL_0 digitalWrite(LCD_DC, LOW) #define LCD_BL_1 digitalWrite(LCD_DC, HIGH) #define SPI_Write_Byte(__DATA) SPI.transfer(__DATA) Pierwsze uruchomienie Czas skompilować i uruchomić program przykładowy. Po drobnych poprawkach oraz ustawieniu wybranych pinów powinno udać się program skompilować. Warto zwrócić uwagę na ilość użytej pamięci: Jak widzimy wykorzystane zostało raptem 9348 bajtów pamięci Flash (28%) oraz 453 bajtów pamięci RAM (22%). To bardzo mało i jak później się przekonamy to jeden z powodów "niedoskonałości" tego rozwiązania. Ale na razie czas zaprogramować Arduino i podłączyć zasilanie: Dobra wiadomość jest taka że działa - i to w wysokiej rozdzielczości (160x128) oraz w kolorze... Zła jest taka, że może "niezbyt szybko" działa. Zanim stwierdzimy, że wyświetlacz do niczego się nie nadaje, warto nieco dokładniej przyjrzeć się przyczynom takich, a nie innych osiągów. Dzięki temu może uda się działanie programu nieco poprawić. Czas rysowania zawartości ekranu Pomiary "na oko" to niezbyt doskonała metoda, nieco lepiej dodać wywołanie millis() przed rozpoczęciem i po zakończeniu rysowania ekranu. Różnica między zwróconymi czasami pozwoli nam oszacować jak szybko (albo wolno) działa pierwszy program. Przy okazji możemy jeszcze sprawdzić ile zajmuje skasowanie zawartości ekranu. Nowy program w pętli rysuje i kasuje zawartość ekranu: Wyniki pomiarów to ok. 1240 ms dla rysowania oraz 96 ms dla kasowania zawartości. "Not great, not terrible" chciałoby się powiedzieć... Prosta animacja Wyświetlanie ekranu demonstracyjnego jest oczywiście interesujące, ale może warto sprawdzić jak ekran zachowa się w nieco bardziej pasjonującym zastosowaniu. Zacznijmy od odbijającej się piłeczki, taki wstęp do napisania gry w "ponga". Pierwsze podejście jest mocno uproszczone - w pętli głównej kasujemy zawartość ekranu, obliczamy pozycję piłki i rysujemy: Jak widzimy tempo gry jest raczej spokojne, a miganie irytujące. Warto jeszcze przetestować ile czasu zajmuje naszemu programowi rysowanie: Wyszło trochę ponad 100ms, to nieco więcej niż czas samego kasowania ekranu, więc jak łatwo się domyślić właśnie ta czynność zajmuje najwięcej czasu. Optymalizacja Skoro już wiemy, że najwięcej czasu zajmuje kasowanie ekranu, to może zamiast kasować wszystko warto usuwać jedynie poprzednią pozycję "piłki" i rysować nową. Taki program działa już znacznie lepiej: Porównajmy jeszcze czasy rysowania: Jak widzimy skasowanie i narysowanie piłeczki zajmuje o wiele mniej czasu. Nieco jednak uprzedzając dalsze części, spróbujmy jeszcze zamiast okrągłej piłki użyć kwadratowej. Może nie brzmi to zachęcająco, ale efekt robi wrażenie: Podsumowanie To co zobaczyliśmy to pierwsze możliwości optymalizacji. Nawet jeśli odrysowanie całego ekranu zajmuje mnóstwo czasu, możemy uzyskać o wiele lepsze efekty zmieniając sposób rysowania. To jedna z metod optymalizacji - nie jedyna i w kolejnej części postaram się opisać dlaczego rysowanie działa tak wolno i o ile możemy poprawić wydajność. Spis treści: Sterowanie wyświetlaczem TFT - część 1 - wstęp, podstawowe informacje Sterowanie wyświetlaczem TFT - część 2 - analiza problemu Sterowanie wyświetlaczem TFT - część 3 - testy prędkości na STM32 Sterowanie wyświetlaczem TFT - część 4 - własny program Sterowanie wyświetlaczem TFT - część 5 - optymalizacja programu
  15. 10 punktów
    Jakiś czas temu zakupiłem sobie ESP32 CAM, niestety nie umiałem dla niej znaleźć jakiegoś sensownego zastosowania. Przeleżała z pół roku a może i więcej, aż wpadłem na pomysł zrobienia foto-pułapki. I tak oto powstała: Po mojej posiadłości często biegają dzikie zwierzęta takie jak: sarny, bażanty, dziki i zające. Te ostatnie to raczej szkodniki ale lecimy z tematem dalej. Założenia: Zapis zdjęć na karcie SD Wysyłka zdjęć na FTP Wysyłka zdjęć na maila jakiś czujnik temperatury praca możliwie jak najdłużej z jednej baterii wspomaganej panelem PV Po ogarnięciu softu na biurku podłączeniu czujnika PIR wszystko ładnie działało. Za zasilanie odpowiada jedno ogniwo 18650, przetwornica podnosząca napięcie do 5V i mały panel PV 6V 167mA. Jak widać powyżej kamera jest przylepiona klejem dwuskładnikowym, tak by uniknąć uszkodzenia tasiemki. Wszystko zostało umieszczone w obudowie po NanoStation Loco M5. Która została dostosowana do zamontowania panelu PV, czujnika PIR oraz kamery. Poniżej etap pasowania elementów. Został również wydrukowany daszek oraz uchwyty dla szyby która osłania kamerę od deszczu. Obudowa Została dodatkowo pomalowana na czarno - ale chyba będę jej robić jakieś malowanie taktyczne, lub pójdzie w ruch “termoglut” i trzcina żeby się lepiej wtapiała w otoczenie. Pierwsze wyjście w teren i klapa, wszystkie zdjęcia były przejaśnione. Po kilku próbach okazało się że kamera potrzebuje 2s! aby dostosować czas ekspozycji, (lekka tragedia bo przy zajączkach to już go może dawno nie być w kadrze) oczywiście w warsztacie wszystko działało jak należy. Następnym nietrafionym pomysłem okazało się wysyłanie zdjęć na maila, trwa to stosunkowo długo a co za tym idzie zużycie energii jest większe, co doprowadziło do rozładowania baterii po 2 dniach. Konieczne było zrezygnowanie z wysyłki zdjęć na maila. W tej chwili kamera działa bez ładowania już 5 dni. Przykładowe zdjęcia z kamery poniżej: Trapi mnie jeszcze jeden problem mianowicie jeśli na zdjęciu jest więcej szczegółów np: cały kadr trzciny lub trawy, to obraz jest obcinany tak około 100-200px z dołu. Nie jest to chyba problem buforu w ESP bo przy kompresji ustawionej w sofcie na 10 zdjęcia zajmują 384KB jeśli zwiększę kompresje zdjęcia zajmują mniej a obraz i tak jest obcinany. Oprócz zdjęć wyzwalanych czujnikiem ruchu, procesor budzi się co 30 min wykonuje zdjęcie i wysyła je na FTP. To aby mieć pewność że bateria nie uległa rozładowaniu. A i jest jeszcze nieszczęsny czujnik temperatury DS18B20, nie było łatwo go tam upchać bo okazało się że wszystkie piny na płytce są wykorzystywane i jedyny wolny pin który mogę wykorzystać to pin serial RX, co niesie za sobą konieczność wypięcia czujnika w razie chęci przeprogramowania układu. Lista wykorzystanych elementów: ESP32-CAM AI-Thinker Przetwornica step-up 5V wraz z modułem ładowania ogniw 18650 Koszyk na ogniwo 18650 Czujnik PIR Mini panel PV 6V 167mA Antena 2.4 Ghz Podsumowując, działa aczkolwiek widać pewne ograniczenia tego układu chociażby czas jaki kamera potrzebuje na uruchomienie się. Z ciekawostek do ESP32 została podłączona zewnętrzna antena, gdzie przetestowany zasięg to około 200 m :), ale pewnie to też zasługa tego że łącze się do AP który mam wystawiony na dworze. Kodu programu pozwolę sobie w tej chwili nie udostępnić bo mam tam niezły bałagan, a jeszcze staram się uporać z obcinaniem fotek, za jakiś czas na pewno go zamieszczę.
  16. 10 punktów
    Jako fan klawiatur z makrami chciałbym podzielić się z Wami kolejnym projektem. Zaczęło się od małej klawiatury, o której wpis powstał na blogu, a tu już 3 klawiatura (w tym 2 na ESP32). Główną motywacją jest upraszczanie rozbudowanych skrótów klawiszowych, zastąpienie skrótów fikuśnym układem klawiszy oraz automatyzacja powtarzalnych czynności (niewykrywalny bot w grach?). Klawiatura ESP32 V1 Pierwsze podejście do klawiatury na ESP32 było dość udane. Dość... bo klawiatura była niezbyt praktyczna, acz jak na samoróbkę bardzo ładnie wykonana. Brakowało jej jedynie wieczka z czymś do klikania. Składając całość z kawałków HIPSu stwierdziłem, że wieczko to taki banał że wydrukuję w 3D... i tak wydrukowałem że niebyło jak tego przymocować. W końcu zniechęciłem się i projekt poszedł do szuflady. Upakowanie całkiem udane, zwłaszcza że nie ma tu dedykowanej płytki. Co więcej da się to rozebrać i ani grama hot glue! Klawiatura ESP32 V2 Do kolejnego projektu zabrałem się nieco lepiej. Założenia są takie: przyciski mechaniczne i zwykłe, różne rozmieszczenia (żeby czymś się wyróżniały), przyciski mają być duże, nie jak w pierwszej wersji, wzór dla "gejmerów", żeby był WSAD i co tam gejmer potrzebuje do klikania, wyświetlacz i menu do zmiany trybów, zasilanie USB C / akumulator. Wyświetlacz jest o tyle ważna, że używam różne programy (Corel, przeglądarka, Eagle, Fusion 360, TexWorks) i fajnie by było mieć coś do każdego, idealnie byłoby gdyby przy zmianie trybów coś działo się z przyciskami ale ostatecznie skończy się na wypaleniu w drewnie jakiś ślaczków jako wzorki przycisków. To jednak musi poczekać, najpierw elektronika i program. I tak powstał projekt płytki w programie Eagle, częściowo bazując na inżynierii odwrotna ESP32 dev module. Układ zasilania Myślę że za wyjątkiem walorów estetycznych jakiekolwiek powyżej widać, lepiej będzie obejrzeć schemat. Zacznijmy od zasilania, które pochodzi z 2 źródeł: USB C używanego do programowania i ładowania, akumulatora litowo polimerowego. Tu blok dotyczący USB: Złącze USB C oporządzone zgodnie ze sztuką, do tego transile żeby nie groziły przepięcia (to raczej wodotrysk ale niech będzie) i tu pierwsza gafa... zamieniłem D + z D- co odkryłem dopiero, gdy polutowana płytka nie chciała pogadać z komputerem. Wiec pierwsze 2 poprawki zagościły na płytce. Po prawej stronie widnieje typowy układ z dev modułów CP2101 zmontowany w konfiguracji zasilania z zewnętrznego źródła 3,3V. Więcej na ten temat można znaleźć we wpisie na temat układu CP2101/2, który dodałem jakiś czas temu. Z ciekawszych sygnałów mamy tu RX/TX służące do programowania, oraz DTR i RTS służące do wyzwalania programowania. Mamy tu też sygnał USB_5V (jest to nieco zbite 5V pochodzące z USB, które służy do aktywowania układu komunikacyjnego. Jest to potrzebne gdyż 3,3V będzie trafiać na układ cały czas, a ma on działać tylko przy podłączeniu po kablu (przy zasilaniu z akumulatora układ powinien być wyłączony). Widnieje tu też bardzo ważny sygnał, a zarazem zasilanie - VBUS. Jest to istotny sygnał przy przełączaniu źródła zasilania widoczny w kolejnym bloku: Tu widać diodę sygnalizującą zasilanie z USB (przy zasilaniu z baterii, gdzie VBUS wisi w powietrzu nie świeci). Widać też moduł ładowarki podpięty do VBUS. Chyba najciekawszą częścią elektroniczną jest fragment, w którym następuje przełączenie źródła zasilania. Jest to jeden z tematów często poruszanych przez początkujących walczących z Arduino UNO, które ma 2 opcje zasilania. W tym przypadku sposób sterowania jest prostszy: Przy podłączeniu zasilania przez USB na VBUS jest około 5V, trafia to na bramkę tranzystora Q1 odcinając akumulator, prąd dostarczany jest przez diodę shottkyego D1. Tu nie do końca pomyślałem, bo dioda BAT60J ma dość małą moc, raptem 310 mW, więc przy spadku napięcia około 0,3V to 100 mA to dość mało. Ale z drugiej strony pobór prądu nie powinien być tu zbyt wysoki. Gdy odetnie się zasilanie z USB to bramka ściągana jest do masy i podawane jest zasilanie z baterii. Tu widać drobną rozbieżność w wydajności źródeł zasilania, tranzystor AO4459 jest w stanie udźwignąć 3W. Dobierałem go jednak głównie po to by dało się go łatwo wysterować z niskich napięć i napięcie progowe VGSth przy znikomym prądzie drenu to jedynie 1,9V. Dalej prąd trafia na rezystor pomiarowy żeby móc pomierzyć pobór prądu. Wynik jest mierzony przez komparator w układzie różnicowym. Prąd trafia też na regulator napięć MCP170. Dygresja o regulatorach Jakiś czas temu miałem możliwość przetestować sporo regulatorów LDO 3,3V i 5V. Przyznam że do tamtego momentu obierałem 3 drogi: jak chce 5V to LM7805, jak chce 3,3V to LM1117, jak coś innego to pewnie przetwornica impulsowa. Zaś temat regulatora w zasilaniu bateryjnym wiał grozą. A tu okazuje się, że niekoniecznie... Przeanalizowałem kilka modeli patrząc na parametry: napięcia zasilania, maksymalny prąd wyjściowy, prąd w stanie spoczynku (Quiescent Current). I gdy wziąłem układ LDO LM1117, który często widnieje na płytkach ESP to szło się złapać za głowę... Układ ten ma koszmarnie wielki prąd spoczynkowy! Wieje grozą... wielkie miliampery! Oczywiście zależy co chcemy zbudować, ale do zasilania bateryjnego nie polecam... Regulator MCP170 Tak więc moja perełka czyli układ MCP170 posiada takie cudne parametry: 2 uA prądu spoczynkowego to już coś dodając do tego bardzo oszczędne tryby pracy ESP32 to można śmiało uznać to za coś co nada się do zasilania z akumulatora. Oczywiście taki układ musi mieć wadę, no i jest - max prąd raptem 250 mA, ale... po co większy? No może do tego bloku: ale postaram się nie robić z klawiatury lampy dyskotekowej. Ktoś zapyta po co te LEDy? A to się później przyda jak będę robił obudowę mam nadzieję, że się przyda, bo obudowa jest na razie tylko w wyobraźni. Jest tu zatem wąskie gardło dla tranzystora Q1 i wyzwanie dla diody D1, która nie jest w stanie przepuścić prądu 250mA. Więc albo ją wymienię na coś większego albo będę dbał o to żeby nie przekroczyć prądu 100mA. Wydaje mi się, że podmianka jest lepszym pomysłem, bo może to byc jakakolwiek dioda, nawet 0,7 krzemowa, gdyż zapas napięcia jest dość duży. LDO wymaga zapasu jedynie 625 mA przy max poborze prądu 250 mA więc spokojnie 5V da radę wyciągnąć na 3,3V. Matryca przycisków Dalej to co w klawiaturze najważniejsze - matryca! Układ zwyczajny, tylko jest drobny mix przycisków. Część to bezgłośne przyciski Cherry, inne to zwykłe duże i małe Omrony. Układ sterowania I ostatni bloczek - widać tu wszystkie sygnały wyciagnięte z ESP32 (wszystkie dostępne piny są przewidziane do użycia. Jest tu listwa 4 pinów dla małego OLEDa 128x32 px, który ma służyć do informowania o wybranym układzie makr/programie: Widać tu też typowy układ 2 tranzystorów i przycisków służących do sterowania przebiegiem programowania. Taki układ znajdziemy na płytkach dev module i jest on domyślnie ustawiony podczas wgrywania przy użyciu esptool.py. Wątpliwości może budzić te coś z komparatorem... co to w ogóle jest? Historia zaczyna się od próby znalezienia układu z 1 komparatorem... wiecie że ciężko taki znaleźć? Za to z 2 jest pełno. Ale zostawić taki komparator to szkoda więc postanowiłem zaprojektować dość eksperymentalnie jakiś generator. Nie mam z nimi doświadczenia ale wygląda jakby miał działać. Ale jakby nie działał to otoczyłem go zworkami żeby odciąć en eksperyment i użyć zwykłego LEDa w formie wskaźnika. Do czego będzie to jeszcze się zobaczy, najpewniej będzie wskazywał stan parowania BT. Ciekawe jaki jest pobór prądu... o tym nie pomyślałem. Płytka PCB i montaż Kilkanaście dni czekania i otrzymałem śliczne płytki: Kilka testów i jak zawsze jestem w szoku gdy coś idealnie pasuje jak te przyciski Cherry i Omrony... żeby wszystko tak pasowało jak te przyciski: Tu się Pan Chińczyk się nie popisał (albo Pan projektant-płytkarz) bo na płytce została wyfrezowana miedź pod nóżki złącza, ale już nie laminat. Nie wiem czy nie mieli tak cienkich frezów, ale złącze to wylutowałem z modułu ładowarki do akumulatora i tam jakoś to wyfrezowali i przylutowali. No mniejsza, działa to najważniejsze. Testy Jak myślicie czy projekt ruszył po zlutowaniu? Oczywiście że nie! polutowanie układu CP2101 to niemałe wyzwanie ale w końcu udało się. Programowanie jednak nie powiodło się - komputer wykrywa coś ale nie rozpoznaje. I tu wyszedł mój błąd - zamienione linie D+ i D-. Szybka poprawka i komputer już coś rozpoznaje, ale... nie da się zaprogramować Kilka testów i ustaliłem, że ESP32 działa! Ale CP2101 nie reaguje na test echa ze zwartymi RX i TX... to nie dobrze. Na plus to że USB C działa i tu nic nie mieszam. Czyli chyba jednak upaliłem ten konwerter... Na tym koniec tej części. Stanąłem teraz przed małym murem (nazwijmy płotkiem) - bo ESP32 da się zaprogramować ale z osobnego układu CP2101 na płytce konwertera i teraz pytanie czy usmażyłem układ podczas lutowania? Chyba tak... Plany W najbliższym czasie mam zamiar przelutować układ CP2101 na nowy wyglądający na bardziej markowy (obecny pochodzi z wylutu i nie ma żadnego nadruku). Jeżeli wszystko będzie się ładnie programować to ruszam z klawiszami i obudową. Tu moja wizja jest następująca - sklejka, naturalne drewno i odlewana żywica w miejscu LEDów. W podobnym stylu robiłem jeden projekt, wiec jest szansa na coś ładnego ale tu nie obiecuję cudów na kiju, jak będzie coś nowego to o tym opowiem. Nie wiem jednak jak zrobić krzyżykowe mocowania klawiszy. Mam w głowie pomysł na przyciski - drewniane kołki z miedzianymi obręczami... ale czy nie będą za ciężkie? Potestuję i opiszę niebawem A i wypadałoby jakoś to nazwać... z wymyślaniem nazw zawsze jest problem, bo jak ma się kojarzyć? Ale to może wyjdzie w międzyczasie. Ostatecznie jak przybędzie kabelków i poprawek będzie śmiało można nazwać "MAKaROn". Stan na dzień 16.10.2020 Poprawki w układzie komunikacyjnym Zgodnie z zapowiedzią przelutowałem układ CP2102, tu miałem wątpliwość czynie wpakuję się znowu w maliny. Płytki ESPx są wyposażone w taki układ tylko wygląda jak od Chińczyka pracującego od godziny 16... brak nadruku. Dlatego dla pewności wziąłem układ który działał rewelacyjnie przy testach i po przelutowaniu tak pozostało. Wszystko ładnie się programuje, ESP32 wchodzi w reset zgodnie z założeniami. I też słuszny wniosek - opalarka z regulowaną temperaturą niekoniecznie nadaje się do lutowania, jakikolwiek Hot Air jest lepszym pomysłem.
  17. 10 punktów
    Kiedy zaczyna się zabawę z lampami, czy to do budowy radia, czy wzmacniacza audio, należy załatwić sobie dobre zasilanie. Zwykle to zasilanie jest wbudowane w urządzenie, więc co nowe urządzenie lampowe (czy to radio, czy wzmacniacz) musiałbym kupować nowy transformator. To czego potrzebowałem to zasilacz, jak najbardziej uniwersalny (układy lampowe buduję bardziej w celach edukacyjnych niż praktycznych), co pozwoli mi na wykorzystanie tylko jednego transformatora do wszystkich moich projektów lampowych. Chciałem, aby zasilacz był podobny do szkolnych zasilaczy laboratoryjnych, i był możliwie bezpieczny. Zacząłem sobie od rozrysowania schematu, a zarazem obliczeń: Jak widać, wiele do szczęścia nie potrzeba. Jest to jeden z najprostszych zasilaczy jaki można zrobić - i to wykorzystując elementy głównie z odzysku. Zaczynając od lewej: zasilanie do układu jest dostarczane przez popularne złącze IEC. Faza jest odcinana pierwszym wyłącznikiem, nie można było także zapomnieć o bezpieczniku. Transformator jaki wykorzystałem to TS50/5 polskiej firmy Zatra, który dostałem od znajomego nauczyciela. Posiada on 3 uzwojenia wtórne - 2x 270v, 6.3v i 4v (na schemacie dwa ostatnie powinny być rozłączone). Jeżeli ktoś nie ma takiego transformatora, może wyprostować bezpośrednio napięcie gniazdkowe, ale tylko przy zastosowaniu transformatora o przekładni 1:1. Będzie on stanowił izolację galwaniczną. Napięcie żarzenia wielu lamp to 6.3v. Niektóre lampy grzeje się wyższym napięciem, którego ten transformator niestety nie dostarcza, więc musiałem się zadowolić tymi ponad 6 woltami. Uzwojenie to od razu zasila małą żaróweczkę sygnalizującą pracę zasilacza. Dla jasności: lampy można żarzyć napięciem zarówno stałym, jak i przemiennym. Napięcie anodowe lamp (to wysokie, niebezpieczne) jest prostowane scalonym mostkiem greatza (z zasilacza komputerowego). Wyprostowane napięcie jest wygładzane przez filtr RC, a następnie ograniczane bardzo prostym układem z wykorzystaniem tranzystora MOSFET. Ten także jest z odzysku, posiada niską rezystancję w stanie przewodzenia, wytrzymuje dużą moc - i co najważniejsze - posiada zabezpieczenie w postaci diod zenera między bramką a źródłem. Działają one jako zabezpieczenie przeciwprzepięciowe - w teorii, potencjometr tutaj służy jako dzielnik napięcia, a rezystor obniża napięcie (gdyż mosfet to element sterowany napięciem). Jeżeli nastąpi tam przebicie, tranzystorowi na szczęście się nic nie stanie. Ale dlaczego w ogóle ten tranzystor dałem? Nie wszystkie lampy mają jedno napięcie anodowe, więc napięcie to można ograniczać - w czym pomaga panelowy woltomierz wskazówkowy, z posobnikiem w szeregu. Trudno znaleźć cyfrowe woltomierze na tak wysokie napięcie. Na samym końcu układu - jest przełącznik, który pozwala na zasilenie docelowego urządzenia, lub poprowadzenie napięcia przez rezystory mocy. Mają one 2 zastosowania: pozwalają dobrać napięcie, kiedy zasilacz nie jest zewnętrznie obciążony, oraz rozładowują kondensator, co jest bardzo ważną rzeczą. I najważniejsza rzecz - cała obudowa jest porządnie uziemiona. Aby wyrównać potencjały, masę napięcia anodowego także uziemiłem. Obliczenia skomplikowane nie są - na początku potrzebowałem znać moc urządzenia, aby wiedzieć jaki bezpiecznik dobrać. Z racji tego (a przynajmniej tak myślę, może błędnie myślę ), że poza transformatorem nie ma elementów LC (po stronie napięcia przemiennego), cos fi jest bliski 1, a więc moc bierna jest niewielka - dlatego jej nie brałem pod uwagę (równania 1.1-2). Nie brałem pod uwagę także strat na samym transformatorze. Następnie obliczyłem rezystor jaki jest potrzebny do filtru RC, oraz prąd i napięcie jakie będą po wyprostowaniu. Miałem na uwadze, że napięcie w gniazdku wynosi 240v, a transformator był na 220v, i że napięcie to może być wyższe (równania 3.1-3.4). Na samym końcu, korzystając z praw Ohma i Kirchoffa, obliczyłem posobnik dla woltomierza. Oryginalnie wyskalowany był na 0-40v, więc zmieniłem to na 0-500v. Woltomierz miał rezystancję 48kΩ. Starą skalę zeskanowałem, w gimpie przerobiłem, i wydrukowałem na papierze samoprzylepnym. Po zebraniu wszystkich potrzebnych elementów, wziąłem się za obudowę. Trochę mi to zajęło, ponieważ prawie wszystko robiłem ręcznie. Bazą obudowy jest aluminiowy radiator z starego zasilacza impulsowego - do którego z boku są przykręcone blachy aluminiowe, a u góry profil. Wszystko ze złomu. Rączka została wykonana z stali nierdzewnej. Najwięcej czasu zajął front obudowy, do którego wykonałem rysunek, a następnie wyfrezowałem blachę zgodnie z tym rysunkiem. (Niestety zdjęć z tego procesu nie mam). Następnie zasilacz zacząłem lutować - oczywiście wszystkie przewody są zakończone termokurczkami, wszystko jest porządnie przykręcone, a obudowa działa jak świetny radiator. No i podsumowanie. Zasilacz działa, bez obciążenia napięcie anodowe wynosi maks. 428v, oraz 375v z obciążeniem. Maksymalny prąd wynosi 48mA, co można zwiększyć, podłączając równolegle drugą połówkę uzwojenia. No i - zgodnie z przewidywaniami, napięcie faktycznie jest wyższe. Napięcie żarzenia wynosi obecnie 6.8v, ale jest to dość nieznaczna różnica. Rozładowanie kondensatora trwa ok. 5 sekund, z włączonym obciążeniem. Myślę że bez obciążenia, nawet w ciągu doby nie rozładowałby się do zera. Przy budowie jednak popełniłem kilka błędów: górny łącznik, łączący front z górą obudowy, ma źle umiejscowione utwory, przez co górna blacha trochę wystaje. Żarówka (jak i kondensator) trzyma się na kablach, co nie jest dobrą praktyką. Mogłem także dać więcej zabezpieczeń, np. ograniczenie prądu, zabezpieczenie przeciw odwrotnej polaryzacji, czy przeciw zwarciowe. Rezystor filtru także jest mocno przedobrzony - moc którą pobierze wynosi mniej niż 1 wat, i bardziej on służy za element montażowy. Mimo wszystko, zasilacz działa, poza obciążeniem nic się nie grzeje. Projekt tym samym uznaję za udany.
  18. 10 punktów
    Cześć! To mój pierwszy post, a także pierwszy projekt jaki zrealizowałam przy pomocy Arduino. Zastanawiałam się czy w ogóle wrzucać swój banalny projekt ale może przyda się komuś kto tak jak ja dopiero zaczyna działać w temacie Arduino. Za pare dni wyjeżdżam, a że nie chciałam zostawiać głównie pomidorów na pastwę losu albo znajomych postanowiłam więc zbudować system podlewania. Czasu było mało ale chyba się udało. Po drodze miałam dwie koncepcje, jedna zakładała podlewanie o konkretnej godzinie, a druga podlewanie kiedy się ściemni. Ostatecznie zdecydowałam się na użycie RTC ale wrzucę oba warianty. Możliwe, że po przyjeździe będę kontynuować prace i dodawać kolejne elementy jak wyświetlacz z odczytem parametrów (temp, wilgotność) itd. Mam nadzieję, że o niczym nie zapomniałam i post jest poprawny . Elementy projektu: Arduino UNO Pompa do wody 12V Zasilacz 12V Koszyk na baterie + 6x AA Moduł przekaźnika 1-kanałowego 5V Zegar czasu rzeczywistego (RTC) DS3231 (koncepcja 1) Fotorezystor + opornik (koncepcja 2) Wężyki fi6 i fi4 Trójniki i czwórniki do wężyków Koncepcja z fotorezystorem: const int pumpPin = 8; // Zdefiniowanie pinów przekaźnika pompy i fotorezystora const int lightPin = A0; const long onTime = 30 * 1000; // Czas działania pompy 30s const int dayResistance = 150; // Wartość graniczna z fotorezystora dla dnia const int nightResistance = 80; // Wartość graniczna z fotorezystora dla nocy int lightReading = 0; boolean isDay = true; void setup() { Serial.begin(9600); pinMode(pumpPin,OUTPUT); // Wyjście na moduł przekaźnika digitalWrite(pumpPin, HIGH); } void loop() { int lightReading = analogRead(lightPin); // Odczytanie realnej wartości z fotorezystora Serial.println(lightReading); // Wyświetlenie wartości w konsoli if (isDay and lightReading < nightResistance) { digitalWrite(pumpPin, LOW); delay(onTime); digitalWrite(pumpPin, HIGH); isDay=false; } if (!isDay and lightReading > dayResistance) { isDay = true; } } Koncepcja z RTC: #include <DS3231.h> int pumpPin = 8; DS3231 rtc(SDA, SCL); Time t; const int OnHour = 11; const int OnMin = 00; const int OnSec = 0; const int OffHour = 11; const int OffMin = 00; const int OffSec = 45; void setup() { Serial.begin(9600); rtc.begin(); pinMode(pumpPin, OUTPUT); digitalWrite(pumpPin, HIGH); } void loop() { t = rtc.getTime(); // Odczytanie czasu Serial.print(t.hour); // Wyświetlenie w konsoli Serial.print(":"); Serial.print(t.min); Serial.print(":"); Serial.print(t.sec); Serial.println(" "); delay (1000); if(t.hour == OnHour && t.min == OnMin && t.sec == OnSec){ digitalWrite(pumpPin,LOW); Serial.println("POMPA WŁĄCZONA"); } else if(t.hour == OffHour && t.min == OffMin && t.sec == OffSec){ digitalWrite(pumpPin,HIGH); Serial.println("POMPA WYŁĄCZONA"); } }
  19. 10 punktów
    Cześć, pewnego razu na spotkaniu ze znajomymi okazało się, że na hasło „polej” nikt nie zareagował. Wtedy zrodził się pomysł, aby zaradzić takim przykrym sytuacjom w przyszłości postanowiłem stworzyć robota do nalewania alkoholi wysokoprocentowych. Z założenia robot miał nalewać alkohol do każdego kieliszka jaki się postawi oraz miał być zasilany przy pomocy baterii. Pierwsze prototypy zawierały prostą elektronikę opartą na czujnikach i przekaźnikach – jestem laikiem oraz samoukiem w kwestiach elektroniki. Projekty nie spełniały oczekiwań, ponieważ w normalnym użytkowaniu zawodziły. Około rok temu natknąłem się na Arduino i zacząłem pogłębiać swoją wiedzę w tym kierunku. Wydruki 3D wykonałem na swojej drukarce. Robot spełnił założenia. Poprzez zastosowanie czujnika ultradźwiękowego jest w stanie nalać do każdego kieliszka, a potencjometrem można ustawić ilość nalewanej wódki w zakresie około 10 - 50ml. Do zasilania użyłem 8 akumulatorów AA. Wykonałem obudowę z kilku elementów żeby mieć lepszy dostęp do podzespołów. Rynienka na pompce została stworzona po zalaniu układu... z wyciekiem sobie poradziłem ale dla pewności została Części których użyłem do budowy: Płytka stykowa 170 pól - 1 szt Stabilizator L7805CV 5V 1,5A – 1 szt Ultradźwiękowy czujnik odległości HC-SR04 2-200cm – 1szt Potencjometr liniowy 1K – 1 szt Wtyk DC 2,1/5,5mm z zaciskami skręcanymi – 1 szt Pompa membranowa - silnik R385+ - 12V - 3W - mini pompa wodna – 1szt Moduł sterownika L298N do silników DC – 1 szt Przełącznik kołyskowy 15x10mm – 1 szt Koszyk na baterie 8xAA (R6) – 1 szt Arduino Nano – 1 szt Uniwersalny Proto Shield do Arduino Nano – 1 szt Serwo TowerPro MG-995 – 1szt. Zawór zwrotny – 2szt. Moduł dioda LED RGB 5050 wspólna katoda – 1 szt. Magnesy neodymowe 10x5 – 8 szt Przycisk monostabilny – 1 szt. Rurka sylikonowa – 0,5m Rezystory Przewody połączeniowe Aby "polewacz" był mobilny jego elementy zaprojektowałem tak, aby zmieściły się w drewnianej skrzyni 30x20x15cm.
  20. 10 punktów
    Czasem patrzymy na dostępne na rynku płytki z mikrokontrolerami i myślimy sobie "ja bym to zrobił lepiej". Zazwyczaj nie mamy pretekstu żeby rzeczywiście tak zrobić, ale czasem tak się życie ułoży, że mamy okazję spróbować. Tak właśnie miałem z płytką firmy Feather M0 Basic firmy Adafruit i wydaje mi się, że wychodząc z oryginalnego projektu udało mi się dokonać kilku ulepszeń (ale także przyszło mi pogodzić się z paroma kompromisami). A zaczęło się od tego, że często używam w moich projektach mikrokontrolera SAMD21 w jego najmniejszej obudowie QFN32 i nieraz przydałaby się możliwość przetestowania układu zanim zamówi się płytkę. Niestety, płytki które posiadam nie wyprowadzają wszystkich pinów, więc testowanie za ich pomocą nie zawsze jest możliwe. Postanowiłem zatem zrobić swoją płytkę, ale dać jej standardowy układ pinów — padło na standard Adafruit Feather. Najbardziej rzucającą się w oczy polskiemu użytkownikowi wadą płytki Adafruita jest niewątpliwie cena. Niestety, produkcja w USA, koszty wysyłki, a także konieczność pokrycia wypłat dla armii ludzi piszących dokumentację i rozwijających oprogramowanie powoduje, że nie jest ona tania. Zatem pierwszym celem, który sobie postawiłem, jest takie zaprojektowanie nowej płytki, żeby można było ją wykonać jak najtaniej. Oczywiście od razu pojawiła się konieczność kompromisów — postanowiłem usunąć część układu odpowiedzialną za obsługę i ładowanie baterii — nie ma zatem gniazdka do baterii, a nóżka do której byśmy ją podłączali jest niepodłączona. Usunąłem też wszystkie komponenty, które nie są absolutnie niezbędne — nie ma zatem kwarcu, zamiast tego używany jest wewnętrzny oscylator, wyleciał przycisk reset, zastąpiony zworką bezpośrednio na płytce (trzeba tylko dotknąć czymś metalowym), poleciały też diody świecące — choć potem jedna wróciła. Oryginalna płytka używa mikrokontrolera w opakowaniu QFN48, ale ja potrzebowałem QFN32 — tańsze, ale też ma mniej nóżek. Na szczęście odrobina gimnastyki pozwoliła mi brakujące nóżki zastąpić takimi, które były niepodłączone w oryginalnej płytce. Ba, dodałem nawet trzy dodatkowe nóżki dostępne dla użytkownika: dwie analogowe i jedna zwykła. Została mi jedna nóżka, którą postanowiłem podłączyć do diody świecącej, aby mając gołą płytkę można było sobie chociaż pomrugać. Oczywiście i tu nie obyło się bez kompromisu — aby obsłużyć SPI musiałem poświęcić nóżki normalnie używane do debugowania — zatem albo debugujemy, albo używamy SPI. W pierwszej wersji płytki zostało mi dużo wolnego miejsca, a że koszty wysyłki płytek zależą od ich wagi, postanowiłem zmniejszyć tę wagę dodając parę losowej wielkości dziur. Kiedy przyszło do wybierania koloru płytki, podobieństwo do sera skłoniło mnie do wybrania koloru żółtego. A właśnie, wprowadziłem jeszcze jedno ulepszenie: dziurki na piny są ułożone w zygzak w taki sposób, że da się w nie wetknąć nóżki goldpinów bez konieczności lutowania. Ostatnią częścią, którą postanowiłem usunąć jest gniazdko USB. Nie ma się co dziwić, bo tylko są z nim same kłopoty — ludzie narzekają, że jest w złym miejscu, że się urywa jak pociągną za kabel, do tego jest to jedyna część wymagająca dziur w płytce — i podrażająca tym montaż.Tylko jak bez gniazdka USB będziemy naszą płytkę zasilać, o wgrywaniu do niej programów i obserwowaniu ich wyników już nie wspominając? Okazuje się, że da się zrobić "gniazdko" USB z samej płytki, po prostu wycinając ją we właściwy kształt i umieszczając w odpowiednich miejscach styki. Płytka musi wówczas też mieć odpowiednią grubość, ale na szczęście nie ma dzisiaj wielkich problemów z zamówieniem takich płytek (i wychodzą nawet taniej niż standardowe, z powodu mniejszej wagi). Zatem zaprojektowałem nową wersję, z gniazdkiem USB-C (jak szaleć to szaleć). W tej wersji dziury są tylko w miedzi, zamiast przez całą płytkę, bo wykoncypowałem sobie, że taką cienka i płaską płytkę mogę używać jako wizytówki, a do tego potrzebowałem po drugiej stronie miejsce na zamieszczenie wizytówkowych informacji. Niestety, kiedy płytki wreszcie przybyły (dzięki zawirowaniom czasoprzestrzennym po 4 tygodniach, odwiedziwszy po drodze Niemcy i Wielką Brytanię) okazało się, że co prawda mechanicznie gniazdko działa doskonale, ale prąd płytka dostaje tylko jeśli podłączę ją kablem USB 2.0, podłączona do portu USB-C kablem USB-C nie jest wykrywana przez komputer i w związku z tym nie dostaje zasilania. Czas zatem na poczytanie co tam w standardzie piszą — okazuje się, że wzmianka o rezystorach ściągających na nóżkach CC, którą zignorowałem, bo wydawała się dotyczyć tylko trybu OTG, jest jednak istotna. Rozczarowało mnie to trochę, bo nie tylko musiałem zaprojektować nową płytkę, ale jeszcze nie oszczędzam na liczbie komponentów — jedno gniazdko USB zastąpić będę musiał dwoma rezystorami. No ale rezystory przynajmniej są tanie i montowane powierzchniowo, zatem wziąłem się do pracy. Zrezygnowałem ostatecznie z pomysłu wizytówki, puste miejsce wypełniłem obszarem prototypowym, w którym można sobie wlutować własne elementy, a dziury są teraz już tylko narysowane. Poza tym dodałem dwie nóżki CC do gniazdka USB i podłączyłem do dwóch rezystorów 5.1kΩ. Przez chwilę jeszcze rozważałem użycie tylko jednego rezystora, bo większość kabli i tak używa tylko jednego pinu CC, ale okazuje się, że to właśnie jest błąd, który popełnili projektanci Raspberry Pi 4, a który spowodował problemy z bardziej zaawansowanymi kablami. Postanowiłem błędu nie powtarzać. Ostateczna wersja projektu wygląda tak: Na razie używam płytki do własnych eksperymentów i sprawuje się dobrze, ale zastanawiam się nad zamówieniem większej liczby już zmontowanych i zaprogramowanych płytek — mogą się przydać do prowadzenia warsztatów z CircuitPythona gdy epidemia się skończy.
  21. 10 punktów
    Jakiś rok temu pomyślałem, ze może spróbuję swoich sił w tematyce robotów typu "delta". Zainspirowała mnie również konstrukcje Kolegów, @Eukaryota Delta Robot V3.0 oraz @deshipu Deltabot; którym serdecznie dziękuję za opisanie rezultatów swoich prac Zacząłem nieco od tyłu, bo od zakupu 3 silników krokowych NEMA17 z przekładnią planetarną (przełożenie ~5-krotne) i związku ztym robot wyszedł dość duży - teraz zastanawiam się, czy istnieje możliwość jest transportu np. pociągiem... Ale przechodząc już do konkretów, zamieszczam poniżej krótki film ( z góry przepraszam za jakość, ale w związku z obecną sytuacją, zmuszony byłem nagrywać telefonem): Założenia Celem projektu było zbudowanie robota typu delta, 3-osiowego (to jest bez dodatkowych osi obrotowych w efektorze) i długości ramion rzędu kilkunastu centymetrów. Koniecznie chciałem wykorzystać w tym projekcie RaspberryPi 3B+ (o czym za chwilę), coś związanego z pneumatyką (gdyż posiadam cały kartonik pneumatycznych przyda-mi-się), dodać jakiś prosty panel operatora, a samo demonstracyjne zadanie miało być w miarę efektowne, ale jednocześnie możliwe przy luzie na poziomie kilku milimetrów - wybór padł na sortowanie krążków według kolorów. Konstrukcja mechaniczna Sam stelaż składa się z profili V-slot 20x20mm, bardzo lubianych w środowisku "konstruktorów - DIY". Jest on przykręcony do podstawy-płyty spienionego PCV. Jak łatwo zauważyć, profile oprócz konstrukcji nośnej pełnią również rolę mocowanie elektrozaworów, kilku elementów elektronicznych itd... Do stelażu przykręcona jest płyta a'la trójkąt ramienny z rezokartu, a do niego trzy główne silniki. Od silników odchodzą drukowane 3D (wszystkie drukowane w tym robocie elementy to ABS). Od pomarańczowych ramion, przez przeguby kulowe firmy Igus® (której w tym miejscu serdecznie dziękuję , gdyż otrzymałem je bezpłatnie w ramach sponsoringu) i odcinki gwintowanego prętu M6 całość "schodzi się" do wspólnego efektora, na koncu którego zamontowana jest ssawka podciśnieniowa. Peryferia - szufladka pneumatyczna i podajnik rewolwerowy Będąc przy sprawach mechaniki, wspomnę o dodatkach zamieszczonych w robocie celem wyznaczonego zadania - podajniku rewolwerowym (stole obrotowym), który składa się z silnika krokowego, drukowanej 3D przekładni planetarnej oraz talerza (plexi + drukowana 3D obwódka) z 9 gniazdami, każde umożliwiające umieszczenie obiektu krążka. Sama szufladka natomiast to siłownik pneumatyczny SMC (nietypowy, gdyż tłok został zastąpiony magnesem, który sprzężony jest z wózkiem na nim umieszczonym, zatem w czasie pracy siłownik nie zmienia swojej długości) oraz 2 prowadnice o średnicy 10mm, na których umieszczony jest również 9-gniazdowa płytka, ale już nie okrągła, a kwadratowa). Po zakończonym cyklu układania może się ona wysunąć "na zewnątrz", co pozwala zabrać krążki i ponownie ułożyć je na talerzu. Elektronika "Mózgiem" robota jest płytka Nucleo F401RE, programowana w środowisku mBED. Ponadto w "sterowniku" (żółta płyta z plexi) umieszczony jest układ dystrybuujący zasilanie, przetwornica step-down (12V -> 5V) oraz moduł 2x przekaźnik, celem sterowania elektrozaworem eżektora i siłownika 5/2. Na zewnątrz sterownika "wychodzą" przewody sygnałowe dla łącznie 4 sterowników silników krokowych (czwarty, dla stołu obrotowego, jest znacznie mniejszy (TB6560) i umieszczony jest z tyłu, na profilu ). Warto dodać, że płytka rozdzielająca zasilanie została wyposażona w 3 transoptory, które pośredniczą między czujnikami krańcowymi umieszczonymi u góry, a samym STM32. Zasilanie Zasilanie robota jest dość złożoną sprawą, gdyż dla trzech głównych silników wykorzystałem zasilacz 36V 10A - tak duże napięcie pozwala na osiągnięcie dość dużych prędkości obrotowych, natomiast czwarty, "mały sterownik", nie może być takim napięcie zasilany - konieczne było użycie przetwornicy step-down (36V -> 24V). Logika/elektrozawory są natomiast czerpią energię z osobnego zasilacza, 12V 5A, które do logicznego 5V obniżane jest wymienioną w podpunkcie "Elektronika" wspomnianą przetwornicą. Ostatecznie, napięcie 3,3V wymagane przez Nucleo jest uzyskane z jego wewnętrznego stablizatora. Mamy więc linię napięcia stałego 36V, 24V, 12V, 5V, 3V3 "Panel operatora" U góry konstrukcji umieszczono przycisk bezpieczeństwa, który po naciśnięciu zwiera pin RESET Nucleo z masą - nie jest to może rozwiązanie profesjonalne (nie zadziała, jeśli np. naderwałby się kabel łączący sterownik z "grzybkiem"), ale stosunkowo proste i skuteczne. Poniżej znajduje się właściwy "panel", składający się z wyświetlacza 2,8" opartego o sterownik ILI9341. Wyświetla on na początku "menu", a po rozpoczęciu pracy robota - informacje o kolorach krążków oraz koordynaty XYZ. Poniżej znajdują się przyciski z podświetleniem, pozwalają one na rozpoczęcie cyklu (właściwej pracy), wsunięcie/wysunięcie siłownika, wyzerowanie osi oraz odłączenie silników tak, aby można było nimi ręcznie poruszać (to ostatnie muszę jeszcze dopracować). Warto zaznaczyć, że samą obsługą modułu "HMI" zajmuje się NodeMCU, a z samym sterownikiem komunikuje się po UART'cie. System wizyjny - RapsberryPi 3B+ Wspomniane RPi posłużyło jako prosty system wizyjny. Wiem, że można było zrobić rozpoznawanie barw znacznie prościej, ale za pomocą kamerki jest to znacznie skuteczniejsze i ponadto stanowiło łagodny wstęp do OpenCV - wycinam odpowiednie fragmenty obrazu, obliczam składowe średnie RGB i porównuję. kamerka jest na małej prowadnicy, ponownie od firmy Igus®, możliwa jest jej regulacja. Tutaj również komnikacja RPi <-> STM32 zachodzi po UART'cie. Układ pneumatyki Pneumatyka w robocie jest stosunkowo prosta, składa się na wejściu z osuszacza powietrza i regulatora ciśnienia wraz z manometrem (robot wymaga ciśnienia 4 barów). Następnie, przez elektrozawory, sprzężone powietrze doprowadzone jest do eżektora (generowanie podciśnienia dla ssawki) oraz siłownik SMC (ruch szufladki). Kilka zdjęć Podziękowania Projekt ten nie powstałby bez pomocy kilku firm, którym chciałbym serdecznie podziękować: wspomniany już wyżej Igus®, Mondi Polska, ST oraz ENEA (Akademia Talentów), a także mojej Szkole, Zespołowi Szkół Łączności im. M. Kopernika w Poznaniu Pozdrawiam, zapraszam do zadawania pytań
  22. 10 punktów
    No wreszcie - po jakimś szale na prezenty, naprawy różnych domowych urządzeń i inne przyziemne sprawy mogłem zabrać się za następnego z rodziny Konserwatorów Płaskich Powierzchni - czyli małego Kopłapowa. Miał on w założeniu służyć do wycierania podłogo w trudniej dostępnych miejscach (np. pod kabiną prysznicową) więc siłą rzeczy musiał byc jak najmniejszy. Założenia były proste: zasilanie 1 x 18650; dwa silniczki N20 do napędu z driverem DRV8825; z przodu pojedyncza gąbka kuchenna; wysokość taka, aby się zmieścił pod brodzikiem; z czujników: zderzak, żyroskop i kilka czujników odbiciowych; Arduino Pro Mini jako "mózg" urządzenia; żadnego skomplikowanego algorytmu - ma się przejechać po podłodze i tyle, z możliwością zdalnego sterowania. Z takimi założeniami zabrałem się do roboty. Sterownik już miałem - kiedyś zrobiłem sobie coś w rodzaju uniwersalnego nadajnika, sprawdził się już w trzech konstrukcjach a więc tę część miałem gotową. Tym razem postanowiłem w maksymalnym stopniu wykorzystać drukarkę. Ponieważ miałem felgi z kół Pololu (opony zostały użyte w innym projekcie) wystarczyło dodrukować jakieś ładne oponki z TPU. Również dolna płyta podwozia wraz z koszykiem na 18650 oraz mocowaniami na ładowarkę, przetwornicę i inne drobiazgi typu wyłącznik została wydrukowana w jednym kawałku. Zadowolony z siebie zmontowałem podwozie, podłączyłem prowizorycznie silniczki pod 5V... i w tym momencie szczęście się skończyło. Okazało się, że robot nawet po lekkim dociążeniu jest jeszcze za lekki i nie da rady przepchnąć gąbki nawet po śliskich kafelkach. Zmartwiony odstawiłem konstrukcję na skraj biurka i zająłem się swoimi sprawami. Na szczęście był to skraj biurka przy którym pracuję i co chwila chcąc nie chcąc spoglądałem na biednego robocika. Jak go wykorzystać... Pomysł przyszedł sam, gdy nastąpiłem bosą nogą na jakąś śrubkę. A gdyby tak wyposażyć go w magnes i kazać zbierać śrubki z podłogi? Wywaliłem uchwyt gąbki, w to miejsce zamontowałem obrotowe kółko (o nim więcej w dalszej części), uchwyt na magnesy i również podłączając bezpośrednio do przetwornicy silniczki puściłem go po podłodze. Okazało się, że śrubki i podobne niewielkie metalowe farfocle zbiera doskonale! Tak więc robocik zmienił swoje przeznaczenie, miałem już gotowe podwozie i mogłem zabrać się za dalsze projektowanie. Oczywiście - potrzebne były nowe założenia. Przede wszystkim - wysokość nie była już krytyczna (robot miał zbierać śrubki porozrzucane po podłodze i nie wjeżdżać do łazienki). Z uwagi na to zrezygnowałem z czujników odbiciowych, w ich miejsce postanowiłem zamontować obrotowy laserowy czujnik TOF o kącie 180°. Pozostał oczywiście żyroskop. Z uwagi na przykre doświadczenia z MPU6050 przy okazji zakupów w Botlandzie zamówiłem moduł L3G, czujnik VL53L0X kupiłem już wcześniej, tak więc zabrałem się za dalsze projektowanie. I tu mała dygresja: odrzuciłem MPU6050 z uwagi na to, że potrafił zawiesić Arduino po kilkudziesięciu sekundach od włączenia (a z tego co wyczytałem w sieci nie tylko ja miałem z tym problemy). Oczywiście: nie doczytałem, że dotyczy to wyłącznie odczytu danych z DMP, odczyt surowych danych z żyroskopu i akcelerometru był prawidłowy. Dopiero po zmontowniu całości przypadkiem natknąłem się na nową wersję biblioteki która (podobno) nie sprawia takich problemów... a szkoda, bo niepotrzebnie wydałem trzy dychy na nowy żyroskop Ale wróćmy do robocika. Ponieważ laser na serwie i tak musiał dość mocno wystawać nie było konieczności zachowania wysokości reszty konstrukcji. Postanowiłem zrobić więc coś podobnego jak w poprzednim robocie - podłoga ze spienionego PVC (idealna do eksperymentów z uwagi na łatwość obróbki), do niej mocowane serwo i płytka z elektroniką. Z tamtej konstrukcji skopiowałem również zawieszenie zderzaka i przekładnię do serwa obracającego laser. Płytka z elektroniką miała początkowo być wykonana na frezarce - niestety, wskutek pandemii zostałem odcięty od warsztatu kolegi i musiałem zadowolić się płytką uniwersalną. Przyszedł więc czas na najprzyjemniejszą część pracy programowanie. Na zdjęciu wyżej widać przytwierdzony do robota najnowszy model SMARDZ-a. Tym razem SMARDZ ma własne zasilanie (akumulatorek Li-Ion 1000 mAh, ładowarka i przetwornica) co uniezależnia go od akumulatorów robota i - co ważniejsze - przy większych wstrząsach (np. uderzenie w przeszkodę) nie ma możliwości, że zrobi sobie reset. Większych niespodzianek nie miałem z wyjątkiem jednej - ale za to bardzo śmiesznej... Otóż po zmontowaniu wszystkiego na płytce uniwersalnej jak zwykle przedzwoniłem wszystkie połączenia. Po stwierdzeniu że wszystko jest w porządku rozpocząłem testowanie. Wszystko działało - oprócz serwa. Zdjąłem płytkę, wyjąłem Arduino, sprawdziłem połączenia - wszystko było w porządku. Ki diabeł? Zacząłem szukać w programie czy coś mi nie blokuje timera - nie, najprostszy program ruszający serwem z przykładów też nie chciał działać. Co prawda serwo było sprawdzone (przed zamontowaniem musiałem ustawić środkowe położenie, a do tego używałem testera serw) - ale wiadomo, popsuć się mogło. Niestety - inny egzemplarz zachował się tak samo. Co ciekawsze - mały HD-1370A zaczął kręcić się w kółko... Nie bardzo mi się chciało podpinać sondę, ale jakoś chęć zbadania przyczyny owego dziwacznego działania przeważyła nad lenistwem. No i co się okazało? Otóż na nóżce 8 do której podłączone było serwo radośnie trwało 5V. Wtedy sobie przypomniałem, że płytkę Arduino wziąłem z pudełka gdzie leżą wszystkie podejrzane moduły (jako że miał wszystkie piny polutowane) - po prostu wyjście 8 było najprawdopodobniej uszkodzone i zwarte na stałe z Vcc Na szczęście połączenia robione Kynarem mają to do siebie że szybko można je zmodyfikować - podłączenie serwa do wolnego pinu obok pomogło! Ech, znowu się okazało, że elementy sprawne działają z reguły lepiej od uszkodzonych! I jeszcze drobiazg - w pewnym momencie jeden z silniczków uległ uszkodzeniu (mechanicznemu). Chciałem kupić dwa w Botlandzie na wypadek gdyby drugi też miał jakieś skłonności samobójcze - niestety, już nie było (tzn. był jeden ale trochę się bałem). Kupiłem więc podobne - działają chyba nawet lepiej. W sumie mam na płytce: Arduino Pro Mini cztery mikroswitche zderzaków (połączone parami, czyli wykrywane jako dwa oddzielne) podpięte do jednego pinu analogowego moduł radiowy nRF24L01 (zasilany z wyjścia VDD żyroskopu) żyroskop L3GD20H driver DRV8835 buzzer służący do wygrywania różnych krzepiących melodyjek związanych z wykonywaną funkcją wyjścia na silniki, serwo i diody WS2812 (wskaźnik wykonywanej funkcji oraz wskaźnik poziomu naładowania akumulatora). Wszystko zasilane z jednego napięcia 5V z przetwornicy MT3608, do pinu analogowego podpięte wejście przetwornicy (kontrola napięcia akumulatora). O dziwo działa bez żadnych dodatkowych kondensatorów z wyjątkiem jednego 100nF przy module radiowym i dwóch przy silnikach. W efekcie robot wygląda tak: Tak więc robot w tej chwili potrafi realizować następujące programy: Sterowanie zdalne (ot, wielki mi program). Jedyne co go różni od samochodzika wnuczka na bateryjkę to fakt, że używa żyroskopu do jazdy prosto (podobnie jak reszta programów). Wałęsak - Bradiaga - najprostszy z możliwych - przejeżdża kawałek i skręca sobie w losowym kierunku. Po spotkaniu z przeszkodą po prostu cofa i zakręca. Wałęsak - Moocher - taki włóczęga bardziej inteligentny. Używa lasera do stwierdzenia czy nie dojeżdża do przeszkody oraz do wyszukania najlepszej (w jego rozumieniu najdłuższej) trasy do dalszej jazdy po spotkaniu z przeszkodą lub gdy mu się zamami zmiana kierunku. Odplamiacz - jedzie sobie po spirali. W przypadku napotkania na przeszkodę wykonuje wcześniej zaplanowany skręt, poprzedzając lekkim cofnięciem jeśli sygnał pochodzi od zderzaków a nie lasera.. Przerywa pracę, gdy nie może skręcić (tzn. w czasie skrętu dostanie sygnał od zderzaków). Polowiec - obrabia prostokątny kawałek podłogi - przejeżdża kawałek, zawraca, znowu przejeżdża, zawraca... jakby orał pole. Również używa oprócz zderzaków lasera jako czujnika przeszkody. Ponieważ zawraca zawsze na zasadzie zastopowania jednego koła (wewnętrznego) przesuwa się nieco za każdym nawrotem. Podobnie jak Odplamiacz przerywa pracę, gdy nie może zawrócić. Patrol - robot stara się ustawić jak najbliżej ściany równolegle do niej, a następnie jeździ od ściany do ściany aż do momentu, kiedy nie może zawrócić. Kod jest w sumie bardzo prosty, jednak chciałbym zwrócić uwagę na dwie rzeczy: Używam funkcji printf do wyświetlania różnych informacji o tym, co robi robot. Ponieważ wszystkie funkcję dotyczące żyroskopu działają na liczbach float, musiałem zmusić Arduino do wyświetlania ich właśnie przez printf. Niestety - nie ma możliwości ustawienia tego dla pojedynczego szkicu, ale globalne ustawienie jest bardzo proste: otóż w katalogu, gdzie znajduje się plik platform.txt dla naszego Arduino (czyli w tym przypadku ARDUINO_HOME/hardware/arduino/avr) trzeba założyć nowy plik o nazwie platform.local.txt, a w nim umieścić skopiowaną z platform.txt linię rozpoczynającą się od ciągu "recipe.c.combine.pattern=" z jedną drobną modyfikacją: na końcu linii należy (po spacji) dodać: -Wl,-u,vfprintf -lprintf_flt W przypadku wersji 1.8.12 (a podejrzewam, że wielu innych) będzie to wyglądać tak: recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o {build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -l m -Wl,-u,vfprintf -lprintf_flt Druga sprawa to laser. Na potrzeby programu zmodyfikowałem nieco bibliotekę Pololu dodając możliwość nieblokującego odczytu danych. Mimo to czujnik zachowywał się dość dziwnie: czasami zwracał bardzo pięknie prawidłowe odległości, a czasami kompletnie wariował. Bliższe przyjrzenie się problemowi poskutkowało stwierdzeniem, że czujnik zwraca nieprawidłowe dane po wgraniu kolejnej wersji programu (ściślej po programowym resecie Arduino). Ponieważ w bibliotece zabrakło funkcji resetowania lasera postanowiłem wypróbować najprostszą możliwość - w funkcji setup przed init() wstawiłem następujący kod: lidar.writeReg(VL53L0X::SOFT_RESET_GO2_SOFT_RESET_N, 0); delay(100); lidar.writeReg(VL53L0X::SOFT_RESET_GO2_SOFT_RESET_N, 1); delay(100); Od tej pory laser przestał mieć fochy i grzecznie zwraca odczytane odległości. I jeszcze jedna uwaga dla kogoś, kto na tej podstawie chciałby zbudować własną wersję robota. Otóż funkcja "Patrol" w teorii działa, w praktyce jednak robot nie jest w stanie ustawić się dokładnie równolegle do ściany. Co najmniej w czasie pierwszego przejazdu powinno się dokonać korekty... niestety, o ile laserowy czujnik jest wystarczająco precyzyjny, o tyle brak enkoderów nie pozwala na pomiar przebytej odległości. Prawdopodobnie i tak dałoby się to zrobić oceniając mniej więcej prędkość robota, i dokonując korekty zanim robot dojedzie do ściany z przodu... ale prawdę mówiąc już mi się nie chciało Natomiast uważam zadanie za całkiem ciekawe i pozostawiam sobie na przyszłość - na razie muszę niestety przerwać pracę nad robocikiem i zająć się bardziej przyziemnymi sprawami Aha, obiecałem jeszcze o kółku. No więc początkowo chciałem wyposażyć robota w kulkę podporową. Bliższa analiza zawartości szuflady wykazała, że mam dwa rozmiary: mianowicie za dużą i za małą. Drukowanie kulki raczej nie wchodziło w grę, natomiast obrotowe kółko można wydrukować na dowolej taniej drukarce. Wygląda to tak: Oprócz trzech drukowanych elementów do zrobienia kółka potrzebne są: 1 x śrubka M3x8 1 x śrubka M3x16 2 x nakrętka M3 2 x łożysko kulkowe 3x10x4 Kółko mocowane jest dwiema śrubkami M2x10 do podwozia. Załączam plik OpenSCAD (gdyby ktoś chciał sobie takie kółko zmodyfikować do własnych potrzeb) oraz pliki STL (gdyby ktoś chciał tylko wydrukować bez modyfikacji). Kółko dopasowane jest wysokością do silników Pololu Micro (lub tańszych N20) mocowanych bezpośrednio pod dolną płytą podwozia oraz kół o średnicy 42mm. Łożyska trzeba wcisnąć we właściwe otwory (ja użyłem zwykłego małego imadełka), gdyby okazały się za luźne należy po prostu w OpenSCADzie zmniejszyć nieco ich średnicę. Nie załączam schematu ani programu sterownika - nie jest specjalnie udany, używam go przede wszystkim dlatego, że nie chce mi się robić innego. Lepiej zastosować np. bezprzewodowy gamepad (w sumie cenowo wyjdzie na jedno). No i na koniec filmik demonstrujący działanie robota - niestety nie we wszystkich programach (Moocher i Patrol wymagają więcej miejsca, a na dziś nie bardzo dysponuję takim które się nadaje do kamery). A - oczywiście winien jestem jeszcze wyjaśnienie, skąd takie dziwne imię Zbignaś. To po prostu skrót od Zbieracz Gwoździków, Nakrętek i Śrubek Pora na podsumowanie i wnioski. A więc: Robot powinien być okrągły - konstruktorzy Roomby nieprzypadkowo tak go zaprojektowali. Zderzak powinien obejmować cały obrys robota (nie tylko przód jak w Roombie) oraz całą wysokość (robot nie może wjechać pod mebel jeśli jest za mało miejsca). Nic nie może wystawać ponad zderzak Laser musi obejmować 360°, oś obrotu (niekoniecznie sam laser) powinna być w środku robota (jak to połączyć z poprzednim punktem?) Enkodery nie muszą być super dokładne kwadraturowe, wystarczą zwykłe niewielkiej rozdzielczości, ale powinny być. W załączniku: program robota, zmodyfikowana biblioteka do czujnika, pliki do kółka oraz (może się komuś przydadzą) opona i felga (STL i SCAD, do opony/felgi potrzebny openscad w wersji nightly).Zbignas.zip W razie pytań i pretensji jestem do dyspozycji. Gdyby coś z moich STL-i było potrzebne proszę o informację (tylko nie na priv, błagam).
  23. 10 punktów
    Stacja meteorologiczna służy do przeprowadza dokładnych pomiarów pogody oraz sprawdzania jakości powietrza. Urządzenie pobiera dane z czujników, następnie zapisuje je do bazy danych po czym zostają wyświetlone na stronie internetowej. Całe urządzenie zostało zamknięte w obudowie wydrukowanej w drukarce 3D. Czujniki zainstalowane w urządzeniu pobierają dokładne dane pogodowe. Stacja posiada zaawansowaną metodę pomiaru prędkości wiatru przy użyciu ultradźwiękowych czujników ruchu. Stacja działa na Raspberry PI 3+, obsługuje również starsze modele (z wbudowanym wifi) oraz na Raspberry PI ZERO (W). System operacyjny to Linux wersja Raspbian STRETCH LITE bez interfejsu graficznego. Kod źródłowy czujników został napisany w Python’ie. Dane z czujników zapisywane są przy użyciu Raspberry PI do bazy danych MySQL. Następnie zostają wyświetlone w aplikacji internetowej, która napisana została w PHP. Urządzenie wymaga połączenia z Internetem. Aktualnie wykorzystywane jest połączenie poprzez WIFI. Komunikacja pomiędzy urządzeniem a administratorem przeprowadzana jest poprzez protokół SSH i FTP. Stacja jest zbudowana w taki sposób, żeby użytkownik mógł w łatwy sposób ją obsługiwać. Aby włączyć stację należy podłączyć ją do prądu. Działanie urządzenia zostanie zasygnalizowane świeceniem diody (czerwonej) oraz miganiem diody zielonej, która świeci przy wysyłaniu danych do bazy. Oprócz graficznego przedstawienia danych aplikacja posiada skrypty do obliczenia m. in. wschodu i zachodu słońca w danej lokalizacji. Oprogramowania posiada opcje, w których m. in. możemy ustawić czas pomiaru pogody i zapisu do bazy danych. Jest to ważne ponieważ możemy sami ustalać jak często stacja ma sprawdzać stan pogody Projekt obudowy Obudowa została zaprojektowana w programie FreeCAD. Składa się ona z 9 elementów. Została wydrukowana w drukarce 3D – Anet A8 (moja własna drukarka). Materiał wykorzystany podczas druku to PLA, temperatura druku 205°C. Łączny czas druku wynosi 19 godzin, zużywa 174 gram materiału przy wysokości warstwy 0.2mm. Projekt obudowy został wykonany w taki sposób, aby urządzenie było odporne na deszcz i wiatr. Opływowość stacji pozwala na wykonywania dokładnych pomiarów prędkości wiatru. Na samej górze stacji zamontowany został czujnik opadów deszczu oraz czujnik natężenia światła. Następnie pod nimi umieszczone są ultradźwiękowe czujniki prędkości wiatru. Kolejny element to obudowa chroniąca RB PI i elektronikę. Obudowa posiada specjalne mocowanie na RP PI, które sztywno trzyma urządzenie. Następnym elementem jest rdzeń, do którego przymocowane są pozostałe czujniki. Obudowę zamyka podstawka, w której znajduję się główny przewód zasilający oraz diody sygnalizujące działanie. Czujniki Urządzenie w czasie rzeczywistym pobiera dane z 7 czujników, następnie są one w odpowiedni sposób przekazywane do modułu detektorów i mikrokontrolerów, które zwracają dane do Raspberry PI. Lista czujników: Czujnik opadów Czujnik pomiaru opadów atmosferycznych składa się z dwóch części: sondy pomiarowej „YL-83” oraz modułu detektora „LM393”, który posiada wyjście analogowe umożliwiające pomiar deszczu. Moduł zasilany jest napięciem 5V. Czujnik natężenia światła Czujnik światła bazuje na fotorezystorze „GL5537-1”. Jest to opornik fotoelektryczny, który zmienia swoją rezystancję pod wpływem padającego światła. Prędkość wiatru Pomiar prędkości wiatru bazuje na ultradźwiękowym czujniku odległości „HC-SR04”. Ultradźwiękowy pomiar prędkości polega na zmierzeniu różnicy czasu przejścia impulsów ultradźwiękowych propagujących w kierunku przeciwnym do kierunku przepływu. Temperatura i wilgotność Do wykonywania pomiaru temperatury i wilgotności powietrza został wykorzystany popularny moduł „DHT11”. Moduł składa się z czujnika oraz niezbędnego do poprawnego działania układu: rezystora i kondensatora filtrującego napięcie zasilania. Ciśnienie Moduł z cyfrowym barometrem „BMP180” wykonuje pomiar ciśnienia w zakresie od 200hPa do 1100hPa. Układ komunikuje się przy użyciu interfejsu IC2, co zapewnia wysoką dokładność i stabilność wykonywanych pomiarów. Jakoś powietrza Moduł jakości powietrza „MQ-135” wykrywa w atmosferze: benzen, amoniak (NH3) oraz dwutlenek węgla (CO2). Inne: Przetwornik A/C i C/A 8-bitowy I2C Głównym układem przetwarzania danych w tej pracy jest przetwornik PCF8591. Moduł posiada czterokanałowy przetwornik analogowo-cyfrowy działający w oparciu o 8-bitowy systemem akwizycji danych. Komunikacja opiera się na szeregowej wysyłce danych za pomocą dwukierunkowej magistrali I2C.
  24. 10 punktów
    Kolejna ciekawostka - mało widowiskowa, ale dla mnie bardzo ważna! Po 11 miesiącach udało się uzyskać 2 poniższe dokumenty od Urzędu Patentowego RP. Oznaczają one, że od tego roku logo FORBOT oraz słowo FORBOT są zastrzeżonymi znakami towarowymi (m.in. w kontekście produktów związanych z nauką elektroniki i programowania). W praktyce chroni to FORBOTa przed wieloma nieprzyjemnymi sytuacjami. Od teraz mogę też zgodnie z prawem dodawać obok logo to słynne R w kółeczku FORBOT®
  25. 9 punktów
    Chcielibyście, aby urządzenie z ESP8266 wysyłało do Was e-maile lub powiadomienia push? Może zastanawialiście się, jak połączyć najnowsze DIY z asystentem głosowym od Google? Te pozornie trudne zadania można bardzo łatwo rozwiązać za pomocą popularnego IFTTT! [blog]https://forbot.pl/blog/praktyczny-poradnik-laczenia-esp-z-ifttt-if-this-then-that-id41663[/blog] IFTTT_przyklad_IO.zip
  26. 9 punktów
    Masz już dość irytujących buzzerów? Pora pójść krok dalej! Mikrokontrolery, takie jak STM32, bez problemu mogą odtwarzać muzykę. W tym celu konieczne jest jednak opanowanie podstaw I2S. Oto praktyczny poradnik, który omawia krok po kroku, jak generować pojedyncze tony, a nawet odtwarzać gotowe melodie pobrane z Internetu. [blog]https://forbot.pl/blog/co-warto-wiedziec-o-odtwarzaniu-dzwiekow-na-stm32-id43313[/blog]
  27. 9 punktów
    Witam! To mój pierwszy wpis w dziale DIY. Projektem jest (a właściwie dopiero będzie) mini konsolka do gier na STM32F1. Robię ten projekt dla mojego 3-letniego synka. Docelowo będę mu wgrywać na nią różne napisane przeze mnie gry, ale na początek zacznę od klasyki, czyli gra w węża Robiłem już podobny projekt przy okazji kursu SMT32 na Forbocie, więc szybko powinienem napisać niezbędny kod. Tym razem ma to być gotowe urządzenie które bez problemu będzie mógł obsłużyć 3-latek. Założenia projektu: 1. Mikrokontroler STM32F1 2. Ekran TFT kolorowy 240x320 3. Zasilanie bateryjne LiPo z ładowaniem przez gniazdo USB (więcej szczegółów w moim wątku w dziale Zasilanie - szczególnie ostatni mój post) 4. Obudowa w całości drukowana w 3D 5. Żadnych gotowych modułów. Własny projekt PCB i własny montaż. 6. Klawiatura: Krzyżyk, przycisk A, przycisk B oraz przycisk POWER, jak w starych Game - Boy'ach 7. Dzwięk: Nad tym jeszcze nie myślałem, brak I2S oraz DACa na mojej płytce Nucleo trochę utrudnia sprawę. Może będzie coś na Timerach i PWM. Zobaczymy. Teraz po kolei. Pierwsze co musiałem zrobić to ogarnąć wyświetlanie na TFT. Zakupiłem trochę w ciemno kilka wyświetlaczy 2,8" na ILI9341. Mój brak doświadczenia z TFT natychmiast się zemścił. Po odbiorze przesyłki okazało się że obsługa SPI wcale nie jest oczywista i jestem skazany na 16-bitową magistralę. Nie znalazłem nigdzie driverów na STM32 do sterowania tym kontrolerem przy takim połączeniu, ale znalazłem kilka projektów na GitHub'ie gdzie było sterowanie przez magistralę 8-bitową. Postanowiłem więc na podstawie tych projektów napisać własne drivery i procedury wyświetlania podstawowych kształtów. W trakcie prac nad optymalizacją wyświetlania okazało się że jednak 16-bitowa magistrala to doskonały pomysł i jest 4-krotnie szybsza od 8-bitowej. Dlaczego? Już tłumaczę: Gdy używa się 8-bitowej szyny danych to wysłanie piksela wygląda następująco (już po ustawieniu adresu): - Ustawiamy pierwsze 8 bitów koloru - WR strobe - czyli szybka zmiana linii WR na 0 i powrót 1 - Ustawiamy kolejne 8 bitów koloru - WR strobe - czyli szybka zmiana linii WR na 0 i powrót 1 I powtarzamy do czasu wypełnienia zaadresowanego okienka. Czyli na każdy piksel przypadają 4 kroki. Gdy używamy 16-bitowej magistrali - wygląda to następująco: - Ustawiamy 16 bitów koloru - WR strobe - czyli szybka zmiana linii WR na 0 i powrót 1 I powtarzamy do czasu wypełnienia zaadresowanego okienka. Czyli na każdy piksel przypadają 2 kroki. Ale przecież pisałem że jest 4 razy szybciej, a tu wychodzi że 2 razy No więc łatwo można zauważyć, że przy 16 bitach raz ustawiony kolor na linii danych możemy zostawić do czasu aż będziemy musieli użyć innego koloru. Więc jeżeli mamy kilkaset pikseli do wypełnienia jednym kolorem to raz go ustawiamy, a później już tylko WR strobe tak długo jak potrzebujemy Czyli realnie wykonujemy tylko jeden krok. Zaimplementowałem to w moich driverach i rezultaty były doskonałe. Na tyle dobre że odpadła mi konieczność posiadania pamięci pod bufor klatki. Wszystko wyświetla się błyskawicznie: Aktualnie mogę wyświetlać do 8Mpix/s, co teoretycznie pozwala odświeżyć ekran 240x320 ponad 100 razy na sekundę na STM32F1 taktowanym 64MHz. Czyli mogę jeszcze podnieść tą częstotliwość do 72 MHz i jeszcze zwiększyć transfery. Niestety chwilowo mam odcięty programator od płytki Nucleo i muszę kożystać z wewnetrznego oscylatora który pozwala rozkręcić mikroprocesor do 64MHz. Kolejnym problemem z którym musiałem się zmierzyć to mała ilość flash na grafiki do gier. Jak łatwo policzyć jedna pełnoekranowa grafika to 153600 bajty, a mam tylko 128k do dyspozycji. A jeszcze musi się zmieścić program. Rozwiązaniem problemu jest kompresja. Tu znów musiałem od zera napisać program do kompresji grafiki który spełniałby moje wymagania. Kompresor został napisany w Pythonie. A szybki dekoder zaimplementowany w C w driverach na STM32. Pisałem program praktycznie od zera wg mojego pomysłu. Otóż dzieli on grafikę na bloki o jednolitych kolorach, a ich metadane zapisuje w binarnym pliku wyjściowym, albo w pliku C. Bloki są następujące: pozioma linia, pionowa linia, prostokąt. Pojedynczy piksel to pozioma linia o długości 1. Kompresja odbywa się przez rozkład grafiki na takie bloki, a następnie zapisaniu ich parametrów do pliku wyjściowego. Procedurę dekompresji zaimplementowałem w driverach do wyświetlacza, a każdy blok łatwo można wysłać bezpośrednio do pamięci ekranu, gdzie obraz zostaje odtworzony. Kolejną funkcją którą zaimplementowałem w kompresorze jest możliwość kodowania różnicy pomiędzy dwoma grafikami. Tzn jeżeli robię animację to program kompresuje tylko piksele które różnią dwie klatki. Poniżej proces odtwarzania obrazka na wyświetlaczu w zwolnionym tempie: Skoro miałem już ograne wyświetlanie grafiki, przyszedł czas na prototypowanie konsoli i pisanie samego kodu gry Aktualnie moje stanowisko pracy wygląda następująco: Sama gra jest na etapie tworzenia grafiki. Na razie mam animacje na intro: To tyle na dzisiaj. Wraz z postępami będę aktualizował ten wątek. Pozdrawiam, Marek
  28. 9 punktów
    Mam zaszczyt przedstawić: Roko Kopłapow - czyli Robot Koncepcyjny, Konserwator Płaskich Powierzchni. Co mniej więcej ma oznaczać: mopopodobny twór samojezdny, którego zadaniem jest sprawdzenie wszelkich koncepcji przed zaprojektowaniem i skonstruowaniem prototypu robota do czyszczenia podłogi na mokro. Niestety - nie wszystko poszło po mojej myśli. Niektóre koncepcje okazały się absolutnie nietrafione, inne wymagają dopracowania i ponownego sprawdzenia. Sam robot jednak doskonale się sprawdził pokazując mi, w którą stronę mają iść dalsze prace. Jakie były założenia: robot ma służyć do przetarcia podłogi na mokro; ma być sterowany pojedynczym Arduino Pro Mini; miło by było aby realizował wszystkie funkcje, ale równie dobrze może pracować jako "inteligentne podwozie ze szczotkami", czyli jako nośnik różnej maści przystawek; Robot powinien umieć poruszać się po podłodze bez jej zmywania (czyli podnieść mechanizm szczotek choćby w celu przejechania przez próg); Robot powinien umieć znaleźć stację dokującą lub miejsce parkingowe. Co się nie sprawdziło: Podnoszone szczotki Założenie całkiem fajne, ale zbyt duża siła jest potrzebna do podniesienia całego mechanizmu. W dodatku podniesiony mechanizm zajmuje zbyt dużo miejsca. Teoretycznie dało by się to obejść ale robot musiałby być dużo większy, a tego nie chciałem. Podwozie gąsienicowe O ile na normalnym podłożu zachowywało się bez zarzutu - o tyle na mokrej, śliskiej podłodze to absolutna porażka, gąsienice po prostu nie łapią przyczepności. Podwozie Pololu (testowo z pojedynczą nieruchomą gąbką) w ogóle nie chciało skręcać, jeśli napędzana była tylko jedna gąsienica jechał sobie dalej prosto, przy napędzanych dwóch przeciwbieżnie robił jakieś dziwaczne ewolucje nie mające nic wspólnego ze skręcaniem. Podwozie Tamiya (maksymalna długość gąsienic, szerokość zwiększona do 15 cm) - niewiele lepiej. Co prawda przy podniesionych szczotkach dało się tym manewrować, ale jako że podnoszone szczotki też nie zdały egzaminu - zrezygnowałem z gąsienic i zrobiłem kołowe. Żyroskop Teoretycznie wszystko było w porządku, robot bardzo ładnie jechał prawie po prostej mimo wirujących szczotek które rzucały nim na boki, skręcał dokładnie o tyle ile chciałem... przez pierwsze 30 sekund. Tyle czasu udało mi się utrzymać mojego MPU6050 przy życiu. Niestety - po bardziej wnikliwych poszukiwaniach okazało się, że nie tylko ja mam takie problemy, niektóre egzemplarze działają bezbłędnie, inne się wieszają (zawieszając przy okazji Arduino). Tak więc na razie robot obywa się bez żyroskopu, chociaż w przyszłości na pewno się na niego zdecyduję (może taki? Poradzicie?). Stacja dokująca W związku z brakiem podnoszonych szczotek musiałem z niej zrezygnować - robot nie przejedzie przez próg, a stacja dokująca powinna być w innym pomieszczeniu. Szkoda... Na razie zamiast dokowania robot powinien wjechać w wyznaczony kąt pomieszczenia i się wyłączyć, ale do tego muszę wymyśleć jakiś inteligentny wyłącznik (to już w oddzielnym wątku). Wąska wiązka czujnika laserowego Chciałem przy "rozglądaniu się" robota ograniczyć szerokość matrycy. Niestety - tu już nie pozwoliło mi na to oprogramowanie. Mamy do dyspozycji dwie biblioteki do czujnika VL53L1X: jedną uproszczoną (która nie pozwala na ustawienie regionu) i drugą pełną (adaptacja ST, pozwala na wszystko tyle że zajmuje 20 kB, jak na małe Arduinko to nieco za wiele). Być może któregoś pięknego dnia uda mi się dopisać tę możliwość do tej mniejszej biblioteki, ale na razie niespecjalnie mam na to czas, a z szerokością wiązki 27° muszę nauczyć się żyć... Inna możliwość to postawienie drugiego procesorka tylko do obsługi lasera, mógłbym wtedy zmienić serwo na mały silnik krokowy (nawet taki mi w szufladzie leży), tylko czy jest sens? A co się sprawdziło: Przede wszystkim - napęd szczotek. Obie szczotki to po prostu kuchenne gąbki włożone w uchwyty, napędzane są pojedynczym silnikiem z dwustronnym wałem. Szczotki są obrócone wobec siebie o kąt 90°, aby zmniejszyć szerokość robota i pozbyć się martwego pola pomiędzy szczotkami, obracają się przeciwbieżnie. Gąbki można w każdej chwili wyjąć i wymienić na czyste, w dodatku mogą być włożone zarówno miękką, jak i szorstką stroną do podłogi. Druga rzecz bez której dalsza praca nie miałaby sensu to przedni zderzak. Musi być bardzo lekki, znajdować się dość nisko nad podłogą (progi) a jednocześnie mieć wysokość wystarczającą, aby robot nie usiłował wleźć pod jakąś kuchenną czy łazienkową szafkę. Jednoczęściowy zderzak zapewnia wykrycie przeszkody w promieniu 180°, jest na tyle lekki że nie mam nawet żadnych sprężyn - cztery krańcówki wystarczają. Krańcówki są połączone po dwie równolegle z każdej strony, zwierają przez rezystor do masy co umożliwia bezproblemowy odczyt zderzaków przez pojedyncze wejście analogowe Arduino. Z drobiazgów: materiał. Oprócz elementów drukowanych z PLA mam tu: płytę główną podwozia z 3mm PCW. Łatwe w obróbce, w miarę elastyczne i wystarczająco wytrzymałe. podłogę piętra ze spienionego PCW 4mm. Nie musi wytrzymywać dużych obciążeń, jest bardzo lekkie i możliwe do cięcia zwykłym ostrym nożem. koszyki na akumulatory wydrukowane z PET-G z integralną sprężyną. Początkowo obawiałem się że nie będą kontaktować - okazało się, że sprawują się dużo lepiej niż kupowane podwójne (już nie mówię o porażce pod tytułem "koszyk na jeden akumulator"), a przy okazji mam tu porządny przewód (ucięty od pecetowego zasilacza) a nie jakiś chiński włosek. Dla zainteresowanych podaję link na thingiverse. A z rozwiązań: Enkodery na kołach. No - powiedzmy częściowo, trochę za mała rozdzielczość ale działają. Do bardziej precyzyjnych rzeczy pewnie by się nie nadały, ale tu zdają egzamin. Ponieważ nie wyszedł mi napęd gąsienicowy, zacząłem szukać jakichś fajnych kółek. Kiedyś znalazłem na Allegro za jakieś śmieszne pieniądze silniczki z kątową przekładnią (odpowiedniki Pololu), dokupiłem do tego koła Pololu 42x19, zmontowałem jakieś prowizoryczne podwozie... i na tym się skończyło bo jakoś straciłem zainteresowanie projektem. Czyli silniki z kołami już miałem. W pierwszej wersji robot miał się orientować w przestrzeni za pomocą żyroskopu i laserowego czujnika odległości, ale z braku żyroskopu zostałem skazany na enkodery. Co prawda oficjalnie te silniki nie miały możliwości zamontowania enkoderów, ale na szczęście w to nie uwierzyłem Postanowiłem umieścić enkodery wewnątrz kół. Co prawda miejsca jest dość mało, musiałem wydrukować nowe felgi, ale jakoś cała konstrukcja się zmieściła. Użyłem popularnego TCRT5000L (zawsze mi kilka w szufladzie leży), dokleiłem uchwyty do silników... i ruszyło! Co prawda enkodery czasami fałszują, ale uczciwa bramka Schmitta powinna im w przyszłości pomóc. Na razie podłączenie wygląda tak: Dla zainteresowanych - zdjęcia i pliki STL/SCAD. Czujnik odległości 360° Niedawno ktoś pytał o coś takiego - o ile pamiętam chodziło o ultradźwiękowy czujnik odległości o zakresie ruchu 360°. Ponieważ moje rozwiązanie działa całkiem nieźle (należałoby tylko maksymalnie zmniejszyć luzy, ale to już zależy od możliwości drukarki) mam tu prostą przekładnię, zakładaną bezpośrednio na serwo i mocowaną tymi samymi śrubami co serwo, z tarczą pozwalającą na zamocowanie czujnika (w moim przypadku laser, ale może to być równie dobrze czujnik ultradźwiękowy). Dwie wersje: większa i kompaktowa (jeśli nie starcza miejsca). Jako osi użyłem śruby z podwozia Tamiya oryginalnie służącej do mocowania kół jezdnych z uwagi na fagment bez gwintu, ale w ostateczności można spróbować ze zwykłą śrubą M3. Tym razem nie ma STL-i jako że każdy ma inne potrzeby, zamiast tego plik dla OpenSCAD-a. Potrzebne będą biblioteki: spur_generator oraz parametric_involute_gear_v5.0. Co do programu: Program jest dość prosty, nie ma sensu publikowanie bo pewnie jutro jak mi się coś przyśni to będzie inny (możliwe że lepszy, ale niekoniecznie). Zresztą tak jak wspominałem - to jest egzemplarz koncepcyjny, wystarczy mi stwierdzenie że "da się to zrobić". Mój SMARDZ niesamowicie ułatwia programowanie, musiałem go tylko trochę inaczej zamocować (dodatkowy uchwyt i przedłużacz) bo przy gwałtowniejszych manewrach zsuwał się z pinów - prawdopodobnie bez czegoś takiego rzuciłbym to po paru godzinach. Robot ma cztery tryby pracy: Zdalne sterowanie - wiadomo o co chodzi. Zrobiłem kiedyś takiego uniwersalnego radiopilota, to już czwarte urządzenie które nim steruję; Jazda losowa - taki typowy wszędołaz, potrafi omijać przeszkody, stara się nie jechać prosto za długo aby się poszwendać w ciekawszych miejscach; Plama - analogicznie jak w Roombach, wyciera podłogę w promieniu do ok. 70 cm od miejsca startu i zatrzymuje się po skończeniu pracy; Sprzątanie - tu program nie jest dopracowany, ale w wersji koncepcyjnej nie ma to większego sensu. Ogólnie robot powinien podjechać do najbliższej ściany (to potrafi), ustawić się do niej równolegle (to też potrafi) i krążyć po pomieszczeniu coraz bliżej środka (tu ma problemy związane z niedokładnością enkoderów). Tak wygląda robot w trybie "plama": Ktoś za chwilę powie: zaraz, przecież to robot do sprzątania na mokro, a gdzie woda? Na razie nie ma. Po prostu: ponieważ nie ma stacji dokującej, przed uruchomieniem robota należałoby ręcznie uzupełnić wodę w zbiorniku. Dużo wygodniejsze jest po prostu spryskanie wodą podłogi w pomieszczeniu przed uruchomieniem robota. A czemu "na razie"? Bo jak wspomniałem na początku, ten robot powinien mieć możliwość współpracy z przystawkami, a taką przystawką może być np. urządzenie do spryskiwania płynem do mycia paneli. Ale taka przystawka powinna mieć swój procesor, robot w tym momencie powinien przestawić się w tryb "inteligentnego podwozia", a to wszystko jest kwestią przyszłości Na razie robot spełnił swoje zadanie, popracuję jeszcze trochę nad programem (dopóki się da), i zaczynam zbierać kasę na wersję finalną Obiecane pliki STL i SCAD w załączniku:koplapow.zip Jak zwykle jestem gotów odpowiedzieć na pytania - choć tym razem chyba ich nie będzie...
  29. 8 punktów
    Na licznych forach istnieje tradycja witania się nowych użytkowników z aktualnymi członkami społeczności. Ostatnio na Forbocie pojawia się coraz więcej nowych osób - głównie za sprawą naszych kursów elektroniki. W związku z tym zakładam oficjalny temat do takich powitań. Na pewno takie miejsce sprawi, że nasza społeczność będzie jeszcze lepsza Jesteś nowym użytkownikiem? Jeśli chcesz możesz się przywitać z innymi. Napisz czym się zajmujesz, skąd zainteresowanie elektroniką. Nad czym teraz pracujesz itd.
  30. 8 punktów
    Witam wszystkich! Około rok temu, w oczekiwaniu na coroczny konkurs techniczny organizowany w mojej szkole postanowiłem wykonać robotyczne ramię sterowanie kontrolerem w formie rękawicy. Ramię miało powtarzać ruchy dłoni oraz nadgarstka w czasie rzeczywistym. Głównym celem było stworzenie działającego prototypu dzięki któremu zwiększę swoją wiedzę w dziedzinie elektroniki, robotyki oraz programowania. Ramię Projektowanie Zabrałem się więc za projekt. Na samym początku rysowałem oraz testowałem różne konstrukcje przekazania momentu do odpowiednich stawów aż zdecydowałem się na linki w pancerzach. W mojej opinii jest to najlepsze rozwiązanie w konstrukcjach amatorskich z ograniczonym budżetem. Serwomechanizmy TowerPro SG90 wymieszane ze swoimi klonami, plecionka wędkarska 0.23mm, oraz wężyki silikonowe 3mm/1mm powinny załatwić sprawę. Powrót określonej części palca realizowany za pomocą gumek recepturek . Przeszedłem więc do programu fusion 360 i tak prezentują się efekty mojej pracy. Składanie Po otrzymaniu przesyłki z serwami od naszych wschodnich kolegów przystąpiłem do drukowania poszczególnych części projektu. Wszystkie elementy drukowałem na delikatnie zmodyfikowanym enderze 3 z PLA ora PETG. Serwa zostały przykręcone oraz przyklejone na klej cyjanoakrylowy. następnie przystąpiłem do przedziewania wężyków silikonowych i podklejania linek do odpowiedniej części dłoni. Szybko okazało się że wężyk, który zamówiłem kompletnie nie nadaje się do takiego zastosowania ze względu na duże tarcie oraz małą sztywność powodującą ściskanie się wężyka zamiast zginania palca w odpowiedzi na ciągnięcie linki przez serwo. Dlatego aby konstrukcja działała chociaż trochę lepiej owinąłem wszystkie wężyki koszulkami termokurczliwymi co w większości pozwoliło pozbyć się problemu ściskania. Jednakże dodało to dodatkowy milimetr średnicy każdemu z nich. Coś za coś. Zostało tylko dodać gumki i cała konstrukcja mechaniczna skończona. Kontroler Jako czujniki zgięcia zastosowałem potencjometry. Początkowo miały to być zwyczajne montażowe jednak niezliczone wady tego rozwiązania ujawniły się natychmiast po złożeniu pierwszego prototypu. W poszukiwaniu innej opcji trafiłem w Internecie na podobną konstrukcję również wykorzystującą potencjometry jednakże z otworem umożliwiającym przedzianie przez nie wału. Zakupiłem więc wystarczającą ilość sztuk i podczas oczekiwania na przesyłkę zaprojektowałem naprędce projekt drugiej rękawicy który okazał się finalnym. Dodatkowo do podłączenia potencjometrów użyłem wyjątkowo giętkich przewodów odpornych na wielokrotne zginanie( skrętka nie poradziła sobie w tej roli). Elektronika Mózgiem całego układu jest atmega 8 , otoczona elementami pasywnymi niezbędnymi do jej właściwego działania oraz do właściwego działania przetwornika ADC. Płytkę zaprojektowałem w programie Eagle, a wykonałem na zrobionym samodzielnie ploterze wykorzystując czarny pisak permanentny laminat zamiast kartki. Po kąpieli w wytrawiaczu płytka była gotowa do montażu. Oczywiście nie obyło się bez błędów wynikających z mojego małego doświadczenia oraz zwyczajnej nieuwagi. Drugim niezwykle ważnym układem był multiplekser 16 kanałowy wykonany z trzech multiplekserów 8 kanałowych. Takie rozwiązanie było zdecydowanie tańsze oraz niemiałem żadnych problemów z dostępnością części. Ponownie odpaliłem Eagle-a i w ruch ruszył mój ploter. Pierwsza płytka wykonana na elementach SMD okazała się całkowitą porażką natomiast druga na THT wyszła dokładnie tak jak powinna. Starałem się aby w całej części elektronicznej projektu jak najmniej elementów było lutowane "na stałe". Dlatego używałem złączek IDC, ARC oraz oczywiście goldpinów. Dzięki temu całość uzyskała budowę modułową niezwykle ułatwiającą przenoszenie oraz wszelakie naprawy. Program Program został napisany w języku C na mikrokontrolery AVR w środowisku Eclipse. Gdyby nie książka: " Mikrokontrolery AVR - podstawy programowania" Pana Mirosława Kardasia nie sądzę aby udało by mi się nauczyć się programować AVR-y oraz napisać mój program w tak krótkim czasie. Program jest niezwykle prosty. Co 20 ms czyli z częstotliwością odświeżania właściwą dla serw SG90 przestawiane są multipleksery za pomocą odpowiednich bitów, a wartość odczytana z potencjometru przez przetwornik ADC jest zamieniana funkcją map()( przekopiowaną z biblioteki arduino) na wartości odpowiadające odpowiedniemu wypełnieniu sygnału PWM. Dzieje się to ze względu na właściwość użytych przeze mnie serwomechanizmów. Przy odpowiedniej wartości wypełnienia PWM przyjmują one odpowiednią pozycję( w moim przypadku 0 stopni to około 1ms wypełnienia natomiast 180 stopni to około 2ms wypełnienia). Następnie 16 programowo generowanych kanałów PWM przyjmuje przekonwertowane dane i wysyła je złączem IDC na serwomechanizmy. Lista części: Serwomechanizmy SG90(klony + oryginalne) - ok. 80zł Plecionka, wężyk + rurka termokurczliwa- ok. 60zł Potencjometry APC ( z otworem ) - ok.20 zł Atmega 8 , złączki, elementy pasywne- ok.30zł Multipleksery CD4051BE - ok.6 zł Koszty druku( filament + prąd)- ok.40zł Wady: Konstrukcja zawiera ich bardzo wiele : mała sztywność całego układu złe wężyki ( zbyt wiotkie oraz zbyt grube) nieoryginalne serwa mające ogromne problemy właściwie ze wszystkim nieprzemyślana konstrukcja dłoni (zbyt wiele kleju zbyt mało połączeń rozłącznych) gumki zamiast sprężyn jako powrót po ściśnięciu brak prawidłowej filtracji zasilania!!! niedziałający nadgarstek(spowodowany przez: brak pinów na mikrokontrolerze, brak czasu , za słabe serwa , zbyt mało miejsca na prawidłowe działanie, nieprzemyślana budowa itp. Podsumowanie Jestem niezwykle zadowolony z całokształtu mojej pracy. Mimo wielu błędów( a raczej dzięki nim) nauczyłem się bardzo bardzo wiele. Od programowania, projektowania, trochę mechaniki oraz wiele więcej. Jeśli mógłbym doradzić coś osobą początkującym takim jak ja chcącym wykonać podobną konstrukcję to: proszę was kupcie oryginalne serwa! Mimo ich 3 razy większego kosztu działają nieporównywalnie lepiej do chińskich odpowiedników a ich właściwości także są o wiele lepsze. Na swoim przykładzie przekonałem się że niema czegoś takiego jak za trudny projekt jest tylko za mało czasu i pieniędzy. Wszystkiego da się nauczyć w trakcie pracy jednakże będzie to skutkować błędami tak jak w moim przypadku. Bogatszy w doświadczenie zacząłem już tworzyć drugi projekt ręki , która to min. będzie realizowała ruch palców w bok. Pozdrawiam wszystkich serdecznie i dziękuję za uwagę!
  31. 8 punktów
    Coś nieskomplikowanego na początek. Ponieważ moja dziewczyna jest maniakiem kwiatów, zaznaczyła sobie coś co by można wetknąć w grunt, zapomnieć o tym, że w tym gruncie jest przez parę miesięcy a w międzyczasie dowiadywać się z tego ile mniej więcej wody znajduje się w ziemi (aka "kiedy najlepiej podlewać"), najlepiej po WiFi. Z WiFi nic nie wyszło, bo w sumie wszystko co używa WiFi ma pobór prądu z kosmosu, a chcemy mieć tak około pół roku pracy na baterii 300-400mAh. Opcją był jeszcze BLE (nRF52), ale też odpadł z powodu w sumie małej wygody. Skończyło się na STM32F030 w parze z LT8920. STMa chyba nie trzeba przedstawiać, a LT8920 jest transciverem radiowym w pasmie 2,4GHz, którego główną zaleta jest mała liczba potrzebnych dodatkowych elementów, potrzebne są całe dwa kondensatory i 12MHz kryształ. Do tego pobór prądu w uśpieniu na poziomie 6uA i do tego koszt 25 centów za sztukę. Ale nie ma róży bez kolców, zasięg w praktyce jest ok, ale mogło by być lepiej: około 1-2 betonowe ściany, do tego tragiczna dokumentacja. Pomiar wilgotności odbywa się metoda pojemnościową: Na wejście układu pomiarowego podawany jest 2,4MHz sygnał PWM z 30% wypełnieniem. Ten po przejściu przez filtr złożony ze ścieżek na PCB, ewentualnej wody w otoczeniu i R2 ulega spłaszczeniu. Interesuje nas w tym momencie jaki jest mniej więcej maksymalny poziom po przefiltrowaniu, a zmierzenie tego umożliwia detektor maksimów złożony z D1 (to tak na prawdę dioda 4148, pod ręką nie było odpowiedniego symbolu w eagle), C1 i R3. Potem już wystarczy nawet niezbyt szybki ADC i określenie poziomów napięcia w suchym i mokrym otoczeniu celem kalibracji. Ładowanie przez gniazdo mini USB za pomocą TP4057, stabilizację do 3V zapewnia HT7530-7, oba w obudowach SOT23-5. Szczytowy pobór prądu w trakcie pomiaru/nadawania osiąga około 60mA, 22mA w odbiorze, a w trybie uśpienia nie przekracza 30uA. Pomiar/wysyłka odbywa się raz na 5 minut, trwa około 55ms. To teoretycznie powinno pozwolić na pracę z 400mAh akumulatorka lipo przez około 8 miesięcy, uwzględniając 3% samorozładowanie i bez uwzględnienia ręcznego trybu nasłuchu. Układ posiada jeden przycisk, którego działanie rożni się w zależności od czasu przytrzymania: * pojedyncze naciśniecie - natychmiastowy pomiar i wysłanie aktualnych danych w pakiecie (migniecie diodą) * przytrzymanie przez 3s - układ przechodzi w tryb nasłuchu, to umożliwia zdalne przejście do bootloadera i wgranie nowego firmware przez radio lub odczyt danych na żywo przez centralkę, ewentualnie także zmianę parametrów (miganie diodą co 1s) * przytrzymanie przez 10s - reset + wejście do bootloadera na 30s (miganie diodą 3x s) Obecnie nie ma innej opcji wyłączenia transmisji danych niż odłączenie baterii. Ale tak sobie myślę, że zmiana STM32F030 na F07x dała by opcję konfiguracji przez USB, przydatną w wypadku wprowadzenia przypadkiem jakichś bardzo złych ustawień. To jednak może w kolejnej wersji, obecna jak na nasze potrzeby się sprawdza całkiem dobrze. Przy okazji pomiaru wilgotności gleby układ mierzy tez napięcie na baterii, opcjonalnie temperaturę (NTC), napięcie na USB podczas ładowania. Jako, że czujniki jednak nie mają WiFi, zbierania danych z czujników wykorzystywany jest zegar: Zbudowany na STM32F107 (i 18 wyświetlaczach matrycowych 8x8 20/1.9mm), posiada port ethernet, kilka czujników podających parametry środowiska w który się znajduje i transciver na LTC8920 co umożliwia mu wymianę danych z czujnikami. Ale ten opisany będzie dokładniej jak w moje kochanie zrobi coś sensownego z jego WebUI Oraz dlaczego tu nie ma podglądu posta przed wysłaniem.
  32. 8 punktów
    Witam serdecznie wszystkich czytelników. Chciałbym wam dziś przedstawić mój projekt jaki wykonałem na zakończenie technikum. Mianowicie zaprojektowałem i zbudowałem router sieciowy wyposażony w 5 portów ethernet oraz WIFI 2,4Ghz i 2x2 MIMO. Projekt zacząłem od wybrania jednostki sterującej , znajomy elektronik polecił mi SKW92a. Jest to mały moduł idealny do tego typu zastosowań. Można na nim uruchomić OpenWRT, bardzo ekonomiczna w zajmowane miejsce na dysku( tylko około 8 MB) wersja Linuxa. Tak więc użyłem tego modułu do budowy tego urządzenia. Następną rzeczą do zrobienia było dobranie zasilania. Chciałem aby router mógł być zasilany z np.takiej oto ładowarki , gdyż wejście microUSB i 5V jest dość popularne w dzisiejszych czasach. SKW92a działa jednak na zasilaniu 3,3V, konieczne więc było dodanie przetwornicy z 5V na 3,3V. Postanowiłem dodać jeszcze LEDy , aby służyły jako wskaźniki oraz port USB który będzię mógł posłużyć do podłączenia pamięci zewnętrznej w razie potrzeby przywrócenia systemu. Na końcu oczywiście też filtry dopasowujące transmisje ethernet i porty szeregowe do debuggowania. Projekt PCB routera Zaprojektowałem płytkę w Ki-Cadzie, dodałem swoje logo i wysłałem do produkcji ( sam proces projektowania PCB , rysowania footprintów itp. zajął około 30 h). Po polutowaniu wszystkiego router zaczął nabierać kształtu. Wszystko na miejscu Niestety pierwsze uruchomienie nie poszło zbyt kolorowo, gdyż mimo poboru prądu nie dało się wejść przez UART do SKW , po dogłębnej diagnostyce okazało się że nie jest to błąd portu szeregowego ale przetwornicy która była wadliwa.Musiałem umieścić tam osobną przetwornice step-down na osobnej płytce. Po tym zabiegu router zaczął działać wyśmienicie. Działający router Zainstalowanie OpenWRT nie było większym problemem, a także późniejsza konfiguracja była dość prosta. Z pomocą znajomego odkryliśmy że bez problemu można także przełączyć router w tryp switcha i można nawet tworzyć VLANy. Ostatnią rzeczą do zrobienia zostało zrobić ładną obudowę, którą zaprojektowałem w programie Designspark mechanical i wydrukowałem w drukarce 3D. Obudowa A tak wygląda w pełni działający router Dziękuję za uwagę i zapraszam do zadawania pytań w komentarzach
  33. 8 punktów
    Wstęp Jeśli sięgnąłeś po ten artykuł, to prawdopodobnie jesteś programistą, a co więcej, chcesz być lepszym programistą! To bardzo dobrze, ponieważ rynek IT potrzebuje lepszych programistów, a wytwarzanie czystego kodu według przyjętych standardów programowania jest zdecydowanym krokiem w tę stronę. Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. Czym właściwie jest czysty i dobry kod? Na to pytanie nie ma jednoznacznej odpowiedzi. Istnieje jednak zbiór pewnych reguł i narzędzi, które skutecznie wspomogą pracę programisty, a stosowane w całym zespole, polepszą jego efektywność i skuteczność. Spis treści serii artykułów: Czysty kod w praktyce - część 1 Czysty kod w praktyce - część 2 Jak więc tworzyć oprogramowanie pozbawione błędów? Podstawową regułą jest stosowanie właściwie dobranych nazw opisujących zmienne, funkcje czy struktury – jeśli kwestia ta nie jest spełniona, to żadna konwencja nie zda egzaminu. Nazwa taka powinna być odpowiedzią na wszystkie ważne pytania – w jakim celu istnieje, co robi, jakiego jest typu i jak jest używana. Jeżeli nazwa zmiennej wymaga komentarza, to znaczy, że nie ilustruje swojej intencji (dobry kod jest samokomentujący!). Przedrostki określające typy zmiennych Przykładowe przedrostki określające typy zmiennych: diGripperOpen – cyfrowy sygnał wejściowy mówiący, że chwytak jest otwarty; doGripperOpen – cyfrowy sygnał wyjściowy mówiący, aby chwytak został otwarty; aiTemperatureSensor – analogowy sygnał wejściowy czujnika temperatury; giTemperatureSensor – grupowy sygnał wejściowy czujnika temperatury (cyfrowy sygnał zakodowany na przykład na 16 bitach); nIndex – zmienna typu int zawierająca dane licznikowe; rRadius – zmienna typu real zawierająca promień; bMP3Module_On – zmienna typu bool informująca o załączeniu modułu mp3; Nie bądźmy dowcipni (ale tylko w kodzie ;d) Jeżeli nazwy są dowcipnymi określeniami, mogą być zapamiętane wyłącznie przez osoby z identycznym co autor poczuciem humoru i tylko dopóki dane określenie nie wyjdzie z mody. Nazwa zmiennych i funkcji powinny odzwierciedlać ich znaczenie. Dowcipne hasła z najnowszego standupu Rafała Paczesia zostawmy na integrację po pracy. Jedno słowo na pojęcie Należy stosować zasadę jedno słowo na jedno abstrakcyjne pojęcie i trzymać się jej w całym swoim programie. Na przykład diHumiditySensor. Nie twórzmy zgadywanek! Należy unikać używania różnych określeń do jednego celu. Powoduje to brak jednoznaczności. Czujnik zmierzchu oprogramowany w kodzie musi mieć jedną nazwę – używanie zamiennej terminologii jak czujnik optyczny, czujnik zmierzchu czy czujnik zmierzchowy powodują tylko bałagan w kodzie. Jeśli w systemie, który programujemy mamy kilka czujników, dla ich rozróżnienia nazwijmy je zgodnie z ich rolą i lokalizacją – nie stosujmy na przykład: aiHumiditySensor, aiMoistureSensor, aiWetnessSensor a na przykład aiHumiditySensor_Room, aiHumiditySensor_Kitchen, aiHumiditySensor_Bathroom. Dodajmy znaczący kontekst Jeśli mamy grupę danych, możemy posłużyć się różnymi zabiegami (w zależności od możliwości języka w jakim programujemy), aby panował w nich ład i porządek, grupując np. dane adresowe jako addrFirstName, addrLastName, addrState i tak dalej. Dzięki temu inni programiści będą wiedzieli, że zmienne te są częścią większej grupy danych. Możemy również użyć struktury, klasy – wszystko w zależności od języka programowania. Stosujmy terminologię klienta Jeśli tylko to możliwe, to do nazewnictwa zmiennych stosujemy terminologie klienta – jeśli istnieją dwa lub więcej terminów klienta na jedno pojęcie, wybieramy jedno i konsekwentnie się do tego stosujemy. Na przykład jeśli programujemy system do zarządzania produkcją u klienta, który wytwarza pakiety baterii z ogniw, używajmy zmiennych nBatteryIndex, bBatteryPresent itd. Podsumujmy dobre nazwy w kodzie przedstawiają intencje; bez mylących i fałszywych wskazówek; bez zbyt subtelnych różnic; są spójne; można je wymówić; łatwo je wyszukać; nazwy zmiennych mają rzeczowniki; nazwy funkcji mają czasowniki; dowcipne nazwy mogą nie być zrozumiane; dodajemy znaczący kontekst; nazwy zmiennych, funkcji, podprogramów w języku angielskim; zmiana nazwy na czytelniejszą to nic złego. Stosujmy dobry, konsekwentny styl Jak zapewnić tę czytelność? Po pierwsze: nazwy - zmiennych, stałych, funkcji, klas, metod, struktur itd. Każda nazwa powinna być znacząca, chyba że ma marginalne znaczenie. Jednoliterowe nazwy mogą się nadawać do zmiennych tymczasowych, takich jak np. zmienne pętli, ale tylko i wyłącznie wtedy. Nazwy powinny odzwierciedlać zastosowanie – zmienna przechowująca indeks tablicy może nazywać się „index”, a funkcja dodająca do siebie dwie liczby – „add”. Trudno się nie zgodzić, że są to o wiele czytelniejsze nazwy niż np. „dupadupacycki” czy „qwert”. Jeśli chodzi o dokumentację i komentarze, to lepiej jest używać długich nazw zmiennych (o ile dany język programowania na to pozwala), procedur, programów i funkcji, które dobrze określają ich znaczenie, zamiast używać krótkich nazw i zaopatrywać ich długim komentarzem. Poza tym długie nazwy pomagają w przypomnieniu sobie działania programu jeśli zaglądamy do niego po długiej przerwie. Jaki sens mają szczegółowe komentarze? Nie powinno się pisać kodu wyłącznie czytelnego, bądź wyłącznie optymalnego. Kod powinien być zrównoważony i wypośrodkowany – na tyle zoptymalizowany na ile nie straci na czytelności. Argument czytelności można w ogóle pominąć dopiero wtedy gdy wydajność kodu jest niewystarczająca, jednak wtedy należy taki kod opatrzyć stosownym komentarzem. Komentarze – kiedy nie mają sensu? Niewiele jest rzeczy tak pomocnych, jak dobrze umieszczony komentarz. Jednocześnie nic tak nie zaciemnia modułu, jak kilka zbyt dogmatycznych komentarzy. Nic nie jest tak szkodliwe, jak stary komentarz szerzący kłamstwa i dezinformację. Komentarze nie są szminką dla złego kodu! Jednym z często spotykanych powodów pisania komentarzy jest nieudany kod. Napisaliśmy funkcję i zauważamy, że jest źle zorganizowana. Wiemy, że jest chaotyczny. Mówimy wówczas: „Hm, będzie lepiej, jak go skomentuję”. Nie! Lepiej go poprawić! Precyzyjny i czytelny kod z małą liczbą komentarzy jest o wiele lepszy niż zabałaganiony i złożony kod z mnóstwem komentarzy. Zamiast spędzać czas na pisaniu komentarza wyjaśniającego bałagan, jaki zrobiliśmy, warto poświęcić czas na posprzątanie tego bałaganu i poprawić nasz kod - czytelny kod nie wymaga komentarza. Komentarze – kiedy mają sens? W wielu przypadkach stosowanie komentarza jest jak najbardziej słuszne. Często musimy zastosować komentarz prawny z powodu korporacyjnych standardów klienta. Czasami przydatne jest umieszczenie w komentarzu podstawowych informacji – na przykład typu czy informacji o wartości zwracanej zmiennej i wtedy warto zawrzeć taką informację w komentarzu informacyjnym. Na etapie projektowania często praktyką są komentarze TODO jako notatki zagadnień, które pozostały jeszcze „do zrobienia”. Formatowanie kodu Pamiętajmy, że kod powinien być ładnie sformatowany. Należy wybrać zbiór prostych zasad, które rządzą formatowaniem kodu, a następnie w konsekwentny sposób je stosować. Jeżeli pracujemy w zespole kilku programistów, to wszyscy jego członkowie powinni przyjąć zbiór zasad formatowania i stosować się do nich. Bardzo dobrą praktyką jest stosowanie pionowych odstępów pomiędzy segmentami kodu oraz wcięć – do poszczególnych programów w pliku, do funkcji i bloków funkcji. Z naszego programu należy również usunąć cały martwy kod – to znaczy taki, który nigdy nie jest wykorzystany (na przykład kontrolują go nigdy niespełniane warunki) lub taki, który mógł służyć jedynie do testów. Zamiast stosować magiczne liczby, użyjmy stałych nazywanych – na przykład liczba 86 400 powinna być ukryta w stałej SECONDS_PER_DAY. Jeżeli wyświetlamy 70 wierszy na stronę, to liczba 70 powinna być ukryta w stałej LINES_PER_PAGE. Spis treści serii artykułów: Czysty kod w praktyce - część 1 Czysty kod w praktyce - część 2
  34. 8 punktów
    W poprzedniej części zobaczyliśmy jak działa wyświetlacz TFT podłączony do Arduino Uno. Wiemy już, że nie jest to demon szybkości, czas przeanalizować nieco dokładniej przyczyny takiego, a nie innego działania. Ta część będzie nieco bardziej techniczna od poprzedniej, znajdziemy w niej więcej obliczeń oraz odniesień do dokumentacji. Niestety pewna dawka "teorii" będzie konieczna dla zrozumienia działania wyświetlacza oraz poprawienia wydajności. Spis treści: Sterowanie wyświetlaczem TFT - część 1 - wstęp, podstawowe informacje Sterowanie wyświetlaczem TFT - część 2 - analiza problemu Sterowanie wyświetlaczem TFT - część 3 - testy prędkości na STM32 Sterowanie wyświetlaczem TFT - część 4 - własny program Sterowanie wyświetlaczem TFT - część 5 - optymalizacja programu Dlaczego to tak wolno działa? Na początek coś prostego, czyli oszacowanie ilości danych koniecznych do przesłania. Dla porównania zacznijmy od wyświetlacza alfanumerycznego, takiego jak był używany w kursie Arduino. Wyświetlacz posiada dwa wiersze po 16 znaków, a każdy znak jest przesyłany jako bajt. Mamy więc razem 32 bajty danych. Mnożąc przez 8 bitów w każdym bajcie otrzymujemy więc 256 bitów. W kursie STM32 F1 używany był graficzny wyświetlacz o rozdzielczości 84 na 48 pikseli. Każdy piksel mógł być albo zapalony, albo wygaszony, więc do jego sterowania wystarczał jeden bit. Mamy więc 84 x 48 = 4032 bity, czyli inaczej 504 bajty danych. Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. Teraz czas na bohatera tego artykułu - domyślna biblioteka używa trybu 16-bitowego koloru, a rozdzielczość ekranu to 160 na 128 pikseli. Mnożymy więc 160 x 128 x 16 i uzyskujemy wynik 327680 bitów, albo 40960 bajtów. Z tych ogólnych rachunków łatwo wywnioskować, że aby wyświetlić obraz na naszym ekranie TFT musimy przetworzyć 1280 razy więcej danych niż w przypadku wyświetlacza alfanumerycznego. To chyba jest najprostsza i najbardziej ogólna odpowiedź na pytanie dlaczego jest wolno... Oczywiście nie jest to pełna odpowiedź, ale mam nadzieję że pokazuje ona o ile trudniej jest szybko wysterować wyświetlacz TFT. Jak szybko powinien działać nasz program? Poprzednio zmierzyliśmy czas rysowania ekranu i wyszło nam ponad 1200 ms, kasowanie zawartości zajmowało ok. 96 ms. Spróbujmy teraz oszacować jak szybko "powinien" nasz program działać, albo raczej jaka jest granica związana z prędkością interfejsu SPI. W konfiguracji interfejsu widzimy linijkę: SPI.setClockDivider(SPI_CLOCK_DIV2); A jak wiemy Arduino UNO jest taktowane z częstotliwością 16 MHz. Dzieląc przez dwa, otrzymujemy 8 MHz dla interfejsu SPI, co daje 8'000'000 bitów na sekundę. Skoro dane obrazu wymagają 327800 bitów, więc teoretycznie przesłanie danych zajmuje 327800 / 8000000 = 0,041 s, czyli 41 ms. Taki czas dawałby nam przyzwoite 24 klatki na sekundę, ale nawet kasowanie ekranu działa ponad dwa razy wolniej niż powinno, o rysowaniu nawet lepiej nie wspominać. Analiza procedury kasowania ekranu Zacznijmy od podłączenia analizatora stanów logicznych i upewnienia się, że wszystko działa jak oczekujemy. Na początek pomiar czasu kasowania ekranu - łatwo go zmierzyć, bo wysyłamy kod koloru białego czyli same bajty 0xff: Na razie wszystko wygląda zgodnie z oczekiwaniami. Sprawdźmy więc, czy na pewno SPI pracuje z częstotliwością 8 MHz. Częstotliwość się zgadza, ale niemiłym zaskoczeniem są przerwy między wysyłanymi bajtami danych: Niestety, ale między wysłaniem kolejnych bajtów procesor musi mieć trochę czasu - na odczyt statusu zakończenia transmisji, powrót z procedury, załadowanie kolejnej danej, a to wszystko trwa. Optymalizacja programu jest oczywiście możliwa, ale wymagałaby rezygnacji z użycia klasy SPI dostarczanej przez Arduino oraz chyba wskazane byłoby dodanie wstawek w asemblerze. W każdym razie taka optymalizacja nie jest prostym zadaniem, to niewątpliwie ciekawe wyzwanie, ale niekoniecznie przeznaczone dla początkujących. Na tą chwilę pozostaje się chyba pogodzić z tym, że maksymalna transmisja to nie 8 Mb/s, ale około połowa tej prędkości. To nadal całkiem niezły wynik, gdyby rysowanie zajmowało tyle samo czasu, co kasowanie mielibyśmy 10 klatek na sekundę. Zobaczmy więc dlaczego rysowanie jest tak strasznie powolne. Sterownik obrazu Nasz wyświetlacz wyposażony jest w kontroler ST7735S, poprzednio podawałem do niego link, ale na wszelki wypadek podam jeszcze raz. Zachęcam do zapoznania się z całą dokumentacją, ale chwilowo opiszę tylko absolutne minimum niezbędne z zrozumienia sterowania oraz poprawienia wydajności programu. Do komunikacji z ST7735S można użyć jednego z czterech interfejsów. Dostępne są dwa interfejsy równoległe (6800/8080) oraz dwa szeregowe, określane jako 3- i 4- przewodowy. W przypadku opisywanego modułu niestety nie ma wyboru i dostępny jest tylko ostatni, czyli "4-line Serial". Jak pisaliśmy wcześniej jest to SPI, ale nie do końca... co więcej nazewnictwo linii w module, standardzie SPI i dokumentacji sterownika jest inne. Poniżej przykładowy diagram przedstawiający komunikację: Linia CSX to odpowiednik linii CS zarówno w module wyświetlacza, jak i standardzie SPI. Nazwa SDA jest najczęściej używana w interfejsie i2c, ale tutaj oznacza po prostu linię danych, która na module ma nazwę DIN, a łączymy ją z pinem MOSI (Master-Output-Slave-Input). Warto pamiętać, że SDA może być używana też do odczytu danych... Zostańmy jednak przy jednokierunkowej transmisji. Kolejna linia to D/CX, na naszym module oznaczona jako DC - która nie jest częścią standardu SPI, więc pozostaje ją połączyć z pinem GPIO i sterować "ręcznie". Na koniec SCL, czyli linia zegara, na module dostępna jako CLK, a standardowo nazywana SCLK, albo SCK. Mamy więc straszny bałagan w nazwach, ale na koniec w sumie prostą sytuację - jednokierunkowy interfejs SPI oraz dodatkową linię DC. Jak widzimy transmisja polega na przesyłaniu 8-bitowych bajtów, czyli nic strasznego. Sterowanie ST7735S polega na przesyłaniu do niego komend. Pierwszy bajt zawiera wówczas kod komendy, a podczas jego przesyłania linia DC powinna być ustawiona w stan niski. Same kody dostępnych poleceń znajdziemy w dokumentacji sterownika, przykładowo: Po niektórych komendach przesyłane są parametry - podczas ich transmisji linia DC musi być w stanie wysokim. To ile parametrów jest potrzebnych znajdziemy w dokumentacji. Obsługiwanych komend jest dużo, na szczęście nie musimy ich wszystkich od razu poznawać. Dostarczony program przykładowy zawiera kod niezbędny do uruchomienia wyświetlacza, właściwie jedyne na co warto w nim zwrócić na początek uwagę to możliwość zmiany orientacji wyświetlacza. To bardzo wygodna opcja, dzięki niej nasz wyświetlacz może pracować zarówno w pionie (jak w przykładach z poprzedniej części), jak i w poziomie, co moim zdaniem ładniej wygląda. Ale najważniejsze, że wszystko jest wspierane sprzętowo, nie musimy więc programowo obracać obrazu. Przesyłanie danych obrazu Inicjalizacja wyświetlacza jest wykonywana tylko raz, więc w naszych amatorskich zastosowaniach jej optymalizacja może być mniej istotna. Warto natomiast zrozumieć jak wygląda przesyłanie obrazu. Do tego celu wykorzystywane są trzy komendy: CASET (0x2a), RASET (0x2b) oraz RAMWR (0x2c). Pierwsze dwie definiują wielkość okna, do którego będziemy zapisywać dane: Gdy przesyłamy CASET podajemy dwa parametry (każdy 2-bajtowy), które ustalają współrzędne x początku i końca okna, RASET ustala współrzędne y. Ustalenie wielkości okna jest konieczne przed rozpoczęciem zapisu danych. Do zapisu używamy komendy RAMWR: Po wysłaniu RAMWR możemy przesyłać już dane obrazu. Jak widzimy to nic specjalnego. Dlaczego więc kod przykładowy działa tak wolno? Teraz gdy wiemy już trochę więcej o działaniu ST7735S, możemy wrócić do kodu dostarczanego przez WaveShare. Na początek metoda LCD_ST7735S::LCD_SetWindows: void LCD_ST7735S::LCD_SetWindows( POINT Xstart, POINT Ystart, POINT Xend, POINT Yend ){ //set the X coordinates LCD_WriteReg ( 0x2A ); LCD_WriteData_8Bit ( 0x00 ); //Set the horizontal starting point to the high octet LCD_WriteData_8Bit ( (Xstart & 0xff) + sLCD_DIS.LCD_X_Adjust); //Set the horizontal starting point to the low octet LCD_WriteData_8Bit ( 0x00 ); //Set the horizontal end to the high octet LCD_WriteData_8Bit ( (( Xend - 1 ) & 0xff) + sLCD_DIS.LCD_X_Adjust); //Set the horizontal end to the low octet //set the Y coordinates LCD_WriteReg ( 0x2B ); LCD_WriteData_8Bit ( 0x00 ); LCD_WriteData_8Bit ( (Ystart & 0xff) + sLCD_DIS.LCD_Y_Adjust); LCD_WriteData_8Bit ( 0x00 ); LCD_WriteData_8Bit ( ( (Yend - 1) & 0xff )+ sLCD_DIS.LCD_Y_Adjust); LCD_WriteReg(0x2C); } Można oczywiście dyskutować, czy używanie "magicznych liczb" to elegancki sposób programowania, ale jak widzimy są tutaj wykonywane trzy, znane nam komendy: CASET, RASET oraz RAMWR. Więc po wywołaniu tej metody możemy już przesyłać dane obrazu (używając np. metody LCD_SetColor). To brzmi całkiem nieźle, ale teraz zobaczmy implementację rysowania punktu: void LCD_ST7735S::LCD_SetPointlColor ( POINT Xpoint, POINT Ypoint, COLOR Color ){ if ( ( Xpoint <= sLCD_DIS.LCD_Dis_Column ) && ( Ypoint <= sLCD_DIS.LCD_Dis_Page ) ){ LCD_SetCursor (Xpoint, Ypoint); LCD_SetColor ( Color , 1 , 1); } } void LCD_ST7735S::LCD_SetCursor ( POINT Xpoint, POINT Ypoint ){ LCD_SetWindows ( Xpoint, Ypoint, Xpoint , Ypoint ); } Czyli chcąc narysować jeden punkt najpierw ustawiamy okna o wielkości 1x1, a następnie zapisujemy dwa bajty koloru. Czyli jak łatwo policzyć na jeden piksel przesyłamy 13 bajtów. Pomijając niezbyt optymalny kod, to właśnie jest przyczyna tak strasznie powolnego rysowania. Każda linia, okręg, a nawet znak rysowane są jako punkty. A każdy z tych punktów wymaga aż 13 transmisji przez SPI (po których są jeszcze przerwy). To wszystko daje nam rysowanie demonstracyjnego ekranu w czasie ponad sekundy zamiast 40-90 ms. Co ciekawe kasowanie obrazu jest wykonywane optymalniej - raz ustawiane jest okno na cały ekran, a następnie po prostu przesyłane są wszystkie dane. Dlatego zajmuje to 96, a nie 1000 ms. Podsumowanie Mam nadzieję, że w tej części udało mi się pokazać dlaczego sterowanie wyświetlaczem działa wolniej niż moglibyśmy tego oczekiwać. Okazuje się, że kod dostarczany przez producenta to raptem demo. Jeśli chcemy sensownie sterować wyświetlaczem, musimy napisać własny program. Możliwości optymalizacji to między innymi: ograniczenie odrysowywanego obszaru zwiększenie prędkości komunikacji przez SPI (wyświetlacz obsługuje do 15MHz, wypadałoby również wyeliminować przerwy między wysyłanymi bajtami) o wiele wydajniejsze jest jednoczesne odrysowywanie okna, rysowanie punktów działa strasznie wolno Użyte rzez Waveshare rozwiazanie ma za to jedną, niezaprzeczalną zaletę - używa bardzo mało zasobów mikrokontrolera. Wszystkie dane obrazu są od razu wysyłane, więc za cenę prędkości ograniczyliśmy wykorzystanie pamięci. W kolejnej części przetestuję działanie przykładów dla STM32 oraz pokażę jak można przyspieszyć rysowanie obrazu - chociaż już nie na Arduino Uno. Spis treści: Sterowanie wyświetlaczem TFT - część 1 - wstęp, podstawowe informacje Sterowanie wyświetlaczem TFT - część 2 - analiza problemu Sterowanie wyświetlaczem TFT - część 3 - testy prędkości na STM32 Sterowanie wyświetlaczem TFT - część 4 - własny program Sterowanie wyświetlaczem TFT - część 5 - optymalizacja programu
  35. 8 punktów
    Researcher jest robotem badawczym przeznaczonym do badania składu gleby oraz powietrza. Robot jest wyposażony w łamane ramię z łyżką przeznaczoną do pobierania próbek gleby oraz umieszczania próbek w specjalnych pojemniczkach wyposażonych w czujniki składu gleby (np. wilgotności, ph). Próbki mogą być pobierane z głębokości 10 cm dzięki zastosowaniu wiertła zamontowanego na siłowniku liniowym o wysuwie 10cm. Za obroty wiertłem jest odpowiedzialny silnik DC. Element wiertniczy jest zamontowany na zawiesie i mocowany na jedną śrubę, ułatwia to transport robota. Za działanie ramienia odpowiedzialne są 4 serwa, ramię jest wykonane z aluminium, dzięki czemu jest wytrzymałe i lekkie. Aby odciążyć serwo odpowiedzialne za obracanie ramieniem zastosowaliśmy płytę przymocowaną do podwozia, poruszają się po niej kułeczka zamocowane do części ruchomej. Konstrukcja robota jest wykonana w całości z aluminium i stali. Obudowa i podstawka pod elektronikę są wykonane z polisterynu. Robot jest w stanie poruszać się po trudnym terenie i wjeżdżać na krawężniki, umożliwia mu to zastosowanie zawieszenia biegunowego dla dwóch przednich osi. Tylna oś jest zamocowana na amortyzatorach. Za ruch silników odpowiedzialnych jest 6 silników DC zamontowanych do płaskowników aluminiowych za pomocą obejm i śrub. W tylnej części zamontowany wspornik mocujący do czujników wiatru. Robot waży około 13 kilogramów i ma 70 cm długości i ok 40 cm szerokości. Za pracę odpowiada moduł Arduino MEGA 2560, w robocie zastosowaliśmy 4 sterowniki silników jednokanałowych po jednym na każdą stronę robota (po 3 silniki do jednego) 2 pozostałem odpowiadają za ruch siłownikiem oraz silnikiem w module wiertniczym. Zastosowaliśmy czujniki temperatury powietrza i gleby, składu powietrza i gleby. Aby nie uszkodzić robota zastosowaliśmy czujniki odległości dzięki którym robot nie wjeżdża w ściany i większe przeszkody. Do komunikacja pomiędzy robotem a aparaturą używamy modułu radiowego. Do sterowania używamy przerobionej aparatury. Znajduje się w niej Arduino UNO, 3 gałki analogowe, wyświetlacz i płytka dotykowa z przyciskami oraz da przełączniki dźwigniowe do zmiany trybu sterowania. Całego robota budowaliśmy około 10 miesięcy w 3 osobowym zespole, uczestniczyliśmy w licznych zawodach m in East Robo, Mikrobot, Explory. Do sukcesów można zaliczyć 4 miejsce w Konkursie El Robo Mech dzięki któremu zdobyliśmy indeksy na studia. Zastosowaniem robota ma być wykorzystywany do badania gleb w miejscach trudno dostępnych oraz jako robot ratunkowy w wypadku skażeń chemicznych i biologicznych. Robot mógłby zbadać glebę i powietrze na terenie skażonym, a dzięki czujnikom kierunku i prędkości wiatru można będzie oszacować przemieszczanie się chmur z zanieczyszczeniem. Operator robota może odczytywać dane z czujników z wyświetlacza na kontrolerze oraz mieć podgląd z kamery umieszczonej na robocie.
  36. 8 punktów
    Witam całego Forbota. Chciałbym przedstawić tu mój autorski projekt, który stworzyłem w sumie w technikum, później go udoskonalałem, aż do wersji mikroprocesorowej. Dzisiaj chciałbym wam pokazać jego jedną z pierwszych wersji (to nie znaczy gorszą tylko ciekawszą). Zapraszam do lektury. Wprowadzenie Niniejsze urządzenie powstało jako unowocześnienie i ulepszenie tanich popularnych na rynku tzw. „klaskaczy”. Jako że te opierają się wbrew temu co mówi nazwa na pomiarze głośnych dźwięków, a nie klaśnięcia to ich niezawodność pozostawia wiele do życzenia. Główną ich wadą jest działanie na wszelkie głośniejsze dźwięki co uniemożliwia np. słuchanie głośniejszej muzyki, ponadto czasem nawet upadający przedmiot jest w stanie aktywować taki „klaskacz”. Projekt włącznika akustycznego jest wysoce efektywnym i niezawodnym zamiennikiem wcześniej wspomnianego rozwiązania, duża czułość powoduje iż nawet najsłabszy gwizd będzie efektywnie interpretowany, jedynym chyba mankamentem jest fakt, że trzeba potrafić gwizdać. Zasada działania jest prosta. Należy gwizdnąć zmieniając w odpowiedni sposób ton gwizdu aby włączyć lub wyłączyć podłączone urządzenie (np światło w pokoju). Włącznik akustyczny w wersji v 1.0 jest układem niemalże całkowicie analogowym. Elektroniczny: Blokowy: Ogólny opis zasady działania Sygnał akustyczny z mikrofonu elektretowego o małej amplitudzie musi zostać najpierw wzmocniony aby mogła zostać przeprowadzona jego analiza, dlatego też trafia najpierw na wzmacniacz oparty na tranzystorach T5,T4 Następnie wzmocniony sygnał podawany jest przez kondensator separujące na wejścia dwóch układów detekcji tonu LM567 gdzie jest porównywany do częstotliwości wzorcowej ustawionej przez zewnętrzne elementy RC. Układy te posiadają wyjście typu open colector, dlatego konieczne stało się zastosowanie rezystorów pull up. Wykrycie takiej samej częstotliwości podawanej na wejście jak częstotliwość referencyjna objawia się pojawieniem stanu niskiego na wyjściu LM567. Dalej sygnał trafia na układy czasowe NE555 pracujące w trybie monostabilnym, których zadaniem jest powiązanie czasowe wystąpienia obu sygnałów z detektorów tonu. Zwiększa to niezawodność całego układu dlatego, że wykrycie drugiej częstotliwości w odpowiednim przedziale czasowym zapoczątkowanym wykryciem pierwszej częstotliwości umożliwia przełączenia układu wykonawczego. Czas trwania sygnału aktywnej częstotliwości można płynnie regulować zmieniając stałą czasową RC układów NE555. Następnie sygnały z generatorów monostabilnych trafiają na bramkę AND zbudowaną w oparciu o 3 tranzystory T2, T3, Q1. Sygnał z bramki jest podawany na wejście zegarowe aktywowane zboczem narastającym przerzutnika T (ang. Toggle) zrobionego z przerzutnika D zawartego w układzie CD4013. Pod wyjście przerzutnika podłączony jest tranzystor wykonawczy w roli klucza T1. Obciążalność tego tranzystora reguluje nam jakim urządzeniem możemy sterować. Na płytce została umieszczona dioda włączona w kierunku zaporowym na wypadek indukcyjnego obciążenia tegoż tranzystora np. cewką przekaźnika. Szczegółowy opis zasady działania Układ wejściowy i wzmacniacz Na układ wejściowy składa się taki mikrofon podłączony przez rezystor 3,3k który polaryzuje wewnętrzny tranzystor polowy. Następnie sygnał trafia przez kondensator separujący składową stałą na wzmacniacz zbudowany na tranzystorze T5 BC547B . Jest to bardzo prosty wzmacniacz, którego baza polaryzowana jest jednym rezystorem. Punkt pracy został dobrany na podstawie charakterystyk tranzystora BC547B, prąd bazy wynosi około 3,3uA, a współczynnik wzmocnienia prądowego β wynosi około 310 daje to prąd kolektora na poziomie 1[mA], zakładając spadek napięcia na rezystorze równy połowie napięcia zasilania, a więc 4V można przyjąć, że wartość rezystora powinna wynosić ok. 4000Ω. W projekcie została użyta wartość znormalizowana 3,3k. Co przesunęło nieco charakterystykę pracy w kierunku wyższego potencjału. Następnie sygnał trafia przez rezystor - w celu zwiększenia impedancji wejściowej i kondensator - aby wyeliminować składową stałą na układ dzielnika napięcia wstępnie polaryzującego bazę tranzystora bipolarnego NPN BC547B. Tranzystor ten pracuje w układzie wspólny emiter. Pomiar współczynnika wzmocnienia prądowego tranzystora β wykazał wzmocnienie na poziomie 310. Zakładając niewielką rezystancję emiterową rzędu 220 Ohm oraz przyjmując na niej spadek napięcia 1V możemy wyliczyć prąd emitera, który wynosi Ie = 1/220 = 4,5[mA]. Upraszczając, że prądy emitera i kolektora są sobie równe jesteśmy w stanie policzyć przy spadku napięcia zasilania 9V o połowę wartość rezystora R1 która będzie równa R1 = 4,5/0,0045 = 1k. Prąd bazy wynosi Ic/Beta = 4,5/310 = 14,5[µA] Należy zatem przyjąć dzielnik napięcia w którym prąd płynący będzie wielokrotnością prądu bazy. Ponieważ wcześniej przyjęte zostało, że spadek napięcia na rezystancji emiterowej R4 wynosi 1[V] to napięcie jakie się odłoży na rezystorze R3 będzie wynosiło 1 + 0,7V =1,7[V], a na rezystorze R5 odpowiednio 9 - 1,7 = 7,3V. Przyjmując wartość rezystora R5 = 22k prąd płynący przez ten rezystor wyniesie 7,3/22000 = 330[µA] , natomiast przez rezystor R3 popłynie ten sam prąd pomniejszony o prąd bazy, więc będzie on wynosił 315,5[µA]. Znając spadek napięcia oraz prąd obliczamy rezystancję i przyjmujemy najbliższą znormalizowaną jej wartość – w tym przypadku 4,7k. Poniżej znajduje się wykres oscyloskopowy sygnału wejściowego i wyjściowego wzmacniacza na samy tranzystorze T1: Do pomiarów sygnału posłużyła karta dźwiękowa i program SoundCard Osciloscope v1.41. Wzmacniacz został przetestowany na sygnale 1kHz. Jak widać cechują go bardzo małe zniekształcenia oraz wzmocnienie napięciowe na poziomie = 3.37. Oprócz tego sygnał jest przesunięty w fazie o 180ᵒ co jest cechą charakterystyczną wzmacniacza w układzie OE. Jeśli jeszcze chodzi o realizację praktyczną to pierwszy stopień wzmacniacza został zrealizowany na osobnej płytce. Układ detekcji tonu LM567 Następnie sygnał akustyczny z wzmacniacza trafia na układ detekcji tonu oparty na popularnym LM567, zawiera on w swojej strukturze wewnętrzny wysokostabilny generator (źródło częstotliwości wzorcowej) oraz wejście do którego podaje się sygnał badany. Częstotliwości obu przebiegów są porównywane w układzie fazowej pętli synchronizacji (PLL) i – o ile są one z zadaną dokładnością sobie równe – następuje uaktywnienie wyjścia układu. Wejściem sygnału jest nóżka nr 3. Do wyprowadzeń nr 5 i 6 dołączone są zewnętrzne elementy generatora decydujące o częstotliwości jego pracy. Kondensator podłączony do nóżki nr 2 służy do ustalenia głównego parametru wewnętrznej pętli PLL: tzw. zakresu trzymania. Jest to największa dopuszczalna wartość o jaką mogą różnić się porównywane częstotliwości, by układ uznał je za równe. Kondensator podłączony pod nóżkę nr 1 jest elementem wyjściowym filtra dolnoprzepustowego eliminującego ewentualne przypadkowe krótkotrwałe przełączenia wyjścia. Wejście układu jest spolaryzowane wewnętrznie i wymaga jedynie doprowadzenia sygnału wejściowego, wyjście natomiast jest typu open colector, dlatego konieczne jest zastosowanie rezystorów podciągających. Dokładna zasada działania układów LM567 jest długa do opisania. Generalnie cały układ opiera się na detektorze I-fazowym (In-phase detector) i Q-fazowym (quadrature-phase detektor). Sygnały I/Q są sygnałami wartości składowych zespolonych sygnału, a otrzymuje się je przez mnożenie sygnału wejściowego przez sygnał referencyjny i przez sygnał referencyjny przesunięty w fazie o 90*. Następnie wartość zespolona sygnału wejściowego przechodzi przez filtr dolnoprzepustowy gdzie regulowana jest maksymalna wartość o jaką mogą różnić się sygnał referencyjny i wejściowy aby układ mógł uznać je za równe sobie. Sygnał z filtru przestraja odpowiednio generator sterowany napięciowo (VCO), którego sygnał porównywany jest z sygnałem wejściowym w detektorze fazy (I chase detector) składowej rzeczywistej sygnału wejściowego. Na wyjściu pojawia się różnica tych dwóch sygnałów, więc jeśli są sobie równe wyjście układu przyjmuje stan niski. Częstotliwość detekcji wylicza się ze wzoru podanego przez producenta: Fo=1/(1.1*R1*C1), w naszym przypadku R1=R10+R9, C1=C8 Układ czasowy NE 555 NE555 zawiera komparatory mające swe wyprowadzenia na nóżki 2 i 6. Napięcia na tych nóżkach są porównywane z napięciami panującymi na wewnętrznym dzielniku napięcia. I tak jeśli napięcie na nóżce 6 przekroczy 2/3 napięcia zasilania to wyjście układu przyjmuje stan niski, a wewnętrzny tranzystor przewodzi. W przypadku spadku napięcia poniżej poziomu 1/3 Ucc sytuacja jest analogicznie odwrotna czyli na wyjściu jest stan wysoki, a wewnętrzny tranzystor nie przewodzi. W zależności od podłączenia zewnętrznych elementów można uzyskać 3 rodzaje pracy: układ astabilny, monostabilny oraz przerzutnik RS. W projekcie został zastosowany tryb monostabilny w przypadku którego sygnał wyzwalający podawany jest na nóżkę 2 układu. Sygnałem wyzwalającym jest sygnał o wartości mniejszej niż 1/3 Ucc, a więc w naszym przypadku mniejszym niż 3V(ponieważ cały układ zasilany jest z 9V). Sygnał ten pobierany jest z wyjść układów LM567. Pojawienie się go na nóżce 2 powoduje iż na wyjściu pojawia się stan wysoki, a kondensator wcześniej non stop rozładowywany przez wewnętrzny tranzystor zaczyna się ładować. Stan wysoki na wyjściu trwa dopóty dopóki napięcie na zewnętrznym kondensatorze ładowanym przez potencjometr osiągnie wartość większą niż 2/3 Ucc. Gdy to nastąpi stan na wyjściu układu zmienia się na niski, a wewnętrzny tranzystor zaczyna rozładowywać kondensator do zera. Powtórne aktywowanie stanu wysokiego na wyjściu wymaga podania stanu niskiego na nóżkę 2. Jak podaje datasheet układu NE555 czas trwania impulsu na wyjściu opisuje zależność: T=1.1*R*C, w naszym przypadku R= Bramka AND Aby mogło nastąpić przełączenie układu wykonawczego w stan przeciwny sygnał z układów czasowych NE555 musi zostać podany na bramkę AND, innymi słowy aktywacja urządzenia wyjściowego następuję wówczas gdy oba sygnały wyjściowe z przerzutników monostabilnych, są aktywne jednocześnie. Bramka AND została zrealizowana na 3 tranzystorach. Schemat bramki został przedstawiony niżej: Gdy nie ma żadnego sygnału na wejściach podpisanych channel A channel B tranzystor Q1 nie przewodzi, rezystor R20 podciąga do dodatniej szyny zasilania jego bazę dzięki czemu nie ma możliwości aby jakikolwiek potencjał zgromadzony w okolicy nóżki bazy tranzystora Q1 przez przypadek go aktywował natomiast wyjście bramki jest podciągnięte rezystorem pull down R25 do ujemnej szyny zasilania. W momencie podania sygnału na bazy tranzystorów T3 i T4 te zaczynają przewodzić. Przez rezystory R20, R19 oraz bazę tranzystora Q1 zaczyna płynąć prąd w skutek czego na wyjściu bramki pojawia się stan wysoki. Rezystory zostały dobrane tak żeby bez problemu każdy tranzystor pracował w stanie nasycenia, a jednocześnie nie zostały przekroczone dopuszczalne parametry pracy. Maksymalny prąd płynący przez tranzystory T2,T3 wyniesie uwzględniając napięcia Ucesat na obu tranzystorach ok. 1,3 [mA] Przerzutnik T Aby móc zrealizować przerzutnik typu T na przerzutniku typu D należy sygnał z jego zanegowanego wyjścia podać na wejście. Sygnał wyjściowy będzie pobierany z jego niezanegowanego wyjścia. Zmiany stanu wyjścia na przeciwny idą w takt zbocza narastającego sygnału podawanego na wejście zegarowe. Sygnał podawany jest na wejście zegarowe przez rezystor zabezpieczający prosto z bramki AND. Przerzutnik T został zrealizowany na jednym przerzutniku typu D zawartym w układzie CD4013BP. Drugi przerzutnik zostaje niewykorzystany dlatego jego nóżki wejściowe (CLOCK2, RESET2, SET2,D2) są wg zasady podłączone na stałe do masy aby ograniczyć straty mocy. Stopień wyjściowy Stopień wyjściowy został zaprojektowany tak aby był możliwie jak najbardziej uniwersalny. Jako element przełączający posłużył tranzystor BC237 o maksymalnym prądzie kolektora Ic = 100mA , co w zupełności wystarcza do zasilenia cewki przekaźnika, oraz maksymalnym napięciu kolektor emiter Uce wynoszącym 45V. Mimo iż układ zasilany może być maksymalnie z 9V bo na tyle pozwalają układy LM567 to napięcia panujące na złączu tegoż tranzystora mogą być znacznie większe np. z racji indukcyjnego obciążenia przez cewkę przekaźnika, która w momencie odłączenia zasilania indukuje wysokie napięcie, o polaryzacji przeciwnej do wcześniejszego zasilania cewki. Aby zniwelować wpływ tego napięcia na tranzystor T4 została wprowadzona dodatkowo dioda podłączona równolegle do obciążenia, której zadaniem jest ograniczenie wyindukowanego się wysokiego napięcia do napięcia spadku na diodzie 0,6-0,7V. Rezystor R24 ogranicza prąd bazy tranzystora T7 i został tak dobrany aby tranzystor w momencie aktywacji znalazł się w stanie nasycenia przy jednocześnie dopuszczalnym prądzie bazy. Przy zasilaniu układu z 9V spadek napięcia na rezystorze wyniesie: 9V-0,7V=8,3V Rezystancja wynosi 4,7k co po podstawieniu do wzoru daje nam prąd I=1,7[mA], który wystarcza do pełnego otwarcia się tranzystora. Testy praktyczne Na podstawie testów przeprowadzonych w laboratorium można stwierdzić bardzo małą awaryjność urządzenia. Dzięki wysokiej selektywności układów LM567 układ reagował nawet przy dużym hałasie z mnóstwem innych składowych np. przy słuchaniu muzyki, znacząco deklasując tradycyjne „klaskacze”. Zdarzały się jednak sporadyczne aktywacje jednej z nastawionych częstotliwości co oczywiście nie zmieniało stanu wyjścia układu. Dzięki podwójnemu wzmacniaczowi urządzenie wychwytuje określone częstotliwości już przy najcichszym sygnale akustycznym. Testy wykazały, że reaguje na słaby gwizd do 2.5m, natomiast największa odległość z jakiej udało się aktywować urządzenie wynosiła nieco ponad 10 m. Parametry te są w zupełności wystarczające biorąc pod uwagę metraż przeciętnego pokoju. Układ powinien być zasilany napięciem z przedziału 5-9V. Dolną granicę zasilania determinują głównie układy NE555, ponieważ poniżej tej wartości zaczynają się same wzbudzać, natomiast górną komparatory częstotliwości LM567. Najlepsze efekty (czułość) uzyskuje się zasilając układ z 8-9 V. I to już koniec tego mam nadzieję wyczerpującego opisu. Troszkę może to przypomina powtórkę z podstaw elektroniki, ale mimo wszystko mam nadzieję że komuś taka analiza się przyda w przyszłości aby łatwiej rozpocząć przygodę z elektroniką. Dodam tylko, że całość została zaprojektowana w programie Eagle i wykonana metodą termotransferu na laminacie jednostronnym oraz starannie pocynowana i zabezpieczona kalafonią (stąd ten może brzydki wygląd). Wzięło się to stąd, że układ robiłem koledze do zamontowania w ścianie z kartongipsu, dlatego też cała elektronika nie ma stosownej obudowy oraz trzeba było jakoś ścieżki zabezpieczyć przed ewentualną wilgocią w ścianach ;D Na zakończenie filmik przedstawiający działające urządzenie oraz zdjęcia. W załączniku płytka w Eaglu. Eagle.rar
  37. 8 punktów
    Zgodnie z nazwą ten robot nie miał powstać. Jego historia zaczyna się w maju 2019 roku. Został mi wtedy przyznany przez Wydział Elektroniki Mikrosystemów i Fotoniki Politechniki Wrocławskiej grant na realizację robota kategorii nanosumo. Postawiłem sobie jako deadline na pierwszy działający prototyp Robocomp 2019. Wtedy myślałem że to dużo czasu. Niestety koła zębate biurokracji wolne są, Digikey nie miało kluczowej części a na mój brak czasu i problemy z nim zarządzaniem już na łamach tego forum narzekałem. Złożyło się to na brak funkcjonalnej wersji czegokolwiek na tydzień przed konkursem. Na szczęście w zamówieniu było trochę modułów a w moich szufladach jeszcze więcej. No i druk 3d uratował dzień jak zawsze: Jako napęd robota posłużyły cztery silniki sub-micro 26:1. Cztery silniki dają sporą mechaniczną przewagę w *sumo ponieważ pozwalają na przeniesienie przez koła praktycznie całej masy robota, a jak wiadomo Td = µN. Do tego zamontowałem opadający pług który dociążyłem około połowy wysokości metalową ośką 1mm co podniosło jego środek ciężkości. Okazał się bardzo skuteczny, szczególnie przeciwko robotowi z stałym pługiem dość daleko od ziemi z którym walczyłem w półfinale. Aby ciężar wyniósł jak najbliżej 100g w robocie umieściłem około 30 nakrętek M5 bo akurat były pod ręką. Początkowo silnikami miał sterować chiński moduł opisywany jako mini-L298N do którego dokumentacja prawdopodobnie nie istnieje ale po tym jak nie zadziałał od ręki wymieniłem go na 2x Pololu DRV8838. Prawdopodobnie źle go podłączyłem (autopsja w planach) przez co na jednym silniku nie działała praca w tył. Zostało to "rozwiązane" programowo. Sercem robota było Arduno Pro Micro (wybrane ze względu na to że leżało pod ręką) zasilane przez przetwornicę step-up do USB poddaną subtelnej modyfikacji kombinerkami z pojedynczej celi LiPo (która zasilała też mostek H bezpośrednio). No i ostatecznie jedyna ciekawa rzecz w tym robocie - VL53L1X-SATEL - breakouty do świetnych czujników odległości TOF od ST. Zdążyłem tylko wstępnie ogarnąć ich możliwości ale wydają sioę bardzo obiecujące. Niestety zupełnie nie widziały robota przeciwnika (wydrukowanego 3D) w finale, przyczyny zostaną zbadane. Kod powstał w autobusie do Krakowa i strefie dla zawodników. Jest napisany w bardzo nieeleganckim Arduino C++. Jego logika składa się z 3 if-ów. Działa. W "najbliższym" czasie powinny się pojawić worklog do nanosumo bo tam planuję sporo ciekawsze rozwiązania jak customowe elastyczne PCB. Pewnie jeszcze tu wrócę i trochę poprawię.
  38. 7 punktów
    Algorytmy związane z szeroko pojętą sztuczną inteligencją (AI, Artificial Intelligence) są ostatnio bardzo popularnym tematem. Na ogół AI kojarzy się z ogromnym zapotrzebowaniem na moc obliczeniową, wykorzystaniem GPU (Graphics Processing Unit) oraz obliczeniami w chmurze. Okazuje się jednak, że sztuczna inteligencja znajduje również zastosowanie w świecie mikrokontrolerów. Powstał nawet termin na określenie takich zastosowań - Edge AI. O tym jak popularny jest temat AI świadczy chociażby pojawienie się sprzętowych akceleratorów przeznaczone dla urządzeń wbudowanych, tzw. TPU (Tensor Processing Unit), przykładowo Google Coral, albo Intel Neural Compute Stick. Dostępne są również mikrokontrolery z wbudowanym TPU, np. Kendryte K210 . Spis treści serii artykułów: Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.1 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.2 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.3 Firma STMicroelectronics, czyli producent popularnych również na naszym forum układów STM32 postanowiła dostarczyć produkt związany z AI. Na razie nie oferuje sprzętowej akceleracji, ale możemy za darmo pobrać pakiet oprogramowania o nazwie X-CUBE-AI, który pozwala na łatwe wykorzystanie możliwości jakie daje sztuczna inteligencja. [blog]https://forbot.pl/blog/sztuczna-inteligencja-na-stm32-przyklad-uzycia-x-cube-ai-id41588[/blog]
  39. 7 punktów
    Dzień dobry, na wstępie opiszę z grubsza założenia projektu - w przyszłości pracy inżynierskiej. Priorytetowym zadaniem, jakie ma stanąć przed moim robotem jest okrążenie kampusu mojej uczelni. Teren nie jest prosty, robot będzie miał do pokonania wyboiste drogi(częściowo przejazd przez las), krawężniki, trawniki i parkingi. Sterowanie ma być ręczne, realizowane zdalnie, za pośrednictwem internetu. Okrążenie to około 3km, zakładany czas przejazdu to niecała godzina. Konstrukcja opiera się na ramie zbudowanej z profili alu, o wymiarach 400x600. Do ramy będzie przymocowane większość osprzętu robota. Zawieszenie niezależne, 4 wahacze wzdłużne zawieszone na amortyzatorach do samochodów rc. Jako napęd 4 silniki wraz z przekładniami od samochodów dla dzieci. Koła 12 cali od wózka dziecięcego Część elektroniczna składa się z: Raspberry Pi 3, ICSTATION UNO, 4xmostek H VNH2SP30, przetwornica napięcia 5v USB, czujniki odległości(jeszcze nie wybrane), kamera(prawdopodobnie internetowa usb) Tyle z założeń, robot jest już w zaawansowanej fazie budowy. Zaczęło się od projektu w semestrze zimowym 2019/2020, projekt został zaliczony, jego dokumentacja tutaj(dokumentacja), a filmik zaliczeniowy z pierwszej jazdy terenowej poniżej Na tej fazie robot całą elektronikę miał zamontowaną "na taśmę", ze względu na zamówienie niewłaściwych kołków do pcb, a termin gonił. Obecnie robot jest rozebrany z całej elektroniki, powstaje miejsce w którym pojawią się akumulatory i elektronika(puszka elektryczna), osobny wyłącznik awaryjny oraz doprowadzenie kabli do silników. Poniższe zdjęcie przedstawia obecny stan robota: Aktualnie czekam na osłony na silniki wydrukowane w 3d, po zamontowaniu wszystkiego z zewnątrz będę mógł przejść do środka. W środku planuję zrobić ramkę z kątownika alu 20x20, w której będą miejsca na akumulatory(dwa akumulatory umieszczone po bokach), a pomiędzy nimi ma zostać umieszczona elektronika w sposób warstwowy(poziom 1: mostki H, poziom 2: ICSTATION UNO, poziom 3: Raspberry Pi 3). Poza tymi warstwami muszę znaleźć jeszcze miejsce na przetwornicę napięcia i mobilny ruter wifi. Całą ramkę chcę umieścić na gąbce, która by amortyzowała wstrząsy, tak samo zabezpieczyłbym moduł od góry. Dziękuję za uwagę, postępy i pytania będę starał się wrzucać tu na bieżąco.
  40. 7 punktów
    Stacja pogodowa z wysyłką danych na stronę WWW Od paru tygodni testuję stację pogodową którą udało mi się zmontować w ostatnim czasie. Stacja oparta o sterownik Lan Kontroler V2.5 firmy Tiny Control. Jest to kompaktowe rozwiązanie zawierające: 5 wejść analogowych: pomiar temperatury, napięcia i prądu, oraz innych wielkości fizycznych, wejście cyfrowe w standardzie 1wire, wejście cyfrowe do obsługi czujnika temperatury i wilgotności DHT22, 4 wejścia logiczne: jako czujnik stanu do monitoringu, jako licznik impulsów z licznika energii, 1 przekaźnik (NZ, NO, C), 1 wyjście tranzystorowe, 4 wyjścia do załączania przekaźników oraz pomiar temperatury i napięcia zasilania na płytce. Do sterownika podłączyłem następujące czujniki: temperatury/wilgotności/ciśnienia - wszystko w jednym: CZUJNIK BME280/SPLITER 1WIRE/ RJ12 Grove - czujnik opadów / wody DFRobot Gravity - analogowy czujnik wilgotności gleby - odporny na korozję DFRobot Gravity - czujnik światła ultrafioletowego UV analogowy Miernik prędkości wiatru (chiński, zamówiony na aliexpress) Podłączenie Urządzenie Lan Controler wymaga podłączenia czujników do odpowiednich wejść analogowych/cyfrowych. Czujnik BME280 podłączany jest do złącza wire1. Po zmontowaniu całość prezentuje się następująco: Oprogramowanie Sterownik Lan Controler posiada wbudowany serwer www i panel zarządzania parametrami sterownika oraz wejściami: dodatkowo posiada możliwość wysyłki danych do serwerów protokołem HTTP, taką opcję zbierania danych umożliwia np. serwer Thing Speak (https://thingspeak.com/) ThingSpeak to aplikacja i interfejs API dla urządzeń IoT (opensourcowe) do przechowywania i pobierania danych z urządzeń elektronicznych za pomocą protokołu HTTP i MQTT. tak wyglądają dane z mojej stacji pogodowej na platformie Thinspeak: dzięki opcji zagnieżdżania poszczególnych widgetów z ThingSpeak na innych stronach, zrobiłem własną zawierającą kluczowe parametry pogodowe: Rozwój: w planie dodatkowy czujnik - przepływu wody, mierzący ilość opadów, planuję oprzeć to o czujnik przepływu YF-S402, natomiast przed zimą czujnik zanieczyszczenia powietrza. Oczywiście wszystkie dane będą publikowane na stronie WWW automatycznie.
  41. 7 punktów
    Hej! Chciałem się z wami podzielić projektem, który od jakiegoś czasu rozwijam z grupą znajomych. Nazywa się on Wroob i jest to aplikacja pozwalająca zaprogramować swój telefon. Głównym celem projektu jest urozmaicenie procesu nauki programowania w Pythonie, głównie przez wprowadzenie elementów robotyki. Jest to też system, który umożliwia wykorzystanie możliwości współczesnego smartphona we własnych projektach. Jeżeli chcemy na przykład śledzić twarz manipulatorem, nie potrzebujemy do tego celu RPi z kamerą, możemy użyć własnego telefonu z aplikacją Wroob. Ponieważ projekt jest już dość złożony. W tym tekście postaram się wyjaśnić na dość ogólnym poziomie czym jest system Wroob i co można z nim zrobić. Jeżeli będziecie zainteresowani to w kolejnych częściach omówię szczegółowo jak zostały zrealizowane poszczególne elementy systemu lub przygotuje poradniki jak stworzyć coś własnego używając aplikacji Wroob. Czym jest system Wroob? System Wroob składa się z trzech głównych elementów: 1. Aplikacja Wroob Jest to serce całego systemu. To na niej uruchamiane są wszystkie programy napisane przez użytkownika. Aplikacja umożliwia dostęp do Panelu Użytkownika Wroob i modułów (funkcjonalności) systemu. Słowem – zamienia telefon lub tablet w mózg robota. 2. Moduły System Wroob jest modularny, tzn. każda z funkcjonalności systemu jest dostarczana przez odpowiedni moduł. Na przykład telefon będzie odtwarzał dźwięki korzystając z modułu Audio Player Module, a dostęp do kamery czy rozpoznawanie twarzy realizowane będzie przez Video Processing Module. 3. Panel Użytkownika Wroob Otwiera się go w przeglądarce internetowej na komputerze lub innym urządzeniu. Panel umożliwia włączanie i wyłączanie modułów, graficzne widżety ułatwią zapoznanie się z ich funkcjami, a edytor kodu pozwala pisać programy w Pythonie. Panel Użytkownika Wroob to aplikacja webowa, której hostem jest telefon z aplikacją. Telefon udostępnia Panel Użytkownika w sieci lokalnej, więc możemy wejść z dowolnego urządzenia znajdującego się w tej samej sieci - najwygodniej pracuje się przy użyciu komputera Co można zrobić z aplikacją Wroob? Każdą funkcjonalność dostarczaną przez moduły można wykorzystać w dowolny sposób we własnych programach. Aktualnie dostępne moduły pozwalają między innymi na odtwarzanie dźwięków, rozpoznawanie twarzy, robienie zdjęć, syntezę i rozpoznawanie mowy czy podłączenie kontrolera do gier. Przygotowaliśmy kilka przykładów w formie kursów na YouTube/Wroob (znajdziecie tam też film jak rozpocząć pracę z systemem Wroob). Krótki filmik jak to działa: Gotowy kod programu alarmu wykorzystanego w filmie wygląda następująco: from wroob.modules.apm import Apm from wroob.modules.vpm import Vpm from time import sleep apm = Apm('apm001') vpm = Vpm('vpm001') THRESHOLD = 60 SENSITIVITY = 200 def alarm_callback(msg): if apm.state["status"] == "stopped": apm.play_sound("breach_alarm.wav") vpm.start_motion_detection_reporting(THRESHOLD, SENSITIVITY, alarm_callback) while(True): sleep(1) A tutaj prosty Chatbot: from wroob.modules.srm import Srm from wroob.modules.ssm import Ssm import time srm = Srm("srm001") ssm = Ssm("ssm002") slownik_zwrotow = { 'cześć' : 'Witaj, jak masz na imię?', 'tomek' : 'Miło cię poznać. Czym się zajmujesz?', 'programuje' : 'Doskonale. Widzę, że dobrze Ci idzie', 'na razie' : 'Miłego dnia!' } def odbior_mowy(data): print(data) if data in slownik_zwrotow: ssm.start_speech_synthesis(slownik_zwrotow[data]) else: ssm.start_speech_synthesis("Nie rozumiem, czy możesz powtórzyć?") srm.start_speech_reporting(odbior_mowy) while True: time.sleep(1) Hardware Oczywiście najciekawsza zabawa rozpoczyna się w momencie, gdy połączymy aplikację Wroob ze sprzętem. Na przykład w relatywnie prosty sposób możemy zaprogramować zdalnie sterowanego robota z podglądem z kamery na żywo czy robota sterowanego mową. We Wroob mamy własne moduły sprzętowe które pozwoliły nam na zbudowanie robota mobilnego (Wrooby). Aplikacja wspiera też komercyjne roboty firmy Makeblock, mBot-S i mBot-Ranger. Pojawiają się one w systemie jako moduły. Otwarty system System Wroob z założenia jest systemem otwartym. Oznacza to, że można go łączyć z własnymi autorskimi projektami stworzonymi na przykład na Arduino czy napisanymi w dowolnym języku programowania na komputerze i traktować je jako moduły w systemie Wroob. Posiadamy gotową bibliotekę na Arduino która pozwala na obsługę naszego wewnętrznego protokołu komunikacji. Znajdziecie ją na GitHub’ie https://github.com/wroob-io lub możecie pobrać bezpośrednio w Arduinio IDE. Jak podłączyć płytkę Arduino do systemu Wroob i stworzyć własny moduł z przyjemnością opiszę w kolejnym artykule. Jeżeli projekt Wam się podoba, z chęcią odpowiem na wszelkie pytania w komentarzach. Oprócz łączenia Arduino z Wroob i pisania własnego modułu, mam też kilka propozycji na kolejne posty: 1. Własny moduł w Pythonie 2. Opis architektury systemu Wroob 3. Opis funkcjonalności i implementacji wybranego modułu 4. Robot mobilny Wrooby Dajcie znać co was najbardziej interesuje. Zachęcam do testowania możliwości aplikacji Wroob na własną rękę - do końca czerwca jest całkowicie darmowa Do pobrania w Google Play Wroob - Robotyka dla każdego! – Aplikacje w Google Play
  42. 7 punktów
    Witam! Konsolka gotowa! Poniżej ostatni update: Czas oczekiwania na zamówione PCB wykorzystałem głównie na pracę nad oprogramowaniem: 1. Rozszerzyłem moją bibliotekę do obsługi TFT o wyświetlanie dowolnych fontów. Wystarczy wybrany Font skompresować napisanym przeze mnie skryptem Pytona i wkleić wynikową tablicę do kodu oprogramowania w C. Funkcja wyświetla tekst z antyaliasingiem, więc wszystkie litery i znaki wyglądają ładnie. 2. Dopracowałem funkcje odpowiedzialne za dzwięk 3. Tworzyłem animacje, grafikę oraz dodawałem ścieżkę dzwiękową do gry. Ostatecznie odebrałem zamówione PCB, więc od razu zabrałem się do składania. Wszystkie części już czekały. Składałem i testowałem konsolkę w następującej kolejności: Charger -> Układ zarządzania -> Przetwornica DC-DC -> Mikrokontroler i elementy towarzyszące-> Wyświetlacz, Klawiatura W porównaniu do prototypu bazującego na płytce NUCLEO, zastosowałem wersję STM32F103 z większą ilością pamięci. W międzyczasie ukończyłem też oprogramowanie. Gdy miałem już całą elektronikę, przyszedł czas na złożenie wszystkiego w całość. Poza przyciskiem krzyżykiem, na tym etapie, nie musiałem już modyfikować żadnych innych elementów obudowy. Przycisk okazał się trochę za bardzo dopasowany i naciskając np strzałkę w górę, jednocześnie wciskały się inne kierunki. Problem łatwo dało się rozwiązać drukując poprawiony element. Ostatecznie konsolka wygląda następująco: A tu filmiki z działania konsolki: 1. Intro gry 2. Game play: 3. Animacje na Game Over PODSUMOWANIE: Ostatecznie jestem zadowolony z projektu. Wiele się przy nim nauczyłem i przy okazji powstała fajna zabawka dla synka. Nie wszystko poszło jednak idealnie. Przy montażu okazało się że mam błąd w schemacie, co przełożyło się na błąd na płytce. Na szczęście dało się to załatwić jednym mostkiem i jednym cięciem ścieżki. Zaprojektowałem też połączenie USB (pull up D+ z opornikiem do 3,3V itp...). Ostatecznie nie udało mi się jednak połączyć z mikrokontrolerem przez USB. Urządzenie było wykrywane, ale cokolwiek robiłem nie dało się zainstalować poprawnych sterowników. Gdy zamówiłem lepszy STM32F103, okazało się że wyższe wersje różnią się od tej zainstalowanej na NUCLEO (najuboższa). Nie tylko mają więcej pamięci ale też DAC, I2S, sprzętową obsługę kart SD itd... funkcje których tak mi brakowało. No nic... już było za późno na zmianę projektu. Pozdrawiam, Marek
  43. 7 punktów
    Z góry zaznaczam, iż projekt jest baaardzo stary, ma już blisko 3 lata. Jego celem było zbudowanie czegoś pływającego, a związku z tym, że aktualnie trwały wówczas wakacje, pomyślałem, że spróbuję swoich sił w pseudo-modelarstwie Tak powstała bardzo prosta łódka - w założeniu, miała być gabarytowo podobna do kartki A4, sterowana przez Bluetooth i pozwolić na zdalne sterowanie na odległość kilku-kilkunastu metrów - na początku może krótki film: Konstrukcja Na początku, próbowałem wyfrezować klocek drewniany w kształcie korpusu, ale okazał się zdecydowanie za ciężki - chciałem, by był lity, bez drążenia wewnątrz, gdyż nie miałem żadnego doświadczenia z uszczelnianiem i zabezpieczaniem elektroniki/mechaniki przed wodą. Wybór padł więc na wycięcie kadłuba z dużego kawałka pianki poliuretanowej, który potem odpowiednio wyszlifowałem, ściąłem przód (aby był odpowiednio wyprofilowany), a całość pomalowałem kilkukrotnie czerwonym spray'em. Napęd i ster Silnik jest umieszczony na specjalnej (drukowanej 3D) podstawce, jego oś jest skierowana 30 stopni w dół względem płaszczyzny podłoża. Następnie jest połączony z wałem - fragmentem prętu gwintowanego M3, na końcu której znajduje się 3-łopatkowa śruba napędowa. Sam pręt umieszczony jest w dwóch, wklejonych w piankę, tulejkach stalowych, które toczyłem samodzielnie. Ich podstawową funkcją jest łożyskowanie, nie musiały być idealnie wodoszczelne przez to, że całość elektroniki.mechaniki jest umieszczona na, a nie w kadłubie. Sam ster to również drukowana 3D (jak patrzę z perspektywy czasu, to daleko było tym wydrukom do doskonałości ) płytka, umieszczona na wysięgniku i poprzez popychacz (odpowiednio wygięty drucik) połączona z orczykiem serwomechanizmu modelarskiego. Elektronika i oprogramowanie Tutaj również nic wyszukanego - prosty układ składający się Arduino Pro Mini, kilku kondensatorów chroniących mikrokontroler przed spadkami napięć wywołanymi rozruchem silnika, moduł BT HC-05 oraz przekaźnik (wklejony w korpus), służący właśnie do załączania napędu. Całość zasilana jest akumulatorem Li-Pol 7,4V 700mAh. Aplikacja sterująca na system Android to oczywiście stworzona w App Inventor'ze prosty program, umożliwiający połączenie się z modułem BT oraz przyciski: silnik ON/OFF oraz te służące do regulacji kąta wychylenie serwa. Wsad dla Arduino "nasłuchuje" natomiast software'owego SerialPort'u i podejmuje odpowiednią akcję w zależności od otrzymanej literki. Kilka zdjęć Wnioski Łódka, mimo, że stosunkowo prosta, wręcz jak teraz na nią patrzę, to banalna , dostarczyła wiele radości, spełniła podstawowe założenie - pływała i to w sposób kontrolowany oraz uświadomiła mi, że jednak bardziej wolę amatorską robotykę. Odnośnie pytań, dlaczego nie zabezpieczyłem elektroniki i całość jest przyklejona "tak luzem", to zdecydowałem tak zrobić ze względu na prostotę i fakt, że powierzchnia górna kadłuba jest podwyższona względem lustra wody o jakieś kilka cm; a całość jest stabilna i wolna, związku z tym przy spokojnej wodzie żadne zalanie (czy, co gorsza, wywrócenie "do góry nogami") konstrukcji nie grozi Pozdrawiam
  44. 7 punktów
    Witam, Z racji, że z zawodu jestem chemikiem, a hobbistycznie lubię „pobawić się” nieco elektroniką, chciałbym zgłosić projekt DIY, który łączy te dwie pasje. Pomysł na stworzenie „inteligentnego obrazu luminescencyjnego” narodził się po remoncie pokoju, gdy na ścianach zrobiło się dużo wolnego miejsca. Inteligentny obraz luminescencyjny składa się z kilku głównych elementów, do których należą: 1) Matryca obrazu została przygotowana z transparentnej masy na bazie polisiloksanów, znakowanej luminoforem nieorganicznym w postaci siarczku cynku. Luminofor ten wybrałem ze względu na wysoką wydajność luminescencji (świecenia) oraz prostą syntezę. Dla wyjaśnienia dodam, że siarczek cynku (z dodatkiem odpowiedniego aktywatora) wykazuje silną fosforescencję, czyli zdolność do emitowania światła (w kolorze zielonym) po wcześniejszym naświetleniu go promieniowaniem z zakresu światła UV lub światła widzialnego o barwie niebieskiej ( do około 450nm). 2) System silników krokowych jest odpowiedzialny za ruch głowicy rysującej. Składa się on z dwóch silników krokowych 28BYJ-48 wraz ze sterownikami (rozwiązanie budżetowe – dla większej szybkości rysowania można zamontować silniki krokowe wyższej klasy), płytki Arduino UNO oraz uchwytów wydrukowanych na drukarce 3D (materiał niebieski PET-G). 3) Głowica rysująca, której zadaniem jest punktowe dostarczanie światła ultrafioletowego. Składa się ona z obudowy wykonanej przy pomocy technologii druku 3D (materiał niebieski PET-G), obciążenia (dwie baterie typu „paluszki”) oraz lasera o długości fali 405nm wraz z zasilaczem TP4056 (obecnie zastosowany jest budżetowy laser o mocy 5mW). Matryca obrazu została przygotowana poprzez wymieszanie luminoforu z masą polisiloksanową, którą następnie wylano między dwie płyty wykonane z płyt plexi (grubość 1mm) i całość oprawiono aluminiową ramą od obrazu (wymiary 80x60cm). Głowica jest przymocowana za pomocą transparentnej żyłki do dwóch silniczków krokowych zamontowanych na górnych rogach obrazu. Silniczki krokowe są natomiast połączone poprzez sterowniki z płytką Arduino UNO, na którą wgrany został program sterujący ich pracą. Możliwe jest wgranie na płytkę wzoru, który jest rysowany od razu po podłączeniu całości do zasilania lub komunikacja z płytką Arduino UNO bezpośrednio z komputera. W drugim przypadku możemy rysować nieskończoną ilość wzorów, które są wgrywane do programu (skrypt Arduino) polargraphcontroller w postaci grafiki wektorowej. W głowicy rysującej umieszczony jest laser UV (zasilany ładowarką TP4056). W momencie, gdy załączymy zasilanie (lub załadujemy odpowiednią grafikę przy pomocy komputera) laser zostaje załączony a silniczki krokowe poruszają się w ten sposób aby wiązka lasera padająca na matrycę znakowana luminoforem „rysowała” zadany kształt lub napis. Warto zaznaczyć, iż po kilku godzinach obraz znika (luminescencja zanika) i możemy załadować kolejną grafikę. Obecnie mogę więc mieć w pokoju inny obraz każdego dnia. Zamontowanie lasera UV o większej mocy (rzędu 50mW) powinno zapewnić utrzymywanie się obrazu przez cały dzień/noc. Dodatkowo ponieważ przez dzień obraz absorbuje również światło słoneczne wpadające do pokoju przez okno w nocy nawet bez wyrysowanego wzoru widać lekką emisję światła z całej powierzchni obrazu, co pomaga mi w nawigacji po pokoju gdy zdarzy się konieczność przemieścić się gdzieś po przebudzeniu. Oczywiście taki obraz najlepiej wygląda wieczorem lub w nocy przy zgaszonym świetle (przykłady na fotografiach powyżej). Poniżej wstawiam także filmik ilustrujący działanie inteligentnego obrazu. Do otrzymywania "pełnych" obrazów wygodniej jest stosować (zamiast lasera) rzutnik UV, który zbudowałem do tego celu. Jego głównymi elementami są dioda UV 3W, soczewka powiększająca, ładowarka TP4056 oraz przezrocze z wypalonym wzorem. Przezrocza przygotowuję poprzez wycięcie z czarnej tektury odpowiedniego wzoru (przy pomocy grawerki laserowej), a następnie zaklejenie wygrawerowanego otworu przezroczystą taśmą. Fotografie rzutnika przedstawiono poniżej. Mam nadzieję, że projekt się spodobał Uwagi: 1) Z racji że system sterujący silnikami i zasilanie lasera jest zamontowane z tyłu za obrazem (od strony ściany), a nie mam możliwości ściągnięcia obrazu (jest dosyć ciężki i boję się że mógłbym go z powrotem nie założyć) wysunąłem te elementy z obudowy i na fotografii są przedstawione w formie „surowej” (bez obudowy). 2) Dźwięk, który słychać na nagranym filmiku pochodzi od drukarek 3D, które ostatnimi czasy nieprzerwanie pracują nad drukiem przyłbic ochronnych. Sama maszyna nie wydziela praktycznie jakichkolwiek dźwięków, a przynajmniej nie takich, które byłyby dla mnie słyszalne.
  45. 7 punktów
    Mam w domu licznik prądu starego typu. Kiedy rachunki za prąd wzrosły powyżej 150 zł / mieś stwierdziłem, że czas na poszukiwanie przyczyn tego stanu rzeczy. Zacząłem od chińskiego watomierza, który doprowadził mnie do amplitunera Technics który w trybie standby zżera 30W. Byłem jednak ciekaw ile pobiera cały system monitoringu, lampy ogrodowe, NAS i kocioł itp. w rozkładzie godzinowym. Rozważałem zmianę taryfy z G11 na G12 lub G12W. Potrzebowałem danych. Ręczne spisywanie stanów licznika jest nużące i nudne. Przyszedł czas na emeocv - Electric meter with OpenCV. To darmowa biblioteka udostępniona na github. Pozwala na odczyt licznik na podstawie analizy zdjęć i zapis do RRD (Round Robin Database). Program napisany jest w C++ i korzysta ze znanej biblioteki OpenCV. Uruchomienie odczytów zajęło mi sporo czasu i nie dawało satysfakcjonujących wyników z uwagi na potrzebę dostosowania wielu zmiennych i rekalibracji po nawet delikatnej zmianie położenia kamerki. Przyszedł czas na instalację IDE pod C++ i wydanie własnej wersji programu. Krótka lista ficzerów: analiza zdjęć licznika dostarczanych z kamerki trening algorytmu poprzez ręczną klasyfikację przykładowego materiału zapis danych do CSV wewnętrzna kontrola jakości danych możliwość zapisu zdjęć do plików i późniejszą analizę statystyki Przejdźmy do rzeczy. Potrzebujesz: Raspberry PI (Zero, Zero W, testowałem też na RPI4b) z kartą pamięci. Alternatywnie: wystarczy dowolny komputer z pochodną Debiana (np. Ubuntu albo Linux Mint) oraz telefon komórkowy z Androidem. Kamerki (ja korzystałem z ArduCam OV5647 5Mpx) Uchwytu do kamerki - ja skorzystałem z połamanego uchwytu do telefonu (można kupić na allegro za 5-10 zł) Źródła światła (np.Lampka LED za mniej niż 5 zł) - musiałem dodać do niej rezystor bo świeciła zbyt mocno ja potrzebowałem hub'a USB żeby zasilić lampkę i malinkę z jednego zasilacza (koszt ok 10zł) Kolorowych karteczek samoprzylepnych Aplikacji Emeocv2 (moja własna wersja aplikacji wspomnianej powyżej) Dobrego nastroju i trochę czasu Wersja dla Raspberry PI Przygotowanie sprzętu: zamocuj kamerkę na statyw lub uchwyt, podłącz do malinki, ustaw światło tak aby niezależnie od światła dziennego licznik był równomiernie oświetlony. Ważne żeby nie świecić na wprost na szybkę licznika, bo pojawią się silne refleksy które utrudnią odczyt. Potem przyklej do licznika dwa kolorowe (najlepiej niebieskie) markery z karteczek samoprzylepnych (jeśli będą odpadać - użyj taśmy dwustronnej). Dzięki nim pogram bedzie w stanie ustalić obszar na którym znajdują się cyfry do analizy. Na zdjęciu poniżej widać przykładowy setup. Nie jest to za piękne ale to nie dzieło sztuki Instalacja: 1. Zainstaluj czystego Raspbiana na swoje malince 2. Podłącz kamerkę do Raspberry PI i włącz poprzez komendę raspi-config 3. Połącz się z RPI przez SSH (lub VNC) i pobierz Emeocv2 z https://github.com/wof2/emeocv2 4. Wejdź do katalogu głównego Emeocv2 i uruchom: ./debian_ubuntu_dependencies.sh Skrypt pobierze potrzebne zależności (przede wszystkim OpenCV) 5. Zbuduj make RELEASE=true 6. Wejdź do katalogu Release chmod +x emeocv 7. Zrób trochę zdjęć z kamerki aplikacją raspistill i zapisz pliki .png do wybranego katalogu. Hint: jeśli twój licznik znajduje się w pomieszczeniu gdzie zmieniają się warunki oświetlenia to jak będziesz wygładzał parametry najlepiej skorzystaj z trybu timelapse żeby zebrać zdjęcia z całej doby (np. co 15 min.). Najlepiej rób zdjęcia w rozdzielności nie większej niż 800x600. 8. Uruchom aplikację w trybie 'adjust' (najlepiej przeczytaj help do komendy - opal ją bez parametrów: ./emeocv) wskazując katalog w którym zapisałeś wcześniej zdjęcia. Pewnie analiza zakończy się błędem - musisz dostosować kilka parametrów - w katalogu Release edytuj plik config.yml. Najważniejsze parametry to: rotationDegrees: 0 #obraca obraz przed analizą cannyThreshold1: 120 # dolna granica dla algorytmu znajdowania konturów dostosuj metodą prób i błędów. Możesz zapisywać plik yml w trakcie analizy w trybie 'adjust' - co zdjęcie konfiguracja wczytywana jest ponownie. cannyThreshold2: 260 # górna granica znajdowania konturów. digitYAlignment: 20 # maksymalne różnie z położeniu kolejnych cyfr w osi Y mierzone w pikselach. counterMarkerHLOW: 85 # kolor markera (karteczki) w skali HSL (poczytaj w necie). Domyślne wartości ustawione są na detekcję niebieskiego. Wartość H (Hue) min. counterMarkerHHI: 110 # jak wyżej tylko max counterMarkerSLOW: 120 # wartość minimalnego nasycenia (Saturation) counterMarkerVLOW: 120 # minimalne V (Value) koloru karteczki. maxImageHeight: 600 # automatyczne przeskalowanie w dół - ustaw jeśli karmisz program dużymi obrazkami. digitCount: 7 # Łączna liczba cyfr na liczniku (łącznie z tą po przecinku) 9. Kiedy będziesz miał satysfakcjonujące wyniki z wcześniej zapisanych zdjęć to pora na trening naszego algorytmu. Uruchom emeocv z opcją -l (Learn). Teraz program będzie pokazywał serię zdjęć i pytał cię o klasyfikację zdjęć poszczególnych cyfr do skali 0-9. Potrzebujesz z grubsza tyle samo próbek dla każdej z cyfr. Możesz skorzystać z opcji emeocv -p żeby pokazać statystyki nauki. ./emeocv -p OCR stats: Trained responses: 1094 Trained responses histogram: Digit '0'->167 Digit '1'->184 Digit '2'->152 Digit '3'->148 Digit '4'->64 Digit '5'->60 Digit '6'->60 Digit '7'->112 Digit '8'->73 Digit '9'->74 10. Pora na automatyczne rozpoznanie cyfr na całym zbiorze zdjęć i pokazanie wyników ./emeocv -t -i obrazki/ -vDEBUG -s 10 11. Jeśli wyniki są ok to produkcyjnie odpalamy robienie zdjęć (np. co 2 minuty), analizę i wyplucie wyników do CSV. Służy do tego opcja -w (Write). Dla kamerki raspberry PI polecam wykorzystanie operacji -k, która pobiera zdjęcia z wyniku działania komendy w pliku config.yml. Domyślnie jest to raspistill czyli miniprogram na raspbianie do robienia zdjęć: cliCaptureCommand: raspistill -w 800 -h 600 -n -o Teoretycznie możesz tu nawet wsadzić pobieranie zdjęć z innego urządzenia. Alternatywnie użyj operacji -c (czyli Camera, podaj nr kamery np. -c0). Opcja wykorzystuje API openCV do odczytu z kamery. Mnie się ta opcja nie sprawdziła bo zdjęcia wychodziły albo za ciemne, albo poszczególne odczyty bardzo różniły się od siebie. 12. Wyniki będą się pojawiać w pliku emeocv.csv w katalogu Release. Patrz w logi emeocv.log i nie przejmuj się jeśli po kilkunastu przeanalizowanych zdjęciach plik jest pusty. Program cache'uje wyniki z ostatnich chyba 12 wyników i dopiero kiedy uzyska sensowną niemalejącą serię odczytów to dokonuje zapisu do pliku. Plik CSV możesz potem wciągnąć gdzie chcesz np. do arkuszy Google. Skorzystaj z mojego. Więcej informacji znajdziesz na https://github.com/wof2/emeocv2 Wersja z wykorzystaniem telefonu komórkowego - wkrótce
  46. 7 punktów
    Serwer WWW jest jednym z podstawowych programów używanych na Raspberry Pi. Ponieważ instalacja serwera jest dokładnie omówiona w kursie, a i pierwsze spotkanie z Apache najprawdopodobniej mamy już za sobą - nie będę opisywać podstaw, a przejdę od razu do trochę (naprawdę tylko trochę) bardziej zaawansowanej konfiguracji, ułatwiającej nam pracę i zabawę z serwerem. Pierwszą przykrą rzeczą, na którą się na pewno natkniemy będzie fakt, że nie mamy dostępu do katalogu /var/www/html, gdzie znajdują się pliki strony serwowanej przez Apacza. Większość radzi sobie z tym w ten sposób, że po prostu zmienia właściciela owego katalogu na użytkownika, na którego się loguje i teoretycznie wszystko działa... Niestety, tylko teoretycznie. Operowanie jakimiś danymi poza własnym katalogiem domowym jest niewygodne, a czasami (np. w przypadku ftp/sftp i ustawionego chroota) wręcz niemożliwe. W dodatku istnieje niebezpieczeństwo, że przy jakimś upgradzie system po prostu nadpisze zawartość tego katalogu i nasza strona będzie istniała tylko w przepastnych czeluściach /dev/null... Tymczasem Apache jest chyba najbardziej konfigurowalnym programem na naszej malince, i najprostszym sposobem będzie umieszczenie katalogu ze stroną w naszym katalogu domowym (czyli np. /home/pi/). Apache potrafi serwować różne zawartości z różnych katalogów poprzez mechanizm tzw. hostów wirtualnych, ale jako że konfiguracja tego jest na tyle obszerna, że zasługuje co najmniej na jeden oddzielny artykuł - na razie interesuje nas wyłącznie konfiguracja domyślnego katalogu. Zacznijmy od utworzenia katalogu ze stroną i umieszczeniu tam jakiegoś najprostszego testowego pliku: mkdir ~/html echo "To tylko test" > ~/html/index.html Następnie musimy poprawić konfigurację domyślnej strony serwera. W tym celu otwieramy w edytorze plik konfiguracyjny: sudo nano /etc/apache2/sites-enabled/000-default.conf Znajduje się tam linijka: DocumentRoot /var/www/html informująca serwer o położeniu domyślnej strony. Musimy zmienić ją na: DocumentRoot /home/pi/html Ale to jeszcze nie wszystko. Należy również poinformować serwer, co może z tym katalogiem robić. Pod tą linijką dopisujemy więc: <Directory /home/pi/html> AllowOverride all Require all granted </Directory> Dyrektywa AllowOverride pozwala na późniejsze dokonfigurowywanie poprzez plik .htaccess, Require otwiera nielimitowany dostęp do strony. Fragment pliku odpowiedzialny za naszą konfigurację powinien wyglądać więc tak: Teraz możemy zrestartować Apacza: sudo systemctl restart apache2 lub po prostu kazać mu jeszcze raz wczytać konfigurację: sudo apachectl graceful Po prawidłowym przeprowadzeniu wszystkich operacji powinniśmy po wpisaniu do przeglądarki adresu malinki ujrzeć na ekranie napis "To tylko test". Sytuację z położeniem katalogu ze stroną mamy więc już naprawioną - ale za chwilę natkniemy się na następną, niemniej przykrą rzecz: otóż Apacz mimo że już wie o tym, że pliki ze stroną są w naszym katalogu domowym - wciąż działa z uprawnieniami użytkownika www-data. To może doprowadzić do absurdalnej sytuacji, kiedy w naszym katalogu domowym znajdują się pliki i subkatalogi nie będące naszą własnością, z którymi nie bardzo możemy cokolwiek zrobić (np. pliki upload WordPressa). Stwórzmy więc testowy plik html/test.php: <?php if (file_put_contents('test.txt','To jest test php')) { echo "Zapisane"; } else { echo "Nie dało się zapisać"; } ?> Po wpisaniu w przeglądarkę adresu http://ip_malinki/test.php zobaczymy niestety napis "Nie dało się zapisać", a w logu błędów (czyli /var/log/apache2/error.log) komunikat podobny do tego: PHP Warning: file_put_contents(test.txt): failed to open stream: Permission denied in /home/pi/html/test.php on line 2 Widzimy, że nasz wielce ambitny program nie ma uprawnień do zapisu Ale i na to jest sposób: musimy przekonać Apacza, aby naszą stronę serwował jako użytkownik pi a nie www-data! W tym celu instalujemy moduł ruid2, odpowiedzialny za zmianę "w locie" uprawnień: sudo apt install libapache2-mod-ruid2 -y Po instalacji moduł zostanie włączony w Apaczu, pozostanie nam więc tylko dodanie linijek odpowiedzialnych za zmianę użytkownika. W tym celu znów otwieramy w edytorze plik 000-default.conf i przed sekcją <Directory> dopisujemy: <IfModule mod_ruid2.c> RMode config RUidGid pi pi RGroups @none </IfModule> (co oznacza, że ręcznie podajemy dane, serwer ma działać z uprawnieniami użytkownika pi.pi bez żadnych dodatkowych grup). Po restarcie lub reloadzie serwera, jeśli nic się nie będzie działo, możemy spróbować czy nasze działania przyniosły spodziewany efekt. Jeśli teraz skierujemy przeglądarkę na adres ip_malinki/test.php - powinniśmy zobaczyć napis 'Zapisane'. Po wydaniu polecenia ls -l zobaczymy, że plik test.txt został utworzony z właściwymi uprawnieniami, czyli coś w rodzaju: $ ls -l html razem 12 -rw-r--r-- 1 pi pi 5 kwi 22 06:11 index.html -rw-r--r-- 1 pi pi 84 kwi 22 10:30 test.php -rw-r--r-- 1 pi pi 15 kwi 22 10:35 test.txt Tyle na dziś - w następnej części zobaczymy, jak można uruchamiać poprzez serwer programy w Pythonie (w rzeczywistości w dowolnym języku programowania) oraz w jaki sposób udostępnić tym programom GPIO czy też magistrale SPI oraz I2C.
  47. 7 punktów
    Cześć! Jako początkujący elektronik nie zdawałem sobie początkowo zbytnio sprawy z szkodliwości wdychania dymu powstającego przy lutowaniu, dlatego przy pracy nie używałem dotychczas żadnego wentylatora, siłą rzeczy opary leciały wprost na mnie i po kilku godzinach w takich warunkach najczęściej wieczorem pojawiały się np. bóle głowy, kaszel, już nie myśląc o tym jakie skutki przyniosło by to przyszłości. Postanowiłem coś w tym kierunku w końcu zrobić i wzorując się na układzie AVT3215 chciałbym przedstawić bardzo prosty w założeniu jak i konstrukcji projekt odciągacza oparów, który można zbudować tanim kosztem: Sterowanie wentylatorem odbywa się poprzez regulowany stabilizator LM317, kręcąc potencjometrem zmieniamy napięcie dostarczane do wentylatora, możemy dzięki temu płynnie zmniejszyć lub zwiększyć jego obroty, chociaż szczerze powiedziawszy ta funkcja jest mała przydatna w moim odczuciu, ponieważ i tak zawsze lutuje przy największych obrotach. Całość jest zasilana z zewnętrznego zasilacza 12V 0,5A, który zapożyczyłem od lampki biurkowej. Dużym atutem tego układu jest to, że można go zbudować dosłownie z części znalezionych w szafie, osobiście musiałem dokupić gniazdo DC oraz stabilizator na co w sumie wydałem +/- 10 zł (gdzie kupiłem sobie od razu kilka sztuk na zapas) Wentylator nie jest przymocowany na stałe, dzięki temu można go złożyć i łatwiej przechować np. w szufladzie. Jako podstawkę wykorzystałem tą, która została mi z kursu arduino, akurat pasowały mi otwory, także uznałem, że dam jej 'drugie życie' Lista potrzebnych komponentów: gniazdo DC płytka uniwersalna 2x diody LED 2x rezystory 1k 2x rezystory 330Ω 2x kondensatory elektrolityczne 220uF 1x kondensator elektrolityczny 47uF 2x kondensatory ceramiczne 100nF potencjometr 5K regulowany stabilizator LM317 złącze ARK wentylator na 12V Schemat ideowy: Działanie w praktyce:
  48. 7 punktów
    Ki-Cad to program, a właściwie zbiór programów służących do tworzenia schematów elektrycznych i obwodów drukowanych. Cechuje się dużą możliwością personalizacji interfejsu i posiada kompleksowy zestaw narzędzi pozwalający na przeniesienie pomysłu na gotowy projekt układu. Pełny program można pobrać ze strony producenta: https://kicad-pcb.org/. Pobieramy program, instalujemy go i otwieramy. Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. Tworzenie projektu Po otwarciu programu ukaże się nam takie oto okno: Tworzymy nowy projekt klikając ikonę z niebieskim folderem i nadajemy mu nazwę. W naszym przypadku będzie to “poradnik-forbot”. Gdy stworzymy nasz projekt razem z nim utworzą się dwa pliki. Pierwszy z rozszerzeniem “.kicad_pcb” służy do projektowania fizycznej wersji układu(tj. rysowania ścieżek na obwodzie drukowanym, stawiania footprintów itp.). Drugi plik z rozszerzeniem “.sch” służy do tworzenia schematu ideowego naszego układu(tj. tworzenie logicznych połączeń, dodawanie logicznym reprezentacji układów itp.). Najprostszym sposobem na stworzenie projektu jest rozpoczęcie go od schematu ideowego, gdyż gdy stworzymy schemat ideowy na schemacie fizycznym automatycznie pojawią się połączenia między footprintami, które ułatwią nam rysowanie ścieżek. Schemat ideowy i dodawanie elementów Schemat ideowy stworzymy za pomocą edytora schematów “Eeschema”. Po otwarciu ukaże się nam taki widok: Po zapoznaniu się z interfejsem możemy wejść w “Ustawienia strony”, aby zmienić jej wymiary, autora, datę itp. W tym projekcie spróbujemy zrobić prostego, okrojonego klona Arduino Pro Mini. Projektowanie warto rozpocząć od postawienia portów zasilania , wykonujemy to poprzez otwarcie interfejsu oznaczonego jako “D”. W “Dodawanie portów zasilania” znajdziemy możliwe do dodania porty zasilania. W moim naszym przypadku użyjemy portu 5V i GND. (widok po otwarciu okna “Dodawanie portów zasilania”) Dodanie portów zasilania w taki sposób jest istotne, aby program mógł poprawnie zinterpretować nasz układ. Gdy już mamy porty zasilania czas dodać elementy elektryczne, klikamy na przycisk “Dodaj Symbol”, ukaże się nam takie oto okno: Analogiczny do interfejsu “Dodawanie portów zasilania”, jednak z większą ilością zakładek. Najpierw dodamy ATmega 328p do naszego schematu. Jest to mikrokontroler używany w Arduino Pro Mini. Szukamy zakładki MCU microchip ATmega, rozwijamy ją i szukamy “ATmega328p-AU”. Skrót AU oznacza, że ten mikrokontroler jest w obudowie TQFP-32, taka sama jak w Arduino Pro Mini. Zaznaczamy i klikamy “ok”, aby dodać element do schematu. Taki element możemy podczas przesuwania obracać klawiszem R ,a także najeżdżając kursorem na element bądź napis kliknąć M ,aby poruszać elementem. Jest to wygodniejsze niż zaznaczanie gdyż zaznaczając możemy przez przypadek oznaczyć także inny element lub połączenie. Następnie, tak samo jak mikrokontroler dodajemy potrzebne rezystory , kondensatory oscylatory itd. Łączymy za pomocą narzędzia “Dodawanie połączeń”. Dodawanie Etykiet Podczas procesu łączenia elementów warto pomyśleć o dodaniu Etykiet. Etykiety pozwalają na połączenie wszystkich pinów do których mają być przyłączone. W ten sposób tworzy się sieć połączeń. Ma to dwie główne zalety w porównaniu do tradycyjnych połączeń. Po pierwsze schemat staje się bardziej czytelny, gdyż przy dużej ilości połączeń może wyjść nieczytelne spaghetti połączeń. Po drugie nadaje to nazwę naszej sieci połączeń, przyda się nam to szczególnie w trakcie projektowania samej PCB. Aby utworzyć Etykietę naciskamy przycisk “dodaj Etykietę globalną”. Nazywamy ją w polu “Etykieta” i umieszczamy na schemacie. Utworzyliśmy tym samym typ etykiety np.”VCC”. Aby dodać kolejną etykietę robimy to samo, tylko nie wpisujemy nazwy w pole etykieta, ale je rozwijamy. Wewnątrz powinna się znajdować nasza etykieta “VCC” wybieramy ją i klikamy “ok”. Tym sposobem dodaliśmy naszą etykietę do schematu. Podobnie jak elementy, etykiety można obracać klawiszem “R”. Teraz, gdy przyłączymy te etykiety do określonych pinów, program połączy je w sieć o nazwie “VCC”. Właściwości elementów i znacznik "niepołączone" Zaznaczając element i klikając przycisk “E” możemy wejść w właściwości danego elementu. Możemy tutaj edytować różne parametry, takie jak ułożenie, wyśrodkowanie napisów itp. A także wpisać wartość naszego elementu( tak jak na rysunku poniżej, oscylator o wartości 16 MHz). Zwróćcie uwagę na znak zapytania obok oznaczenia, oznacza on jeszcze nie nadaną numerację tego elementu. Ważne jest by każdy element był oznaczony, możemy to zrobić za pomocą pewnego narzędzia, które przedstawię wam później. Może się tak zdarzyć że niektóre piny np. w mikrokontrolerze nie będą przez nas używane i do niczego ich nie podłączymy. Należy wtedy użyć narzędzia "znacznik niepołączone" i oznaczyć nim nasze nieużywane piny. (Wtedy program nie będzie wskazywał błędów) (Wygląd gotowego schematu z ATmega328p) Gdy nasz układ jest już połączony zostały nam tylko trzy kroki. Są nimi: numeracja elementów, przypisywanie footprintów do elementów i generowanie listy sieci. Numeracja elementów: Klikamy przycisk “Numerowanie symboli na schemacie”, ukaże nam się taki widok: Klikamy “Numeruj”, narzędzie automatycznie ponumeruje nam elementy na schemacie. Przypisywanie footprintów do elementów: Elementy na schemacie są tylko ideowe, więc trzeba przypisać do nich footprinty, czyli fizyczne miejsca dla elementów na obwodzie drukowanym. Robimy to za pomocą przycisku “Przypisywanie footprintów do symboli”. Następnie ukazuje się nam takie oto okno: W pierwszej kolumnie mamy listę folderów zawierających footprinty, w drugiej symbole z naszego schematu, a w trzeciej rozwinięty, aktualnie otwarty, folder z lewej kolumny. ATmega328p-AU ma już przypisany swój footprint, z uwagi na dostępny tylko ten konkretny model obudowy. Możemy to zmienić, lecz ta obudowa jest w pełni kompatybilna. Do reszty elementów musimy konkretne footprinty przypisać sami. Wyszukujemy w pierwszej kolumnie odpowiedni folder, zaznaczamy go i w trzeciej kolumnie wyszukujemy footprint, który jest nam potrzebny. Klikamy dwa razy lewy przycisk myszy, aby przypisać footprint do naszego symbolu. Jeśli potrzebujemy mieć wgląd w dokładny wygląd footprintu, możemy go zaznaczyć prawym przyciskiem myszy i wyświetlić jego fizyczne przedstawienie na płytce. (Wygląd okna z przypisanymi footprintami) Generowanie listy sieci Gdy już to skończymy musimy jeszcze wyeksportować listę sieci z naszego schematu do pliku , które program Pcbnew (Ten w którym robimy już fizyczny obwód) mógł odczytać nasz schemat. Klikamy więc po zamknięciu przypisywanie footprintów klikamy przycisk “Generowanie listy sieci”. Zaznaczmy zakładkę Pcbnew i klikamy “generowanie listy sieci” . Plik ten zostanie utworzony w folderze naszego projektu. Pcbnew i właściwe tworzenie układu drukowanego Następnie otwieramy program Pcbnew , aby rozpocząć właściwe tworzenie obwodu drukowanego. Po otwarciu programu ukaże się nam taki oto widok: Interfejs jest bardzo podobny do programu Eeshema. Domyślnie program obsługuje dwie warstwy miedzi (warstwa F i warstwa B). Możemy to zmienić wchodząc w “Ustawienia projektowe płytki”. Kiedy zapoznamy się z interfejsem “Pcbnew” możemy przystąpić do załadowania listy sieci, którą zrobiliśmy przed chwilą. Klikamy “Załaduj listę sieci”, ukaże się nam taki widok: Klikamy na ikonkę folderu w prawym górnym rogu i wybieramy naszą wcześniej utworzoną listę sieci. Następnie klikamy przycisk “Uaktualnij PCB”. Dzięki temu wszystkie footprinty, które dodaliśmy do schematu zostaną dodane do naszego obwodu drukowanego. Powinno to wyglądać mniej więcej tak: Jak widać wszystkie footprinty zostały dodane. Dodatkowo zostały utworzone linie pomocnicze, które mówią nam co powinno być sobą połączone na podstawie schematu. Jest to bardzo pomocne, jeśli chcielibyśmy coś dodać do naszego układu, ale nie usuwać istniejących footprintów i połączeń. Możemy jeszcze raz załadować listę sieci. Wtedy zostaną zaaplikowane poprawki, które wykonaliśmy na schemacie. Pamiętajmy także o opcji “Odbuduj połączenia wspomagające”, aby zostały one uaktualnione. Ustawienia obwodu drukowanego Zanim zaczniemy rysować ścieżki warto jeszcze dostosować ich parametry . Robimy to wchodząc w “Ustawienia obwodu drukowanego”. Możemy tam dostosować różne parametry naszego obwodu drukowanego, np.szerokość ścieżek, odległość między ścieżkami itp. oraz przypisać te właściwości do konkretnych sieci w naszym układzie. W naszym przypadku dodamy tylko dwie klasy sieci domyślną oraz zasilania(trochę grubszą z uwagi na większe możliwe prądy przepływające przez te ścieżki). Przypiszemy też klasę zasilania do sieci GND i 5V. Klikamy “ok” i od teraz program automatycznie przełączy nam właściwą szerokość ścieżki w zależności od sieci którą będziemy rysować. Skróty klawiszowe Pcbnew Przejdźmy do właściwego układania footprintów i rysowania ścieżek. Skróty klawiszowe są podobne jak w programie “Eeschema”, też klawisz “M” używamy aby przemieścić obiekt, “R” aby obracać obiekt. Ważny skrót klawiszowy to “V”, gdyż nim przełączmy między warstwami miedzi. Można też, gdy trzymamy obiekt tym klawiszem, przełożyć go na drugą stronę płytki oraz podczas rysowania ścieżki możemy utworzyć przelotkę. Jest to mała metalizowana dziura która pozwala na przejście wertykalne przez płytkę i np. połączyć elementy na dwóch różnych warstwach, stworzyć przejście pod ścieżką która nas blokuje na innej warstwie itp. Istnieje możliwość przełączania się tym klawiszem między warstwami, gdy nie jest zaznaczony żaden element. Strefy Warto pomyśleć o dodaniu warstw miedzi jako masę na całej dolnej warstwie naszej płytki. Nie tylko ułatwi to nam dołączanie elementów do uziemienia ale także zapewni proste ekranowanie układu. Robimy to za pomocą narzędzia “Dodaj strefy”. Naszym oczom ukaże się takie oto okno: Zaznaczamy warstwę “B.Cu” oraz wybieramy sieć “GND”, resztę ustawień pozostawiamy domyślne. Następnie klikamy “OK”. Potem fizycznie musimy narysować obrys strefy na naszym układzie. Strefa następnie zostanie dodana na całym obrysowanym przez nas obszarze. Musimy też pamiętać że podczas rysowania w obszarze strefy nie aktualizuje się on w czasie rzeczywistym i musimy po dokonaniu jakiś zmian nacisnąć klawisz “B”, aby na nowo wypełnić strefę (np. strefa usuwa się z utworzonych przez nas ścieżek, elementów oraz wypełniła puste miejsca na płytce) Po tym możemy już spokojnie połączyć wszystkie elementy układu. Oto efekt: (Gotowy układ z uruchomioną kontrolą DRC. Wszystko jest dobrze , nie ma błedów) Warto po zakończonej pracy sprawdzić układ kontrolą DRC, aby upewnić się że wszystko jest odpowiednio połączone, itp. Należy też pamiętać że : Ścieżki powinny zginać się pod kątem 45 stopni nie 90 stopni Napisy warstwy opisowej (np. C1 , R2 itp. zaznaczone kolorem zielonym) nie powinny się znajdować na padach lutowniczych naszych footprintów) (Przegląd 3D naszego układu) Po kliknięciu przycisku ALT+3 możemy włączyć widok 3D naszej płytki , aby zobaczyć jak wygląda i czy napisy są umieszczone czytelnie. Eksportowanie projektu Na końcu, aby wyeksportować naszą płytkę tak, aby fabryka PCB mogła ją zrobić należy wejść w “Rysuj”. Ukaże się nam takie okno. Zależnie od fabryki, w której będziemy chcieli wyprodukować płytkę, możemy użyć różnych formatów projektu. Zazwyczaj potrzeba plików w formacie GERBER. Zaznaczamy, więc warstwy jakie chcemy wyeksportować, wybieramy format wyjściowy i folder wyjściowy(jeśli tutaj nic nie wybierzemy program utworzy nam pliki w folderze projektu). Następnie klikamy “Rysuj”, a potem “Generuj pliki wierceń”, aby stworzyć pliki wierceń (wyświetli nam się podobne okienko w którym możemy wybrać format wyjściowy itp.). I takim sposobem stworzyliśmy swoją pierwszą płytę w KiCadzie. Dziękuję za uwagę! Aleksander Flont
  49. 7 punktów
    Idea działania Komora jonizacyjna, to urządzenie składające się z dwóch elektrod do których doprowadzane jest stałe napięcie, co powoduje powstanie pola elektrycznego w jej środku. Gdy kwant promieniowania "uderzy" w atom gazu znajdującego się w komorze, "rozbija" go na dwa jony (dodatni i ujemny), które są przyciągane do elektrod (dodatni do ujemnej i vice versa). Mierząc prąd płynący między dodatnią, a ujemną elektrodą, będzie on proporcjonalny do ilości tych jonów, zaś to będzie proporcjonalne do mierzonego promieniowania. Utrudnieniem jest, że wspomniane prądy są małe, więc wymagają dużego wzmocnienia, co zaś wymaga m.in. starannego filtrowania zasilania, oraz ekranowania, by urządzenie się nie wzbudzało. Poniżej znajduje się schemat blokowy prezentowanego rozwiązania. Część elektroniczna Pierwotnie do wytworzenia napięcia polaryzującego, miałem w planach użycie przetwornicy, jednak okazało się, że napięcie 12V z baterii jest wystarczające. Sygnał z komory trafia do wzmacniacza transimpedancyjnego, w pętli sprzężenia znajdują się szeregowo dwa rezystory o wartości aż 50G. Połączenie owych rezystorów, elektrody komory jonizacyjnej i nóżki wzmacniacza musi być wykonane w powietrzu, by uniknąć pasożytniczych rezystancji. Poniżej znajduje się render w KiCADie, oraz rzeczywiste urządzenie (wiem, fotka jest dość niskiej jakości). Część programistyczna Sygnał analogowy trafia do przetwornika ADC, i jest zbierany przez procek - tu użyłem dość mało popularnego STM8. Zaskoczeniem było dla mnie, że GCC nie obsługuje tych procesorów, zaś poświęcony im SDCC nie umie wycinać z binarki funkcji, które nie są używane! Do komunikacji z hardwarem użyłem stdperiph. Komunikacja z światem zewnętrznym jest jednokierunkowa (urządzenie wysyła pomiary co kilka sekund) za pomocą UARTa. Założeniem było, by urządzenie można było pozostawić same sobie i zdalnie je flashować, czy też pobierać z niego dane. W skrócie, wolę programować leżąc w łóżku, niż garbiąc się nad stołem pełnym kabli :) Zostało to zrealizowane przez dodanie Raspberry Pi, do której podpięty jest zarówno programator, jak i przelotka UART/USB. Soft na procka napisałem w C. Pobieranie danych po stronie maliny jest wykonywane przez skrypt w Pythonie, dane są wizualizowane skryptem w R. Użyłem R, mimo, że Python też ma biblioteki do tworzenia wykresów, bo bardzo podobają mi się wykresy w R. Dokumentacja powstała w LATEXie. Całość dostępna jest na GitHubie - zapraszam do odwiedzenia Wyniki Poniżej znajdują się dane pomiarowe zebrane za pomocą urządzenia.
  50. 7 punktów
    Dziś wydrukowałem kilka ostatnich części i zmontowałem mechaniczną część konstrukcji robota czworonożnego. Dalej muszę: - zoptymalizować 'nóżki' - sensory kolizji, żeby zapewniały także dobrą przyczepność. W tej chwili widać zakończenia na 'kwadrat', żebym mógł robić szybkie testy i wymieniać na nowe wersje bez drukowania całej dalszej części kończyny. - zamontować zasilanie - przetwornicę step-down, ogniwa li-ion z bms i zabezpieczenia dla serw i logiki - zacząć programować schematy ruchowe (odwrotną kinematykę napisałem wcześniej i przetestowałem).
Tablica liderów jest ustawiona na Warszawa/GMT+01:00
×
×
  • Utwórz nowe...