Skocz do zawartości

Tablica liderów


Popularna zawartość

Pokazuje zawartość z najwyższą reputacją od 28.04.2020 w Posty

  1. 13 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. 12 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!
  3. 9 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.
  4. 8 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
  5. 8 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ń
  6. 8 punktów
    Witam. Chcę pokazać swoją kolejną konstrukcję, zapoczątkowaną w listopadzie zeszłego roku. Jest nim robot balansujący, który miał jedno specjalne zadanie - pomóc mi zrozumieć działanie regulatorów. Na początku myślałem "wystarczy jechać do przodu/do tyłu jak się robot przewraca" - byłem w ogromnym błędzie. Tak wygląda finalna wersja robota: Tak więc, na początku obmyśliłem konstrukcję robota. Pod ręką miałem zmodyfikowane serwa SG90 do wykonywania pełnych obrotów - przykleiłem je do akumulatora, tam gdzie się dało dokleiłem klejem na gorąco Pro Mini, żyroskop i akcelerometr MPU6050, moduł z TP4056, wyłącznik i czujnik odbiciowy, jako prosty przełącznik do debugowania. Wszystko polutowałem, koła wydrukowałem na drukarce 3D - za "opony" posłużyły tutaj gumki recepturki. Kod był prosty: odczytujemy aktualny kąt - jeżeli jest dodatni, jedziemy do przodu, jeżeli jest ujemny - do tyłu, a kiedy robot jest pionowy - wyłączamy silniki. Jak można się domyślać (ja się nie domyśliłem), robot nigdy nie osiągnął pozycji stabilnej. Zacząłem czytać projekty podobnych robotów. Dużo z nich wywnioskowałem. Przede wszystkim - kilka faktów o naturze robotów balansujących. Są one bardzo dobrym przykładem odwrotnego wahadła - tak samo działa np. balansowanie kija na palcu. Tam, gdzie kij upada - tam dajemy palec, zapobiegamy upadnięciu. Jako że potrafimy kojarzyć kilka zmysłów, i analizować to co z nich odbieramy, bez problemu dobieramy prędkość palca. Brak regulatora (tak jak było z robotem) skutkowałby tym, że palec przesuwalibyśmy z maksymalną prędkością w te i we wte - kij by się przewrócił. Robotowi zatem brakowało takiego regulatora, który by regulował prędkość silników. Jako, że serwa nie mogłem już regulować, konstrukcję zmieniłem: wykorzystałem silniki z Botlandu, z przodu dałem akumulator z Nokii z logiką. Z tyłu - mniejszy akumulator Li-ion z TP4056, i przetwornicą step-up, dla silników. Wydrukowałem kolejne koła, tym razem "opony" są z TPU: Zmiana konstrukcji przyniosła jeszcze jedną, ważną zmianę. Dlaczego kij nam łatwiej balansować od długopisu? Z moich "doświadczeń", wywnioskowałem że im kij jest dłuższy, tym jego drugi koniec ma dłuższą drogę do przebycia. Daje nam to więcej czasu na zbalansowanie go. Poprzedni robot był krótki - ok. 30mm, co dawało bardzo mały czas na dojechanie na miejsce. (bardzo chciałbym dać obliczenia, ale nie mam pojęcia o momencie czy prędkości silników). Kod lekko zmieniłem, dodałem obsługę mostka H. Zaimplementowałem regulator PID - proporcjonalno-całkująco-różniczkujący, co (na razie) nic mi nie mówi. Jak przeczytałem, jest to jeden z najpopularniejszych regulatorów w robotyce. Nawet po przeczytaniu tego artykułu, dalej za dużo mi się nie rozjaśniło - brakuje mi wiedzy. Dlatego zacząłem się "bawić", eksperymentując z różnymi wartościami poszczególnych członów. Robot mimo wszystko ZA NIC nie chciał się ustabilizować (przy lekkiej pomocy, coś mu się udało). Zauważyłem, że brakuje mu "pary". Dlatego zamiast bawić się z tą konstrukcją, wydrukowałem jeszcze większe koła, o promieniu samego robota. Dzięki większemu obwodowi, pokonujemy większą drogę w tym samym czasie (kosztem momentu - jak coś pokręciłem, dajcie znać w komentarzach). No i bardzo ważna rzecz, robot przestał upadać - po upadku zaczyna się toczyć. Wyłączyłem wszystkie człony, za wyjątkiem proporcjonalnego. Po kilkunastu minutach eksperymentów, robot osiągnął pozycję stabilną. Mogłem mu w końcu zrobić zdjęcia, kiedy jest włączony: Po eksperymentowaniu z pozostałymi członami, wywnioskowałem, że: człon całkujący (D) próbuje "przewidzieć" ruch robota. Za dużo tego członu spowodowało, że robot cały się trząsł - po odpowiednim dobraniu, robot był w miarę stabilny. człon różniczkujący (I) zamiast w przyszłość, patrzy w przeszłość. Po odpowiednim dobraniu, zmalała ilość oscylacji potrzebnych do osiągnięcia stanu stabilnego. Człon proporcjonalny akurat zrozumiałem "na sucho" - im większy błąd, tym większa moc podawana na silnik. Napotkałem jednak jeden problem, który mnie przerósł... napędy nie są jednakowe. Prawy napęd reaguje na dość małe napięcie i jest dokładny, ale lewy załącza się dopiero od pewnego progu, a wtedy pędzi dość szybko. Na to niestety nie wiem jak zaradzić, może w przyszłości coś będę jeszcze robił. Ważne, że robot spełnił swoje zadanie, bo całkiem dużo się dzięki niemu nauczyłem.
  7. 7 punktów
    Witam. Ten projekt, mimo że wygląda na dość prosty, musiałem go bardzo rozpracować - jest to praca na "wprowadzenie do wykonywania zawodu", czyli mechatronikę. Założenia były takie: zrobić projekt, który widać że działa, jest stosunkowo prosty w konstrukcji. Wybór padł na useless box, czyli bezużyteczne pudełko. Bezużyteczne pudełka nie robią nic pożytecznego - jeżeli ktoś im przeszkodzi w byciu przyciskiem do papieru, albo kurzołapem - same się wyłączą. Tak więc, uznałem że optymalnie będzie to zrealizować na timerze 555 i serwie modelarskim. Zacząłem od sprawdzenia datasheeta serwa. Gdzieś przeczytałem, że serwa steruje się nie przez PWM a PPM (pulse position modulation). Nie miałem czasu badać tego aż tak, więc przyjąłem po prostu informacje z datasheeta. Kąt nachylenia od 0 do 180 stopni, i moment 1,8kg/cm powinien starczyć z dużym zapasem. Zgodnie z tym diagramem, trzeba wygenerować sygnał PWM o częstotliwości 50Hz - jedna ramka ma długość 20ms. Z forbotowego kursu elektroniki wiemy, że takie coś można wygenerować timerem w trybie astabilnym. Tak wygląda schemat żywcem wzięty z datasheeta 555: Działanie tego układu jest następujące: po podłączeniu zasilania kondensator C ładuje się - przez co na wyjściu jest stan wysoki. Ładuje się on przez rezystory Ra i Rb podłączone do zasilania. Kiedy kondensator naładuje się do 2/3 napięcia zasilania, wyjście jest ustawiane na stan niski, a kondensator się rozładowuje przez rezystor Rb podłączony do pinu “discharge”. Po rozładowaniu do 1/3 napięcia zasilania, wyjście znowu jest ustawiane na stan wysoki, a kondensator się ładuje - cykl się powtarza. Czas wysoki będzie zatem zależny od Ra i Rb, a niski od Rb. Zgodnie z pierwszym diagramem, aby wychylić serwo o -90 stopni wypełnienie musi wynosić 1ms. Aby orczyk się obrócił do +90 stopni, sygnał musi mieć wypełnienie 2ms. Wykonałem wstępne obliczenia - do powyższego schematu zostały dołączone wzory: Rezystancja niestety wychodziła ujemna. Wniosek prosty - ten układ nie nadaje się do naszego zastosowania, a przynajmniej w takiej formie. Tak jak w forbotowym przykładzie z kursu elektroniki, dodałem diodę równolegle z Rb. Od teraz Ra odpowiadał tylko za ładowanie kondensatora, a Rb tylko za rozładowywanie. Dlatego we wzorze na th mogę pominąć Rb: Jak widać, obliczyłem 3 rezystory - wspólny, rozładowujący, i 2 ładujące. Pierwszy spowoduje schowanie ramienia, drugi spowoduje jego wychylenie. Wszystko powinien rozjaśnić schemat: Nie miałem akurat żadnego akumulatora, więc źródło zasilania stanowią 4 paluszki AAA. Kondensator C1 filtruje zasilanie, i tam gdzie się dało umieściłem konektory. Płytkę zlutowałem na protoboardzie: Obudowę wydrukowałem na drukarce 3D, białym PLA od Spectrum. "Wnętrzności" pudełka wydrukowałem kolorem czerwonym. Po złożeniu, całość wyglądała tak: Wykorzystałem tutaj sprężynę z długopisu, spinacz jako oś dla klapki, całość skręciłem różnymi śrubkami. Przyszedł czas na odpalenie, a tu niespodzianka: nie działa (wow). Znaczy - działa, ale ramię ma za mało mocy do przełączenia dźwigni. Orczyk był prawidłowo przykręcony, okazało się że wypełnienie musiało być złe. Szybkie rozkręcanie, i patrzymy w oscyloskop: Eksperymentalnie dobrałem nowe wartości rezystora. Potencjometr szeregowo połączyłem z Rb, i udało się dobrać dobrą rezystancję. Po zmierzeniu miernikiem, okazało się że należy wlutować rezystor 2.7kΩ. Tak też zrobiłem - a bezużyteczne pudełko w końcu mogło się bronić przed napastliwą działalnością człowieka. Założenia projektu zostały spełnione, a projekt zaakceptowany. Projekt można uznać za zakończony sukcesem. Linki: datasheet SG90: http://www.ee.ic.ac.uk/pcheung/teaching/DE1_EE/stores/sg90_datasheet.pdf datasheet NE555: http://www.ti.com/lit/ds/symlink/ne555.pdf
  8. 7 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
  9. 6 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
  10. 6 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.
  11. 6 punktów
    Witam, z okazji sytuacji w Polsce i na Świecie związanej z koro... sami wiecie z czym, postanowiłem w końcu zrobić coś zamiast robić nic. Może nie jest to jakiś bardzo ambitny projekt ale jednak nauczyłem się paru nowych rzeczy. Najpierw przedstawię co to : Jest to poduszkowiec bez poduszki nie wiedziałem jak to nazwać więc wymyśliłem nazwę Slidejunk. Nazwa jest z języka angielskiego i oznacza ślizgający się(slide) śmieć(junk). Ślizgający się ponieważ się ślizga , śmieć ponieważ zrobiłem go z kartonu i rzeczy które miałem w domu . Spis rzeczy użytych do samego pojazdu: Silnik BLDC bezszczotkowy A2212/10T 1400KV. Sterownik silnika BLDC 30A. Pakiet Li-Pol 11.1v 3S 20C 2200mAh Servo SG90 Karton Na początku chciałem zbudować samolot ale zniechęciłem się po tym jak położyłem baterię na wagę . Bateria waży 135 g , nie chciałem ryzykować . Budowa samolotu to wyższy poziom . A ja mam tylko karton i ciężką baterię. Kiedyś kupie sobie specjalnego styropianu i coś z tym pokombinuję. Odbiornik - ma 7 kanałów , mózgiem jest arduino nano, sygnał jest odczytywany przez nrf24. Nadajnik - na razie ma 5 kanałów i więcej nie potrzebuję mózgiem znowu jest arduino nano a sygnał jest wysyłany przez nrf24 (ten z anteną).Zasilanie to 2 baterie 18560.W sumie używam 3 kanały : sterowanie silnikiem BLDC, sterowanie serwem, precyzyjne sterowanie serwem (potencjometr). Na górze widać spalone oczka na płytce, jestem amatorem w lutowaniu więc musiało się coś nie udać.Po zlutowaniu wszystkiego nadajnik nie działał , zdenerwowałem się i nie ładnie wylutowałem nrf-a. Wlutowałem go jeszcze raz i potem już działało. Nie udane pomysły Chciałem całość zamknąć w 2 kanałach ale, nie ma idealnego ustawienia domyślnego dla serwa dlatego musiałem dodać trzeci kanał . Był też pomysł na informowanie o stanie naładowania baterii po przez buzzer na nadajniku .Buzzer miał "pikać"gdy napięcie spada poniżej 11V. Nie udało się . Okazało się że nadawanie sygnału i odbieranie go jednocześnie przez pilota do pojazdu RC nie jest najlepszym pomysłem w tym przypadku. Ustawienia sterowania Joystickiem po lewej steruję silnik BLDC . Joystickiem z prawej serwem. Z okazji że te joysticki nie są z najwyższej półki, musiałem ustawić maksymalną moc silnika na 50% (po minimalnym przesunięciu silnik osiągał około 30% mocy a to sporo jak na ten pojazd). A maksymalny skręt serwa 30 stopni w każdą stronę . Podsumowanie Podczas projekt uważam za udany da się ślizgać. Planuję kiedyś kupić lepsze joysticki. Nie mam trzech rąk więc przy nagrywaniu trzymałem telefon w kolanach mam nadzieję że taki film wystarczy. Pozdrawiam czytelników .
  12. 6 punktów
    "Blink" jest chyba najpopularniejszym projektem odpalanym na wszelakich systemach wbudowanych. Kawałek kodu migającego jedną lub większą liczbą diod LED pozwala na szybkie przetestowania sprzętu i narzędzi służących do pracy z kodem. Większość płytek w stylu Arduino jest dostarczana z jakąś wersją "Blinka" w pamięci. Bawiąc się starymi systemami mikroprocesorowymi już parę razy testowałem projekty na wczesnym etapie rozwoju w bardzo podobny sposób - podpinając diodę do jakiegoś portu wyjściowego i uruchamiając kawałek kodu, który cyklicznie zapisuje odpowiednią wartość pod przypisany mu fragment pamięci. Tak właśnie wpadł mi do głowy pomysł na jeden z najbardziej bezsensownych "weekendowych" projektów, jakie do tej pory opracowałem. Mianowicie zacząłem się zastanawiać, czy nie dałbym rady przeportować "Blinka" na starego, dobrego Pegasusa. Przecież złącze kartridza tej konsoli ma wyprowadzoną kompletną magistralę systemową. Wystarczy tylko podpiąć do niej pamięć EPROM, port wyjściowy na układzie 74LS573 oraz prosty dekoder adresów, pozwalający na rozróżnienie jednego od drugiego. Projekt dwustronnej płytki powstał w jakieś dwie godziny. Następnego dnia ją wytrawiłem, wywierciłem otwory i zabrałem się za montaż. Lutowanie podstawek pod układy DIP nie należy do najprzyjemniejszych czynności na płytce bez metalizacji otworów. Normalnie pewnie zamówiłbym wykonanie paru takich PCB w chińskiej fabryce, jednakże z uwagi na pandemię i opóźnienia w wysyłce nie chciało mi się czekać. Początkowo użyłem zwykłych podstawek, ale te okazały się być wyjątkowo kłopotliwe w montażu - trudno było dotrzeć z grotem i cyną do wszystkich pól lutowniczych po stronie. Potem więc zmieniłem koncepcję i zastosowałem precyzyjne listwy pinowe. Kod odpowiedzialny za naprzemienne miganie diodami napisałem w asemblerze procesora 6502. Mając trochę więcej wolnego czasu dodam zapewne trochę więcej funkcji, m.in. możliwość "pauzowania" oraz zmiany częstotliwości migania z poziomu pada. Podejrzewam, że to nie będzie mój ostatni projekt w klimatach "pegasusowych", mam już w głowie kilka kolejnych pomysłów.
  13. 5 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
  14. 5 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ę.
  15. 5 punktów
    Na początku jedna uwaga: ten cykl artykułów nie jest podręcznikiem Pythona ani nie rości sobie praw do bycia takim. Używam w przykładach Pythona jako najbardziej popularnego języka programowania na RPi - ale równie dobrze mógłbym użyć Perla, C++ czy nawet Basha, a cykl jest po prostu "boczną odnogą" napisanego wcześniej cyklu o protokole HTTP. Dlatego też wiele kwestii zostało pominiętych i użytkownik musi większość problemów rozwiązać we własnym zakresie (czyli najprawdopodobniej znaleźć właściwe rozwiązanie w innym artykule). Ale przejdźmy do rzeczy. W poprzednim odcinku dowiedzieliśmy się, jak uruchomić z poziomu serwera WWW skrypty pisane w dowolnym języku, i jak pozwolić im na komunikację z GPIO i magistralami SPI/I2C na przykładzie odczytu danych z czytnika RFID. Dzisiaj spróbujemy komunikacji w drugą stronę: z poziomu przeglądarki spróbujemy wysłać coś na magistralę. Ale najpierw trochę teorii. Z artykułu o protokole HTTP (jeśli ktoś go nie przeczytał, to teraz jest najwyższy czas) mogliśmy dowiedzieć się, jak jest zbudowany URL. Widzimy tam, że w najprostszej postaci URL wygląda tak: http://<host><ścieżka>[?<zapytanie>] Możemy się domyślać, że host informuje przeglądarkę (i serwer) z jakim serwerem i jaką stroną ma się połączyć, ścieżka wskazuje na plik który mamy z serwera odczytać (lub - w przypadku skryptu - serwer ma go wykonać i przekazać nam wyniki), ale czym jest to całe zapytanie? Otóż są to dodatkowe dane przekazywane od klienta (czyli w naszym przypadku przeglądarki) do skryptu. Jak uprzednio wspominałem, format zapytania jest dowolny i zależy praktycznie od tego co potrafi klient i serwer, ale w praktyce używa się pewnej ustalonej składni: nazwa=wartość z możliwością przekazania większej ilości parametrów, oddzielając je znakami '&', czyli coś w rodzaju: nazwa1=wartość1&nazwa2=wartość2&nazwa3=wartość3 Zarówno nazwa jak i wartość mają swoje ograniczenia - mogą zawierać wyłącznie drukowalne siedmiobitowe znaki ASCII bez spacji (czyli z zakresu od 0x21 do 0x7E włącznie) z wyłączeniem niektórych znaków zastrzeżonych (np. trudno by było zastosować nazwę zawierającą w sobie znak równości, czy też umieścić znak '&' wewnątrz wartości). Dlatego też opracowano pewien sposób kodowania (tzw. "urlencode"), pozwalający na przekazanie dowolnych danych. Sposób jest bardzo prosty: znak spacji zamieniamy na '+' znaki które nie kolidują ze składnią zapytania pozostawiamy bez zmian pozostałe znaki (oraz znak + występujący w wartości) zamieniamy na ciąg %XX, gdzie 'XX' to szesnastkowa reprezentacja znaku. Tak więc np. ciąg znaków 'ala+ma kota' zostanie zakodowany jako: ala%2Bma+kota Oczywiście nie ma żadnych innych ograniczeń (poza oczywistymi, wynikającymi z maksymalnej długości URL-a którą może przyjąć serwer oraz takim, że nazwa nie może mieć aerowej długości). W szczególności przesłanie kilku wartości (np. informacji o zaznaczonych kilku możliwościach wyboru) nie wymaga jakichś specjalnych zabiegów, po prostu wystarczy zapytanie w stylu: nazwa=wybór1&nazwa=wybór3&nazwa=wybór7 O, i tu słyszę głosy programistów PHP - jak to? Przecież aby przesłać kilka wartości nazwa musi kończyć się znakami '[]' wskazującymi na tablicę, a dopiero wtedy w tablicy $_GET w pozycji wskazywanej przez 'nazwa[]' znajdzie się nie pojedyncza wartość, a tablica wartości! Niestety - dotyczy to wyłącznie PHP i jest to zaszłość historyczna (pochodzi z czasów, gdy nikt z twórców PHP nie wpadł na to że można przesyłać więcej niż jedną wartość; w związku z tym trzeba było dorobić na szybko jakąś protezę - i to taką, która nie wysadzi w kosmos wszystkich dotychczas napisanych skryptów w tym języku). No - ale dość już teoretyzowania, przejdźmy do praktyki. Serwer mamy już skonfigurowany, spróbujmy na początek napisać prosty program, wpisujący otrzymane zapytanie do pliku/ Utwórzmy więc w katalogu html plik "napis.cgi" z następującą zawartością: #!/usr/bin/env python3 import cgitb, os print("Content-Type: text/plain; charset=UTF-8\n") cgitb.enable(format="text") napis=os.environ.get("QUERY_STRING") if not napis: print ("A gdzie zapytanie?") else: open("dane.txt","w").write(napis) print ("Zapisałem:", napis) Po zmianie uprawnień na 0755 i wpisaniu w przeglądarkę np: http://<ip_malinki>/napis.cgi?Hello powinna ukazać się odpowiedź "Zapisane: Hello", a w pliku html/dane.txt znajdzie się otrzymany napis Dobra - ale przecież wspominałem o jakichś nazwach, wartościach, urlencode... a tymczasem przy próbie wpisania: http://<ip_malinki>/napis.cgi?Cześć, świecie pokazuje się zakodowana treść zapytania, i taka też ląduje w pliku! Powód jest prosty: Python - w przeciwieństwie do PHP - nie ma żadnych superglobali ani innych automagicznych zaklęć będących częścią języka i zajmujących się dekodowaniem tego, co przysłał serwer. To tego służy biblioteka o nazwie - jak łatwo zgadnąć - cgi. Do pobierania i udostępniania w programie parametrów przesłanych do skryptu służy klasa FieldStorage. Zainteresowanych odsyłam do dokumentacji, nas będą interesować jedynie dwie metody: getlist(name) zwracająca listę wszystkich wartości związanych z daną nazwą oraz getfirst(name, default=None) zwracająca pierwszą napotkaną wartość związaną z daną nazwą lub wartość określoną przez parametr default (domyślnie None), jeśli dana nazwa nie wystąpiła w zapytaniu. Przeróbmy nieco nasz skrypt - niech napisem będzie wartość skojarzona z nazwą "tresc": #!/usr/bin/env python3 import cgitb, cgi print("Content-Type: text/plain; charset=UTF-8\n") cgitb.enable(format="text") form = cgi.FieldStorage() napis = form.getfirst("tresc", '').strip() if not napis: print ("A gdzie treść?") else: open("dane.txt","w").write(napis) print ("Zapisałem:", napis) Teraz wysłanie zapytania typu: http://<ip_malinki>/napis.cgi?tresc=Cześć, świecie spowoduje pojawienie się prawidłowej odpowiedzi oraz zapisanie prawidłowego tekstu do pliku. Ponieważ wpisywanie tego typu poleceń do pola adresu przeglądarki nie jest specjalnie wygodne, możemy zrobić prosty formularz, z którego dane będziemy przesyłać do naszego skryptu: #!/usr/bin/env python3 import cgitb, cgi, html print("Content-Type: text/html; charset=UTF-8\n") cgitb.enable(format="html") form = cgi.FieldStorage() napis = form.getfirst("tresc", '').strip() wynik="""<!DOCTYPE html> <html> <head> <title>Prosty formularz</title> </head> <body> %s <form method="post"> <input type="text" name="tresc" value="%s"> <input type="submit"> </form> </body> </html> """ if not napis: komunikat = "A gdzie treść?" else: open("dane.txt","w").write(napis) komunikat = "Zapisałem: "+ napis print(wynik % (html.escape(komunikat), html.escape(napis, True))) Teraz mamy już prawdziwy formularz. Spróbujmy więc przekazać dane do jakiegoś urządzenia podłączonego do naszej malinki. Jako przykład wybrałem popularny wyświetlacz tekstowy LCD 16x2 z interfejsem I2C. Połączenie jest w tym przypadku dużo prostsze, niż było to przy czytniku RFID. Interfejs I2C wymaga podłączenia tylko dwóch przewodów poza zasilaniem. Pamiętać należy, że wyświetlacz wymaga zasilania 5V! A więc układ połączeń jest taki: Pin 2 (+5V) do VCC wyświetlacza Pin 6 (GND) do GND wyświetlacza Pin 3 (SDA1) do SDA wyświetlacza pin 5 (SCL1) do SCL wyświetlacza Spróbujmy najpierw uruchomić wyświetlacz. Ciekawy artykuł na ten temat można znaleźć w serwisie Circuit Basics, ale dla niecierpliwych przygotowałem krótki sposób uruchomienia. Przede wszystkim potrzebny będzie moduł obsługi szyny I2C: sudo apt install python3-smbus Niestety - programu obsługi wyświetlacza w repozytorium nie ma. Na szczęście wspomniany artykuł pokazuje prosty, niewielki moduł który to umożliwia. Moduł wraz z programem demonstracyjnym można ściągnąć z githuba, na wszelki wypadek sam plik RPi_I2C_driver.py dodałem do załącznika. Plik ten należy umieścić w naszym katalogu html wraz z programem. Sprawdźmy najpierw, czy nasz wyświetlacz działa. Napiszemy krótki program (umieśćmy go przykładowo w pliku nasz_program.py): #!/usr/bin/env python3 import RPi_I2C_driver lcd=RPi_I2C_driver.lcd() lcd.lcd_clear() lcd.lcd_display_string_pos("Witaj swiecie!!!",1,0) Po uruchomieniu poleceniem: python3 nasz_program.py wyświetlacz powinien wyświetlić tekst "Witaj swiecie!!!". Co się jednak stanie, jeśli wyświetlacz nie będzie potrafił wyświetlić zadanego napisu? Przeróbmy nieco nasz program, aby można było podawać mu bezpośrednio napis: #!/usr/bin/env python3 import RPi_I2C_driver, sys lcd=RPi_I2C_driver.lcd() lcd.lcd_clear() napis = ' '.join(sys.argv[1:]) lcd.lcd_display_string_pos(napis,1,0) Jeśli teraz wywołamy go z parametrem: python3 nasz_program.py żółć zobaczymy na wyświetlaczu coś, co w żadnym przypadku z żółcią nie ma nic wspólnego... Jak to rozwiązać? Można oczywiście stworzyć własne znaczki i je wyświetlać w miejsce brakujących. Jest to jednak nieco żmudne, poza tym w języku polskim występuje 18 dodatkowych liter, a mamy do dyspozycji tylko 8 możliwości. Najprostszym rozwiązaniem będzie takie przekształcenie tekstu, aby mógł być bez problemu pokazany nawet na wyświetlaczach nie pozwalających na wprowadzanie dodatkowych znaków. Do tego posłuży nam moduł unidecode. Zaczynamy od instalacji, czyli: sudo apt install python3-unidecode Moduł zawiera jedną tylko interesującą nas funkcję unidecode, tak więc nasz program będzie teraz wyglądać następująco: #!/usr/bin/env python3 import RPi_I2C_driver, sys from unidecode import unidecode lcd=RPi_I2C_driver.lcd() lcd.lcd_clear() napis = unidecode(' '.join(sys.argv[1:])) lcd.lcd_display_string_pos(napis,1,0) Po uruchomieniu możemy zobaczyć, że program tym razem zamiast krzaków wyświetla po prostu literki pozbawione znaków diakrytycznych. Teraz możemy już przerobić nasz skrypt tak, aby wpisywane wartości zamiast do pliku wypisywane były na wyświetlaczu: #!/usr/bin/env python3 import cgitb, cgi, html, RPi_I2C_driver from unidecode import unidecode print("Content-Type: text/html; charset=UTF-8\n") cgitb.enable(format="html") form = cgi.FieldStorage() napis = form.getfirst("tresc", '').strip() wynik="""<!DOCTYPE html> <html> <head> <title>Prosty formularz</title> </head> <body> %s <form method="post"> <input type="text" name="tresc" value="%s"> <input type="submit"> </form> </body> </html> """ if not napis: komunikat = "A gdzie treść?" else: napis2 = unidecode(napis) lcd=RPi_I2C_driver.lcd() lcd.lcd_clear() lcd.lcd_display_string_pos(napis2,1,0) komunikat = "Wyświetlam: "+ napis2 print(wynik % (html.escape(komunikat), html.escape(napis, True))) Jak widać, nasz skrypt radzi sobie bez problemu nawet z takimi alfabetami jak chiński czy koreański! Tyle na dziś - następnym razem postaram się pokazać kilka przydatnych (szczególnie dla początkujących) dyrektyw konfiguracyjnych Apacza i spróbuję rozwiązać problem jednoczesnego dostępu do GPIO. W załączniku driver wyświetlacza: driver.tgz
  16. 5 punktów
    Jakiś czas temu pisałem o moich eksperymentach z procesorami retro: wyprodukowanym w Polsce MCY7880 oraz kultowym 6502. Ostatnio wpadło mi do rąk kilka sztuk innego starego, ośmiobitowego mikroprocesora - MC6802. Jest to nieco udoskonalona wersja układu 6800 Motoroli. Od swojego poprzednika różni się ona właściwie tylko posiadaniem niewielkiej ilości (128 bajtów) wbudowanej pamięci RAM oraz oraz układem taktującym. Szczególnie ta druga cecha jest sporym udogodnieniem, bo oryginalny 6800 musiał współpracować z osobnym układem, generującym wielofazowy sygnał taktujący. Do 6802 wystarczy podłączyć zwykły rezonator albo oscylator kwarcowy. Procesory mogły skończyć jako kolejny element mojej "kolekcji" zabytkowych części elektronicznych, w pewnym momencie zaczął mi jednak chodzić po głowie pomysł zbudowania w oparciu o nie jakiegoś urządzenia i odpalenia fragmentu choćby najprostszego kodu. Niedługo potem zaczął powstawać prosty "zestaw deweloperski", mający służyć do zabawy z procesorami z lat osiemdziesiątych. Zaprojektowanie podstawowej płytki nie było na szczęście szczególnie trudnym zadaniem i nie musiałem robić tego od postaw - procesory Motoroli pracowały na podobnej Magistrali i posiadają podobny układ wyprowadzeń do układu MOS6502, który wykorzystałem w jednym ze swoich wcześniejszych projektów. Nie są one ze sobą kompatybilne, więc konieczne było wprowadzenie pewnych modyfikacji, szczególnie w układzie zegara i dekodera adresów. Na płytce poza procesorem znajduje się 64kB pamięci RAM, 16kB pamięci EPROM oraz prosty port wyjściowy, za pomocą którego można migać dwiema diodami LED. Sygnały magistrali systemowej, wolne wyjścia dekodera adresów oraz linie portu zostały wprowadzone na złącze IDC, do którego można podpiąć kolejne moduły, pełniące funkcję podobną do arduinowych shieldów. Na chwilę obecną zaprojektowałem jedną taką płytkę, która zawiera: Port szeregowy (MOS6551) Potrójny timer/licznik (MC6840) Zegar czasu rzeczywistego (M6242) Interfejs pecetowej klawiatury AT (8242) Port GPIO (8255) Chyba najtrudniejszym zadaniem nie było tak naprawdę zbudowanie części sprzętowej, ale zdobycie narzędzi pozwalających napisać soft na tę "platformę". Niestety, o ile mi wiadomo nie istnieje żaden kompilator języka C dla rodziny 6800 (w przypadku MOS6502 można korzystać z CC65). Byłem więc skazany na posługiwanie się asemblerem. Jednak i tutaj pojawiły się pewnej problemy - na Githubie znalazłem kod starego asemblera, który dawał się skompilować w gcc. Było to jednak wyjątkowo ograniczone narzędzie, które nie radziło sobie z bardziej złożonymi tabelami czy zbyt długimi komentarzami. Na szczęście trochę później wpadłem na fenomenalny SB-Aseembler i wszystko poszło z górki. Na chwilę obecną układ nie ma żadnych zastosowań praktycznych. Przeprowadziłem za jego pomocą trochę eksperymentów, pomigałem diodami i uruchomiłem wszystkie ze wspomnianych wcześniej peryferiów. Jeśli uda mi się namierzyć odpowiedni interpreter BASIC-a. być może uda mi się z tego zbudować ośmiobitowy komputer w stylu lat osiemdziesiątych. Konieczne będzie tylko dodanie sterownika ekranu i jakiejś pamięci masowej. Ponieważ płytkę podstawową złożyłem w trzech egzemplarzach nie wykluczam, że nadmiarowe w przyszłości wykorzystam do stworzenia jakiegoś urządzenia "embedded", np. robota albo stacji pogodowej.
  17. 5 punktów
    Pięć lata temu miałem termometr avt. Zepsuł się po roku więc kupiłem kolejny, kolejny też się zepsuł. Pół roku temu postanowiłem zrobić termometr na arduino. Termometr cały czas udoskonalam. Obecnie posiada cztery czujniki : jeden czujnik DS18B20, Czujnik wilgotności i temperatury DHT11, Dwa czujniki temperatury i wilgotności DHT22. Pozostałe rzeczy, które użyłem to: Wyświetlaczem 4x20 znaków Konwerterem i2C LCD Moduł RTC DS3231 Koszyk na baterie AA do podtrzymania zegara Dwie baterie AA Czujnik ruchu Arduino uno Początkowo nie wiedziałem jak zapisać godzinę i datę w pamięci modułu RTC więc całość posiadało akumulator 12v 7Ah po to by godzina i data była prawdziwa a nie odczytywana z kodu po podaniu zasilania. Nie posiadał w tedy też czujnika ruchu więc posiadał włącznik, którym włączało się podświetlenie LCD. W tym momencie posiadał tylko trzy czujniki temperatury DS18B20 oraz jeden DHT11. Teraz termometr włącza się gdy ktoś przed nim się poruszy, mierzy temperaturę maksymalną i minimalną z każdego z czujników. Oraz posiada zasilacz 12V 1A. Całość umieściłem w obudowie z sklejki 6 mm pomalowanej szarą farbą. Z przodu znajduje się wyświetlacz, czujnik ruchu oraz dioda informująca że termometr oczekuje na ruch wyłącza się jeśli ktoś przednim się poruszy i włączy się wyświetlacz. Po lewej stronie znajduje się czujnik DHT22 mierzący temperaturę w pokoju. Specjalnie oddaliłem go od obudowy, żeby wynik był jak najbardziej prawidłowy. Na arduino wytrawiłem płytkę moją wytrawiarką do PCB (ma się dobrze i ostatnio dorobiłem do niej pompkę powietrza) są do niej podłączone wszystkie rzeczy. Czujniki które są poza pokojem jeden na zewnątrz DS18B20 i DHT11 drugi na dole DHT22 są podłączone przez złącze RJ45 do arduino. Do modułu RTC na miejsce fabrycznej baterii przylutowałem koszyczek na baterie AA ponieważ zegar na fabrycznej baterii wytrzymał 4 miesiące. Temperatury maks. i min. wyświetliłem na osobnym ekranie. Od lewej Strzałki oznaczają temperaturę minimalną i maksymalną oraz jest ona wyświetlana najpierw minimalna potem maksymalna. Galeria pozostałych ekranów: Dziękuję za przeczytaniem oraz liczę na komentarze.
  18. 5 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).
  19. 4 punkty
    Witam serdecznie wszystkich czytelników Forbota w tym artykule chciałbym opisać projekt, który udało mi się skończyć całkiem niedawno. Mowa o urządzeniu do monitorowania prądów fazowych silników elektrycznych. W kwestii, krótkiego wstępu warto wspomnieć, że silniki elektryczne wykorzystywane są jako jednostki napędowe w znacznej większości maszyn i urządzeń, dlatego niezbędne jest utrzymanie ich w dobrej kondycji w trakcie eksploatacji. Do przeprowadzenia oceny stanu technicznego silników eklektycznych wykorzystuje się m.in. metodę MCSA (ang. Motor Current Signature Analysis), która polega na pozyskaniu informacji o stanie technicznym silnika poprzez analizę widma prądu fazowego stojana. Na tej podstawie możliwe jest wykrycie uszkodzeń zarówno części mechanicznej jak i obwodów elektromagnetycznych silnika. Aby możliwe było przeprowadzenie analizy MCSA należy pozyskać sygnał związany z prądem fazowym silnika. Stało się to motywacją do opracowana ww. urządzenia. Zaprojektowany układ, dedykowany dla silników zarówno jedno jak i trójfazowych, pozwala na pozyskanie informacji o prądzie pobieranym niezależnie przez poszczególne fazy silnika. W tym celu wykorzystano trzy przekładniki prądowe TA28E-00 o przełożeniu 1:50 (max. 5A – 100mA). Zastosowanie przekładników prądowych pozwala na przeniesienie całego spektrum sygnału prądowego na sygnał napięciowy, a także zapewnia izolację galwaniczną pomiędzy stroną wysoko i niskonapięciową. Przykładowy układ przekładnika prądowego przedstawiono na rysunku poniżej. Prąd po stronie wtórnej przekładnika przepływa przez pomiarowy rezystor bocznikowy o rezystancji 1 Ohma. Układ wzmacniacza odwracającego LM324D wzmacnia spadek napięcia na rezystorze pomiarowym, proporcjonalny do przepływającego przez niego prądu. Wzmocnienie układu uzależnione jest od rezystora zamieszczonego w pętli sprzężenia zwrotnego wzmacniacza. Wybór wzmocnienia (x1, x4.7, x10, x47, x100, x500) następuje poprzez wybór odpowiedniej pozycji przełącznika obrotowego GAIN. Następnie za układem wzmacniacza zamieszczono przełącznik bistabilny opisany jako RANGE, umożliwiający wybór zakresu sygnału wyjściowego (±2.5V lub 0-5V). Urządzenie wyposażone jest w 3 tego typu układy. Urządzenie ma możliwość zasilenia układów wewnętrznych bezpośrednio z jednej z faz podłączonych do wejścia trójfazowego 3x400V, zewnętrznego źródła napięcia przemiennego 230V 50Hz oraz napięcia stałego 5V (min. 100mA). Zmiana źródła zasilania dokonywana jest przy pomocy przekaźników. Najwyższy priorytet ma zewnętrzne źródło napięcia stałego 5V. Wynika to z możliwości zasilenia układów ze źródła zasilania bateryjnego (np. power bank). Dzięki temu sygnał wyjściowy pozbawiony jest zakłóceń pochodzących z sieci elektrycznej tj. niskonapięciowe składowe o częstotliwości 50Hz. Podczas zasilania układów elektronicznych ze źródła napięcia przemiennego (z wejścia trójfazowego 3x400V lub zewnętrznego 230V) układy elektroniczne zasilane są poprzez przetwornicę AC/DC 230V-5V. Wejście przetwornicy zabezpieczone jest bezpiecznikiem topikowym oraz warystorem. Zasilacz modułowy widoczny na rysunku powyżej stosowany jest tylko w celu załączenia przekaźnika podczas zasilania urządzenia z sieci elektrycznej 230V. Dzięki wyprowadzeniu sygnałów na złącze goldpin urządzenie może zostać wzbogacone o dodatkowy układ mikroprocesorowy umożliwiający konwersję ADC sygnału napięciowego oraz przesłanie danych drogą bezprzewodową do komputera PC. Układ przetestowano pod kątem komunikacji radiowej oraz sieci WiFi. W pierwszym przypadku wykorzystano moduł NUCLEO STM32F303K8, do którego podłączono moduł radiowy RFM73-D. Do odbioru danych z urządzenia pomiarowego wykorzystano autorskie urządzenie USB z tym samym modułem radiowym (rysunek poniżej). Druga możliwość obejmowała wykorzystanie bezprzewodowej platformy pomiarowej OpenScope MZ. W tym wypadku możliwe było monitorowanie maksymalnie 2 kanałów. Wynikało to z ograniczeń zastosowanego modułu pomiarowego OpenScope MZ. O ile platforma OpenScope umożliwia wygodną prezentację wyników, tak wykorzystanie transmisji radiowej pozwala na dowolne wykorzystanie danych cyfrowych przez dowolny system do analizy danych tj. DASYlab. Dane mogą być importowane na bieżąco przez program i wykorzystywane do dalszych analiz, np. wcześniej wspomnianą techniką MCSA. Podsumowując, urządzenie może znaleźć zastosowanie w monitorowaniu prądów fazowych nie tylko silników elektrycznych, ale również dowolnego urządzenia zasilanego napięciem max. 3x400V oraz pod warunkiem, że poszczególne fazy nie będą obciążone prądem wyższym niż 5A. Urządzenie zostało zaprojektowane pod kątem wielu możliwości zasilania oraz przesyłania sygnałów wyjściowych (analogowo oraz cyfrowo), co umożliwia szerokie spektrum zastosowania w układach służących do precyzyjnych pomiarów i analiz prądów zasilających maszyny i urządzenia różnego typu.
  20. 4 punkty
    Rozesłałem ostatnią turę kodów: @Leoneq - 30 zł + 50 zł w formie dwóch oddzielnych kodów. Odpowiadając na pytanie: niestety nie mam możliwości rozłączenia starych kodów. @RaV - 30 zł, ponieważ Twój wpis był bardziej artykułem niż DIY. Na przyszłość zachęcam do zgłaszania takich prac w ramach konkursów na artykuł. @Danieo - 30 zł, ponieważ konstrukcja jest obecnie na płytce stykowej i nie jest w 100% ukończona. @takinijaki - 2x50 zł + 30 zł (połączone w jeden kod) oraz 1x 50 zł @SquareShox - 50 zł. @okjak - 50 zł. @robo_mat - 50 zł. @Kredek - 50 zł. @Wiktor2019 - 50 zł. @Mortis - 50 zł. @jas123 - 50 zł. @Screw58 - 50 zł. @kloss - 50 zł. @Maciek369 - 50 zł @Vroobee - 50 zł. @wn2001 - 2x 50 zł. @atlantis86 - 3x 50 zł.
  21. 4 punkty
    Drogi Święty Mikołaju już wiesz co chcę pod choinkę .
  22. 3 punkty
    Fajny projekt!!:) Spore możliwości zabawy:) Swego czasu zacząłem coś podobnego (RGB ,WIFI,żyroskop) - Niestety nie ukończyłem - a w sumie tylko oprogramować do końca pozostało:
  23. 3 punkty
    A na przykład: int guzik = HIGH; void loop() { // tu jakieś instrukcje int teraz_guzik = digitalRead(jakiśpin); // albo coś podobnego if (guzik && !teraz_guzik) { // znaczy się ktoś pchał paluchy obsluga_palucha(); } guzik = teraz_guzik; // i tu coś jeszcze co sobie chcesz } Ale prostsze będzie użycie biblioteki Bounce2, gdzie fragment kodu będzie mniej więcej taki: guzik.update(); if (guzik.fell()) { // paluch! obsluga_palucha(); } Bliższe informacje w przykłądach do Bounce2.
  24. 3 punkty
    @jas123 Trzeba znaleźć dokumentacje do tych modułów kamer (niestety mi nie udało się nic ciekawego znaleźć po wpisaniu symboli widocznych na zdjęciu) aby dowiedzieć się jaki interfejs wykorzystują, obawiam się że może to być praktycznie niemożliwe, ponieważ te moduły mogły być produkowane na zamówienie producenta tego telefonu Nawet jeżeli udało by się znaleźć konwerter np. z pasującym złączem, może on nie współpracować z tymi modułami kamer.
  25. 3 punkty
    @Andrzej_Macieja Gdy wejdziesz na stronę https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive-ise.html Po prawej stronie wybierz pozycje ISE Archive, i następnie wybierz interesującą Cię wersje 14,7, a następnie trochę niżej znajdziesz Full Installer for Windows 7/XP/Server(zaznaczony czerwoną ramką na rzucie z ekranu poniżej (co prawda jest dopisek Windows 7 ale MD5 się zgadza :)) Dalsze kroki instalacji znajdziesz w kursie: https://forbot.pl/blog/kurs-fpga-instalacja-srodowiska-ise-xilinx-id16215 Powodzenia!
  26. 3 punkty
    Dla androida jest RaspController znajdziesz tam wiele bardzo pomocnych opcji. Możesz standardowo wpisywać komendy ale jest też GUI dla sterowania wyjściami maliny. Testowałem z arduino-cli działa bezproblemowo ale midnight commander nie działa co i tak nie jest problemem ponieważ w samej aplikacji jest graficzny menedżer plików. Najlepiej zainstaluj i przetestuj.
  27. 3 punkty
    Witam. Widzę, że dawno odpuszczony temat... z nudów (Covid )usiadłem i przewertowałem tutejszy kurs FPGA i poprawiłem YT kanałem LBEbooks w temacie VHDL i skleiłem jakiegoś tam "screen savera" z kodu zawartego w lekcjach tam umieszczonych. Projekt ISE w załaczeniu. A tak to wygląda po skompilowaniu: SSaver.rar
  28. 3 punkty
    Cześć majsterkowicze! Jakiś czas temu zakupiłem konsolę Nintendo Switch, po wielu godzinach frajdy jaką mi dała włączył mi się instynkt majsterkowicza i zrodziła idea zbudowania własnej konsoli. Początkowo rozważałem użycie Raspberry Pi i zbudowanie handheldowego emulatora na Retro Pi. Jednak biorąc pod uwagę, że z zawodu jestem programistą a tam nie miałbym za wiele do "kodzenia" stwierdziłem, że zejdę poziom niżej i spróbuję coś zrobić w oparciu o AtMegę. Zamysł był prosty, stworzyć konsolę na AtMedze z własnym firmware i silnikiem do tworzenia gier a potem zaprogramować na nią jakieś gry. Pod ręką jednak nie miałem żadnego wolnego "odpowiednio mocnego" mikrokontrolera od MicroChipa, więc musiałem się poratować Arduino ProMini z AtMegą 328. Do interakcji z użytkownikiem wykorzystałem TactSwitche (4 jako przyciski kierunkowe, 1 akcji ale rozważam dodanie 2 przycisku akcji aby stworzyć układ znany z klasycznego GameBoya) oraz wyświetlacz OLED 128x64 komunikujący się z Arduino przez I2C. Do tego wszystkiego dołączyłem Buzzer aby dodać efekty dźwiękowe i proste melodyjki Zasilanie całej konsoli odbywałoby się przez stabilizator 7805 z baterii 9V (wiem, że jest niekonieczny przy Arduino ale zostawiłem go na wypadek późniejszej wymiany Arduino na suchą AtMege :D). Poniższy schemat pokazuje nieskomplikowaną budowę konsoli. Jako pierwszą grę stworzyłem klona kultowego Pong ale dla jednego gracza (drugą paletką kieruje sztuczna inteligencja). Kod gry można zobaczyć poniżej: #include <Adafruit_SSD1306.h> #include "engine.h" #define PLAYER_SPEED 50 #define ENEMY_SPEED 80 #define BALL_START_SPEED 40 #define BALL_MAX_SPEED 60 float player_y; float enemy_y; float enemy_movement; unsigned long last_decision; unsigned long last_incrementation; float ball_x; float ball_y; short ball_speed; short ball_motion_x; short ball_motion_y; short player_score; short enemy_score; long currentTime; long oldTime; float deltaTime; void resetBall() { ball_x = 62; ball_y = 30; ball_motion_x = -1; ball_motion_y = 1; ball_speed = BALL_START_SPEED; delay(500); } void gameSetup() { player_y = 22; enemy_y = 22; enemy_movement = 0; player_score = 0; enemy_score = 0; resetBall(); } void gameLoop(short axis_x, short axis_y, bool action) { oldTime = currentTime; currentTime = millis(); deltaTime = (float)(currentTime - oldTime) / 1000; player_y += PLAYER_SPEED * axis_y * deltaTime; enemy_y += ENEMY_SPEED * enemy_movement * deltaTime; // Enemy AI float distance = sqrt(pow(ball_x - 121, 2) + pow(ball_y - enemy_y, 2)); enemy_movement = 0; if (distance > 15 && distance < 100) { if (millis() - last_decision > 50) { if (ball_y > enemy_y + 10) { enemy_movement = 1; } else if (ball_y < enemy_y + 10) { enemy_movement = -1; } last_decision = millis(); } } player_y = constrain(player_y, 0, 44); enemy_y = constrain(enemy_y, 0, 44); // Ball movement ball_x += ball_speed * ball_motion_x * deltaTime; ball_y += ball_speed * ball_motion_y * deltaTime; if (ball_y >= 64 - 4 || ball_y <= 0) { ball_motion_y *= -1; } if (ball_x >= 4 && ball_x <= 7 && ball_motion_x < 0) { if (ball_y > player_y - 4 && ball_y < player_y + 20) { ball_motion_x *= -1; } // Increment ball speed with every successfull bounce if (ball_speed < BALL_MAX_SPEED) { ball_speed++; } } if (ball_x >= 121 && ball_x <= 124 && ball_motion_x > 0) { if (ball_y > enemy_y - 4 && ball_y < enemy_y + 20) { ball_motion_x *= -1; } } // Count score if (ball_x > 128) { player_score += 1; resetBall(); } if (ball_x < 0) { enemy_score += 1; resetBall(); } // Game over condition if (enemy_score > 10) { gameOver(); } // Win condition if (player_score > 10) { playerWins(); } } void gameDraw(Adafruit_SSD1306 display) { display.clearDisplay(); // Draw player display.fillRect(0, player_y, 3, 20, SSD1306_WHITE); // Draw enemy display.fillRect(125, enemy_y, 3, 20, SSD1306_WHITE); // Draw ball display.fillRect(ball_x, ball_y, 4, 4, SSD1306_WHITE); // Draw mid line for (int i = 0; i < 32; i++) { int position = 4 + (4 * (i-1)); display.fillRect(63, position, 2, 2, SSD1306_WHITE); } // Draw score display.setTextColor(SSD1306_WHITE); display.setTextSize(1); display.setCursor(50, 0); display.println(player_score); display.setCursor(72, 0); display.println(enemy_score); display.display(); } Nie jest to "samowystarczalny" kod Arduino, do działania wymaga on jeszcze firmware i silnika do gier, którego ze względu na niedopracowanie nie mogę go teraz pokazać (ale gdy tylko go skończę udostępnię całość na GitHub :D). Kod gry jest banalny. Do grafiki używam biblioteki od AdaFruit. Sztuczną inteligencją kieruje implementacja algorytmu "Chaser" do gry PONG z małymi moimi modyfikacjami (reakcja dopiero w momencie gdy piłka będzie na odpowiednim dystansie oraz opóźnienie reakcji AI aby ją bardziej "uczłowieczyć" i dać jakieś szanse na zwycięstwo graczowi (aczkolwiek i tak z tym cieżko bo czas reakcji bota jest dosyć niski XD, obecnie jest to ok. 50ms. Dla porównania człowiek przeciętnie ma reakcję po ok. 200ms). Gra się kończy gdy jeden z graczy zdobędzie 10 punktów, punkty zdobywamy odbijając piłeczkę tak aby przeciwnik nie mógł jej odbić (gdy piłka "wyleci za paletkę" punkt otrzymuje gracza używający przeciwnej paletki). W silniku brakuje jeszcze wielu rzeczy min. obliczania delta time wewnątrz silnika i przekazywanie wyniku do gry czy bardziej dopracowanego kodu odpowiedzialnego za sterowanie dźwiękiem (w tym prostego "odtwarza" melodyjek zapisanych jako sekwencja dźwięków). Do tego nie ma jeszcze obsługi ekranu końca gry (oraz zwycięstwa) i tak zwane splash screenu przed startem. Jednak gra jest grywalna co można zobaczyć na filmiku na samym dole. Prototyp prezentuje się tak: Jest zbudowany na płytce stykowej (podłączone są na razie tylko dwa przyciski, które są wykorzystywane w grze. Odłączony tak samo jest Buzzer, który na razie odtwarza w pętli trzy dźwięki). W planach jest również stworzenie na drukarce 3D obudowy w tym przeniesienie całego układu na PCB by zrobić z urządzenia pełnoprawną konsole Gdy uda mi się skończyć firmware i silnik w planach mam dalsze wspieranie konsoli tworząc na nią kolejne gry (następne w kolejce są klon Froggera i Tetrisa). Z powodu dodawania kolejnych gier może dojść potrzeba dołączenia dodatkowej pamięci EEPROM lub modułu z kartą SD. (Koncepcja finalnego produktu. Wiem, że artysta ze mnie średni :D) Link do wideo z działaniem konsoli
  29. 3 punkty
    Wymagania Postanowiłem zbudować zegar. O, kolejny projekt zegara, jakich w necie jest setki lub tysiące? No tak właśnie pomyślałem, przecież wśród tysięcy projektów zegara na pewno znajdę odpowiedni dla siebie ale niestety, po kilku dniach szukania dałem sobie spokój, nie ma takiego jak ja chcę. Dlatego rozpisałem wymagania i podzieliłem na obowiązkowe oraz opcjonalne, aby jeszcze raz przemyśleć i poszukać lub zastanowić się nad własnym projektem. Wymagane obowiązkowe: zasilanie akumulatorowe (najlepiej li-ion typu 18650) z okresem działania co najmniej 2 miesiące, dobra widoczność w nocy - wymagane podświetlenie wraz z regulacją jasności świecenia aby w nocy nie rozświetlał połowy pokoju tylko delikatnie się jarzył. duże cyfry min. 4 cm dokładność +/- 1 min/rok. Wymagania opcjonalne: automatyczne przestawianie czasu na letni i zimowy, nie musi pokazywać czasu non stop, wystarczy szybkie włączenie w reakcji na czujnik ruchu. No i niestety żaden projekt który znalazłem nie spełniał wszystkich 4 punktów obowiązkowych. Najczęściej jak w projekcie były duże widoczne wyświetlacze LED to było wymagane zasilanie sieciowe bo nikt się nie przejmował poborem prądu. Pierwsza myśl była taka, że może nie da się tego pogodzić, więc z ciekawości zabrałem się za analizę i weryfikację wymagań. Czy da się technicznie zrobić co spełnia wymagania obowiązkowe? Projekt Wstępne wyliczenia pokazały, że 7 segmentowe wyświetlacze o wielkości 1,8 cala są widoczne w nocy przy prądzie ok. 0,02 mA na segment, całkiem nieźle. Jednak w drugą stronę przy świetle dziennym do wyraźnego widzenia godziny wymagany jest prąd około 5-10 mA na segment no to dużo gorzej. Jednak opierając się o te wyliczenia i dodając czujnik ruchu PIR oraz czujnik oświetlenia zaprojektowałem zegar który powinien spełnić moje wymagania. Centralny mikrokontroler to Atmega88PA, który większość czasu jest uśpiony i pobiera tylko kilkanaście µA. Jako dokładny zegar wykorzystałem gotowy moduł DS3231. Bałem się trochę o prąd pobierany przez czujnik PIR, jednak okazało się, że moduł SR-505 zadowala się tylko ok. 50 µA. Dodatkowo do kontroli ładowania i zabezpieczenia akumulatora użyłem modułu z TP4056. Budowa Po etapie analizy wstępnie mogłem narysować schemat, w sumie prawie standardowy zegar tylko z dwoma obwodami zasilania. Pierwszy obwód o napięciu ok. 3.3V zasila mikrokontroler i pozostałe moduły: zegar i czujnik PIR. Drugi obwód z przetwornicą 5V zasila drivery 74HCT541 i wyświetlacze LED. Do narysowania schematu i projektu PCB użyłem programu KiCad oraz FreeRouting. Oto schemat, zaprojektowana płytka PCB i wizualizacja 3D Niestety już po zleceniu wykonania płytki PCB, eksperymentując z Atmega88PA, doczytałem i sprawdziłem też w praktyce na płytce stykowej, że wykorzystując do sterowania jasnością LED licznik 2 zamiast licznika 0 można znacząco ograniczyć pobór prądu. Sposób polega na generowaniu za pomocą licznika 2 modulacji PWM w której pomiędzy okresami CPU jest uśpiony w trybie SLEEP_MODE_EXT_STANDBY. Dlatego już podczas składania zegara dolutowałem dwa dodatkowe przewody zamieniając piny PD3<->PD5 czyli funkcje OC0B z OC2B, które one pełnią, dzięki temu uzyskałem zmniejszenie poboru prądu podczas wyświetlania godziny. Dodatkowo jeszcze wejścia sterujące jednego z buforów 74HCT541 podłączyłem na stałe do masy co zwolniło jeden z pinów Atmega do ewentualnego wykorzystania w przyszłości. Jeszcze po testach modułów postanowiłem zasilanie modułu DS3231 podłączyć do wyjścia Atmega i włączać zasilanie tego modułu tylko na moment odczytania aktualnego czasu co dodatkowo zredukowało pobierany prąd. Docelowo po uruchomieniu wersji testowej inne zmiany, w porównaniu do pierwszej wersji schematu z której było projektowane PCB, jak na razie nie były wymagane. Będąc przewidujący wyprowadziłem wszystkie mające znaczenie piny mikrokontrolera na kilka portów umożliwiających dolutowanie w przyszłości złącz szpilkowych tzw. goldpiny. Dzięki wyprowadzeniom szpilkowym zaprojektowana płytka PCB może pełnić rolę modułu dużego wyświetlacza LED sterowanego np. z Arduino lub innego zewnętrznego sterownika zasilanego 2,8-5V. Zegar w trakcie lutowania. Uruchomienie Podzieliłem uruchomienie na dwa etapy. W pierwszym przetestowałem obwód 3.3V co pozwoliło znaleźć kilka błędów programowych które uniemożliwiały przejście w tryb SLEEP_MODE_PWR_DOWN. W drugim etapie podłączyłem obwód 5V na razie bez wyświetlaczy LED i tu małe zaskoczenie, same bufory 74HCT541 w stanie włączenie ale bez żadnego obciążenia pobierają prąd kilka mA. Szybki test na płytce stykowej to niestety potwierdził, więc to nie był błąd w programie czy w montażu. Widocznie ten "model tak ma". Zamiana na D74HC541C nie pomogła a wręcz pogorszyła sytuację. No trudno te kilka mA w stanie aktywnym jakoś odżałuję, na szczęście stan wybudzenia to może 1% czasu pracy. Ostatecznie udało się zmniejszyć w trakcie uśpienia zegara pobór prądu do około 80 µA co uważam za sukces całego projektu. Jak się zegar będzie zachowywał i co ile czasu wymagane będzie doładowanie akumulatora okaże się w praktyce. Zdjęcia zmontowanego i uruchomionego zegara. Podsumowanie Ostatecznie udało mi zegar uruchomić i spełnić moje wymagania. Zdjęcie zegara w docelowym miejscu, a właściwie dwóch zegarów bo z rozpędu wykonałem dwie sztuki. Teraz mam jeden używany jako zegar i drugi do testów, rozbudowy i eksperymentów. Rozbudowa w przyszłości Po pewnym okresie użytkowania pojawiły się pomysły na rozbudowę: Bezprzewodowa synchronizacja z dokładnym zewnętrznym zegarem - niestety pierwszego pomysłu aby synchronizować zegar z siecią GPS nie udało mi się zrealizować z powodu słabego sygnału satelitów dostępnego w docelowym miejscu gdzie zegar ma się znajdować. Dlatego zamiast GPS planuję dołożyć moduł Bluetooth Low Energy HM-10 oraz dopisać prostą aplikację na Androida która będzie przesyłąła aktualny czas do modułu. Zatrzymywanie filmu gestem - zegar powstał jako „dodatek” do TV i jako taki sprawdza się doskonale, szczególnie kiedy wieczorem oglądam film i mogę na bieżąco kontrolować godzinę bez odrywania wzroku od ekranu. Jednak zamarzyła mi się opcja włączania pauzy w TV jedynie poprzez zbliżenie ręki od zegara. Zakupiłem już w tym celu moduł APDS9960 i po pierwszych testach wygląda na spełniający wymagania, czas reakcji na zbliżenie ręki na ok. 10cm jest błyskawiczny. Planuję w reakcji na zbliżenie przez dołączoną diodę IR emitować sygnał pilota Play/Pause.
  30. 3 punkty
    Przed ponad rokiem opisywałem jeden ze swoich projektów, którego celem było stworzenie czegoś przypominającego Arduino za pomocą układów scalonych retro. Powstały wtedy dwie płytki - jedna główna, zawierająca większość logiki, druga będąca czymś w rodzaju shielda z wyświetlaczem hd44780 i kilkoma przyciskami. Układ w takiej formie był tylko ciekawostką, pozbawioną praktycznego zastosowania - jedyne co robił, to wyświetlał trochę tekstu i migał diodami. Jakiś czas temu powróciłem jednak do starego pomysłu i zacząłem projektować trzecią płytkę, która dodała bardziej konkretną funkcjonalność. Postanowiłem przenieść na tę niecodzienną platformę jeden z moich starych projektów, a mianowicie sieciowy licznik Geigera (i nie tylko) o nazwie EtherGeiger. Zrobienie licznika Giegera na współczesnym mikrokontrolerze nie jest taki trudne - wszystkie niezbędne podzespoły są już obecne w układzie. Wystarczy tylko dodać przetwornicę wytwarzającą wysokie napięcie dla rurki STS-5 oraz wzmacniacz operacyjny, kierujący odebrane impulsy na wejście licznika. W przypadku techniki retro nic nie jest takie proste. Procesor 6502 nie posiada żadnych zintegrowanych peryferiów - należy je dodać do projektu w formie osobnych układów scalonych, omijając przy tym paru pułapek. Najprościej było z interfejsem UART, który zrealizowałem na popularnym układzie MOS6551, używanym kiedyś powszechnie w komputerach ośmiobitowych. Port szeregowy obecnie wykorzystuję do debugowania, ale docelowo zostanie on wykorzystany do komunikacji poprzez magistralę RS485. Najważniejszy element - licznik - został zaimplementowany za pomocą układu Motorola MC6840. Pojedynczy scalak zawiera tak naprawdę trzy liczniki. Jeden z nich zlicza impulsy z licznika Geigera, drugi pełni funkcję podobną do arduinowej funkcji millis(), trzeci generuje przebiegi o częstotliwości akustycznej, które można wykorzystać do stworzenia prostej sygnalizacji dźwiękowej. W układzie umieszczony został również zegar czasu rzeczywistego z podtrzymywaniem bateryjnym, zrealizowany na układzie M6242, wykorzystywanym kiedyś w kartach rozszerzeń do Amigi. Ostatnim układem jest równoległy port wejścia/wyjścia 8255. Część jego pinów wyprowadziłem na złącze DIN, dzięki czemu w przyszłości będę mógł wygodnie podpiąć inne czujniki, np. temperatury. Pozostałe są dostępne przez dwurzędowe złącze goldpin na płytce. Dodatkowo układ został wyposażony w złącze karty CF. Jest to trochę eksperymentalna funkcja - jeśli wystarczy mi zasobów, spróbuję skompilować bibliotekę FatFS i dopisać kod logujący odczyty w pliku. Jeśli nie. będę musiał popracować nad bardziej oszczędnym systemem plików. Kod został napisany w C i skompilowany za pomocą CC65. Czy urządzenie tego rodzaju tworzy się prościej, niż za pomocą współczesnych platform? Zdecydowanie nie. Takie podejście ma co prawda swoje zalety - fajna jest np. możliwość podpięcia urządzeń do magistrali systemowej i odwoływanie się do nich przez adres w pamięci. Niemniej jest tutaj też całe mnóstwo pułapek, bo np. jakiś układ życzy sobie, aby pewne adresy odczytywać w określonej sekwencji, czego kompilator nie jest świadom i potem trzeba potem poprawiać po nim kod asemblerowy. Muszę jednak przyznać, że tworzenie takich konstrukcji jest całkiem niezłą frajdą, można się też dzięki temu dowiedzieć jak układy mikroprocesorowe działają na nieco niższym poziomie, np. co tak naprawdę dzieje się w momencie uruchomienia programu albo wywołania przerwania. Na poniższych zdjęciach jest widoczny cały układ, w tym także obok współczesnego "brata", zrealizowanego na mikrokontrolerze PIC32.
  31. 3 punkty
    Witam. Od jakiegoś czasu bawię się arduino UNO, które wybrałem ze względu na niską cenę, ale jak również że jest to dobra platforma dla początkujących, którzy zaczynają od prostych projektów do których ATmega 328 nadaje się idealnie, a także na łatwość przenoszenia projektów na zaprojektowane przez nas PCB. Głównie dzięki temu, że procesor ten nie jest na stałe wbudowane w arduino tylko znajduje się w podstawce. Można go łatwo wyjąć i zastosować w naszym projekcie, lub na przykład gdy procesor ten jest uszkodzony, możemy wymienić go na inny działający w naszym arduino. Co więcej nie musi być to koniecznie ATmega328. Tak naprawdę arduino UNO umożliwia nam skorzystanie z takich procesorów jak choćby ATmega8/8A, która co ciekawe była używana w pierwszych wersjach arduino . Środowisko arduino IDE umożliwia nam także wykorzystanie ATmegi168. Aby wykorzystać wymienione procesory w ardunio najpierw musimy do nich wgrać bootloader. Środowisko arduino IDE wspiera te procesory i umożliwia nam wgranie właściwego bootloadera. Z mojego doświadczenia udało mi się grać bootloader do ATmega8A oprócz standardowej ATmegi 328, a także prosty standardowy sketch - blink LED. Tyle tytułem wstępu. Przejdziemy teraz do dalszego opisu dlaczego tak nie inaczej, projekt ten został zrealizowany. Na samym początku wgrywałem bootloader na odpowiednio przygotowanej do tego celu płytce stykowej. Jak wiadomo takie przygotowanie trwa trochę czasu i wymaga cierpliwości aby wszystko było właściwie podłączone. Co więcej czasem zdarzało się, że nie miałem kondensatorów, lub kwarcu bo wcześniej został on już gdzieś wykorzystany w innym projekcie. Także przy takim połączeniu na płytce stykowej zawsze istnieje ryzyko, że któreś połączenie może nie łączyć i w efekcie bootloader nie wgra nam się do procesora, a my będziemy zmuszeni szukać przyczyny zaistniałej sytuacji. Postanowiłem poszukać w internecie modułów do wgrywania bootloaderów do ATmeg dla arduino. Wyniki wyszukiwań są uzależnione od tego co wpiszemy w wyszukiwarce. Wysyp róźnych shieldów czyli nakładek na arduino, ale właściwy shield jak już znalazłem to przeważnie na zagranicznych stronach, ale na polskich stronach co mnie zdziwiło to komunikat: "wycofany ze sprzedaży" lub brak. Z kolei shieldy na zagranicznych stronach rozbudowane o dodatkowe elementy jak buzzer i ledy, które tak naprawdę nie są nam potrzebne. Generalnie cena max do 20 PLN nie uwzględniając kosztów wysyłki. Następną rzeczą jako, że posiadam klon arduino to niezbyt równo polutowane gniazda więc będę musiał się bawić w odpowiednie ukierunkowanie pinów do gniazd aby włożyć shield. Na koniec ostatnia kwestia, że przy takiej ilości pinów gniazda, takie shieldy nieraz ciężej się wyciąga , ale to indywidualna kwestia. Każdy może mieć własne zdanie na ten temat oraz sam fakt, że piny takiego shielda mogą się powykrzywiać w jakieś sytuacji, bo istnieje większe ryzyko, że gdzieś nimi o coś zahaczymy lub spadnie nam na podłogę. Na podstawie powyższych przemyśleń postanowiłem sam zaprojektować programator do bootloader-ów tylko, że nie w postaci schield-u ale normalnej płytki i tylko z podstawowymi elementami, bez których wgranie bootloadera byłoby niemożliwe. Jedyne dodatkowe elementy to dioda LED1 oraz rezystor R2 o tym do czego służą te elementy wyjaśnię później. Poniżej zdjęcia prezentowanego przeze mnie programatora: Mając garść elementów odpowiednio je rozmieściłem na płytce tzn. gęsto, dzięki czemu płytka ma znacznie małe wymiary w stosunku do shieldu, mimo zastosowania elementów THT oraz nie ma tak jak shieldy wystających pinów, co sprawia że łatwo możemy ją przenosić lub schować bez obawy o to, że jakiś pin złącza ulegnie wykrzywieniu. Dzięki opisom na stronie TOP płytki możemy bez problemu podłączyć programator do arduino. Jak widać opisy pinów gniazda programatora, odpowiadają opisom gniazd arduino. Programator ma wykonane nóżki z nylonowych słupków o wysokości 6mm przykręconych śrubą krzyżakową M3. Dzięki temu stoi prosto i stabilnie. Zamiast tego można zastosować gumowe samoprzylepne nóżki co doda-tkowo poprawi kontakt z podłożem i ustabilizuje nam programator. Na poniższym zdjęciu pokazana została płytka samego programatora, a na następnym zaś jak jest ona podłączona do arduino. Do podłączenia użyłem przewodów do połączeń na płytce stykowej. Nic nie stoi na przeszkodzie aby wykonać to jeszcze w inny sposób. Na przykład lutując przewody w miejscu złącza SV1, zaś na końcu tych przewodów dolutowując odpowiednie złącza goldpin, które możemy umieścić w gniazdach arduino. Jeżeli wgrywamy bootloader piny opisane jako Rx oraz Tx pozostają nie podłączone. Dokładny opis jak wgrywać bootloader do ATmegi 8/168/328 przedstawię za jakiś czas w osobnym wpisie. Na koniec jeszcze wyjaśnię dlaczego na złączu SV1 mamy piny Rx, Tx oraz do czego służy obwód złożony z R2 oraz LED1 1 przykład Jeżeli używamy Arduino do programowania ATmeg, czyli wgrywania stworzonego przez siebie sketcha, którą to ATmegę potem znów wyciągamy z arduino aby przełożyć do zapro-jektowanego przez nas urządzenia. Szczególnie często może się to zdarzać początkującym osobom, które muszą poprawiać coś w kodzie programu zanim znajdą lukę, która unie-możliwiała prawidłową pracę zaprojektowanego przez siebie urządzenia. Takie przekładanie ATmegi może być uciążliwe i wyrabia styki podstawki. Ponadto takie podważanie procesora może za którymś razem uszkodzić nam ubudowę podstawki a nawet procesora nie mówiąc już o powykrzywianych lub ułamanych pinach pinach procesora. O ile tę czynność będziemy musieli powtarzać na zaprojektowanym urządzeniu wyeliminujemy ją przynajmniej na arduino. Zawsze to połowę mniejsze ryzyko uszkodzeń i straty czasu. 2. przykład Jeżeli wgrywamy bootloader do dużo większej ilości ATmeg niż ma to miejsce w przypadku osób zajmujących się tym amatorsko, bo być może są osoby które programują procesory do urządzeń, które są potem gdzieś wykorzystywane na większą skale. Warto sprawdzić czy po wgraniu bootloadera jesteśmy w stanie wgrać do procesora prosty sketch. Sprawdzimy w ten sposób czy nasz procesor oprócz wgranego bootloadera-bez niego nie będziemy w stanie wgrać sketcha, uruchamia się. Tutaj wgrywamy sketch z migającą diodą LED. Uwaga: domyślny sketch w arduino-blink nie będzie działać, ze względu na inny port procesora, do którego jest podłączona dioda LED. Wykaz elementów: a) elektronika SV - złącze goldpin żeńskie, 8-pin IC1 - podstawka testowa ZIF28 (228-3341)-wąska C1,C2 - kondensator ceramiczny 22pF/50V C3,C4 - kondensator ceramiczny 100nF/50V Q1 - kwarc 16 MHz* (opcjonalny) R1 - 10k 0,2W R2 - 120R 0,2W LED1 - Zielona 5mm S1 - tact switch 6x6x5mm czarny J1 - kynar, srebrzanka 0.54mm b) mechanika Słupek dystansowy M3 6mm w/w poliamid 4 szt. Śruba walcowa na krzyżak M3x5mm DIN 7985 4 szt. * Programujemy tylko procesory taktowane częstotliwością 16MHz. Należą do nich ATMEGA8/328 ale są też spotykane wersje tych procesorów taktowane częstotliwością 8Mhz. Dlatego jeżeli wiemy jakich procesorów będziemy używać do tworzenia naszych projektów, bądź jakimi obecnie dysponujemy, musimy zamontować kwarc Q1 o odpowiedniej częstotliwości dla danego procesora. Co ciekawe Atmega168 jest taktowana częstotliwością 20 Mhz. Zatem mamy do wyboru kwarc o częstotliwości 8/16/20 MHz Dodatkowe uwagi odnośnie montażu: Użycie innej wersji podstawki ZIF28 niż ta wymieniona w wykazie może skutkować problemem z montażem takich elementów jak R1, Q1, R2, C3. Chodzi o wersję szerszą podstawki. Użyta w projekcie podstawka o numerze 22-3341 - wąska i pod nią zostało zaprojektowane PCB. Elementy LED1 i R2 są opcjonalne. Jeżeli nie będziemy wykorzystywać programatora do wgrywania sketcha testującego, nie ma potrzeby montowania tych elementów. Przedstawiona na zdjęciu płytka programatora w rev.1 co jak widać nie ma na niej kondensatora C4, który dolutowałem od strony BOTTOM programatora. W załączonych do opisywanego projektu plikach, znajduje się uaktualniony rysunek PCB w rev.2, na którym ten kondensator został dodany oraz dodatkowo płytka została jeszcze nieco zminiaturyzowana względem pierwotnej wersji. Oprócz zdjęć urządzenia zamieszczam schemat, rysunki PCB płytki programatora - do wykonania metodą termo transferu, dzięki czemu jak ktoś będzie chciał to będzie mógł go wykonać oraz sketch testowy blink. Wszystkie wyżej opisane pliki umieszczone są w pliku ZIP pod nazwą "bootloaderburn-Rev.2 W następnym poście opisze wgrywanie bootloaderów do ATmeg: 8/168/328 z użyciem wyżej opisanego programatora, wykorzystując do tego arduino UNO. Płytka została zaprojektowana w programie Eagle. Na początku montażu najpierw zacznijmy od montażu zworki J1, która jest kluczowa do zasilania procesora. Zworka ta znajduje się w miejscu gdzie później będzie montowana podstawka do procesorów. Montaż tradycyjnie zaczynamy od najmniejszych elementów, gdzie na końcu montujemy podstawkę pod procesor. Pobierz:bootloaderburn-Rev.2.zip
  32. 3 punkty
    @atMegaTona prosiłem, żebyś powtórzył podstawy języka C (chociaż akurat tutaj jest mój błąd, bo pownniśmy pisać o C++). Ale niezależnie czy to C, czy C++ wskaźniki i tablice to co innego i nie chodzi tutaj tylko o możliwość zmiany wskaźnika. Wszystkich początkujących bardzo proszę o czytanie wypowiedzi kolegi @atMegaTona z zamkniętymi oczami - tablice i wskaźniki to nie to samo, a takie wpisy są tylko przykrym dowodem na to że w internecie znajdziemy mnóstwo bzdur i to jeszcze pisanych jako prawdy objawione A jak już uda się powtórzyć podstawy C oraz C++ to może będzie warto wyjaśnić, czym tablice i wskaźniki się różnią. PS. dla ustalenia uwagi: piszemy o tablicach statycznych, zostawiamy alokowane dynamicznie w spokoju.
  33. 3 punkty
    Na 100% nie - wtedy to byłby "usable box" a nie "useless box"
  34. 3 punkty
    Wow. Naprawdę fajne cuś. Myślałem, że zrobienie usless boxa jest jakoś bardzo skomplikowane, a tu proszę. Propsy Maciek
  35. 3 punkty
  36. 3 punkty
    Witam chciałem przedstawić wam mój projekt który ostatnio zbudowałem jest to prosta ręka robota oparta o 3 serwach sg90 są to proste serva modelarskie pozwalające na precyzyjne ruchy oraz są stosunkowo tanie. do sterowania układem zastosowałem Arduino Uno Rev3 ale może być to każdy inny moduł, w moim projekcje zastosowałem również moduł bluetooth, przydadzą się również płytka stykowa i kable połączeniowe. Dodatkowo postanowiłem wykonać pudełko drewnianych patyczków. Cały projekt przedstawia się następująco: Teraz trochę o podłączeniu Same podłączenie nie powinno stanowić problemu. Trzeba jednak pamiętać, że pin TX na arduino do pinu RX na module bluetooth a RX do TX Uwaga!!! jeśli macie płytkę Arduino Uno musicie podłączyć konwerter napięć gdyż posiada ono informacje na 5V a moduł bluetooth przyjmuje 3,3V ale możecie drobić taki z dwóch rezystorów przestawiony po niżej, ważne by te rezystory wynosiły minimum 10kΩ Dzielnik napięć Schemat projektu Kod projektu #include<Servo.h> // dodajemy bibliotekę do sterowania serwomechanizmem Servo servo; Servo servo2; // twożymy 3 obiekty klasy servo Servo servo3; void setup() { Serial.begin(9600); //rospoczynamy komunikację z prętkością 9600 botów servo.attach(2); servo2.attach(3); servo3.attach(4);// podpisujemy serva pod odpowiednie piny servo3.write(0); // ustawiamy servo 3 do poziomu startowego } char cmd[100]; byte cmdIndex; // przechwytujemy znaki z telefonu void execmd(){ if(cmd[0] =='a') // dla indeksu a wykonujemy poniższe polecenia { unsigned int val = atof(cmd+2); servo.write(val); // w zależności od zmiennej z indeksem a obracamy servem } if(cmd[0] =='b') { unsigned int val = atof(cmd+2); servo2.write(val); } if(cmd[0] =='c') { servo3.write(180); } if(cmd[0] =='d') { servo3.write(0); }} void loop() { if(test==0){ if(Serial.available() >0) { char c =(char)Serial.read(); if (c == '\n') { cmd[cmdIndex]=0; execmd(); cmdIndex=0; }else{ cmd[cmdIndex]=c; if(cmdIndex<99){cmdIndex++;} } } } } Aplikacja Do obsługi ramienia użyłem aplikacji RoboRemoFree jest to darmowa aplikacja ze sklepu play poniżej przesyłam konfigurację tej aplikacji Myślę ze każdy może wykonać taki projekt nie jest to trudne a nauczy nas trochę o samej komunikacji bluetooth z arduino. PS. jest to mój 1 post tutaj więc jeśli ktoś ma jakieś sugestię lub uwagi to był bym wdzięczy z konstruktywną krytykę
  37. 3 punkty
    Po drodze było kilka aktualizacji Między innymi BrainController update (1.2.3) Sign update (1.2.2) - pozwala na wysyłanie na tabliczki wiadomości Credentials update (1.2) - możliwość podłączenia własnego brokera Smart chest update (1.1) - możliwość tworzenia "inteligentnych" skrzynek Po drodze wydałem też bibliotekę do node-red https://github.com/Mineduino/mineduino-nodered-library https://www.npmjs.com/package/node-red-contrib-mineduino https://flows.nodered.org/node/node-red-contrib-mineduino A możliwość sponsorowania projektu jest już na Patreonie! https://www.patreon.com/mineduino Discord: https://discord.gg/4Pkn99R A, pojawiło się też repozytorium z tutorialami i przykładami: https://github.com/Mineduino/tutorialsandexamples Jeszcze puste, ale z czasem będzie pełne!
  38. 3 punkty
    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.
  39. 2 punkty
    Cześć, witam wszystkich. Próbuję swoich sił z mikrokotrolerami, Arduino i malinkami. Widzę w ostatnich postach duże zainteresowanie FPGA, to i może ja kiedyś liznę ten temat
  40. 2 punkty
    Patrząc na ten filmik przypomniało mi się, ze znalazłem ostatnio na Youtube człowieka który budował podobnego 4 nożnego robota (wiadomo że nie jest to ten sam poziom co na filmiku powyżej :D) Oprócz budowy opisuje on również kinematykę i programowanie takiej konstrukcji.
  41. 2 punkty
    Ten "pomarańczowy" to kondensator ceramiczny i również służy do filtrowania zasilania . Kondensatory ceramiczne dobrze radzą sobie z filtrowaniem wysokich częstotliwości a elektrolityczne dobrze filtrują niskie częstotliwości.Dlatego często stosuje się oba rodzaje. Źródło :Kurs elektroniki – #4 – kondensatory, filtrowanie zasilania
  42. 2 punkty
    @Wortan wygląda dobrze ale do czego podłączasz te kabelki? Bo jak biały do masy a czarny i czerwony do pinów sterujących to będzie działać.
  43. 2 punkty
    @ststag Pullup z programem gpio dla RPi4 nie działa poprawnie na niektórych pinach, choć zdecydowana większość funkcji programu działa i się przydaje np. readall. Sam jak piszę jakiś program z wykorzystaniem GPIO to korzystam z kilku programów, gdyż każdy ma swoje mocne strony. Przy kolejnej rewizji kursu zostanie to uwzględnione, a na razie możesz spróbować podziałać z programem pigpio i modułami Pythona np. gpio zero.
  44. 2 punkty
    @deshipu Dziękuję! Jeśli chodzi o programy, to mamy w sumie trzy, dla Nucleo (najważniejszy), RPi 3B+ (system wizyjny) i NodeMCU/ESP8266 (obsługa wyświetlacza): 1. Nucleo było programowane w online'owym środowisku mBED, coś podobnego jak C dla Arduino. Funkcje kinematyki odwrotnej "pożyczyłem" z forum Trossen, gdzie znajduje się genialny artykuł tłumaczący to zagadnienie w ujęciu robotów delta. Następnie jest też funkcja wywołująca ruch silników (biblioteka AccelStepper, niestety ruch odbywa się "na sztywno" - nie potrafię zrobić tego tak, aby np. końcówka płynnie przejechała z punktu A do B w linii prostej ), załączanie/odłączanie elektrozaworów, brzęczyka czy lampy przy kamerce to wiadomo, sterowanie pojedynczymi pinami. Czwarty silnik (ten od stołu), jest sterowany bez akceleracji, cyklicznie zmieniam stan pinu w pętli for, ale to wystarczy. I wspomniane dwa porty szeregowe, jeden łączący Nucleo z RPi (Nucleo wysyła 'q', a RPi w odpowiedzi zwraca ciąg np. 'czb' - czerwony, żółty, biały). Natomiast drugi port, ten od panelu, "nasłuchuje", czy nacisnąłem jakiś przycisk, a podczas ruchów/detekcji kolorów wysyła na NodeMCU (a ten na wyświetlacz) kolory krążków lub koordynaty typu "X100 Y100 Z200\n" 2. RPi ma bibliotekę OpenCV, napisałem prosty programik (Python), który muszę uruchomić ręcznie przez np. VNC - ten z kolei czeka, aż otrzyma literkę 'q' od Nucleo, jeśli tak, robi zdjęcie, wycina ustawione na sztywno fragmenty, liczy średnie R,G i B; a następnie odsyła wspomniany już wyżej ciąg literek symbolizujących kolory 3. NodeMCU, program pisany w Arduino IDE, ma podpięte 4 przyciski (połączone z rezystorami, dzięki czemu do odczytu, który z nich wcisnąłem, wystarczy tylko jeden pin analogowy) oraz wspomniany już wyświetlacz ILI9341, na start wyświetla się ekran powitalny, jeśli wykryje, że coś przychodzi od Nucleo, przełącza się w tryb coś a'la terminal i wypisuje to, co od niego otrzymał (no chyba, że np. jest to literka c, to wtedy zamiast nie wyświetlam czerwone O). Ponadto cyklicznie sprawdzam, czy nie naciśnięto przycisku bezpieczeństwa (ma dwa niezależne styki, jeden NO służący do twardego resetu Nucleo, drugi NC podłączony jest właśnie pod NodeMCU jako przycisk) i ewentualnie wówczas wyświetlam migający czerwony napis "STOP AWARIA"
  45. 2 punkty
    Wow i jeszcze raz wow. Żeś mnie zaimponował w tej chwili. Masz może jakiś kosztorys? Bo zamiast polować na jakiegoś chińczyka sam sobie może coś zbuduję P. S jak się nazywa ta grupka ba discordzie?
  46. 2 punkty
    Układy FPGA wydają się trochę bardziej tajemnicze niż mikrokontrolery. Można jednak dość szybko rozpocząć z nimi przygodę za pomocą narzędzi graficznych. W tutorialu przyjrzymy się układowi z rodziny Max10 znanej firmy Intel. Wykorzystamy go do sterowania silnikiem krokowym. Gotowy prototyp przedstawia Rys. 1. Rys. 1. Zmontowany prototyp. Składamy sprzęt W projekcie wykorzystamy płytkę Rysino z stosunkowo niewielkim układem z rodziny 10M04. Podłączymy do niej silnik krokowy 28BYJ-48 poprzez sterownik zbudowany z wykorzystaniem popularnego układu ULN2003. Nasz silnik składa się z dwóch uzwojeń. Każde z nich ma w połowie wyprowadzony odczep. Kolory z rysunku odpowiadają kolorom przewodów zamontowanych w użytym modelu. Obrót silnika następuje, gdy zmieniamy ich polaryzację poprzez zasilenie złącza +, albo złącza -. W tym projekcie skorzystamy z najprostszego typu sterowania zwanego pełno krokowym. Rys. 2. Stany na cewkach silnika. Rys. 3. Przebiegi czasowe na cewkach silnika. Na Rys. 2. widzimy, że aby obracać silnik musimy po kolei ustawiać cztery różne kombinację napięcia na cewkach. Natomiast Rys. 3. pokazuje jak będą wyglądały przebiegi przedstawione w tabelce. Jeżeli będziemy przechodzić „z góry na dół” nasz silnik będzie wykonywał obroty zgodnie z kierunkiem ruchu zegara. Aby zmienić kierunek obrotu wystarczy przełączać stany w przeciwnym kierunku. Pojawia się tu słowo klucz: stan, które pozwoli nam wybrać sposób implementacji sterownika. Zbudujemy maszynę stanów. Ale najpierw podłączmy silnik do układu FPGA. Schemat połączenia pokazuje Rys. 4. To jego wykonania potrzebujemy przewodów połączeniowych. Rys. 4. Sposób połączenia płytki Rysino z sterownikiem silnika. Wsad dla układu FPGA Aby zbudować wsad dla układu FGPA potrzebujemy zintegrowane środowisko dostarczone przez producenta. Najpierw musimy jednak się zarejestrować. Następnie ze strony producenta pobieramy środowisko Quartus Prime Lite Edition. Ja korzystałem z wersji 18.1. Pobieramy: Quartus Prime (includes Nios II EDS) (1.7GB) MAX 10 FPGA device support. (330MB) Jak widzimy niestety są to dość duże pliki... Po instalacji możemy przejść do tworzenia projektu. Przygotujemy go w całości w narzędziach graficznych. Składa się on z dwóch głównych części. Najpierw przygotujemy maszynę stanów, którą widzimy na Rys. 5. Rys. 5. Maszyna stanów. Następnie umieścimy gotową maszynę w projekcie, dołożymy licznik zmniejszający szybkość przełączania stanów oraz wejścia i wyjścia. Gotowy schemat pokazuje Rys. 6. Rys. 6. Diagram gotowego projektu. Jednak opisywanie „wyklikiwania” poszczególnych elementów było by dość zagmatwane, dlatego przygotowałem film, w którym zobaczymy wszystko krok po kroku. A na samym końcu znajdziemy demonstrację działania gotowego projektu. Na końcu pozostaje już tylko podłączenie płytki do komputera za pomocą przewodu miniUSB. Do złącza JTAG podłączamy programator USB Blaster i wgrywamy nasz projekt. Cały projekt jest także dostępny w repozytorium.
  47. 2 punkty
    Przecież ja to od dłuższego czasu próbuję wytłumaczyć tylko wszyscy się uparli na delayMicroseconds(10000) w przerwaniu wywoływanym sto razy na sekundę...
  48. 2 punkty
    To fakt, pierwszy raz widzę boxa na czymś innym niż mikrokontroler @Leoneq - proponuję utrudnienie: palec ma wyskakiwać dopiero po jakimś czasie (gdy już cofnę rękę od wyłącznika). Co Ty na to?
  49. 2 punkty
    @woskod w tym kontekście chodzi zwyczajnie o "pamięć" wyświetlacza. Piny RS, RW oraz E służą do komunikacji z wyświetlaczem, za ich pomocą informujemy sterownik wyświetlacza czy będziemy odczytywać, czy zapisywać dane, czy będzie wysyłać informacje, które mają być wyświetlone, czy jakieś komendy sterujące
  50. 2 punkty
    Nie wnikałem tak bardzo w wyrównywanie stosu na stm32, bo jak chodzi o tak niskopoziomowe programowanie zajmuję się cortex-a, a nie cortex-m. W każdym razie bardzo wątpię, żeby to co próbujesz zrobić było problemem. Przeczytaj sobie chociażby programming manual od stm32f10x: https://www.st.com/resource/en/programming_manual/cd00228163-stm32f10xxx20xxx21xxxl1xxxx-cortexm3-programming-manual-stmicroelectronics.pdf "Unless stack alignment is disabled, the stack frame is aligned to a double-word address. If the STKALIGN bit of the Configuration Control Register (CCR) is set to 1, stack align adjustment is performed during stacking." Czyli jeśli nie wyłączyłeś wyrównywania to działa - a jak nie to zgłoś do ST że mają błąd. Wyrównywanie stosu oczywiście ma sens. Sprzętowo odkładane są rejestry, stos jest wyrównywany do 4, rejestry mają po 4 bajty, więc wszystko jest ok. Problemem jest dopiero kompilator. W przypadku cortex-a procedura obsługi przerwania jest pisana w asemblerze i wtedy wyrównanie do 4 jest wystarczające. Natomiast w przypadku cortex-m, procedury obsługiwania najczęściej pisze się w C, a kompilator zakłada że stos podczas wywołania jest wyrównany do 8. Jeśli nie jest to wygenerowany kod może działać niepoprawnie. Nie znajdziesz raczej opisów kiedy taki kod powstaje bo to zależy od wszystkiego - wersji kompilatora, bibliotek, ustawień itd. Najmniejsza zmiana i możesz dostać odrobinę inny kod wynikowy, który już będzie działał. Ale żeby wyjaśnić na czym polega problem, wyobraźmy sobie następujący zupełnie sztuczny przykład. Mamy dwie zmienne lokalne, czyli jak wiemy zapisane na stosie, powiedzmy: uint32_t x,y; Teraz kompilator generuje kod odczytu powiedzmy x ldr r0, =<adr_x> Teraz można sobie do tego x pisać, czytać itd. wykorzystując adres zmiennej zapisany w rejestrze r0. Ale jak kod będzie chciał odwołać się do y, to musi obliczyć adres. Pewnie zrobiłby to inaczej, ale załóżmy że na danym systemie najszybciej działają proste operacje bitowe. Skoro kompilator zakłada, że stos jest wyrównywany do 8, więc adres zmiennej x ma najniższe bity równe 0. Mógłby więc wygenerować taki kod: orr r1, r0, #4 Czyli do r1 wpisać (r0 or 4) - to zadziałą poprawnie jeśli x będzie miał adres wyrównany do 8, a po nim będzie y. Ale jeśli stos będzie wyrównany do 4, ten sam kod już zadziała źle. To oczywiście absolutnie sztuczny przykład, ale chodziło mi o pokazanie na czym polega problem - kompilator, albo raczej optymalizator zakłada że stos jest wyrównany do 8. Może więc wygenerować dziwny, ale optymalny kod, który działa tylko wtedy. A jeśli nie będzie wyrównywania to wszystko się posypie.
Tablica liderów jest ustawiona na Warszawa/GMT+02:00
×
×
  • Utwórz nowe...