Skocz do zawartości

Tablica liderów


Popularna zawartość

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

  1. 12 punktów
    Ten artykuł jest tłumaczeniem (za zgodą autora) na język polski artykułu napisanego przez Paula Stoffregena, dostępnego pod adresem: https://www.pjrc.com/how-to-get-tech-help-from-strangers-on-the-internet/. Internetowe fora techniczne mogą być bardzo onieśmielające. Trzy proste zasady mogą znacznie ułatwić ci życie i zwiększyć szansę na uzyskanie pomocy, niezależnie od poziomu twoich umiejętności. Dobre Pierwsze Wrażenie — aby ludzie chcieli ci pomóc, Wyjaśnij Kontekst — aby ludzie zrozumieli czego potrzebujesz, Podaj Szczegóły — aby ludzie mogli ci pomóc, Poziom 1: Aby dostrzegli twój problem, Poziom 2: Aby mogli go powtórzyć. Dobre Pierwsze Wrażenie "Nie ma drugiej szansy na zrobienie pierwszego wrażenia" to ponadczasowe powiedzenie. Obcy ludzie błyskawicznie wyrabiają sobie o tobie opinię zaledwie na podstawie słów, obrazów lub nagrania w twoim komunikacie. Niech te słowa zadziałają! Największy wpływ na ludzką chęć do pomocy ma pokazanie, że sam włożyłeś wysiłek w rozwiązanie problemu. Ale jaki to może być wysiłek jeśli dopiero zaczynasz? Łatwo jest skorzystać z wyszukiwarki internetowej używając słów ze swojego pytania. Wielu ekspertów nie zdaje sobie jednak sprawy jak trudno jest znaleźć zrozumiałą i istotną informację gdy nie zna się właściwej terminologii, lub gdy te same słowa używane są także w niezwiązanych z twoim problemem dziedzinach. Zatem napisanie czego próbowałeś szukać i jakie wyniki są dla ciebie niezrozumiałe lub nie na temat może pomóc doświadczonym ekspertom w zrozumieniu twojej sytuacji. To nie wyniki są tutaj istotne, ale twój osobisty wysiłek. Szczera chęć nauki także zazwyczaj sprawia dobre wrażenie. Nawet parę słów pokaże twoje podejście. Bycie zniecierpliwionym, ale zdecydowanym na naukę na błędach robi dobre wrażenie. Inteligentni ludzie, którzy mogą pomóc, często doceniają szczere i uczciwe postawienie sprawy. Oczywiście jeśli już rozpocząłeś swój projekt i pracujesz nad nim, wspomnij o tym. Albo nawet lepiej, pokaż czego już próbowałeś. Zrzuty ekranu, zdjęcia, a nawet krótkie nagranie mogą doskonale zaprezentować co już zrobiłeś i upiec dwie pieczenie na jednym ogniu, jednocześnie komunikując i robiąc dobre wrażenie. Nawet kilka prostych słów dodanych do pytania, pokazujących że szczerze się starasz i chcesz się uczyć będzie mieć duży wpływ na odpowiedź, jaką otrzymasz. Kontekst Umożliwia Zrozumienie Istoty ludzkie mają niesamowitą umiejętność dogłębnego zrozumienia. Eksperci mogą zastosować swoją ogromną wiedzę do wypracowania twórczych pomysłów rozwiązujących twój problem... pod warunkiem, że będą wiedzieć czego tak naprawdę potrzebujesz. Kluczowe jest wyjaśnienie kontekstu pytania. Co chcesz osiągnąć? Jak twoje pytanie jest z tym związane? Jakie rozwiązanie byłoby dla ciebie idealne? Dlaczego? Kiedy zajmujemy się techniczną stroną zagadnienia, łatwo jest skupić się tylko na bezpośrednim problemie. Pamiętaj, że przyjaźni ludzie o ogromnej wiedzy i doświadczeniu regularnie czytają fora tylko dlatego, że lubią pomagać. Kiedy piszesz swoje pytanie, nie zapomnij opisać kontekstu. To może zmienić odpowiedź z technicznie poprawnej ale całkowicie bezużytecznej informacji, na rzeczywiście przydatną radę. Diabeł Tkwi w Szczegółach Współczesne zagadnienia techniczne często zawierają oszałamiającą ilość szczegółów. Ile informacji powinno zwierać twoje pytanie? Zanim je wyślesz, zastanów się nad tymi dwoma kwestiami: Czy czytelnik będzie mógł zrozumieć istotę twojego problemu? Czy będzie mógł go odtworzyć? Łatwo jest sobie zakpić "był jakiś błąd, ale zamknąłem go bez czytania", ale bądźmy poważni, minimalny poziom detali pozwoli czytelnikom zrozumieć problem. Zrzut ekranu lub dokładna kopia tekstu błędu, plus dokładna informacja o użytym oprogramowaniu, wersjach, sprzęcie oraz przedsięwziętych kroków to absolutna podstawa umożliwiająca czytelnikowi w ogóle dostrzec problem tak, jak ty go widzisz. W idealnej sytuacji ludzie czytający twoje pytanie powinni móc powtórzyć twój problem. Taki poziom szczegółowości nie zawsze jest praktyczny, ale jeśli dostarczysz wystarczająco dużo informacji, to szanse na rozwiązanie problemu znacznie się zwiększają. Pytania na temat programowania powinny zawsze zawierać cały kod źródłowy, a nie tylko wycięte fragmenty. Często problem ukrywa się w subtelnych szczegółach w definicjach zmiennych daleko od właściwego kodu. Doświadczeni programiści wiedzą czego szukać i potrafią dostrzec takie błędy natychmiast, jeśli tylko pokażesz cały swój kod. Nie zapomnij także poinformować jakich dokładnie bibliotek używasz. Zagadnienia dotyczące sprzętu elektronicznego często nie obejdą się bez zdjęć albo szczegółowych schematów połączeń, oraz linków do użytych części, lub ich symboli katalogowych. Nieśmiałość i niechęć do opisywania szczegółów swojego projektu na forum są powszechne. Nie wstydź się! Eksperci czytający forum naprawdę chcą pomóc. Pokaż dość szczegółów, wyjaśnij kontekst i pokaż, że się starasz, a oni z pewnością pomogą. Częste Błędy Fora nie zawsze działają idealnie. Powyższe trzy kroki najczęściej zadziałają, ale należy też pamiętać o kilku powtarzających się błędach: Zbyt Wiele Zgadywania Rozwiązywanie technicznych problemów polega na obserwacji i dedukowaniu przyczyn. Całkowicie normalne jest, że kiedy jesteśmy na tym skupieniu, to piszemy w zasadzie tylko na podejrzewanych przez nas przyczynach, a zapominamy opisać zaobserwowane efekty. Krótka przerwa przed napisaniem pytania często tutaj pomaga. Kiedy piszesz, staraj się myśleć z punktu widzenia czytelnika. Czy na pewno prosisz o pomoc w problemie, czy tylko chcesz, aby potwierdzili to co sam już odgadłeś? Z drugiej strony, opisanie jak doszedłeś do swoich wniosków może pomóc uniknąć niepotrzebnego powtarzania tego samego toku rozumowania. Nie ma idealnej metody. Po prostu pamiętaj, że zbytnie skupianie się na wnioskach może powstrzymać ludzi od pomocy. Dawanie Upustu Frustracji Szczerze mówiąc niektóre problemy są bardzo trudne i niesłychanie irytujące. Kiedy jesteś zły, dawanie upustu emocjom jest całkowicie naturalne. Zanim wyślesz wiadomość na forum, robiąc tak istotne pierwsze wrażenie, przeczytaj ją przynajmniej raz. Pewien poziom emocji jest normalny i może nawet pomocny. Pokazuje, że naprawdę się starasz. Ale strzeż się częstego błędu, gdy twoja wiadomość jest odbierana jako narzekanie a nie prośba o pomoc. Brak Odpowiedzi Nawet w idealnej sytuacji czasem nie dostaniesz odpowiedzi. To może rozczarować i przygnębić. Postaraj nie dać się ponieść tym emocjom i nie domagać się odpowiedzi. Jest lepszy sposób. Wysiłek jest istotny. Jeśli minęły całe dnie lub tygodnie od wysłania pierwszej wiadomości, to zapewne w tym czasie włożyłeś w swój projekt trochę więcej pracy? Nawet jeśli bezowocny, ten wysiłek jest czymś, czym warto się podzielić, aby przyciągnąć ludzi. Zdjęcia lub kod, albo inne efekty twojej pracy mogą bardzo pomóc. Czasem bardzo trudne i szczegółowe pytania pozostają bez odpowiedzi, bo po prostu nikt jej nie zna. Albo nikt nie jest pewien. W tej sytuacji dobrze jest zapytać o opinie albo sugestie w którym kierunku szukać odpowiedzi, aby usprawnić rozmowę. Ponownie, pokazanie wysiłku jest kluczowym czynnikiem zachęcającym ludzi do pomocy. Większość forów zniechęca lub nawet zabrania wysyłania wielokrotnie tej samej wiadomości czy "krospostowania". To prawie nigdy nie działa. Eksperci, którzy regularnie czytają fora — ludzie najbardziej skłonni do pomocy — na pewno to zauważą. Masz tylko jedną szansę na zrobienie dobrego wrażenia. Natomiast po dłuższym czasie bez odpowiedzi, ponowienie pytania, najlepiej z linkiem do poprzedniej wiadomości i dodatkowym wyjaśnieniem, nie musi być źle odebrane. Nierzetelni Uczniowie Na każdym forum zdarzają się leniwi uczniowie domagający się odrobienie za nich pracy domowej. Eksperci czytający fora regularnie są zalewani takimi marnymi pytaniami. Nie chcesz, aby twoje pytanie zostało potraktowane jak spam i zignorowane. Jeśli twój projekt jest robiony w ramach zajęć, to najlepiej jest szczerze się do tego przyznać (oraz do terminów) i upewnić się, że widać jednak twój własny wkład. Rzetelny wysiłek i szczera chęć nauki wyróżniają dobrych uczniów. Zastrzeżone Projekty Kiedy nie możesz podzielić się kodem źródłowym albo innymi szczegółami technicznymi, pomoc na forum rzadko będzie dobra. Zazwyczaj musisz poświęcić dodatkową pracę aby wydzielić problematyczny fragment z reszty projektu, aby móc go opublikować. Jeśli tego nie zrobisz i po prosty spytasz "czy ktoś spotkał się kiedyś z takim problemem", to traktujesz ludzi jak wyszukiwarkę internetową. Czasem może się udać, ale naprawdę trudno jest zgadywać na ślepo rozwiązania trudnych technicznych problemów. Jeśli twój pracodawca lub organizacja kategorycznie nie zgadza się na publikowanie kodu lub szczegółów, niezależnie jak drobnych, być może zamiast szukać darmowej pomocy na forum powinieneś użyć komercyjnych produktów, które zapewniają kontraktowo wsparcie, albo zatrudnić eksperta z firmy konsultingowej. Kiedy Otrzymasz Odpowiedź Najlepszym sposobem na wyrażenie wdzięczności jest wskazanie osoby, która udzieliła poprawnej odpowiedzi. Wielu ekspertów poświęca niezliczone darmowe godziny swojego czasu pomagając obcym na forach tylko dlatego, że lubią pomagać. Bycie docenionym jest miłą nagrodą. Kiedy twój problem jest rozwiązany, pamiętaj, że wielu innych ludzi trafi do tego wątku szukając rozwiązania podobnego problemu jeszcze wiele lat później. Najlepiej więc jest napisać na koniec krótką wiadomość podsumowującą poprawne rozwiązanie. Jeśli pytałeś w wielu miejscach, to wypada teraz odwiedzić każde z nich i podlinkować do wiadomości z odpowiedzią. O Tym Artykule (i Autorze) Przez ostatnie 6 lat odpowiedziałem 18620 razy na forum PJRC i nawet więcej na innych forach. Udało nam się w tym czasie stworzyć całkiem dobrą społeczność i pomóc w projektach wielu tysiącom ludzi. Obserwowałem i próbowałem się nauczyć co działa i jak możemy dokonać ulepszeń. Oczywiste stało się, że wielu ludzi potrzebuje nieco wsparcia w zadawaniu dobrych pytań. Najbardziej liczą się tu nie technikalia, ale subtelne czynniki ludzkie. Mam nadzieję, że wszystkie fora techniczne się poprawią. Proszę podzielcie się tym artykułem. — Paul Stoffregen
  2. 11 punktów
    Większość osób myśląc o cyfrowej telekomunikacji, myśli o współczesne mikroelektronice: smartfonach, komputerach i Internecie. Nie każdy zdaje sobie sprawę z tego, że idea przesylania informacji zakodowanej w ciągach zer i jedynek jest dużo, dużo starsza. Pierwszym urządzeniem tego rodzaju był telegraf skonstruowany przez Emille'a Baudot w latach siedemdziesiątych XIX wieku. Urządzenie po stronie nadajnika posiadało klawiaturę złożoną z pięciu przycisków, które operator musiał wciskać w różnych kombinacjach. Urządzenie wysyłało na linię ciąg impulsów, odpowiadających wciśniętej kombinacji. Odbiornik interpretował ten sygnał drukując na papierowej taśmie odpowiednią literę lub cyfrę, w jej naturalnej formie. Na początku XX wieku idea to została udoskonalona. Nadajnik został wyposażony w klawiaturę podobną do tych stosowanych w maszynach do pisania. Tak narodził się dalekopis. Transmisja danych pomiędzy tymi urządzeniami przypominała standardowy interfejs szeregowy. Z tą różnicą, że z przeciwieństwie do TTL UART-a czy RS323 poszczególne stany logiczne nie były kodowane przez wartości napięć, ale przez fakt przepływu (bądź nie) prądu w obwodzie. Normalnie przez linię płynął prąd o ustalonej wartości (zazwyczaj 60, 40 lub 20 mA). To był stan domyślny. Rozpoczęcie nadawania kolejnego znaku wymagało nadania bitu startu, czyli chwilowego przerwania obwodu. Potem nadajnik oczekiwał na pięć bitów z kodem znaku w alfabecie Baudot (zwanym także międzynarodowym alfabetem telegraficznym). Na końcu pojawiały się bity stopu w trakcie których odebrany znak był drukowany na papierze. Ktoś zapewne zauważył już, że używając pięciu bitów można było zakodować maksymalnie 32 znaki - zdecydowanie za mało, aby pomieścić wszystkie litery alfabetu, cyfry i znaki interpunkcyjne. To prawda. Stosowano pewną sztuczkę - dwie kombinacje bitów były zarezerwowane do przełączana pomiędzy dwoma rejestrami zawierającymi litery oraz cyfry i inne znaki. Ne stosowano także rozróżnienia na male i duże litery. Dalekopis chociaż w pełni cyfrowy, był urządzeniem elektromechanicznym, radzącym sobie bez pojedynczego tranzystora (chociaż oczywiście w latach osiemdziesiątych i dziewięćdziesiątych produkowano nowoczesne, elektroniczne wersje). Dalekopisy były powszechnie używane do przesyłania wiadomości przez wojsko i państwowe służby. Poczta wykorzystywała je do transmisji telegramów. Stosowano je także w roli terminali komputerowych, przed pojawieniem się monitorów CRT. Ślad tej zaszłości historycznej zachował się w nomenklaturze stosowanej w systemach uniksowych, gdzie terminal jest oznaczany skrótem TTY - od angielskiego słowa "teletype", czyli właśnie dalekopis. Przepraszam za ten przydługi wstęp, nie byłem jednak pewien, czy wszyscy będą jeszcze kojarzyć o jakie urządzenie chodzi... Przechodząc do sedna sprawy. Na co dzień pracuję w krakowskim Muzeum Inżynierii Miejskiej. Jakiś czas temu został nam przekazany dalekopis T100, wyprodukowany w latach siedemdziesiątych w Czechoslowacji, na licencji Siemensa. Ponieważ posiadaliśmy już taki eksponat, zostałem poproszony o sprawdzenie możliwości uruchomienia go i wykorzystywania w roli interaktywnej instalacji, zamiast "martwego" eksponatu ukrytego w muzealnej gablocie. Tak rozpoczęły się moje eksperymenty. Najpierw skonstruowałem prosty interfejs USB, oparty na starym mikrokontrolerze AT89C2051 i układzie FTDI. Do generowania pętli prądowej 40 mA używałem zestawu kilku baterii 9V oraz rezystorów o dużej mocy. Komunikacja z dalekopisem ruszyła bez problemu - pojawiła się jednak inna trudność. Okazało się, że uszkodzony jest moduł wzywaka - urządzenia odpowiedzialnego m.in. za zdalne włączanie silnika dalekopisu przy połączeniu przychodzącym, sygnalizowanym odwróceniem kierunku przepływu prądu w linii. Naprawa tego modułu okazała się bardziej skomplikowana niż początkowo sądziłem, ostatecznie postanowiłem więc wymontować wadliwą część i sterować silnikiem za pomocą przekaźnika, zamontowanego w moim interfejsie. Finalna wersja interfejsu zawiera mikrokontroler PIC32MX270F256B oraz moduł GSM SIM800L. Wykorzystałem także 2MB pamięć SPI flash, do wykonywania elektronicznej kopii przychodzących wiadomości. W osobnej obudowie znajduje się generator pętli prądowej, złożony z zasilacza transformatorowego oraz zestawu kondensatorów dużej mocy. Całość można obecnie oglądać na wystawie "Uwaga! Nieprzyjaciel podsłuchuje." w Muzeum Inżynierii Miejskiej w Krakowie. Po wysłaniu SMS-a na podany numer można oglądać dalekopis podczas pracy.
  3. 11 punktów
    Witam serdecznie Pragnę zaprezentować mój zdalnie sterowany pojazd o wdzięcznej nazwie Przebiegły Tyran Podstępności Konstrukcja powstawała przez 5 miesięcy. Zbudowana jest głównie ze stali i aluminium. Pojazd waży 24 kg i ma 60 cm długości. Prędkość maksymalna to około 15-20 km/h. Konstrukcja nie posiada skrętnej osi, skręcanie odbywa się jak w czołgu Każde koło jest napędzane własnym silnikiem z przekładnią z chińskiej wkrętarki. Każdy silnik pobiera bodajże 26A maksymalnie i działa na 12V. Za zasilanie odpowiadają dwa żelowe akumulatory 12V po 10Ah każdy, a także 8 litowo-jonowych akumulatorów 3,7V - 2200 mAh. Silniki są sterowane z Arduino Pro Mini przez mostki zbudowane z tranzystorów mosfet. Na pokładzie znajduje się także drugie Arduino gdyż zabrakło mi pinów na wszystkie podzespoły Komunikacje z trzecim Arduino będącym pilotem zapewniają moduły radiowe HC-11 433MHz. Oświetlenie przednie zapewniają 2 LEDY 1-watowe, 2 LEDY 3-watowe i 2 halogeny po 35W. Tylne oświetlenie to cztery 1-watowe czerwone LEDY. Na dachu znajduję się odsuwana klapa zasłaniająca wyrzutnie rakiet. Otwiera się dzięki gwintowanemu prętowi zamocowanemu na osi silnika i nakrętce przytwierdzonej do ruchomej części. Wyrzutnia rakiet zmienia kąt strzału dzięki serwu. Mieści 6 pocisków. Odpalanie działa tak że każda rakieta ma wokół lontu owinięty cienki drucik, dwa końce drucika są połączone z akumulatorem poprzez przekaźnik. Gdy przełącze przekaźnik, prąd przepala drucik i następuje zapłon. Każda rakieta ma swój własny przekaźnik więc mogą być odpalane niezależnie.
  4. 9 punktów
    Od momentu poznania ESP8266 bardzo spodobał mi się ten układ. Gdy skończyłem robić pierwszy projekt oparty na tym układzie od razu zacząłem wymyślać kolejny. Dzisiaj chciałbym Wam przedstawić sterownik oświetlenia. Współpracuje on ze zwykłym włącznikiem świecznikowym i mieści się w puszce fi60, dzięki czemu (nad każdym włącznikiem światła mam puszkę fi70) w puszcze fi70 zostaje jeszcze sporo miejsca na kable. Po zaprojektowaniu płytki w programie Eagle zleciłem wyprodukowanie jej firmie jlcpcb. Wszystko trwało tydzień (zamawiałem również inne płytki dlatego tyle to trwało ). Płytki wysłali w piątek po południu czasu lokalnego a w poniedziałek płaciłem już vat u kuriera z DHL . Płytki wyglądają bardzo dobrze (sami możecie ocenić jakość produktu ) Po odebraniu płytek zacząłem wszystko składać w całość. ESP8266 12F zostało wykorzystane jako "mózg" płytki. Jako zasilacz służy Hi-Link HLK-PM01 230V na 5V. Za załączenie napięcia odpowiedzialne są dwa przekaźniki z cewką na 5V. Dodatkowo do każdego przekaźnika dołożyłem diodę prostowniczą. ESP jest zasilane napięciem 3.3v przez co musiałem zastosować LDO. Dodatkowo na wejściu fazy do układu zamontowałem bezpiecznik firmy bel fuse. Żeby esp mogło załączać przekaźnik musiałem wykorzystać tranzystor bc817 w wersji smd. Do tego potrzebowałem jedno złącze ark raster 5mm podwójne, oraz dwa złącza ark raster 5mm potrójne. Całość po zlutowaniu i umieszczeniu w puszcze fi60 wygląda następująco: Teraz przyszła kolej na oprogramowanie. Zdecydowałem się zrobić prostą stronę konfiguracyjną na której możemy: zmienić hasło do urządzenia zmienić dane serwera mqtt (sterowanie z każdego miejsca na świecie ) zmienić przyłączenie do sieci wi-fi zobaczyć jak długo pracuje nasz układ wybrać ilość podpiętych włączników (jedno albo dwa) Całość jest również sterowana z telefonu z systemem android. Teraz przymierzam się do zrobienia wersji v2 tego sterownika, chcę by był oparty na triakach i optotriakach (z tego co wyliczyłem to żarówka led o mocy 15W pobiera tylko 60mA a świeci jak zwykła żarówka 120W) oraz będzie posiadała wsparcie dla dotykowych podświetlanych włączników (moduły httm oraz panele marki weilak, wszystko mam tylko projekt został ) Jestem bardzo ciekaw Waszych opinii, dajcie znać w komentarzach co myślicie mo jej konstrukcji
  5. 9 punktów
    Już na samym początku prosiłem o to, aby darować sobie zgryźliwości. Jeszcze raz ponawiam moją prośbę i obiecuję od teraz usuwać wszelkie posty, które będą miały nawet jedno złośliwe zdanie. Niezależnie od tego czy autorem będzie nowa osoba, czy użytkownik, który ma na koncie 100 tysięcy postów - każdego obowiązują takie same zasady. To, że opisywany projekt jest częściowo reklamą tego projektu jest chyba oczywiste - wystarczy poświęcić kilka sekund i obejrzeć filmy, które są w pierwszym poście. Nie przypominam sobie, aby gdzieś był zakaz publikacji tego typu opisów. Nie jest to produkcja masowa, nie widzę więc powodu, aby od razu "rzucać" się na autora i krytykować za wszystko co możliwe. Czym taki projekt różni się od innych DIY, w których autorzy nie podają dokładnej instrukcji budowy i nie dzielą się projektami? Moim zdaniem niczym. Ten projekt wypada nawet lepiej, bo jak ktoś będzie bardzo chciał to sobie chociaż może kupić takie urządzenie. Prawie nikt nie zadał konkretnych pytań technicznych, pojawiały się tylko różne uwagi "byle udowodnić, że projekt jest zły". Autor próbował Wam wszystko wyjaśnić, wstawiał zdjęcia i filmy, a dla Was nadal jest źle. Rozumiem, że komuś projekt może się nie podobać, wystarczy raz wyrazić swoje zdanie lub zignorować temat. Jak widać po głosach czytelników, raportach oraz otrzymanych przeze mnie wiadomościach jest sporo osób, którym ten projekt się zwyczajnie podoba. Proszę więc wszystkich krytyków, aby wzięli pod uwagę, że nie każdy musi się z Wami zgadzać, niektórym taki projekt się podoba i tyle. Nie musicie na siłę wszystkich przekonywać, że jest źle i atakować ciągle autora. Projekt ten zaakceptowałem świadomie i widziałem, że jest to częściowo reklama. Uznałem jednak, że projekt jest ciekawy, nie było u nas opisu takiej maszynki. Liczyłem więc, że takie DIY może być dla wielu osób ciekawą inspiracją. Autor nie jest pierwszą osobą na świecie, która zrobiła takie urządzenie. W Internecie jest sporo maszynek do ręcznej produkcji filamentu. Jak ktoś będzie chciał to wykona urządzenie samodzielnie. To czy jest sens sprzedawać taka maszynkę to już zweryfikuje rynek - jak będą klienci to będzie sens, a jak nie będzie zainteresowanych to trudno, przynajmniej ktoś próbował. Dziwie się osobom, które poświęcają tyle czasu na pisanie krytyki i szukanie zaczepek. Ciężko mi uwierzyć, że liczą one na merytoryczną dyskusje. Nie macie ciekawszych zajęć od krytykowania projektów? Jeśli macie gorszy dzień lub nadmiar energii to proponuje skupić się na chwaleniu DIY, które według Was są ciekawe. Sprawdźcie listę opisanych projektów, znajdźcie coś ciekawego i napiszcie autorowi, że robi dobrą robotę. Nie widzę wielu postów, które chwaliłyby ciekawe DIY - tak ciężko napisać komuś dobre słowo? Jeszcze raz apeluję o ograniczenia zgryźliwość, a wszystkim będzie przyjemniej czytać posty i więcej osób będzie chętnie brało udział w dyskusjach. Zachęcam również osoby, które nie zgadzają się z takimi złośliwościami, aby wyrażały to jakoś publicznie (np. przez posty lub reakcje). Oczywiście doceniam raporty i PW kierowane do mnie, ale może jednak byłoby dobrze, aby autorzy takich wiadomości widzieli, że to "nie są tylko moje wymysły", a jest wiele osób, którym taki ton dyskusji zwyczajnie nie odpowiada.
  6. 9 punktów
    Cześć! Powoli zauważam, że roboty tego typu zaczynają wymierać i odchodząc na lf-ową "emeryturkę" chciałbym zostawić jakiś ślad po swoim projekcie. Choć na zawodach nigdy nie szczędzę informacji na temat swojego robota i chętnie dzielę się wiedzą oraz doświadczeniem w temacie, to mam wrażenie, że ilość lepszych robotów w konkurencji nie zwiększa się, a nawet spada. Na zawodach starzy bywalce ścigają się między sobą, a młodzi pewnie zniechęcają się do konkurencji, ze względu na wysoki próg wejścia do walki o nagrody. Cukiereczek - LineFollower bez turbiny (Nazwa nawiązuje do mojej poprzedniej konstrukcji - Candy). Jest to robot, którego zbudowałem w ramach pracy przejściowej magisterskiej między styczniem a marcem 2018r. Debiutował na zawodach Robomaticon 2018 w Warszawie, gdzie zajął 3 miejsce, zaraz za Candy (zabrakło czasu na napisanie sensownego programu). Później rozwijane było oprogramowanie, które zostało tematem pracy dyplomowej. Wydaje mi się, że jest to obecnie najszybszy robot w swojej kategorii w Polsce, aczkolwiek scena LF od 2018r. mocno się uszczupliła - być może o potencjalnie szybszą konstrukcję. Główne cechy: 12 czujników linii Mikrokontroler STM32 F7 IMU: żyroskop + akcelerometr RGB Lidar ToF USB karta µSD Bluetooth 4.2 Własny mostek H Enkodery magnetyczne 1. Konstrukcja mechaniczna Wydaje mi się, że kształtem przypomina robota Fuzzy, którym swego czasu mocno się inspirowałem przy robocie Candy. Mam nadzieję, że nikt tutaj nie uzna robota za bezpośrednią kopię - kształt jest zdecydowanie inny, podyktowany konkretnymi założeniami i doświadczeniami z poprzednich konstrukcji. Podwozie stanowią 2 moduły PCB: płytki głównej oraz płytki z czujnikami linii, połączone ze sobą taśmą FFC i usztywnione węglową listewką modelarską. Ślizg przedniej listewki zapewniają 2 ścięte łby nylonowych śrubek, z doklejoną podkładką teflonową. Z tyłu robota doklejony jest wheelie bar, w postaci kawałka listewki węglowej ze śrubką oraz teflonem. Wielokrotnie przerobiony temat - gdyby nie podpórka, robot wywracałby się do góry dołem oraz podskakiwał na każdym zakręcie. Napęd: 2 silniki szczotkowe Pololu HPCB 10:1 z obustronnym wałem, na który nałożono magnes 6x2.5 do enkodera magnetycznego. Koła to felgi wydrukowane na drukarce 3D z oponami Mini- Z. Nie dają takiej przyczepności jak poliuretan, ale nie udało mi się dobrać lepszych kół przy samodzielnym odlewaniu. Silniki zostały odrobinę podniesione podkładkami z PCB o grubości 1mm oraz kauczukiem tłumiącym wibracje. Do ich montażu wykorzystałem standardowe, plastikowe mocowania Pololu. Waga konstrukcji to 55.5g (66g z akumulatorem). Nie była priorytetem. 2. Elektronika Wszystkie płytki PCB zostały wykonane w firmie Techno Service z Gdańska. Płytka główna oraz płytka z czujnikami to płytki 4-warstwowe, pozostałe: płytki enkoderów oraz płytka IMU, 2-warstwowe. Schemat oraz layout stworzyłem w programie Altium Designer. Robot może być zasilany z akumulatora li-po 2-4S (6-17V) lub bezpośrednio z USB (bez możliwości uruchomienia silników). Oprócz pomiaru napięcia wejściowego, dodatkowo wstawiono układ pomiaru prądu pobieranego przez robota. Robot startuje obecnie z akumulatorami 2S, 180mAh, 50C. Sekcję zasilania (oprócz sekcji silnikowej) stanowi przetwornica 5V 1A, oraz układy LDO na napięcie 3.3V (osobne dla MCU, sekcji analogowej oraz czujnika IMU). Na płytce czujników znalazło się 12 transoptorów KTIR0711S. Są gęsto ułożone w jednakowych odstępach tworząc delikatny łuk. Zdecydowano się na proste rozwiązanie hardware'owe, dające równomierne odczyty z trasy. Przekombinowany układ czujników mógłby powodować dodatkowe komplikacje (różne odczyty na odsuniętych czujnikach, wpływ nierówności trasy - odległości sensorów od podłoża), więc wszelkie wykrywania dziwnych elementów na trasie realizowane są software'owo. Moduł IMU został zamocowany na padzie kauczukowym tłumiącym wibracje. Użyto sensora Invensense ICM-20602. Jak widać na zdj. poniżej, bardzo poważnie potraktowałem kwestię wibracji, które mają spory wpływ na odczyty. Wykorzystany czujnik posiada wysoką czułość i jest wrażliwy na wibracje i naprężenia. Sensor posiada dedykowaną linię zasilania z oddzielnego LDO o wysokim PSRR. Mostki H zbudowano na układach przekształtnikowych TI DRV8703 oraz tranzystorach N-FET: Toshiba TPWR8503NL. Taki układ mimo, że skonstruowany mocno na wyrost, pozwala na dowolne wysterowanie silnika, w tym zmianę kierunku obrotu bez żadnych dodatkowych opóźnień. Poprzednio stosowane mostki, popularne TB6612 wymagały łączenia kanałów i stosowania opóźnień. Wydajność takiego mostka szacuję na ok. 10A ciągłego prądu (z prądem chwilowym sięgającym +100A), sensownie byłoby lepiej dopasować mostek do wykorzystanych silników, jednak ze względu brak czasu na testowanie i chęć zamknięcia projektu w jednej rewizji PCB, postawiłem na "zero kompromisów". Dodatkowym założeniem była chęć ewentualnej zmiany silników na mocniejsze. Enkodery to AS5047P zamontowane na pionowych płytkach PCB. Podłączone zostały magistralą SPI. Dokonują pomiaru kąta absolutnego, z rozdzielczością 14 bitów. Uwzględniając przekładnię mechaniczną, można uzyskać ponad 160 tysięcy jednostek na obrót koła. Mikrokontroler zastosowany w projekcie to STM32F722 w LQFP64. MCU taktowany jest z częstotliwością 216MHz. Wszystkie piny procesora zostały wykorzystane. Posiada bardzo duży zasób obliczeniowy, znacznie większy od F1, dzięki czemu algorytmy sterujące mogą być skomplikowane i nie trzeba rezygnować z obliczeń na floatach. Karta µSD podłączona została pod SDMMC, na 4-bitowej szynie SDIO. Czujnik odległości to ST VL53L1X, laserowy czujnik Time of Flight, podłączony pod magistralę I2C. Został umieszczony na mocowaniu silnika, w celu uniknięcia dodatkowej bezwładności na listewce robota. Posiada spory zasięg, więc utrata długości z listewki nie jest problemem. Niestety czujnik domyślnie posiada spory field of view, który można odrobinę zmniejszyć tracąc również na zasięgu. Mam z tym czujnikiem sporo problemów. Na zawodach w Rzeszowie wyłapywał patyczki znaków drogowych postawionych przy trasie (inni zawodnicy nie mieli z nimi problemu) oraz bardzo często zdarza mi się, że silnik potrafi zawiesić czujnik podczas przejazdu. Rozwiązania w tej formie nie polecam. 3. Oprogramowanie Przy prowadzeniu projektu wspomagałem się programem CubeMX, a kod pisany był w środowisku Atollic TrueStudio. Poza bibliotekami CubeHAL, z których korzystam, całość własnego kodu została napisana w języku C++. Kod został podzielony na klasy, często wykorzystując przy tym mechanizm dziedziczenia. Użycie C++ pozwoliło wygodnie operować kodem, którego fragmenty wykorzystuję również w innych swoich projektach. Zrezygnowano z wykorzystania RTOSa (FreeRTOS w tym przypadku), ze względu na spory koszt samego OS przy pętlach rzędu 10kHz. STM serii F7 posiada wystarczająco dużo timerów, aby poszczególne zadania podzielić w niezależne pętle z własnym priorytetem. Do obsługi czujników linii, wykorzystano "tylko" 1 przetwornik ADC. Łączenie kilku przetworników w celu uzyskania szybszych pomiarów uznałem za bezcelowe, gdyż prawdopodobnie i tak musiałbym wyzwalać pomiary timerem, aby nadążyć z przetwarzaniem pomiarów. Obecnie pomiary wykonują się z częstotliwością ok. 56kHz i każda próbka brana jest pod uwagę podczas przejazdu. Pozycja linii wyznaczana jest w prosty sposób, przy pomocy średniej z wag przypisanych do każdego czujnika. Wagi czujników są u mnie odrobinę nieliniowe. Osobno rozpatrywane są "przypadki specjalne", gdy pod czujnikami brakuje linii itp. Osobny przetwornik wykorzystano do pomiaru napięcia i prądu. Liczona jest także zużyta pojemność baterii. Pętla sterowania silnikami z regulatorami PID wykonuje się z częstotliwością 8kHz. Nastawy zostały dobrane po części w Matlabie, później dostrojone empirycznie. Pętla żyroskopu również wykonuje się z częstotliwością 8kHz, taktowana jest przerwaniem dataready czujnika. Żyroskop wykorzystuję obecnie do omijania przeszkód oraz w odometrii. Główna pętla - podążania za linią wykonuje się z częstotliwością 400Hz. Sterowanie odbywa się poprzez typowy regulator PD, którego nastawy dobrane zostały metodą prób i błędów, bazując również na poprzedniej konstrukcji - przyspieszony proces. 4. Dodatki Sygnalizacja RGB - Zamiast niezależnych diod LED, wykorzystałem 4 diody WS2812B, które mogłem podłączyć do 1 pinu mikrokontrolera (a zużyłem wszystkie). Na diodach sygnalizowany są stany poszczególnych elementów robota, np. kalibracji żyroskopu, stanu baterii, stanu załączenia silników czy błędu regulatora linii. Interfejs USB - Jedyne złącze użytkowe w robocie. Jako, że interfejs SWD programowania wyprowadziłem w postaci padów do lutowania, "codzienne" programowanie robota odbywało się przez interfejs USB w trybie DFU. Napisany został kod umożliwiający przejście mikrokontrolera do wewnętrznego bootloadera, a następnie wgranie nowego programu. USB służył także do debugowania poprzez port COM. Karta µSD do logowania danych podczas przejazdu. Logowanie odbywa się w tle, w czasie wolnym procesora. Dane zbieram z częstotliwością ~1kHz i zapisuję binarnie w pliku (system FAT32). Logi dostarczyły mi sporo informacji "ukrytych" w robocie i przydały się w pracy magisterskiej. Poniżej przykładowe wykresy dla poboru energii, sterowania, czy utworzonej mapy trasy z uwzględnieniem omijania przeszkody. Aplikacja na smartfon pod moduł BT 4.2. Stosując moduł inny niż HC-05, zmuszony byłem stworzyć własną aplikację smartfonową do zmiany nastaw robota oraz zdalnego startu. 5. Osiągnięcia: 1 miejsce, LineFollower bez turbiny, Robomaticon 2019 w Warszawie , 9 marca 2019 1 miejsce, LineFollower Standard, XI Robotic Arena – Wrocław, 12 stycznia 2019 1 miejsce, LineFollower Enhanc3D, XI Robotic Arena – Wrocław, 12 stycznia 2019 1 miejsce, LineFollower Standard, Bałtyckie Bitwy Robotów w Gdańsku, 26-27 maja 2018 3 miejsce, LineFollower 3D, Bałtyckie Bitwy Robotów w Gdańsku, 26-27 maja 2018 1 miejsce, LineFollower Standard, Zawody ROBO~motion w Rzeszowie, 19 maja 2018 3 miejsce, LineFollower bez turbiny, Robomaticon 2018 w Warszawie, 3 marca 2018 Poniżej kilka filmów:
  7. 9 punktów
    1) Prolog Cześć, dzisiaj opiszę wam mój projekt inżynierski w którym budowałem model autonomicznego pojazdu. W ramach pracy dyplomowej zaprojektowałem uproszczony model autonomicznego pojazdu. Model przystosowany jest do poruszania się w prostym środowisku testowym, symulującym prawdziwe otoczenie. Mój model wyposażony jest w kamerę, pozwalającą na pozyskiwanie informacji o otoczeniu. Obraz z kamery jest źródłem danych dla zaimplementowanej sieci neuronowej, która odpowiada za podejmowanie decyzji o kierunku przemieszczania się pojazdu. Całość pracy zawiera opis poszczególnych etapów tworzenia modelu, projektowanie architektury, implementacje oraz uczenie jednokierunkowych sieci neuronowych do prawidłowego działania. W projekcie użyłem Raspberry Pi, w którym została zaimplementowana sieć neuronowa stworzona w języku Python oraz Arduino odpowiedzialne za sterowanie podzespołami. Rozwiązanie zaproponowane w pracy opiera się szeregu transformacji obrazu za pomocą biblioteki OpenCV w celu ekstrakcji cech tak, aby sieć neuronowa otrzymywała tylko najistotniejsze informacje na podstawie których podejmie decyzje. 2) Wykorzystane elementy: Raspberry Pi B+ (chociaż lepsza była by Raspberry Pi 3b+) Raspberry Pi Cam 8Mpx Lego 42037 Lego Motor M Serwomechanizm SG90 (wymagało modyfikacji) Arduino UNO Rev3 Konwerter poziomów logicznych 2x18650 z rozbiórki laptopów + koszyk L298N - dwukanałowy sterownik silników - moduł 12V/2A 3) Przebieg Prac Praca nie determinowała typu modelu jaki zostanie opisany w pracy a jej głównym celem miało być czy implementacja w prosty sposób funkcji takich jak jazda na wprost, po łuku, skręt czy poruszanie się po okręgu jest możliwa do implementacji wykorzystując sieci neuronowe i wiedzę wyniesioną z toku studiów. W Pierwszej kolejności zrobiłem małe rozeznanie co do możliwości jakie mogłem wybrać i z grubsza można było je podzielić na 2 rodzaje: a) fizyczne - do których zaliczamy np przerobienie realnie istniejącego samochodu osobowego lub modelu pojazdu zdalnie sterowanego RC lub inne tego typu konstrukcje: b) software-owe - w skład których wchodzą takie propozycje jak: dedykowane symulatory, gry komputerowe (symulujemy wtedy klawisze które normalnie naciska gracz) lub własnoręcznie napisane programy do tego celu, np napisane w matlabie lub specjalna "gra" wykorzystana w tym celu. W moim przypadku realizowałem to w pojedynkę i ograniczały mnie dwa aspekty takie jak czas wykonania, koszt który musiał bym ponieść, oraz zasób wiedzy jaki trzeba było by do tego użyć dlatego musiałem znaleźć swojego rodzaju złoty środek którym był fizyczny model (bardziej namacalny) w pomniejszeniu czyli Model RC, ale ze nie posiadam żadnego modelu RC to wykorzystałem zestaw Lego 40237. 4) Hardware Podstawą pojazdu jest już wcześniej wspomniany zestaw Lego 42037 który posiada pewne braki i w tym rozdziale należało zabawkę z lego dostosować do potrzeb projektu. Głównym problemem był brak napędu oraz zdalnego sterowania, o ile z napędem na tylną oś poradziłem sobie bardzo szybko (były już w modelu półosie, dyferencjał i wał) i wystarczyło wstawić w odpowiednie miejsce kilka klocków i silnik Lego M to z układem kierowniczym trzeba było więcej się nagimnastykować. Aby przenie koła wprawić "w ruch" trzeba było znaleźć miejsce na serwomechanizm + zintegrować go z istniejącym układem kierowniczym, dodatkowym problemem był fakt że standardowe serwo ma "wyjście" na orczyk/ wieloklin) al układ kierowniczy lego był zakończony Axlem. Nie chciałem też ingerować i niszczyć klocków dlatego wykonałem nieinwazyjny adapter i skleiłem klejem na gorąco odpowiednio docięty orczyk z klockami które miały otwór na axle. W ten oto sposób nasza podstawa ma wyprowadzone 2 zestawy przewodów - jeden do Silnika napędowego a drugi do serwomechanizmu połączonego z układem napędowym. 5) Elektronika Teraz czas na elektronikę... która jest bardzo prosta bo w zasadzie sygnały sterujące musimy przesłać do 2 komponentów - silnika oraz serwa. W pierwotnym zamyśle było podłączenie bezpośrednio Raspberry Pi do tych 2 komponentów ale wiedziałem że "nie będzie czasu" na generowanie PWM softwareowo dla serwa + dla silnika napędowego dlatego zostało dołożone Arduino które potrafi to robić sprzętowo i odciąży Raspbery Pi od tego zadania. Zyskałem na tym niewielki wzrost skomplikowania elektroniki i oszczędziłem moc obliczeniową w Raspberry Pi. Z kolei silnik napędowy wymagał zastosowania "jakiegoś" mostka H aby nie upalić Raspberry bo wbrew pozorom Silnki z lego potrafią pobierać znaczącą ilość prądu ( więcej info można znaleźć tutaj ) dlatego wybór padł na wcześniej wymieniony gotowy moduł dwukanałowego (zostały zmostkowane oba kanały) mostka H - wystarczy teraz podać tylko odpowiedni sygnał PWM do mostka H i już mamy możliwość płynnej kontroli nad prędkością modelu. Ostatnim etapem było zestawienie komunikacji po porcie szeregowym Arduino z Raspberry Pi za pomocą portu szeregowego i w tym wypadku. Takie połączenie wymaga zastosowania konwertera poziomów logicznych gdyż Raspberry Pi toleruje tylko 3V3 volta a arduino daje 5V - gdyby tego nie było mogło by dojść do uszkodzenia Rarspberry Pi 6) Software I teraz to co tygryski lubią najbardziej - programowanie i tutaj jest podział na 2 części (ale nie mogę wrzucić tutaj kodów źródłowych) a) Arduino Dla Arduino został napisane proste API (ASCII) sterowane przez raspberry - oferowało zestaw prostych funkcji takich jak: - Ustaw silnik na x PWM (zakres 0-255) - Ustaw serwo na x PWM ( 0 - prawo, 90 - prosto, 180 - lewo) - START - Po tej komendzie można było uruchomić pojazd - STOP - powodowała zatrzymanie silnika i ustawienie serwa na 90 stopni (przygotowanie do jazdy na wprost) b) Raspberry Pi Zasada działania tego modelu wykorzystywała sieci neuronowe i nauczanie pod nadzorem nauczyciela ( w skrócie mamy 2 rodzaje uczenia sieci neuronowych - z wykorzystaniem nauczyciela czyli dajemy jakieś dane uczące, potem sprawdzamy na części danych kontrolnych i korygujemy tak długo aż osiągniemy dobre rezultaty i na koniec testujemy na nigdy nie używanych danych, same dane dzielimy w stosunku 4-1-1. Druga opcja to bez nauczyciela i sieć musi nauczyć się sama i jest to o wiele bardziej skomplikowane). Uproszczony schemat działania programu: Aby to działało musimy zaprojektować sieć ( u mnie rozważyłem kilka przypadków) i jest to zależne od ilości wejść i tego co chcemy uzyskać na wyjściu czyli sygnał sterujący w najprostszej wersji może to wykorzystywać kilka neuronów a najbardziej skomplikowane mogą ich mieć dziesiątki tysięcy ( w różnych warstwach) jednak korzystając z Raspbery Pi mamy ograniczą moc obliczeniową i musiałem ułatwić analizę i pracę sieci. Dlatego dokonałem ekstrakcji danych z obrazu i wstępnego przetworzenia w OpenCV gdzie pozyskuje informacje o położeniu linii drogi którą ma podążać: Idąc od lewej - obraz widziany przez kamerę, dalej sektory które obserwujemy aby dokonać analiz "ucieczki linii", trzeci obrazek to binaryzacja i wykrycie gdzie aktualnie znajduje się linia i jak "ucieka" aby można było określić w którą stronę należy skręcić aby jechać prosto. Dzięki temu na wejściu sieci neuronowej podajemy jedynie 2 parametry (położenie lewej i położenie prawej linii) co znacząco ułatwia obliczenia i projekt sieci. Mając te informacje zbieramy dane z przejazdów i zachowania linii podczas konkretnych manewrów np jazda na wprost, po łuku itp. I zapisujemy do pliku - co ważne w tym momencie sterujemy robotem ręcznie i od naszej precyzji sterowania zależeć będa w dużej mierze efekty jakie uzyskamy. Po zebraniu danych możemy przejść dalej. Uczenie sieci: Realizowałem w matlabie i toolboxie z sieciami neuronowymi i tam testowałem jak wyglądają efekty uczenia a następnie eksprtowałem sieć (sieć to tak naprawdę liczby które decydują o "wadze" neuronu poszczególnego) do własnej implementacji w pythonie i testowałem w realu co było pracochłonne. I tak aż do skutku i poprawiałem błędy aż do uzyskania efektu zadowalającego . Na koniec zostały przeprowadzone eksperymenty jak sieć radzi sobie z poszczególnymi testami. 7) Co bym zrobił inaczej W wersji 2.0 lub po prostu gdybym zaczął robić projekt od nowa zmienił bym niestety dosyć dużo widząc jakie braki / niepotrzebne problemy napotkałem na drodze: Rozwiązanie z modelem było dobre - jednak lepiej było do tego celu wykorzystać nie lego a model RC z uwagi na łatwiejszą integrację i o wiele mniejsze luzy w układzie np kierowniczym co generowało duże odchyłki a także dużo większą sztywność konstrukcji i spasowanie. Zastosowanie wydajniejszego SBC np nVidia Jetson lub nawet przenieść to na jakiś iCore desktopowy co zapewni wielokrotnie większą moc obliczeniową Zastosowanie kilku kamer najlepiej czarno białych + doświetlanie IR co pozwoliło by na działanie np o zmroku Wykorzystanie np biblioteki TensorFlow a nie własnej implementacji SN ( skrócenie czasu pisania i eliminiacja ewentualnych błędów z implementacją sieci) Ps. Ciężko opisać wszystkie zagadnienia związane z budową tego modelu w 1-2 kartkach A4 i tak aby nie zanudzić kogoś szczegółami - mam nadzieje że opis nie jest zbyt lakoniczny ale też nie przesadziłem z dokładnością. Może kiedyś powstanie wersja poprawiona to udostępniona szerszy i dokładniejszy opis.
  8. 9 punktów
    Jakiś czas temu w moje ręce trafił dość specyficzny zabytek techniki - układ MCY7880, będący jedynym mikroprocesorem produkowanym seryjnie w Polsce. Element ten był klonem intelowskiego procesora 8080, wytwarzanym przez nieistniejące już przedsiębiorstwo CEMI. Początkowo potraktowałem go jako kolejną elektroniczną ciekawostkę do kolekcji, po jakimś czasie zacząłem się jednak zastanawiać, czy nie będę w stanie wykorzystać go w bardziej konstruktywny sposób. Zacząłem więc gromadzić pozostałe elementy potrzebne do zbudowania prostego systemu mikroprocesorowego, jednocześnie wczytując się w dokumentację i literaturę komputerową z epoki. Właściwa konstrukcja zaczęła powstawać niewiele później. Z uwagi na mocno eksperymentalny charakter przedsięwzięcia zdecydowałem się pominąć etap projektowania PCB i od razu przystąpić do montażu komputera na płytce prototypowej. Najpierw wlutowane zostały podstawki pod układy scalone, potem grubszą srebrzanką poprowadziłem masę i linie zasilające. Należy tutaj nadmienić, że MCY7880 jest dość kłopotliwym procesorem, jeśli chodzi o zasilanie. Nie tylko pobór prądu jest duży jak na obecne standardy, ale także konieczne jest dotarczenie trzech różnych napięć: +12, +5 oraz -5V. Dodatkowo muszą być one podane w odpowiedniej kolejności, niedopełnienie tego obowiązku grozi uszkodzeniem procesora. Oryginalnie systemy mikroprocesorowe na MCY7880 były zasilane z dużych zasilaczy transformatorowych. Była to pierwsza z kilku kwestii, co do których zdecydowałem się na drobny kompromis i zastosowałem nieco uwspółcześnione podejście. I tak napięcie 12V jest generowane przez przetwornicę boost na MC34063A, a -5V jest pobierane z pompy ICL7660. Głowna linia zasilająca o napięciu 5V jest zasilana bezpośrednio ze współczesnego, stabilizowanego zasilacza impulsowego. Po poprowadzeniu masy i zasilania, a także wlutowaniu wszystkich elementów pasywnych, przyszedł czas na najbardziej mozolny etap projektu. Łączenie linii sygnałowych przy pomocy kynaru. Bardzo dużej ilości kynaru. Zajęło mi to kilka wieczorów. O dziwo pomyliłem się tylko raz, zapominając o podciągnięciu jednego z wyprowadzeń EPROM-u do 5V. Po przebadaniu magistrali oscyloskopem i analizatorem stanów logicznych stwierdziłem, że procesor zachowuje się prawidłowo pracując "na luzie" (szyna danych pociągnięta w sposób wymuszający ciągłe wykonywanie instrukcji NOP i zwiększanie licznika instrukcji). Przyszedł więc czas na zaprogramowanie pamięci EPROM. Na potrzeby tego projektu zaopatrzyłem się w chiński programator oraz urządzenie do kasowania tych zabytkowych pamięci. Zapoznałem się także z podstawami asemblera 8080. Pierwszy napisany program służył rzecz jasna do migania diodą podłączoną do znajdującego się na płytce układu 8255. Potem zabrałem się za portowanie TinyBASIC-a, który po jakimś czasie udało mi się odpalić na tym komputerze. Obecnie POLON 7880 może komunikować się ze światem jedynie przez port szeregowy RS232, zrealizowany za pomocą układu 8251 oraz konwertera MAX232. W planach na bliżej nieokreśloną przyszłość jest budowa dodatkowej płytki z interfejsem monitora CRT i klawiatury, a być może także i sterownikiem stacji dyskietek. Pozwoliłoby mi to na uruchomienie systemu operacyjnego CP/M - organizacja pamięci komputera jest do tego przystosowana. Oczywiście najprostszym rozwiązaniem byłoby symulowanie układów I/O za pomocą jakiegoś współczesnego mikrokontrolera, wolałbym jednak wykorzystać w tym celu oryginalne układy scalone z epoki.
  9. 9 punktów
    Witam wszystkich, od mojego ostatniego postu tutaj minęło sporo czasu ale wcale nie porzuciłem robotyki. Jak wszyscy wiemy życie po studiach zaczyna zjadać coraz więcej czasu. Prawie 4 lata temu wrzuciłem tutaj post z moją konstrukcją robota typu delta (Delta Robot). Mam wrażenie, że bardzo fajnie się przyjął i tamta konstrukcja (jak wspominałem 4 lata temu) była prototypem, na którym zaczynałem się uczyć. Cztery lata rozwoju nie tylko mnie ale też dostępnej technologii jak np. druk 3D i mocniejsze mikrokontrolery niż poczciwa Atmega pozwoliły mi rozwinąć skrzydła. Ale przechodząc do meritum, przedstawiam moją następną wersję robota typu delta: Robot składa się w tym momencie z: ramienia, taśmociągu, systemu wizyjnego. systemu generującego podciśnienie 1.Mechanika Do zrobienia tego robota wykorzystałem tyle części z poprzedniej konstrukcji ile się dało. Ale ze względu na postęp techniki i moje większe możliwości finansowe większość przeprojektowałem w SolidWorksie i wydrukowałem na własnej drukarce 3D. Ramiona zamontowane są na podwójnie łożyskowanym wale, który napędzany jest poprzez pasek zębaty, a ten z kolei przez silnik krokowy z zamontowanym 12bitowym enkoderem. Taśmociąg także sam zrobiłem z profilu aluminiowego z Allegro oraz silnika DC z przekładnią. Pas kupiłem z profesjonalnej firmy na zamówienie. Może to brzmi groźnie i drogo ale tak nie jest. Pas kosztował 110 zł brutto. robot posiada 4 osie, dokładnie tak jak poprzednia konstrukcja. 2. Elektronika Najważniejszym układem scalonym jest mikrokontroler TEENSY 3.6 (link) zajmuje się: sterowaniem silnikami krokowymi, obsługą enkoderów silników jak i taśmociągu, komunikacją z komputerem, zapisem programów, punktów oraz wszelkich ustawień na karcie SD Jest to kontroler kompatybilny z bibliotekami Arduino i szczerze dla całego projektu zbawienne było to, że miałem gotowe biblioteki dla wielu rzeczy i nie musiałem się uczyć tego procka wraz z wszystkimi rejestrami, algorytmami zapisu na kartę SD, protokołu SPI oraz obsługi wielu peryferii jak sterowniki silników krokowych (o tym za chwilę) oraz np. ekranu LCD. Mogłem się skupić na moim celu czyli aplikacji, która ma spełniać moje założenia. Dodatkowo w kontrolerze, a także w ramieniu znajdują się: Teensy 3.2 - obsługa ESTOP, IO (wejść/wyjść), obsługa LCD oraz pomost w komunikacji pomiędzy głównym prockiem, a Arduino w ramieniu, Arduino Nano - obsługa PID taśmociągu, sterowanie serwochwytakiem ( kontroler Pololu Maestro), sterowanie pompą podciśnienia oraz elektrozaworem, Arduino Nano - komunikacja z komputerem poprzez zTCP/IP Silniki wyposażone są w enkodery absolutne AMS AS5045, które dostałem za darmo. Robot wyposażony jest w 4 wejścia oraz 4 wyjścia 24V (standard przemysłowy). W celu testowania czy wszystko dobrze działa zrobiłem dodatkowo prosty panel z 4 diodami oraz 4 przyciskami do testowania czy wszystko dobrze działa. Silniki sterowane są poprzez sterownik silników krokowych AMIS-30543 (link), który pozwala na konfiguracje poprzez magistralę SPI, a także na sterowanie z mikrokrokiem x32, które to sterowanie tutaj wykorzystuję. Dodatkowo jak widać na zdjęciach zaprojektowałem oraz zmontowałem (po dostaniu od Satlandu) płytki, które pozwoliły wszystko spiąć ze sobą. Nie będę wrzucał schematu PCB, bo nie jest to nic interesującego. 3. System wizyjny Robot skalibrowany został z systemem wizyjnym OpenMV (link). Kamera została zaprogramowa w języku Python i jej zadaniem jest w zadanym czasie (komunikat wysłany po uart) zrobić zdjecie i zliczyć bloby o odpowiedniej wielkości. Kamera wurzyca po porcie uart dane do mikrokontrolera głównego w postaci NUMER/X/Y/KĄT/ już we współrzędnych robota. Po dostaniu danych do tablicy punktu dodawana jest aktualna pozycja taśmociągu. Dzięki temu robot jest w stanie trafić w detal podczas ruchu taśmy. 4. System sterowania Całość oparta jest na matematyce, mikrokontroler oblicza zadanie proste oraz odwrotne kinematyki (dla pozycji oraz prędkości). W przeciwieństwie do starej konstrukcji układ sterowania naprawdę bierze pod uwagę pozycję oraz prędkość, dzięki temu robot porusza się bardzo płynnie oraz może zachować określoną prędkość liniową punktu TCP (Tool Central Point). Algorytmy pozwalając na poruszanie się w trybach: JOINT - ruch obliczany jest tak, aby każda oś zakończyła pracę w tym samym czasie, LINEAR - ruch lionowy punktu TCP z określoną prędkością liniową, TOOL - ruch liniowy ale zgodny z układem współrzędnych narzędzia CONV - tryb ruchu liniowego z załączonym śledzeniem taśmy, Cały program posiada w tym momencie jakieś 6 tys linijek kodu i pozwala na pracę w trybie automatycznym jak i ręcznym robota. Całość jest napisana w języku C/C++. 5.Program na PC Program napisany w C# w środowisku VisualStudio. Pozwala na: załączenie silników (przekaźnik odcinający na linii 24V), Zwolnienie napędów (enable na sterowniku krokowców) ułatwia ręczne uczenie punktów, Resetowanie błędów, Sterowanie robotem w trybie ręcznym, Uczenie punktów, Edycję ręczną zapisanym punktów na robocie, ustawienie układu TOOL oraz pozycji domowej robota, pisanie prostych programów w skryptowym języku podobnym do BASICA (jestem w trakcie prac) uruchamianie programów w trybie automatycznym, deklarowanie konkretnych działań pod wejścia oraz wyjścia np. cykl start na wejściu 1 podgląd pozycji robota, podgląd IO robota, sterowanie taśmociągiem, zapisywanie oraz sczytywanie ustawień robota oraz punktów z/do pliku na PC po połączeniu z robotem automatyczne sczytanie ustawień oraz punktów z karty SD w kontrolerze. 6.Filmiki Wiem, że to tylko krótki post na temat tego robota i w temacie dla zainteresowanych jest znacznie więcej do opowiedzenia dlatego jak ktoś ma jakieś pytania to zapraszam do komentarzy oraz wiadomości
  10. 8 punktów
    Już słyszę głosy: O, staremu ethanakowi coś się chyba pokręciło... Post jest o jakimś Kedrigernie w dziale DIY - a na zdjęciu mamy coś przypominającego robota z dumnym napisem "Ciapek"... Spieszę z wyjaśnieniami. To nie pomyłka. Post jest na temat serwera mowy Kedrigern, a Ciapek to żaden robot. Po prostu dość trudno zrobić zdjęcie programu, poza tym wypadałoby raczej pokazać ów program w działaniu - a ten wymaga jednak czegoś co będzie gadać (czyli jakiejś bardziej fikuśnej obudowy na głośnik). A ponieważ ostatnio zapatrzyłem się w rysunki Daniela Mroza... cóż, Ciapek z ludzkimi dłońmi, stopami i uszkami wyszedł tak jak wyszedł Zacznę możę od opisu elektroniki (jako że jest to najprostsze, a użytkownik może sobie ją skomponować z zupełnie innych elementów). Sercem całego układu jest Raspberry Pi. Można zastosować dowolny model (chociaż ze starymi, krótkimi GPIO mogą być lekkie problemy), ja użyłem w swoim egzemplarzu Raspberry Pi Zero W. Oprócz tego potzebny jest jakikolwiek układ odtwarzania dźwięku. "Duże" (pełnpowymiarowe) malinki jak popularny 3B+ mają już wyprowadzone wyjście audio, potrzebny jest tylko jakiś niewielki wzmacniacz. Dla wersji Zero potrzebny jest jednak układ zewnętrzny. Prawdopodobnie doskonale spisałby się opisywany ostatnio moduł z wyjściem audio do Raspberry Pi Zero, ja zastosowałem jednak moduł i2s. Jest on dość wygodny w użyciu jako że zawiera w sobie wzmacniacz mono o całkiem sporej (do 3 W) mocy, poza tym początkujący elektronicy nie muszą się martwić o jakieś dziwne masy audio, filtrowane zasilania i tym podobne dziwactwa interesujące tylko "analogowców" - moduł podłącza się pięcioma przewodami do malinki, z drugiej strony dwoma do głośnika i już gra Ponieważ nasz "robocik" musi potrafić poruszać ustami, zastosowałem najprostsze (i najprawdopodobniej najtańsze) rozwiązanie - czyli matrycę LED 8x8 ze sterownikiem, na której rysowane będą kształty ust. Od razu uprzedzę pytanie: owszem, próbowałem zrobić bardziej skomplikowany mechanizm używający serw. Niestety - oprócz trudności mechanicznych (te są do przezwyciężenia) natrafiłem na rzecz, której nie da się przeskoczyć: prędkość serwa. Typowe serwo potrzebuje 0.1 sekundy na przekręcenie orczyka o 60° - a nawet zakładając, że owe 60° wystarczy (w co osobiście wątpię), jest to co najmniej dwa razy za wolno (przy czym owe "dwa" mogłoby się w rzeczywistych układach rozrosnąć do trzech czy czterech). Będę jeszcze próbować rozwiązania z solenoidami - jeśli mi się uda to opublikuję wyniki. Ale może w międzyczasie ktoś inny napisze moduł "solenoid"? Zresztą - chciałem, aby każdy mógł sobie w domu wypróbować Kedrigerna ponosząc jak najmniejsze koszty, a opisywany układ można (mając RPi z wyjściem audio) zmontować kosztem klikunastu złotych (matryca) bez żadnych płytek - po prostu łącząc matrycę przewodami z GPIO malinki. Jako głośnika użyłem leżącego gdzieś w szufladzie zakurzonego głośniczka od starego telefonu z sekretarką, pasować jednak będzie dowolny pod warunkiem dopasowania mocy głośnika do posiadanego wzmacniacza. I to cała wielce skomplikowana elektronika. Jak widać na zdjęciu - nie ma tam nic skomplikowanego. Przejdę więc do opisu programu. Kilka lat temu udało mi się zmusić Mbrolę do w miarę prawidłowego gadania po polsku (do tego stopnia, że można ją było wykorzystać np. do tworzenia audiobooków). System TTS Milena (tak się nazywa ten "zmuszacz" do Mbroli - czyli bardziej fachowo NLP) bardzo dobrze sprawdził się na pecetowym Linuksie, wersja na Windows była raczej ciekawostką ale również działała - postanowiłem więc przystosować ją do malinki. Po przezwyciężeniu pewnych trudności z kompilacją (np. "char" dla architerktury Intel to w GCC domyślnie signed, w ARM z jakichś przyczyn unsigned) okazało się, że co prawda Milena działa, ale "rozruch" ma straszliwie powolny. Nic dziwnego - pliki tekstowe słowników wymowy i translacji fonetycznej muszą być kompilowane przy załadowaniu programu, a malinka ze swoją wolniutką kartą pamięci i nieszczególnie silnym procesorkiem potrzebuje zbyt dużo czasu, zanim wydobędzie z siebie jakieś zdanie. Postanowiłem więc zrobić inaczej: serwer wczytuje wszystkie pliki raz przy starcie systemu, a prosty program klienta przekazuje mu tylko treść komunikatów. Takie rozwiązanie ma również inne zalety: uruchomiony na sockecie TCP serwer może być na zupełnie innej fizycznej maszynie niż klient. I w ten sposób powstał program Kedrigern (nazwany na cześć pewnego czarodzieja, który postanowił odczarować księżniczkę z zaklęcia odbierającego głos). Jak mi to wyszło - oceńcie sami. Oto filmik ukazujący Kedrigerna w działaniu: Nie będę tu rozpisywał się o wszystkich zasadach działania i możliwościach Kedrigerna i Mileny (to w końcu ma byc post na forum a nie książka z dokumentacją), zacznę więc od instalacji Kedrigerna na malince. Wszystkie konieczne komponenty (z wyjątkiem głosu pl1) są w załączonym pliku tgz. Rozpakujmy go w dowolnym katalogu (np. w głównym katalogu użytkownika malinki) i instalujemy mbrolę wraz z polskim głosem: sudo dpkg -i mbrola3.0.1h_armhf.deb sudo apt install mbrola-pl1 Teraz możemy zainstalować Milenę. I tu uwaga: jeśli ktoś miał starszą wersję Mileny niż 0.2.92 musi ją przeinstalować na tę właśnie wersję - inaczej nie będzie działać moduł ruchu ust Kedrigerna! sudo dpkg -i milena*.deb Po zainstalowaniu wszystkiego powinno działać już polecenie milena_say, czyli musimy wypróbować: milena_say dzień dobry kolego I znów uwaga: jeśli wyjściem audio jest HDMI, polecenie może nie działać prawidłowo! Należy spróbować dodać parametr -d opóżniający generację mowy do czasu "załapania" HDMI, czyli najprościej: milena_say -d 2000 dzień dobry kolego Niestety, przy użyciu wyjścia HDMI mogą pojawić się problemy z późniejszym działaniem Kedrigerna, ale po pierwsze nie jest to miejsce na omawianie problemów z audio, po drugie wcale nie czuję się mistrzem w tym zakresie i prawdopodobnie ktoś tu wie lepiej ode mnie jak tym problemom zaradzić. W każdym razie mając uruchomiona Milenę i Mbrolę możemy przystąpić do instalacji Kedrigerna. Zaczynamy od instalacji serwera, czyli sudo dpkg -i kedrigern_0.2.0-1_armhf.deb Jeśli mamy podłąćzoną matrycę LED (8x8, MAX7219) możemy użyć jej jako wyświetlacz ust: sudo dpkg -i kedrigern-matrix_0.2.0-1_armhf.deb No i oczywiście coś co pozwoli nam korzystać z serwera, czyli: sudo dpkg -i libkedrigern_0.1.2-1_armhf.deb Teraz możemy sprawdzić, co potrafi nasz serwer: kedrigern -h lub (jeśli mamy zainstalowany moduł matrix) kedrigern -M matrix -h W odpowiedzi dostaniemy wykaz opcji, z którymi możemy uruchomić serwer. Aby je przetestować, należy otworzyć drugi terminal; w pierwszym uruchamiamy serwer poleceniem "kedrigern" z różnymi opcjami, w drugim testujemy poleceniem kdr-say. Po ustaleniu opcji należy zedytować plik /etc/default/kedrigern i w nim ustawić domyślne parametry. Po przetestowaniu poleceniem kedrigern -C /etc/default/kedrigern możemy już uruchomić nasz serwer w tle: sudo systemctl start kedrigern Jeśli chcemy, aby serwer startował od razu przy starcie systemu, należy wydać polecenie: sudo systemctl enable kedrigern Do komunikacji z serwerem służą polecenia kdr-say, kdr-stop i kdr-speaking. Moduł matrix pozwala na wyświetlanie ust zsynchronizowane z głosem syntezatora. Oto przykładowe obrazy ust dla różnych fonemów: Fonem A Fonem I Fonem O Fonem U Fonemy M, P i B Wybrałem do pokazania kilka najbardziej charakterystycznych kształtów. Jeśli komuś nie odpowiadają stworzone przeze mnie kształty może w prosty sposób dorobić własne lub poprawić moje na bazie pliku /usr/share/kedrigern/demo.shape i podłączyć go do Kedrigerna, np. za pomocą opcji "-m matrix:shape" lub wprowadzając odpowiednie zmiany w pliku konfiguracyjnym. Protokół komunikacyjny jest bardzo prosty. Nie wnikając w szczegóły - załączony moduł w Pythonie (działa w wersji 2 i 3 Pythona) pozwala na sterowanie serwerem, a jednocześnie stanowi przykład sposobu komunikacji. I to wszystko... A nie, nie wszystko. Bo zaraz ktoś powie że to tylko zabawka, że komu potrzebne gadające roboty... Przede wszystkim: Kedrigern może generować komunikaty diagnostyczne w czasie testowania/programowania robota. Jakie to ma znacze nie nie muszę chyba mówić nikomu, kto choć raz ustawiał np. regulatory silników czy zakres ruchu serw w warunkach polowych. Poza robotyką może być bardzo dobrym rozwiązaniem do urządzeń typu headless - ja np. stosuję podobne (poprzednika Kedrigerna) rozwiązanie do obsługi sterownika pieca CO (podanie np. godzin nieobecności w mieszkaniu) czy jako wygodnego interfejsu do wpisywania wyników pomiaru ciśnienia krwi i poziomu cukru z małej przenośnej klawiaturki. A to już nie są zabawki A w ogóle przypominam, że Roomba też gada (tyle że Ciapek ładniej) Zdaję sobie sprawę z tego, że opis jest bardzo pobieżny. Z chęcią odpowiem na wszystkie pytania - o ile kogoś to będzie interesować... W każdym razie wypróbowanie Kedrigerna nawet bez modułu ust posiadacza RPi z wyjściem audio nic nie kosztuje, a może się przyda? Kody źródłowe Mileny i Kedrigerna są dostępne na stronie http://milena.polip.com A, i ostatnie wyjaśnienie: Ciapek to mały troll, wychowanek czarodzieja Kedrigerna w książce Johna Morressy'ego "Głos dla księżniczki". Nawet trochę podobny Przy okazji: @Treker, czemu pliki zip są cacy a tgz są be? kedrigern.zip pykedrigern.zip
  11. 8 punktów
    Posiadając dwa futrzaki pojawiła się potrzeba zapewnienia im odpowiedniej ilości jedzenia, szczególnie podczas weekendowych wyjazdów. Przeglądając gotowe rozwiązania stwierdziłem, że najlepiej zbudować samemu mając przy tym sporo frajdy i satysfakcji. Urządzenie zostało zbudowane w oparciu o: Raspberry Pi Zero W Kamera do Raspberry Pi Serwo L360 Uchwyt na kamerę Czujnik odległości Główne cechy urządzenia Zdalna możliwość karmienia z dowolnego miejsca na świecie podgląd z ruchomej kamery ultradźwiękowy czujnik wykrywający kota oświetlenie IR pozwalające na podgląd w nocy możliwość wgrywania i odtwarzania dowolnych plików audio opcja "Text To Speach" duży 10 litrowy zbiornik na karę detekcja pustego zbiornika harmonogram automatycznego podawania karmy Pierwszym etapem i najtrudniejszym było wykonanie niezawodnego mechanizmu podającego karmę. Przetestowałem kilka rozwiązań: podajnik ślimakowy mechanizm koszykowy zasuwa podajnik tłokowy - to rozwiązanie sprawdziło się świetnie Układ podający powstał z ogólnodostępnych elementów PCV Niżej widok od tyłu pokazujący montaż tłoka Na filmie pokazana jest idea pracy mechanizmu, były to pierwsze próby ze słabszym serwomechanizmem. Ostatecznie został wymieniony na L360, a ruch obrotowy samego serwa zastąpiony ruchem "po łuku - przód, tył" co pozwoliło zapobiec ewentualnemu zakleszczeniu się karmy. Mechanizm - film Kolejnym etapem było wykonanie dodatkowej elektroniki obsługującej: 2 serwa do kamery 1 serwo podające karmę wzmacniacz audio czujnik odbiciowy IR czujnik zbliżeniowy Dodatkową wyzwaniem było przerobienie zwykłej kamery na kamerę NoIR, w tym celu zdemontowałem układ optyczny i delikatnie usunąłem filtr podczerwony. Poniżej wygląd matrycy po zdemontowaniu tych elementów. Po ponownym zamontowaniu soczewki, kamera działała już prawidłowo przy oświetleniu podczerwonym. Poniżej widok od spodu: Główne oprogramowanie sterujące sprzętem zostało napisane w pythonie, a interfejs użytkownika w PHP, na raspberry pi jest postawiony serwer www razem z mysql, tak więc jest to mały potworek do karmienia kotów. Sterowanie odbywa się przez stronę www, co wyeliminowało pisanie dedykowanej aplikacji na każdy z systemów osobno. Na koniec kilka dodatkowych zdjęć
  12. 8 punktów
    Pojawiło się zapotrzebowanie na zegar cyfrowy, który będzie miał duże cyfry, przynajmniej 8-10cm wysokości. Dodatkowym wymaganiem było to, że cyfry nie mogą być czerwone. Wykluczyło to praktycznie wszystkie wyświetlacze 7-segmentowe. Dodatkowo cena wyświetlaczy tej wielkości jest już znaczna, koszt 4 sztuk to wydatek mniej więcej 200zł. Z tego powodu powstał pomysł realizacji takiego zegara na diodach WS2812. Po wykonaniu wstępnych projektów, zegar miał mieć cyfry wysokości ok 14cm, po dwie diody na segment, a obudowa miała zostać wykonana na drukarce 3D. Cały układ sterujący miał się znaleźć pomiędzy cyframi godzin i minut, co znacznie ograniczyło miejsce na podzespoły. Na początku układ miał bazować na Atmedze 8, jednak po dłuższych poszukiwaniach zdecydowałem się na Attiny814. W sieci nie ma zbyt wielu materiałów na temat tego procesora, jednak jego dokumentacja jest chyba jedną z najlepszych, z jakich miałem okazję do tej pory korzystać. Ponieważ nie jestem fanem ustawiania godziny poprzez przyciski, to zegar miał mieć możliwość zdalnego sterowania. Ostatecznie wybór padł na moduł Bluetooth HM-10. Do odmierzania czasu użyty został zegar DS1307 wraz z baterią CR2032. Dodatkową funkcjonalnością jest pomiar temperatury poprzez ADC i czujnik LM35. Konieczny był także pomiar jasności otoczenia, aby umożliwić automatyczne dostosowywanie się jasności diod. Wykorzystany został do tego zwykły fotorezystor. Jak się okazało, kompilowanie programów na Attiny81x przez gcc i Makefile nie jest proste i oczywiste. Przede wszystkim konieczne jest wykorzystanie gcc w wersji 8.x, oraz trzeba pobrać odpowiednie pliki nagłówkowe ze strony atmela, ponieważ avr-libc ich (jeszcze) nie dostarcza. Kolejnym wyzwaniem był programator, ponieważ Attiny814 korzysta z interfejsu UPDI, nie da się go zaprogramować poprzez USBasp. Programatory UPDI są kilkadziesiąt razy droższe od Attiny814, dlatego mocno wskazane było znalezienie jakiejś alternatywy. Okazało się nią jtag2updi, pozwalające na programowanie poprzez konwerter USB-UART oraz dowolny procesor, przy czym autor dostarcza gotowe wsady do atmegi328p (arduino). Sporą wadą takiego rozwiązania jest brak możliwości korzystania z debuggera, ale z odrobiną cierpliwości i oscyloskopem dało radę i bez niego. Diody led połączone są w dwa łańcuchy, było to konieczne ze względu na budowę zegara, a także pozwoliło zoptymalizować czas pełnego odświeżenia wyświetlacza. Ważne było, aby przeładowywać wszystkie diody w czasie mniejszym niż czas trwania jednego bajtu wysyłanego poprzez UART z prędkością 9600 baud. Wynikało to z faktu, że diody mają bardzo niewielki czas trwania jednego bitu, wynoszący ok 1.25us, przez co konieczne było wyłączenie przerwań na czas przeładowywania diod. Diody WS2812 działają na tej zasadzie, że pierwsza dioda w łańcuchu odbiera 3 bajty (24 bity) danych, a każde kolejne ignoruje i przesyła dalej. W przypadku przerwy w transmisji dłuższej niż 50us stan transmisji jest resetowany i pierwsza dioda zaczyna ponownie odbierać 3 bajty dla siebie. Aby zapewnić czasy możliwie najbardziej zbliżone do tych w dokumentacji, funkcja odświeżająca diody została napisana w assemblerze. Ponieważ nie posiadam drukarki, która umiałaby drukować dwoma kolorami jednocześnie, to cyfry składają się z czarnego szkieletu oraz białych wkładek, wydrukowanych oddzielnie. Efekt jest całkiem dobry. Aby jeszcze nieco poprawić równomierność świecenia segmentów cyfry zostały od środka pomalowane farbą akrylową na biało. Z racji tego że każdy segment składa się z dwóch diód, to możliwe jest wyświetlanie dwukolorowe, dające całkiem ciekawy efekt, jednak z braku czasu na razie zegar jest w stanie świecić tylko na jeden wybrany kolor. Na zdjęciu powyżej niektóre segmenty są pomalowane farbą od środka, stąd te ciemniejsze ramki, ostatecznie wszystkie wkładki zostały wymienione na takie bez farby. Do sterowania zegarem napisana została aplikacja w React Native, pozwalająca na ustawianie czasu, koloru oraz dodatkowych efektów. Komunikacja odbywa się poprzez wspomniany wyżej Bluetooth. Wskaźniki jasności były przydatne głównie w fazie rozwoju zegara, między innymi do testowania korekcji gamma. W aktualnej wersji zegar nie wysyła już pomiarów, ale w razie czego możliwe jest ich przywrócenie. Ostatecznie pomiar temperatury okazał się dość nieskuteczny, ponieważ termometr jest w środku obudowy, to pokazuje temperaturę wyższą niż jest w rzeczywistości. Wynika to między innymi z faktu, że podzespoły w środku nie są idealne i wydzielają trochę ciepła, na tyle dużo że temperatura zawyżona jest o 2-3°.
  13. 8 punktów
    Cześć! Jako że już po sezonie to postanowiłem opisać tu moją i mateuszm konstrukcję. Robot powstał w ramach rekrutacji do koła naukowego robotyków KoNaR i debiutował na Robotic Arenie 2015. Był to nasz debiut w konstruowaniu robotów, ponieważ wcześniej żaden z nas tego nie robił. Mechanika Głównym założeniem mechaniki robota było wykorzystanie w pełni maksymalnej dopuszczalnej masy oraz skupienie jej w podstawie. W osiągnięciu tego celu pomógł nam projekt Autodesk Inventor, w którym to został wykonany szczegółowy projekt robota uwzględniający wszystkie drobne elementy mechaniczne. Podstawa robota została wykonana z trzech elementów: - ostrze z węglika spiekanego - płytka stalowa 3mm - płytka górna, 2mm, która łączyła dwa elementy wymienione wyżej W płytkach zostały wycięte otwory, w których następnie umieszczone były małe, okrągłe płytki z czujnikami białej linii. Stal była cięta laserowo oraz później frezowana. Napęd robota stanowiły znane i lubiane silniczki Pololu HP z przekładnią 50:1 przykręcone bezpośrednio do podstawy za pomocą dedykowanych mocowań. Podpięte do elektroniki były przy pomocy złączy ARK co umożliwiło ich łatwy demontaż w celach serwisowych. Obudowa robota została wykonana z laminatu 1mm. Na obudowie znajduje się nazwa robota oraz nasze imiona i nazwiska. Obudowa mocowana jest do podstawy za pomocą śrub, a jej elementy są do siebie lutowane. Dach robota wykonaliśmy z 2 mm przeźroczystego szkła akrylowego. Finalnie robot mierzy w najwyzszym miejscu 33,7 milimetra od podstawy do dachu, a od podłoza do dachu 37,2. Jego podstawa ma wymiary 98,9 mm na 99,6 mm. Masa waha się od 490 do 499g w zależności jak bardzo nakarmimy robota przed zawodami Elektronika Priorytetem projektu robota była jego dobra konstrukcja mechaniczna, w wyniku czego wymiary płytki z elektroniką były z góry narzucone. Elektronika została zaprojektowana w programie KiCad po zaimportowaniu wymiarów przeznaczonych na nią z programu Inventor. Elektronika robota dzieli się na dwie płytki: główną, która znajduje się tuż nad podstawą robota oraz dodatkowej, na której umieściliśmy włącznik zasilania, interfejs komunikacyjny oraz złącze na moduł startowy. Płytki połączone zostały ze sobą taśmą FFC. Mała płytka widoczna na zdjęciu nad płytką główną służy nam jako podstawka pod akumulator LiPo 7.4V, którym zasilamy robota. Sercem naszego robota został mikroprocesor STM32F1. Wybór tej rodziny wynikał z łatwości ich programowania przez początkujących. Czujniki odległości wykorzystane w robocie to znane i lubiane cyfrowe Sharpy 40cm. Umieściliśmy je 4, dwa z przodu oraz po jednym na bokach. Na czujniki białej linii użyliśmy dwa KTIRy 0711S. Jak wcześniej wspomniałem zostały one umieszczone na małych płytkach, które umieściliśmy w wycięciach w podstawie. Na sterowniki silników wybraliśmy dwa, podwójne mostki H TB6612. Zostały one dobrane ze względu na ich dobrą wydajność prądową, co umożliwiło nam skuteczne wysterowanie silników Pololu bez obawy o to, że przy pełnym zwarciu mostki ulegną uszkodzeniu. Płytki zostały wykonane metodą termotransferu oraz wyfrezowane za pomocą Dremela i pilników ręcznych. Software Kod robota został napisany w środowisku System Workbench for STM32 (SW4STM32) z użyciem generatora kodu konfiguracyjnego STM32CubeMX. Program podzielony był na dwie sekwencje: startową i walki. W pierwszej ustawiana była konfiguracja algorytmu robota oraz dostępne były funkcje testu czujników (widoczny na zdjęciu poniżej - cztery czerwone diody, które odpowiadały za pokazanie aktualnego stanu czujników) oraz czyszczenia kół (drobna funkcja pomocnicza ustawiająca małą prędkość na kołach). Sekwencja walki załączała się po otrzymaniu przez robota sygnału startowego z modułu. Większa część algorytmu walki opierała się na prostych if-ach z odpowiednio dobranymi nastawami silników w każdym przypadku, co okazało się wystarczające w większości starć. Następnie zostały dodane pewne udoskonalenia, o których już rozpisywać się nie będę Osiągnięcia - II miejsce Robomaticon 2016 - I miejsce Robotic Tournament 2016 - III miejsce Festiwal Robotyki Cyberbot 2016 - II miejsce [Minisumo] oraz I miejsce [Minisumo Deathmatch] Trójmiejski Turniej Robotów 2016 - II miejsce Opolski Festiwal Robotów 2016 - I miejsce Robotic Day 2016 [Praga] A poniżej kilka filmów z udziałem robota: 2Weak4U vs Hellfire 2Weak4U w Wiedniu 2Weak4U vs Dzik 2Weak4U vs Shevron (chyba) 2Weak4U w Deatmatchu [Rzeszów] 2Weak4U vs Szwagier Pozdrawiam i do zobaczenia w następnym sezonie, Aleksander
  14. 7 punktów
    Artykuł przeznaczony do wszystkich zapaleńców druku 3D. Można nie kupować dość drogi filament do swojej drukarki 3D, a produkować w domu własny filament z zużytych butelek PET od napojów. Przy tym nieważne, jeżeli butelka jest pognieciona, ona również się nadaje do domowej produkcji filamentu. Filament z butelek ma sporo zalet w porównaniu z firmowym filamentem kupowanym – ABS albo PLA. Przede wszystkim, że produkowany filament nic nie kosztuje, jest po prostu darmowy Produkowany pręt filamentu Jest bardzo sztywny i absolutnie nie łamliwy, wytrzymuje sporo ostrych przegięć. Filament własnej produkcji jest sporo mocniejszy i twardszy, jak na rozciąganie tak i o wiele bardziej odporny na uderzenie. Absolutnie nie pochłania wody, czyli nie trzeba go ani suszyć, ani chronić w zamkniętym zabezpieczonym od nawilżania się opakowaniu. Praktycznie nie skurcze się przy ochłodzeniu w trakcie druku. Nie wymaga chłodzenia drukowanej warstwy. Nie wymaga stołu podgrzewanego. Dla przyczepności wystarczy miejsce na stole posmarować cienką warstwą kleju w sztyfcie na przykład typu „Glue Stick” Wydrukowane detal można obklejać od razu po skończeniu wydruku. Taki filament jest bardzo odporny na działanie rozpuszczalników i środków chemicznych. Jak widać filament produkcji własnej ma sporo zalet w porównaniu z filamentami kupowanymi, a najważniejsze – że jest darmowy. Niżej przedstawiono zdjęcia maszynki do produkcji filamentu: Do domowej produkcji filamentu wykorzystywane zużyte butelki od napojów. Ale butelki muszą być czyste, resztki kleju do nalepki powinni być usuwane. Technologia produkcji jest bardzo prosta i składa się z trzech następujących operacji: Poprawa zgniecionych butelek i butelek z ryflowaną powierzchnią tak, żeby ścianka boczna butelki była gładka. Nacinanie butelek na paski o określonej szerokości, od 5mm do 12mm w zależności od grubości ścianki butelki. Produkcja pręta filamentu z nacinanych pasków na specjalnej maszynce z nawijaniem na bębenek odbiorczy. Na tych wideo można obejrzeć prace maszynki i przyrządu do nacinania pasków z butelek: Zębatka drukowanie:
  15. 7 punktów
    Skoro forum powoli zmienia profil i przestajemy się skupiać na robotach, to postanowiłem, że zrobię sobie tutaj trochę bezczelnej reklamy i napiszę o projekcie, nad którym pracowałem od jakiegoś roku, który choć związany z mikrokontrolerami i programowaniem, robotem stanowczo nie jest. Zaczęło się mniej więcej rok temu, kiedy wpadłem na pomysł jak można sprawić, żeby nauka języka Python była znacznie łatwiejsza, mniej problematyczna oraz przede wszystkim fascynująca. Micro:bit i Raspberry Pi pokazały, że programowanie dedykowanego urządzenia daje bardzo dużo radości oraz poczucie kontroli nad techniką — moim zdaniem bardzo ważne rzeczy przy uczeniu jakichkolwiek technicznych tematów. Niestety, moje doświadczenia z przeróżnych szkoleń i warsztatów pokazały także achillesową piętę takiego podejścia: zawsze coś nie działa. Ludzie przychodzą z własnymi laptopami, niektórzy mają na nich poinstalowane jakieś Windowsy czy inne Makoesiksy, połowa z nich nie potrafi zainstalować sterownika, druga połowa akurat miała system update i sterownik im przestał chodzić, trzecia połowa dopiero ściąga prze konferencyjne WiFi środowisko uruchomieniowe i kompilator, a czwartej połowie nie chcą zainstalować się biblioteki. W efekcie ponad połowa czasu zawsze jest tracona na ustawianie wszystkiego. Do tego kiedy już uczniowie napiszą te swoje gry i będą chcieć się nimi pochwalić, to nie będą mogli — bo działają tylko na ich komputerze gdzie jest wszystko zainstalowane, a uruchomienie na komputerze kolegi wymaga przechodzenia całego procesu ponownie. Koszmar. Zatem postanowiłem zrobić urządzenie dedykowane do pisania gier, usuwając przy tym z drogi jak najwięcej przeszkód tak, aby można się było skoncentrować na celu — czyli samym programowaniu — bez wszystkich dodatkowych problemów. Początkowo stworzyłem shield dla płytek sprzedawanych przez Adafruit, zawierający przyciski i prosty kolorowy wyświetlacz LED 8x8, aby dało się pisać gry w rodzaju snake-a czy tetris-a. Jednak nie było to jeszcze rozwiązanie idealne, choć pozwoliło mi zbadać co działa, a co nie, oraz doszlifować moje umiejętności. Dzisiaj udostępniam szerszej publiczności moje najnowsze dzieło, czyli "prawdziwą" przenośną konsolę do gier. Zawiera ona kolorowy ekran 128x128, głośniczek, 6 przycisków i mikrokontroler programowany w CircuitPythonie. Urządzenie po podłączeniu do komputera widoczne jest jako dysk USB, nie wymagając przy tym żadnych sterowników (chyba, że ktoś ma Windows 7, wtedy niestety konieczne jest zainstalowanie sterownika aby mieć dostęp do konsoli na porcie szeregowym), a programujemy je po prostu edytując widoczne na nim pliki (lub kopiując je z komputera, oczywiście). Wbudowana w firmware prosta biblioteka do obsługi duszków i kafelków ułatwia zadanie. Grafika jest trzymana w plikach BMP, dźwięki w plikach WAV, kod w plikach tekstowych — zatem można użyć dowolnego programu jaki akurat się ma dostępny i jaki umie się już obsługiwać. Więcej informacji o projekcie, wraz z logami z jego konstruowania można znaleźć na https://hackaday.io/project/27629 Tylko, że co daje taki projekt zrobiony dla siebie do szuflady? Oczywiście wszystko jest opisane i opublikowane na otwartych licencjach, ale szanse na to, że ktoś inny zbuduje takie urządzenie są w zasadzie znikome. Aby było ono rzeczywiście przydatne, ludzie muszą go używać, a zatem musi być ono dostępne w sprzedaży. Dlatego kolejnym moim krokiem było zlecenie wyprodukowanie małej serii tych urządzeń. Dzisiaj właśnie przyszła paczka z fabryki i rozpoczynam ich sprzedaż na Tindie. Jest ich tylko 50, nie liczę na zbicie na tym kokosów, ale być może uda się zbudować społeczność zainteresowaną programowaniem tych urządzeń. Oczywiście jak na polskie warunki cena jest wysoka — niestety tak to jest z produkowaniem małych serii niestandardowych urządzeń. Ale być może kogoś jednak to zainteresuje: https://www.tindie.com/products/deshipu/game-10-game-console-kit/ Wreszcie, żeby nie było, że to tylko taka reklama i komercja, bardzo chętnie pomogę ludziom chcącym zbudować swoją własną wersję tej konsoli. Nie trzeba do tego wytrawiać płytek i lutować elementów montowanych powierzchniowo — wystarczy dowolna płytka rozwojowa z mikrokontrolerem SAMD21, moduł wyświetlacza, kilka przycisków, trochę kabelków, kostka pamięci flash i opcjonalnie głośniczek lub słuchawki.
  16. 7 punktów
    Cześć. Chciałbym przedstawić wam mój projekt robota samobalansującego. Jest to mój najbardziej zaawansowany jak dotąd projekt, który pochłonął najwięcej pracy. Pomysł na zbudowanie takiego robota zrodził się w mojej głowie w wakacje po obejrzeniu filmiku przedstawiającego podobną konstrukcję. Pracę nad nim rozpocząłem jeszcze w wakacje, a z przerwami zakończyłem w lutym. Działanie robota jest podobne do dostępnych na rynku Hoverboardów, czyli robot ma za zadanie poruszać się w taki sposób, aby utrzymać się w pionie, oczywiście bez podpierania. Konstrukcję robota zaprojektowałem sam i wykonałem z pręta gwintowanego i plexi. Uznałem że taka konstrukcja zapewni robotowi wymaganą sztywność i niską masę, jednocześnie nie rujnując budżetu. Najpierw wykonałem jej model w Fusion 360, a później przystąpiłem do pracy. Roboty z tym trochę było, bo obróbka plexi do łatwych nie należy. Sporo czasu zajęło przycięcie prostokątów, a jeszcze więcej wywiercenie otworów, które musiały być idealnie rozmieszczone, aby później dało się przełożyć przez nie pręt gwintowany. Po zbudowaniu ramy przyszła pora na elektronikę. Ponieważ robot nie zapewnia dużo miejsca, a jednocześnie środek ciężkości powinien być możliwie wysoko, dla ułatwienia balansu, musiałem się postarać ścisnąć wszystko jak to tylko możliwe. Baterię zasilającą robota (ogniwe Li-Po odzyskane z powerbanka o pojemności 3000 mAh) umieściłem na najwyższej półce. Tam również trafiła przetwornica step-up podnosząca napięcie do 7,4 V. Wiem że lepiej byłoby dać dwie baterie połączone szeregowo, ale w momencie budowania budżet na to nie pozwolił. Szybko okazało się że jedna przetwornica to za mało - Arduino restartowało się przy każdym uruchomieniu silnika, nawet jeśli do układu przyłączyłem bardzo duży kondensator. Dodałem więc drugą - teraz silniki były zasilanie niezależnie od elektroniki sterującej. Pozwoliło to stanąć robotowi po raz pierwszy, jednak wciąż jedna przetwornica zasilająca silniki ograniczała ich moc. Dodałem drugą, co nieco poprawiło sytuację, jednak wciąż nieco ogranicza silniki. Póki co szukam lepszego rozwiązania. Schodząc na niższą półkę. Tam trafiła płytka ze sterownikiem i druga z mostkiem H. Pierwszą płytkę lutowałem sam na płytce uniwersalnej - zajęło to kilka godzin i mnóstwo cyny, ale satysfakcja była nie do opisania, zwłaszcza że wszystkie połączenia wykonałem cyną. Po spędzeniu kolejnej godziny na pozbywaniu się zwarć układ był gotowy do testów Robot aby ustalić swoją pozycję korzysta z modułu żyroskopu i akcelerometru MPU6050 oraz wbudowanych w silniki enkoderów. Dane z tych czujników trafiają do Arduino Nano które poprzez układ L298N steruje dwoma silnikami. Dzięki akcelerometrowi i żyroskopowi robot zna swój kąt przechylenia. W pierwszych wersjach kodu szybko okazało się, że to nie wystarczająco, ponieważ o ile robot stał, to cały czas przesuwał się w jedną stronę. Wynika to z tego że konstrukcja nie jest idealnie wyważona, a robot nie zna swojej pozycji, jedynie kąt nachylenia, więc jeżeli ustawiony na sztywno kąt odbiegał od kąta balansu, robot "dryfował". Aby temu zapobiec dodałem drugie sprzężenie zwrotne, tym razem oparte o enkodery przy silnikach. Enkodery zliczają ilość impulsów które silniki wykonały w każdą ze stron, a oprogramowanie dąży, aby ich różnica była równa 0. Pierwsze próby nie były zbyt udane. Kiedy doprowadziłem kod do stanu w którym robot chociaż próbował się utrzymać, udawało mu się to przez maksymalnie kilkanaście sekund. Jednak wraz z poprawianiem kodu robot stał dłużej i dłużej. Obecnie już się nie wywala, jednak mostek H po dłuższym staniu się przegrzewa, więc czas pracy ograniczony jest do kilku minut. Mimo to robot robi duże wrażenie, chociaż z pewnością nie jest idealny. Zastosowałem tanie chińskie silniki, i jak się okazało, jeden obraca się szybciej niż drugi, więc robot obraca się w jedną stronę. Do tego jak wspomniałem przegrzewa się, a silnikom brakuje momentu, więc robot się trzęsie zamiast stać idealnie prosto. Są to jednak problemy które mam w planach poprawić. Planuję dodać również możliwość sterowania po BT (już nawet na płytce jest miejsce na moduł HC-06), ale na razie nie miałem czasu. Oto filmik prezentujący działanie robota:
  17. 7 punktów
    Witajcie. Chciałbym Wam przedstawić prosty sposób wykorzystania modułu ESP-32, który użyłem do stworzenia urządzenia, za pomocą którego możecie śledzić poziom zainteresowania wybranym repozytorium GitHub. Dzięki wbudowanym dwóm wyświetlaczom, będziecie na bieżąco informowani o: aktualnej liczbie gwiazdek dziennej liczbie gwiazdek aktualnej liczbie obserwujących aktualnej liczbie forków Początkowo chciałem skorzystać ze starszego modułu ESP8266 12-F, jednak napotkałem problem który objawiał się przy wykonywaniu requesta do api GitHub. Podczas oczekiwania na odpowiedź z serwera, na wyświetlaczach zanikały wszystkie cyfry i wyglądało to jakby coś było nie tak z urządzeniem. Z pomocą przyszedł układ ESP-32, który oparty jest na dwóch rdzeniach. Była to świetna okazja aby zapoznać się z tym modułem, ponieważ wcześniejsze projekty wykonywałem na ESP8266. Użycie nowszej odsłony ESP, pozwoliło mi wysyłać requesty asynchronicznie. Do działania ramki wymagane jest połączenie z siecią poprzez WiFi. Tutaj świetnie sprawdziła się biblioteka "WiFi Manager", która umożliwiła mi szybkie podłączenie ramki do dowolnej sieci. Jeżeli chodzi o zasilanie to jest to napięcie 5V, które podaje poprzez wtyki USB. W obudowie ramki znajdują się trzy przyciski. Pierwszy służy jako włącznik. Pozostałe dwa to włączniki chwilowe. Po wciśnięciu pierwszego na wyświetlaczu prezentowany jest adres IP, który wykorzystujemy przy konfiguracji. Natomiast drugi przycisk resetuje liczbę gwiazdek z dnia. Do układu podłączona jest 3 kolorowa dioda LED, która informuje nas o stanie połączenia: CZERWONY – brak sieci, błąd podczas pobierania danych ZIELONY – połączenie sieciowe ustanowione, dane pobrane poprawnie NIEBIESKI – tryb access pointu ( zanik sieci ) Domyślnie odświeżanie danych odbywa się co 90 sekund. Oczywiście interwał można zmienić. Ale należy uważać, aby nie wykonywać do api GitHub więcej niż 60 requestów na godzinę, ponieważ serwer ma ustawiony RateLimit. Po przekroczeniu ilości zapytań zostaniemy zablokowani na godzinę. Jak już wspomniałem wyżej, pod adresem IP jaki przydzielony został do urządzenia działa prosty web server, który serwuje nam stronę z konfiguracją, gdzie musimy wprowadzić nazwę użytkownika repozytorium oraz nazwę repozytorium które chcemy obserwować. Po zapisaniu konfiguracji w pamięci EEPROM urządzenie jest restartowane i gotowe do użycia. Dodatkowym atutem urządzenia jest automatyczna aktualizacja oprogramowania poprzez HTTPS OTA. Sprawdzanie wersji następuje podczas uruchomienia oraz po północy. Urządzenie jest w pełni bezobsługowe. Gdy wystąpi zanik sieci, ESP cały czas będzie próbowało nawiązać połączenie za pośrednictwem zapamiętanych poświadczeń. Jeśli sieć nie będzie dostępna, przełączy się w tryb access pointu ( ssid: "GITHUB-FRAME"). Jeśli nie zostanie wybrana nowa sieć w menadżerze sieci, to po czasie 3 minut, nastąpi restart i proces się powtórzy. Tak pokrótce, wygląda zasada działania całego układu. Poniżej przedstawię Wam główne etapy budowy całej ramki. A więc zaczynamy. LISTA ELEMENTÓW: ESP-32 WROOM DevKit 1.0 – 1 szt. Wyświetlacz LED 4-Cyfrowy TM1637 – 0.56" – 1 szt. Wyświetlacz LED 4-Cyfrowy TM1637 - 0.36" – 1 szt. 4-pinowy przewód, żeński – żeński – raster 2.54 – 4 szt. Gniazdo + wtyk, JST – JST – 2 szt. Gniazdo + wtyk, mikro JST – mikro JST – 2 szt. Płytka uniwersalna PCB 50x70mm PI-01 – 1 szt. Rezystor węglowy – 220 ohm – 5 szt. Rezystor węglowy – 2,2k ohm – 3 szt. Zworki do płytek stykowych - 1 zestaw Wtyk goldpin kątowy 4 pinowy, raster 2,54mm – 4 szt. Dioda LED 5mm RGB wsp. Anoda – 1 szt. Dioda LED 3mm biała – 3 szt. Przełącznik chwilowy okrągły – 10mm – 2 szt. Przełącznik kołyskowy ON-OFF – 1 szt. Kabel USB A – USB micro – 1 szt. Zasilacz 5V z gniazdem USB A – 1 szt. Rurki termokurczliwe - 1 szt. Ramka IKEA RIBBA – 21x30cm ( ważne żeby była dość głęboka, aby zmieścić elektronkę ) – 1 szt. Papier samoprzylepny do drukarki – 1 szt. Rura elektroinstalacyjna RLM 16 – 1 szt. NARZĘDZIA: Lutownica Cyna Obcążki Wiertarka lub wkrętarka Wiertła: 7, 10, 13 Pistolet do kleju na gorąco Nóż Drukarka ZAŁOŻENIA: Stabilność działania Intuicyjna obsługa Szybka adaptacja w miejscu instalacji Estetyka Plan Początkowo ramka miała powstać pod konkretnie wybrane repozytorium i wyświetlać tylko liczbę gwiazdek. Ale stwierdziłem, że i tak pobieram inne dane z endpointa api to czemu miałbym ich nie wyświetlić. Postanowiłem, że dodam dwa nowe klucze: "forks" oraz "watchers" i wyświetlać je kolejno w 5 sekundowym odstępie czasowym. Jeżeli chodzi o repozytorium, to dając możliwość wprowadzenia własnych ustawień url-a, zwiększyłem tym samym skalowalność przedsięwzięcia. Do tego doszły automatycznie aktualizacje software-u. Więc taką ramkę może stworzyć każda osoba, która chociaż trochę ma pojęcie o informatyce i niekoniecznie zna się na programowaniu. BUDOWA Prace nad ramką rozpocząłem od budowy prototypu metodą na "pająka". W tym celu skorzystałem z płytki prototypowej, przycisków typu "tact switch", paru zworek oraz kilkunastu przewodów do połączenia wszystkiego w całość. Całe oprogramowanie zostało napisane za pośrednictwem Arduino IDE czyli w języku C. Gdy miałem już działający prototyp, rozpocząłem prace nad przeniesieniem całości na uniwersalną płytkę PCB. Zadanie wydawałoby się proste ale wymagało procesu planowania. W tym celu wykorzystałem oprogramowanie Fritzing. Oprogramowanie to umożliwia stworzenie całej dokumentacji projektu. Na tę chwilę wykorzystałem tylko narzędzie do stworzenia szkicu płytki prototypowej. Mając gotowy już projekt z rozlokowaniem wszystkich elementów i połączeń. Mogłem przystąpić do lutowania. Jak widać na zdjęciach, podczas montażu elementów używałem uchwytu, który stabilnie trzyma płytkę w miejscu. Bardzo ułatwił mi pracę. Po przylutowaniu wszystkich elementów elektronicznych, wlutowałem przewody z gniazdami, dzięki którym będę mógł odłączyć układ od samej konstrukcji ramki Teraz przyszedł czas na najtrudniejszy etap jakim było dostosowanie drewnianej ramki do potrzeb projektu. W programie Photoshop stworzyłem szablon do wiercenia i wycinania potrzebnych otworów. Szablony te znajdziecie również w repozytorium projektu. Po wydrukowaniu szablonu przykleiłem kartkę do “pleców ramki” i wyciąłem wszystkie otwory. Trochę trzeba się do tego przyłożyć i mieć sporo cierpliwości. Cięcie, pasowanie, cięcie, pasowanie aż do skutku. Ufff. W końcu mogłem przystąpić do zamontowania wyświetlaczy oraz diod LED. Z pomocą przyszedł mi klej na gorąco. Trzyma mocno i pewnie, wystarczająco do tego typu prac. Trzy diody LED umieściłem w przyciętych krążkach z białej rury pcv ( tych do prowadzenia przewodów po ścianach ) a górę zaślepiłem kawałkiem plastiku w którym zamocowałem diody. A tak całość prezentuje się od frontu Za pomocą 4 żyłowych przewodów zakończonych wtykami żeńskimi, połączyłem wszystkie elementy z główną płytką. W celu szybszej identyfikacji przewodów, oznaczyłem każde połączenie za pomocą lakierów do paznokci ( pozdrawiam swoją żonę Magdalenę ). Główny układ przykleiłem do pleców ramki również za pomocą kleju na gorąco. Na koniec pomalowałem cały front na biało farbą emulsyjną, ponieważ papier który używa się w drukarkach ma małą gramaturę co sprawia, że jest półprzezroczysty. Dzięki podbiciu koloru tła biel będzie intensywniejsza. W ostatecznej wersji grafikę wydrukowałem na papierze fotograficznym, który jest na tyle gruby, że malowanie okazało się być zbędne. SOFTWARE Cały program opiera się na dwóch pętlach. Pierwsza pętla Task1, sprawdza czy użytkownik wprowadził url repozytorium z którego mają zostać pobrane dane. Jeżeli konfiguracja została wprowadzona, program wywołuje funkcję getData(), która odpowiedzialna jest za pobranie danych z API. Interwał tej pętli definiuje zmienna requestInterval, która domyślnie posiada wartość 90 ( czyli 90 sekund). Druga pętla Task2, służy do wyświetlania odpowiednich danych na wyświetlaczach oraz podświetlania ikon. Tutaj również sprawdzany jest stan na pinach 27 i 15 ( przyciski BUTTON_IP oraz BUTTON_RESET_TODAY). Interwał tej pętli to około 15 sekund. Po północy następuje sprawdzenie dostępności nowszej wersji oprogramowania oraz resetowany jest licznik gwiazdek otrzymanych w ciągu całego dnia. Poniżej znajdziecie link do repozytorium z projektem: OPROGRAMOWANIE + SZABLONY DO DRUKU PODSUMOWANIE Przyznam się szczerze, że prototyp urządzenia miałem już gotowy rok temu. Ale ze względu na gruntowny remont mieszkania musiałem odsunąć hobby na dalszy plan. Rozciągnięcie projektu w czasie sprawiło, że przy każdym powrocie zawsze coś zmieniałem, rozbudowywałem. Wszystko wtedy można przemyśleć kilka razy i na spokojnie zastanowić się nad rozwiązaniem jakiegoś problemu. Na co dzień zajmuję się programowaniem front-endu, ale dzięki takim projektom mogę połączyć moje główne zainteresowania: majsterkowanie, elektronikę, grafikę i jak już wcześniej wspomniałem, programowanie i stworzyć coś namacalnego i cieszącego oko. Zachęcam wszystkich do twórczego działania i poszerzania swojej wiedzy. Tego typu projekty dadzą Wam satysfakcję, świetną zabawę oraz sporo nauczą. Także klawiatury, lutownice, piły, śrubokręty, wiertarki w dłoń i do działania! Instrukcję już macie Do następnego projektu! Pozdrawiam.
  18. 7 punktów
    Jakiś czas temu na forum pojawiło się kilka wpisów krytykujących Raspberry Pi jako platformę sprzętową. Nie próbuję nawet wmawiać, że malinka jest idealna - jednak niektóre problemy można rozwiązać bardzo (albo chociaż dość) łatwo. Problemy o których piszę to np. zużywanie kart SD, długi czas uruchamiania płytki, problemy z systemem plików jeśli nagle odłączymy zasilanie, długi czas kompilacji programów, czy brak możliwości uruchomienia systemu z pamięci USB. Wiele z opisanych niedogodności wynika ze sposobu używania malinki. Większość osób stara się zrobić z niej mały komputer PC - i nie ma w tym nic złego, w końcu na Forbocie właśnie tak opisywaliśmy kurs Raspberry Pi. Jednak malinka nie we wszystkim może zastąpić komputer stacjonarny i czasem nieco inne podejście może dawać nieco lepsze rezultaty. Komputer stacjonarny, a komputer wbudowany Pierwsza istotna sprawa to rozróżnienie między rozwiązaniami wbudowanymi (embedded), a komputerem stacjonarnym (desktop/laptop). Urządzenia wbudowane są konstruowane do spełniania jednej, z góry określonej funkcji - przykłady to procesor w ekspresie do kawy, bankomacie, czy samochodzie. Oprogramowanie można aktualizować, nawet zmieniać na własne (tym zajmują się hackerzy), ale nadal program ma ściśle określone zadanie do wykonania. System ogólnego przeznaczenia, to nasze komputery stacjonarne lub przenośne - czyli zupełne przeciwieństwo wbudowanych. Można na nich grać w pasjansa, Wiedźmina, a nawet inne gry, przeglądać internet, pisać programy i robić miliony innych rzeczy. Instalacja nowych programów jest łatwa, niekiedy nawet udaje się je odinstalować. Arduino jest kolejnym przykładem platformy wbudowanej. Program kompilujemy na PC, wgrywamy na płytkę i ma on wykonywać to co sobie zaplanowaliśmy - migać diodą, sterować robotem, itd. Ale już nowych progamów nie dodamy, nie będziemy na Arduino kompilować kodu, ani grać w pasjansa (chyba że to jest główna funkcja naszego układu). Raspberry Pi natomiast jest najczęściej używane jako mały komputer PC. Instalujemy na karcie SD Raspbiana (lub inną dystrybucję) i dalej używamy tak samo jak komputer stacjonarny. Może gier jest mniej, ale minecraft działa całkiem fajnie, RetroPie pozwala na emulację starych komputerów i konsol, a użwanie kompilatora (np. gcc) nikogo nie dziwi. Raspberry Pi całkiem dobrze sobie z takimi zadaniami radzi, ale to wbrew pozorom nadal głównie komputer wbudowany. W niniejszym artykule chciałbym chociaż wprowadzić w nową opcję, czyli użycie malinki jako komputera wbudowanego - mającego jedno zadanie, które dobrze wykonuje. System operacyjny Wszyscy wiemy jak działa Raspberry Pi - na karcie SD mamy ulubioną dystrybucję, kartę umieszczamy w czytniku, podłączanie zasilanie, czekamy, chwilę jeszcze czekamy, a może jeszcze jedną chwilę... i mamy pulpit z ikonkami albo chociaż konsolę do wydawania poleceń. Programy pobieramy z sieci (repozytorium), apt jest prosty i sympatyczny w użyciu. A gdybyśmy tak spróbowali przygotować własną, mniejszą ale dopasowaną do naszych potrzeb wersję systemu? Okazuje się że nie jest to aż tak trudne (chociaż proste też nie jest), w nagrodę będziemy za to mogli pozbyć się problemów o których wspominałem na początku artykułu. Yocto Własną dystrybucję Linux-a można przygotować zupełnie od podstaw - zaczynając od kompilacji kompilatora. Jest to jednak dość złożony proces, świetny do nauki, ale niekoniecznie wygodny. Na szczęście znajdziemy gotowe projekty przygotowujące naszą dystrybucję linuksa od podstaw. Buildroot (https://buildroot.org/) jest jednym z takich projektów - pozwala on na łatwe wybranie potrzebnych nam programów oraz ich skompilowanie ze źródeł. Ostatnio coraz większą popularność zyskuje jednak inny projekt - Yocto (https://www.yoctoproject.org/). Działa o wiele wolniej niż buildroot (jak to z narzędziamy opartymi o Pythona bywa), ale lepiej sprawdza się w dużych projektach. W następnym wpisie postaram się opisać jak można użyć Yocto to przygotowania własnej wersji systemu dla malinki. Jeszcze dwa słowa odnośnie buildroot-a. Dawno, dawno temu opisywałem jak użyć go podczas instalowania linuksa na netbook-u domyślnie pracującym z Androidem: https://forbot.pl/blog/sprawdz-jak-tanio-zbudowac-robota-z-systemem-linux-id7751 To co chcę teraz opisać to bardzo podobne rozwiązanie, ale zamiast netbook-a jest Raspberry Pi, a rolę Androida zajmuje Raspbian. No i po tych kilku latach yocto uzyskało pewną przewagę na buildrootem, więc też będzie użyte. Szybki start Żeby nie zanudzić najpierw szybki i dość ogólny opis. Celem będzie utworzenie podstawowego obrazu systemu, z którego wystartuje malinka. Najpierw należy przygotować odpowiedni komputer PC oraz system operacyjny. System to oczywiście Linux - wspierane są dystrybucje Debian, Ubuntu, Fedora, OpenSUSE oraz CentOS. Prawdopodobnie użycie innej dystrybucji jest też możliwe, może jednak wymagać dodatkowych kroków. W zależności od posiadanej wersji musimy zainstalować odpowiednie pakiety oprogramowania, wszystko znajdziemy opisane tutaj: https://www.yoctoproject.org/docs/2.5/ref-manual/ref-manual.html#required-packages-for-the-host-development-system Yocto można używać w systemie Windows lub MacOS wykorzystując maszynę wirtualną. Jednak takie rozwiązanie ma znaczącą wadę - bardzo spowalnia i tak czasochłonną kompilację obrazu systemu. Nie polecam takiego rozwiązania, lepiej używać natywnego linux-a i poszukać możliwie mocnego komputera - 4 rdzenie to raczej minimum, ale yocto potrafi nawet 44 wykorzystać (tyle testowałem), więc im silniejszy komputer tym lepiej i szybciej - a maszyny wirtualne pod względem wydajności niestety nie oszałamiają. Oprócz szybkiego procesora o możliwie wielu rdzeniach, będziemy potrzebowali również sporo miejsca na dysku. Minimum to ok. 30 GB, ale nieco bardziej rozbudowana konfiguracja może potrzebować i 100GB. Oczywiście szybki dysk ma swoje zalety, więc jeśli mamy miejsce na dysku SSD, warto go użyć. Ja wykorzystuję dysk SSD podłączany przez USB. To całkiem wydajne rozwiązanie, a możliwość odłączenia dysku od stacji roboczej i podłączenia do laptopa bardzo się przydaje. Dlatego u mnie ścieżka do projektu jest nieco długa: /mnt/usbssd/raspberry/yocto W tym katalogu należy pobrać sam projekt yocto, czyli wykonać: git clone -b sumo git://git.yoctoproject.org/poky.git Potrzebne będą jeszcze dwie tzw. warstwy, czyli powiedzmy biblioteki: meta-openembedded oraz meta-raspberrypi. Pobiera się je poleceniami: git clone -b sumo git://git.yoctoproject.org/meta-raspberrypi git clone -b sumo git://git.openembedded.org/meta-openembedded Teraz w katalogu /mnt/usbssd/raspberry/yocto znajdziemy trzy podkatalogi: poky, meta-raspberrypi, meta-openembedded. Pierwszy z nich jest dla nas najważniejszy więc wchodzimy do niego, a następnie wczytujemy zmienne ze skryptu oe-init-build-env: cd poky source oe-init-build-env Na ekranie widzimy podpowiedź co zrobić dalej, jednak zanim do tego przejdziemy musimy poprawić domyślną konfigurację yocto. Plik conf/bblayers.conf zawiera listę wybranych wartstw (bibliotek). Musimy dopisać używane przez nas, dopisujemy więc: BBLAYERS ?= " \ /mnt/usbssd/raspberry/yocto/poky/meta \ /mnt/usbssd/raspberry/yocto/poky/meta-poky \ /mnt/usbssd/raspberry/yocto/poky/meta-yocto-bsp \ /mnt/usbssd/raspberry/yocto/meta-raspberrypi \ /mnt/usbssd/raspberry/yocto/meta-openembedded/meta-oe \ /mnt/usbssd/raspberry/yocto/meta-openembedded/meta-multimedia \ /mnt/usbssd/raspberry/yocto/meta-openembedded/meta-networking \ /mnt/usbssd/raspberry/yocto/meta-openembedded/meta-python \ " Kolejny krok to edycja głównego pliku konfiguracyjnego o nazwie conf/local.conf. Domyślnie zawiera on dużo komentarzy, uproszczona wersja wygląda następująco: MACHINE = "raspberrypi3-64" DL_DIR = "${TOPDIR}/downloads" DISTRO ?= "poky" PACKAGE_CLASSES ?= "package_ipk" EXTRA_IMAGE_FEATURES ?= "debug-tweaks" USER_CLASSES ?= "buildstats image-mklibs image-prelink" CONF_VERSION = "1" RPI_USE_U_BOOT = "1" ENABLE_UART = "1" Pierwsza linia ustala typ naszej "maszyny", czyli Raspberry Pi 3 w wersji 64-bitowej. Jeśli używamy innej wersji, musimy odpowiednio zmodyfikować ten wpis. Co ciekawe cała dystrybucja będzie wykorzystywała ustawienia zoptymalizowane dla naszgo procesora - domyślnie Raspbian jest kompilowany tak, aby programy działały na najmniejszym wspólnym mianowniku, czyli starym Raspberry 1 - używając yocto nie tylko jądro, ale i cały system zostanie skompilowany pod nasze potrzeby. Nie zadziała na starszych płytkach, ale na naszej wykorzysta jej potencjał. Kolejny ważny parametr to ustawienie RPI_USE_U_BOOT. Dzięki niemu zostanie użyty bootloader u-boot, co pozwoli na załadowanie systemu przez sieć (TFTP), podłączenie dysku sieciowego (NFS), albo nawet użycie pamięci USB. Jest to pierwszy etap pozwalający na pozbycie się usterek na które wiele osób narzeka. W tym pliku można również wymusić użycie systemu "tylko do odczytu". Jedna dodatkowa linijka i karta SD będzie działać prawie w nieskończoność - do tego wrócimy później. Na razie czas zacząć kompilację i zrobić sobie (długą) przerwę. Wydajemy polecenie: bitbake core-image-minimal Yocto pobierze z sieci źródła wszystkich programów a następnie je skompiluje. Taki proces wymaga szybkiego łącza i trwa... od 20min do 4h. Na szczęście później jest już szybciej, ale za pierwszym razem można sobie zrobić przerwę na lunch. Po zjedzeniu lunchu, albo chociaż przerwie mamy gotowy obraz naszego systemu. Wynikowe pliki znajdziemy w katalogu tmp/deploy/images/raspberrypi3-64: Tym co na początek nas zainteresuje to plik z gotowym obrazem całej karty SD, czyli core-image-minimal-raspberrypi3-64.rpi-sdimg. Warto zwrócić uwagę na wielkość obrazu - u mnie wyszło 56 MB. To nadal bardzo dużo, ale domyślny Raspbian wymaga kilku GB. Kartę SD przygotujemy poleceniem dd, u mnie urządzenie /dev/sdh odpowiada karcie, więc polecenie: sudo dd if=tmp/deploy/images/raspberrypi3-64/core-image-minimal-raspberrypi3-64.rpi-sdimg of=/dev/sdh bs=4M Pozwala na nagranie obrazu na nośnik. Teraz można umieścić kartę w czytniku Raspberry Pi i wystartować system: Uruchomienie sytemu zajmuje znacznie mniej czasu niż w przypadku domyślnego systemu. To nadal bardzo daleka od optymalnej konfiguracja, ale i tak linux jest gotowy do pracy w kilka sekund. To co otrzymaliśmy to pierwsza, minimalna wersja systemu - mała ale zoptymalizowana dla naszego sprzętu. Nie znajdziemy na niej minecrafta, ani nawet interfejsu graficznego, ale to co wybraliśmy działa szybko i wydajnie. Mając taki system jako punkt wyjścia możemy przygotować bardziej rozbudowaną wersję, wyposażoną w potrzebne nam programy i biblioteki. Warto natomiast zwrócić uwagę na nieco inny sposób pracy z systemem. Całą kompilację wykonujemy na komputerze stacjonarnym, malinka tylko wykonuje przygotowane programy. Działa więc tak jak Arduino, a nie typowy Raspbian.
  19. 7 punktów
    Zdecydowałem się przestawić swój kolejny projekt utrzymany w klimatach retro. Wszystko zaczęło się jakiś rok temu, gdy przypadkowo odkryłem, że sprzedawcy na popularnych chińskim serwisie aukcyjnym posiadają podejrzanie duże ilości podejrzanie tanich układów MOS6502. Wydało mi się to zbyt piękne, aby było prawdziwe. Z ciekawości zamówiłem kilka sztuk, płacąc za nie kilka dolarów i zapomniałem o całej sprawie, licząc na to, że pewnie otrzymam podróbki z wygrawerowanymi laserowo oznaczeniami. Jak bardzo się myliłem! Po uruchomieniu na płytce prototypowej okazały się być prawdziwymi układami MOS6502, wykonanymi w technice NMOS. Zabrałem się więc za projektowanie właściwej płytki, myśląc o stworzeniu swojego własnego komputera pracującego pod kontrolą języka BASIC. Ten projekt ciągle jest w realizacji, ale nie o nim chcę tutaj napisać. W międzyczasie bowiem w mojej głowie pojawił się jeszcze jeden pomysł. Chciałem sprawdzić jak ta rodzina procesorów sprawdza się w roli mikrokontrolera. Albo innymi słowy - byłem ciekaw co by było, gdyby Arduino powstało trzydzieści lat temu. Tym razem od brytyjskiego sprzedawcy na eBay-u zamówiłem kilka sztuk nowszych procesorów WDC65C02, wykonanych w technologii CMOS. Zastosowanie tej wersji układów nie tylko zmniejszało znacznie pobór prądu, ale także upraszczało układ, niwelując konieczność stosowania bufora szyny adresowej. Za punkt wyjścia do tego projektu posłużyła płyta procesorowa mojego ciągle powstającego komputera na MOS6502, która została poddana pewnym modyfikacjom. Przede wszystkim zmieniła się organizacja pamięci - zwiększyłem ilość EPROM-u kosztem RAM-u, dodana została także pamięć EEPROM. Organizacja pamięci wygląda następująco, zaczynając od 0x000: 8 kB pamięci RAM 8 kB przestrzeni adresowej I/O 8 kB pamięci EEPROM 8 kB układ EPROM (dodatkowa pamięć, obecnie niewykorzystywana) 32 kB EPROM (główna pamięć, przechowująca program, dane i adresy wektorów) Urządzenie pracuje z prędkością 4 MHz. Sygnał taktowania pochodzi z jednoukładowego generatora kwarcowego. Układ DS1232 odpowiada za obsługę wejścia RST (likwidacja drgań styków i obsługa power-on reset). Urządzenie posiada także port wyjściowy na 74HCT373 - można za jego pomocą migać dwiema diodami, pozostałe linie są wyprowadzone na złącze IDC-40. Dekoder adresów jest zrealizowany na układach 74HCT138 i 74HCT139. Dodatkowo kilka bramek układu 74HCT00 posłużyło do generowania sygnałów !RD i !WR, wykorzystywanych w układach kompatybilnych z magistralą intela (a więc także zastosowanych pamięciach). Wszystkie sygnały szyny danych, adresowej, te związane z obsługą przerwań oraz wyjścia dekodera adresów są wyprowadzone na złącze IDC-40. Moim zamiarem było stworzenie płytki, która nie tylko będzie mogła służyć do eksperymentów z historyczną rodziną procesorów, ale także będzie mogła posłużyć jako podstawa do budowy jakiegoś użytecznego projektu, poprzez dodanie odpowiednich modułów, na wzór shieldów Arduino - z tą różnicą, że podpinanych bezpośrednio do magistrali procesora za pomocą taśmy IDC-40. Na pierwszy ogień poszła płytka zawierająca wyświetlacz HD44780 (4x20) oraz kilka przycisków tact switch. Wyświetlacz pracuje bezpośrednio na magistrali procesora - do tego w końcu został zaprojektowany. Konieczne było tylko dodanie prostej logiki, generującej sygnały sterujące. Od strony programowej obsługa wyświetlacza w takich systemach jest nawet prostsza niż obecnie - wystarczy jedynie wpisywać odpowiednie wartości pod odpowiednie adresy w przestrzeni adresowej procesora. Przyciski posiadają własny port wejściowy, zrealizowany na 74HCT245. Praca nad tym projektem była dla mnie także okazją do zapoznania się z asemblerem 6502, chociaż prawdę mówiąc większość kodu napisałem w C posługując się kompilatorem cc65, uzupełniając go o asemblerowe wstawki. Co prawda jest to dość prosty kompilator i być może nie nadaje się do pisania gier pod Commodore C64, ale w w tego typu zastosowaniach sprawdza się całkiem nieźle.
  20. 7 punktów
    Witam, Chciałbym przedstawić zbudowany ostatnio pojazd inspekcyjny. Założenia były następujące: dobra mobilność w nierównym terenie, sterowanie za pomocą aplikacji na Android'a oraz podgląd z wbudowanej kamery w czasie rzeczywistym. Mechanika W pojeździe zastosowano uproszczoną, 4-kołową wersję zawieszenia rocker-bogie stosowaną m.in. w łazikach marsjańskich. Główną zaletą tego rozwiązania jest niemal równomierny nacisk wszystkich kół na podłoże oraz możliwość uniesienia koła na przeszkodzie. Zastosowane koła pochodzą od "jakiejś" zabawki (znalezione na strychu ) i są zamocowane adapterem hex 12 mm (z małymi przeróbkami, aby schować przekładnię wewnątrz koła). Każde koło posiada własny silnik DC z przekładnią - prędkość wyjściowa: ok. 120 obr/min przy zasilaniu 12V. Silniki zostały zamocowane do aluminiowego profilu kwadratowego 10 mm za pomocą opasek zaciskowych. Profil ten stanowi część wahacza przymocowanego do osi kadłuba przez łożyska z wiertarek (średnica wewnętrzna 6 mm). Z tyłu pojazdu widoczna jest belka różnicowa łącząca wahacze po obu stronach. Dzięki niej kadłub utrzymywany jest w swojej pozycji a wychylenie jednego wahacza powoduje odchylenie drugiego o taki sam kąt przeciwnie skierowany. Jako kadłub wykorzystano obudowę z ABS. Do jej wieczka przymocowano również maszt z kamerą sterowany w dwóch osiach. Elektronika Komputerem sterującym w pojeździe jest Raspberry Pi Zero W z systemem Raspbian w wersji Jessie. Zastosowano ten model z powodu małych rozmiarów, stosunkowo niskiej ceny i małego poboru mocy. Z racji braku przetwornika ADC, zastosowano również arduino w wersji Pro Mini o napięciu 3.3V (aby było zgodne ze standardem w Raspberry). Są również 2 sterowniki silników na bazie modułu L298N (Sterownik ten ma dwa kanały i można było zastosować tylko jeden sterownik, jednak z powodu niewystarczającej wydajności prądowej zastosowano dwa), 2 przetwornice step-down 5V (osobno dla logiki, i osobno dla serwomechanizmów), dwa serwomechanizmy TowerPro SG90, kamera, oraz pakiet 3S ogniw li-ion w rozmiarze 18650. Z racji tego, że kamera jest podłączana przez taśmę FFC, zastosowano również przejściówki z FFC na goldpin, aby nie uszkodzić taśmy podczas obracania kamerą. Oprogramowanie Arduino w tym pojeździe odpowiedzialne jest za odczyt aktualnego napięcia zasilania oraz generowanie sygnałów PWM dla prędkości silników oraz serwomechanizmów pozycjonowania kamery. To jaki sygnał ma być generowany, jest wiadome dzięki połączeniu z Raspberry poprzez UART. Dodatkową funkcją Arduino jest wyłączenie PWM dla silników w przypadku braku komunikacji z Raspberry co zapobiega niekontrolowanej jeździe pojazdu w przypadku np. zerwania zasięgu. Raspberry komunikuje się z użytkownikiem poprzez sieć WiFi (Malinka działa w trybie hot-spot'u). Program działający na Raspberry został napisany w Python'ie i wykorzystuje również biblioteki Flask, w celu utworzenia serwera. Odpowiednie fragmenty kodu są wykonywane po wywołaniu przypisanego do niego adresu. Do transmisji wideo wykorzystano platformę Gstreamer, która pozwala na strumieniowanie w formacie H.264. Dzięki temu udało się uzyskać płynny obraz przy 30 FPS i rozdzielczości 800x600 cechujący się niewielkim opóźnieniem (ok. 300 ms). Powstała również dedykowana aplikacja na system Android, gdzie widoczny jest podgląd z kamery oraz sterowanie pojazdem. Podsumowanie Powstały pojazd zgodnie z założeniami dobrze radzi sobie w terenie, jednak pozostawia również spore możliwości rozbudowy. Można np. dodać zewnętrzną antenę WiFi aby poprawić zasięg (obecnie jest to ok 50m na otwartej przestrzeni), diodę doświetlającą, czy też różne czujniki. Najprawdopodobniej następnym krokiem będzie dodanie przetwarzania obrazów, aby pojazd był w stanie podążać za danym obiektem i być może omijać przeszkody. Na koniec krótka prezentacja działania:
  21. 7 punktów
    Witam, pragnę zaprezentować serwomechanicznę ramię nad którym pracowałem przez jakiś czas, zdaje sobie sprawę iż nie jest doskonałe i wymaga jeszcze dopracowania wielu szczegółów, poniekąd jestem konstruktorem amatorem lecz to co robię sprawia mi wielką przyjemność i poczucie osiągania danego celu poprzez naukę, cierpliwość i wytrwałość Serworamię V.1.0. zbudowane jest na podstawie plastikowej obudowy w której zamieszczony jest transformator wraz z przetwornicą napięcia do której to przytwierdzone jest jedno z wielu serw mg995 towerPro dzięki temu obrot ramienia wynosi niemal 230 stopni :-> Wysięgnik ramienia oraz 2 moduł ramienia napędzany jest przez sprzężone serwa mg995 przez co siła uciągu jest podwójna - zapewnia to stabilność oraz znaczne zwiększenie siły wykonywanej pracy. Ostatni moduł ramienia oraz chwytak to spreparowane gotowe konstrukcje zakupione w sklepie botland również napędzane przez serwa mg995 Ogolnie całość napędza 7 serw mg995, zasilacz 150W/12V wraz z przetwornicą 300W step down nastawioną na 6V za bezpieczeństwem odpowiada moduł czujnika temperatury i wentylatora na przetwornicy który pokazuje aktualną temperaturę stabilizatora napięcia. Prąd jaki osiąga podczas pracy przy dużym oporze to blisko 8 Amper. Sterownik jaki zastosowałem obecnie to serwokontroler Polulu mini Maestro 12 kanałowy lecz nie jest on wystarczający do takich prac z powodu częstego "gubienia" zapisanych sekwencji pracy, przez co odtworzenie przynosi wiele uśmiechu myslę o zastosowaniu Arduino w celu tworzenia skryptu oraz przekaźników do zasilania serw - całość będzie bezpieczna, gdyż styki na mini maestro przy gniazdach GoldPin praktycznie się stopiły od prądu przez nie płynącego. z pewnościa konstrukcja wymaga poprawek i wielu modyfikacji, lecz sam nie ukrywam nie mam wystarczająco wiele czasu by działać z tym na bieżąco. zapraszam na film: (video od polowy filmu) __________ Komentarz dodany przez: Treker Następnym razem pamiętaj o dodaniu zdjęć o proporcjach ~3:2 w załączniku (jest one wyświetlane w katalogu robotów). Teraz poprawiłem to za Ciebie
  22. 6 punktów
    Witam chciałem wam przedstawić wykonaną przeze mnie kierownicę do komputera PC. Kierownica nie jest jeszcze do końca wykonana tak jak bym chciał , ale jest skończona działa można ją będzie jeszcze rozbudować Budowa od strony elektronicznej: Do budowy kierownicy użyłem jako podstawę Arduino Leonardo. Opierałem się o podobny projekt który znalazłem na yt . Lecz ja zrobiłem to trochę ładniej niż tamten chociaż nie ma rewelacji mogło być lepiej , ale w przyszłości myślę zrobić jeszcze jedną lepszą Oprócz Arduino Leonardo , zamiast jakiś potencjometrów i kombinowania z przekładniami użyłem enkoder z drukarki Canon IP2700. Ogólnie to oprócz enkodera to jeszcze parę przycisków potencjometry do pedałów i jakieś diody na podświetlenie. Poniżej schemat jak to podłączone. Oprogramowanie gotowe znalazłem pod tym filmem z którego się wzorowałem, wystarczyło wgrać XLoaderem i to wszystko podłączyć jak na schemacie. Od strony mechanicznej wygląda to tak: Odbijanie i blokada zostały zrobione na sprężynie niestety nie mam zdjęć . Dodam link do filmu na którym jest pokazane jak to działa. Ręczny przerobiony ze starej kierownicy . Elementy skrzyni biegów wydrukował mi kolega w 3D. i wygląda to tak: Pedały ze starej kierownicy , dorobiony jeden sprzęgłowy z innej kierownicy: Ostatecznie wygląda to tak: Link do filmu jak to działa i jak zrobione niektóre rzeczy: To by było na tyle w planach zrobienie Force Feed Back , na silniku DC 12v i przekładniach Pozdrawiam Krzysiek
  23. 6 punktów
    Swoją przygodę z elektroniką zacząłem kilka lat temu z celem zbudowania czworonożnego chodzącego robota. Nie bardzo sobie zdawałem wówczas sprawę ze stopnia skomplikowania tego zadania i śmieszy mnie dziś moja ówczesna naiwność, ale od tego czasu minęło parę lat i wiele się nauczyłem. W międzyczasie stworzyłem projekt taniego i łatwego w montażu robota, który opublikowałem pod adresem http://tote.rtfd.io, żeby nieco ułatwić zadanie innym. Naiwnie myślałem, że skoro dałem ludziom prosty punkt startowy, to teraz będą na jego bazie budować bardziej rozbudowane roboty i eksperymentować z platformą. Oczywiście myliłem się straszliwie, choć wiem o kilku konstrukcjach zainspirowanych moją. Dziś sam jestem dziadkiem^W^Wwiedząc więcej o tym jak to działa, postanowiłem zaprojektować zestaw do samodzielnego montażu oparty na podobnych pomysłach, ale bardziej mający formę gotowca. Zamiast optymalizować cenę postanowiłem tym razem zoptymalizować wygodę. Docelowo zamierzam zestaw sprzedawać częściowo zmontowany na Tindie. Dużo szczegółów konstrukcji pozostało z Tote. Nadal używam tanich serw SG90, które nadal zasilam bezpośrednio z baterii LiPo, kompensując za niskie napięcie większą częstotliwością sygnału sterującego. Nadal wykorzystuję fakt, że robot jest taki lekki, żeby przemycić nie do końca koszerne rozwiązania, jak wykorzystanie serw jako stawów nóg, bez dodatkowego podparcia, albo sklejanie ze sobą dwóch serw za pomocą hot glue. Ale tym razem nie używam taniego Arduino Pro Mini i C++, tylko mikrokontroler Atmel SAMD21 i CircuitPython. Nie ma już brzęczyka piezo na nóżce GPIO, tylko głośniczek podłączony do DAC. Do tego dodany jest akcelerometr dla prostego reagowania na ruszanie robotem i to tyle. Na górze jest header z nieużywanymi pinami do wpinania ewentualnych rozszerzeń — czujników lub dodatkowych serw czy światełek. Największą innowacją jest zrezygnowanie z użycia plastikowych orczyków od serw jako elementów konstrukcyjnych nóg, a zamiast tego płytka PCB zawiera, poza układem sterującym robota także wszystkie elementy mechaniczne. Sprawia to też, że łatwo możemy wymienić fragmenty nóg na inne, zawierające czujniki lub inne elementy elektroniczne. Programowanie, jak to w CircuitPythonie, odbywa się poprzez wgranie plików z kodem w Pythonie do robota, który po podłączeniu przez USB pojawia się w komputerze jako dysk. Możliwe też jest eksperymentowanie na żywo za pomocą konsoli pythonowej dostępnej po serialu. Robot jest pod względem mechanicznym w zasadzie ukończony, jak zwykle pozostaje jego zaprogramowanie, które pomimo wykorzystania języka wysokiego poziomu zajmuje mi sporo czasu — muszę się przyznać, że to nie ze względu na trudność problemu, ale na zmęczenie dzienną pracą i ciągłe odkładanie tego na później.
  24. 6 punktów
    Cześć! Skończyłem budowę mojego pierwszego robota. Jest to też mój pierwszy większy projekt, więc proszę o wyrozumiałość, komentarze, porady mile widziane. Z racji tego, że posiadam jeszcze dwa komplety lego, postanowiłem je wykorzystać do budowy pojazdu. Początkowo miały być silniki lego, ale stwierdziłem, że lepiej będzie zrobić to na zwykłych, uniwersalnych częściach. Konstrukcja miała być mała, zwinna, sterowana przez WIFI. Przednia oś, jak widać, sterowana za pomocą micro serwa. Nie było większych oporów, serwo bez problemów sobie radziło ze sterowaniem. Zacząłem szukać jakiegoś ciekawego i małego silnika DC. Postanowiłem wybrać silnik z podwójnym wałem. Kolejnym zadaniem było przebudowanie konstrukcji tak, żeby silnik się zmieścił i nie wadził w poruszaniu się robota. Z racji tego, że wolałem zaoszczędzić kilkanaście złotych na przejściówkę lego-wał, rozwierciłem otwory w częściach które miałem. Zacząłem myśleć jak wyglądałoby połączenie iPhone - ESP, ale w międzyczasie na uczelni dziekan zapowiedział nam dodatkowy projekt na zajęciach z mikrokontrolerów ( pierwsze takie zajęcia na drugim roku studiów ) - dowolny robot na platformie Arduino lub STM. Chłopaki na Facebookowej grupie Arduino uświadomili mi, że nie ma sensu robić projektu na ESP, bo musiałbym się łączyć tylko przez sieć i lepszym wyborem byłby bluetooth. Tak też się stało, zakupiłem moduł HM-10, który współpracuje z używanym przeze mnie iOS. Do tego całość przeniosłem na klona płytki Arduino. Jako aplikacji sterującej użyłem ArduinoBlue, wraz z biblioteką. Inne aplikacje nie chciały działać. W dodatku albo na iOS nie ma żadnych popularnych aplikacji do sterowania przez BLE albo nie udało mi się znaleźć. Możecie polecić ciekawe aplikacje na iOS, na pewno sprawdzę! Można zauważyć, że na breadbordzie zainstalowałem jakąś płytkę. Jest to sterownik silników DC, polecany, łatwy w użyciu. Dobra, silnik jest, działa, serwo jest, łączność przez BLE również. Wypadało by odpiąć wszystko od zasilania z gniazdka i zastosować akumulatory, baterie. Z początku była to dla mnie czarna magia, większe napięcie, jakieś ampery, przetwornice. Czytałem różne artykuły, oglądałem poradniki, pytałem na Facebookowej grupie. Ostatecznie, zgodnie z zasadami: Arduino + sekcja logiczna zasilana z powerbanka + wyprowadzenie zasilania bezpośrednio do serwa, silnik DC zasilany przez dwa ogniwa litowo-jonowe połączone szeregowo z BMS, napięcie zmniejszane przez przetwornicę Żeby szybko podpinać ogniwa do robota albo ładować, przylutowałem wtyki/gniazda DC 5.5mm. BTW. Bardzo długo męczyłem się z lutowaniem ogniw na 30-watowej lutownicy kolbowej. Metodą prób i błędów wszystko się złączyło. Przed podłączeniem każdego elementu lutowanego, sprawdzałem miernikiem czy nie ma zwarcia! Dodatkowo pokusiłem się o popularny czujnik odległości oraz mała prowizorka - dwie diody z opornikami schowane w obudowie po serwie (spaliło się), informujące o przeszkodzie w danej odległości. Wersja finalna, kilkukrotnie większa i cięższa niż pierwotna wersja. Wzmocniony układ kierowniczy. Jeździ, skręca, hamuje, cofa. Trzymany pod kocem Wszelkie komentarze mile widziane! A tutaj krótki filmik (musiałem zdemontować czujnik odległości, ponieważ powodował zakłócenia całego układu: Tak wygląda sterowanie za pomocą joysticka:
  25. 6 punktów
    Co może zrobić uczeń podstawówki, kiedy nie można w szkole używać telefonów? Specjalny kalkulator! Tak, wiem że urządzenie jest trochę przekombinowane - za pare zł mam nowy kalkulator z kiosku, ale to nie jest zwykły kalkulator.Ten kalkulator, albowiem, robiłem ja Budowa Urządzenie posiada wyświetlacz TFT 1.8" ze slotem na kartę pamięci, z której możemy odtwarzać zdjęcia. Do wprowadzania informacji posłużyła mi klawiatura 4x4 w formie naklejki. Całość napędza Arduino Pro Mini, które przeprogramowałem na korzystanie z wewnętrznego kwarcu 8Mhz i wyłączenie BOD. Energię dostarcza akumulator Lipo wyjęty z tableta, ładowany przez dolutowanie się do akusa. Napięcie obniża stabilizator AMS1117 na 3,3v, co rozwiązało kwestię napięcia logiki (TFT ma 3.3v, arduino normalnie 5v) oraz zużycia energii. Wyświetlacz, do programowania, można zdejmować. Po prawej stronie dostrzegamy przełącznik włączający urządzenie, zaś pod TFT znajduje się przycisk funkcyjny. Obudowy nie chciałem robić, gdyż chciałem wzbudzić zainteresowanie wśród kolegów Funkcje Kalkulator ma funkcję liczenia. Wow. Potrafi dzielić, mnożyć, dodawać i odejmować liczby dziesiętne, dodatnie i ujemne - ale nie umie wykonywać kolejności działań (dlatego według kalkulatora 2+2x2=8). ALE. Oprócz kalkulatora, utworzyłem aplikację paint - służy do malowania piksel po pikselu. Dobre na nudne lekcje polskiego. Po włączeniu urządzenia, wyświetla nam się lista dostępnych aplikacji. Oprócz niedokończonego snejka, jest jeszcze "czwarta aplikacja" - ściąga Wyświetla ona wzory z fizyki, chemii i matematyki oraz prawa dynamiki Newtona. Kalkulator może również w progmemie przechować jedno kolorowe zdjęcie, i wyświetlić je po 8x naciśnięciu przycisku Równa się. Taki kalkulator to fajna rzecz, z racji tego że można go używać w szkole bez ograniczeń i da się na nim pobawić. W ostateczności przeglądać memy, po włożeniu karty SD. Pozdrawiam, Leoneq :3
  26. 6 punktów
    Jak zbudować robota kroczącego? Na czym właściwie polega chodzenie? Jakie czujniki są do tego potrzebne? Na te pytania postaram się tutaj odpowiedzieć. Kroczenie a pełzanie Na początek zastanówmy się co tak naprawdę chcemy uzyskać. Aby zbudować urządzenie przemieszczające się bez kół nie potrzeba wiele — ot, dowolny mechaniczny aktuator wykonujący cykliczne ruchy może, na odpowiednim podłożu i przy odrobinie szczęścia, poruszać się jakimś mniej lub bardziej przewidywalnym kierunku. Istnieje nawet całkiem sporo publikacji naukowych o "robotach uczących się chodzić", w których te periodyczne ruchy są sterowane przez sieć neuronową lub inny ewoluujący element tak, aby zoptymalizować prędkość przemieszczania się. Ale ja osobiście nie nazwałbym tego chodzeniem, a już na pewno nie kroczeniem. Czego zatem wymagamy? Według mnie podstawowym i minimalnym wymaganiem jest to, aby żadna część robota nie była wleczona podczas przemieszczania się — aby tylko stopy dotykały podłogi i aby nie poruszały się względem tej podłogi przez cały czas gdy jej dotykają. Raz postawiona stopa musi pozostać w jednym miejscu aż nie zostanie ponownie podniesiona. W ten sposób gwarantujemy sobie dużą niezależność od rodzaju podłoża i minimalizujemy niszczenie jego oraz elementów go dotykających. Oczywiście w praktyce zawsze będą występować drobne ruchy: szpiczasta noga pająko-podobngo robota może, pozostając w miejscu, obracać się, a nawet stopa humanoida będzie się w momencie odbijania od ziemi lekko przesuwać. Ale wiemy już przynajmniej w którym kierunku chcemy... kroczyć. Kroczysz czy się toczysz? Drugim pytaniem, jakie musimy sobie zadać, jest jak dużo kontroli powinniśmy mieć nad ruchami nóg? Czy jeżeli z drewnianego koła od wozu drabiniastego zdejmę felgę i na odsłonięte tak drewniane szprychy pozakładam stare buty, to uzyskam urządzenie kroczące? Nasz pierwszy warunek jest w zasadzie spełniony — but raz postawiony na ziemi nie przesuwa się aż się od niej nie oderwie — jednak uzyskany sposób lokomocji niewiele różni się od zwykłego transportu kołowego, w szczególności dzieląc z nim problemy z radzeniem sobie z nierównym podłożem czy przeszkodami. To samo rozumowanie dotyczyć będzie wszelkiego rodzaju napędzanych jednym silnikiem mechanizmów takich jak Strandbeest czy Hexbugs. Jasne, wyglądają jakby miały nogi i chodziły, ale tak naprawdę są to tylko bardziej skomplikowane koła. W naszych robotach kroczących chcielibyśmy mieć kontrolę nad miejscem postawienia każdej nogi. Stopnie swobody Skoro jeden silnik to za mało, to w takim razie ile stopni swobody musi posiadać nasz robot żeby kroczyć? Powyższy warunek kontroli miejsca postawienia nogi daje nam minimalną granicę dwóch stopni swobody: poruszanie nogą i jej opuszczanie i podnoszenie. I rzeczywiście, można sobie wyobrazić robota składającego się z dwóch trójnogów przemieszczających się względem siebie w przód i w tył oraz w górę i w dół. W praktyce jednak najczęściej stosujemy konfiguracje wzorowane na zwierzętach, z osobnymi nogami o dwóch, trzech albo i więcej stopniach swobody. Niezależnie od konfiguracji, aby poruszać się w linii prostej nasz robot musi umieć podnieść i opuścić każdą z nóg, oraz przesunąć stojącą na ziemi nogę do tyłu wzdłuż linii prostej. Wymaga to dwóch stopni swobody, jeśli noga porusza się równolegle do ciała (jak u kota czy człowieka), lub trzech, jeśli noga porusza się po łuku (jak u pająka lub jaszczurki). Dodatkowo, niezbędne mogą być dodatkowe stopnie swobody jeśli noga posiada stopę, a także jeśli robot ma być w stanie wykonywać zakręty czy nawet obroty w miejscu. Należy się zatem przygotować na konieczność sterowania dużą liczbą aktuatorów (a także ich pozyskania i zasilania), co niestety często jest największą barierą przy budowanie takiego robota. Siła i masa Drugim, poza liczbą aktuatorów, wyzwaniem dla konstruktora robotów kroczących jest masa. Podobnie jak pojazdy latające, a w odróżnieniu od pojazdów kołowych i gąsienicowych, pojazd kroczący niesie własne ciało (plus ewentualny ładunek) siłą swoich silników. Istnieją co prawda bardzo wydajne chody pozwalające na odzyskiwanie i ponowne użycie znacznej porcji energii (ludzie właśnie taki chód stosują), ale są one na tyle zaawansowane, że nie mamy praktycznych systemów je wykorzystujących. Dla amatora-hobbysty pozostaje opcja niesienia całego robota energią baterii. Chcemy zatem, aby nasz robot był jak najlżejszy. Warto przy tym pamiętać o tak zwanym prawie sześcianów: przy zachowaniu wszystkiego innego, masa robota rośnie do sześcianu jego wielkości. Zatem jeśli robot wielkości 1m waży 10kg, to taki sam robot (tylko przeskalowany) o wielkości 2m ważyć będzie 80kg (możemy sobie wyobrazić 8 mniejszych robotów ustawionych w kostkę wewnątrz większego). Stwarza to wiele problemów, oczywiście, bo konstrukcja większego robota, przy użyciu tych samych materiałów, będzie tylko 4 razy mocniejsza, a silniki tylko dwa razy silniejsze. Na szczęście pojemność baterii także wzrośnie proporcjonalnie do sześcianu wielkości. Dlatego zdecydowanie łatwiej jest budować roboty o mniejszych wymiarach. Możemy sobie wówczas pozwolić na użycie tańszych i łatwiejszych w obróbce materiałów i słabszych silników. Oczywiście ograniczy to nam także wielkość i masę jednostki sterującej, ale przy postępującej miniaturyzacji jest to najmniej bolesne ograniczenie. Bardziej bolesne jest ograniczenie masy ładunku, którym nasz robot będzie w stanie manipulować — nie pojeździmy sobie na pająku. Jednak szczególnie dla początkujących zbudowanie małego robota będzie i łatwiejsze i bardziej praktyczne — łatwiej z nim eksperymentować i więcej się można nauczyć. Stabilność statyczna Dla uproszczenia zaczniemy od modelu, w którym nasz robot jest na tyle lekki i porusza się na tyle wolno, że siły bezwładności są pomijalnie małe i możemy je zignorować. W ten sposób z naszych obliczeń eliminujemy zmienną czasu i znacznie je upraszczamy. Dodatkowym ułatwieniem przy takim podejściu jest fakt, że nasz robot może się wtedy poruszać dowolnie wolno, a nawet w dowolnym momencie zatrzymać się bez przewracania. Oczywiście ogranicza to nas wtedy do statycznie stabilnych chodów, no ale od czegoś w końcu trzeba zacząć. W modelu bez inercji warunek stabilności robota jest bardzo prosty: obrysowujemy znajdujące się na ziemi stopy robota wypukłą obwiednią (czyli tak, jakbyśmy zrobili wokół nich pętlę ze sznurka i ją zacisnęli). Kształt, który uzyskamy nazywamy wielokątem podparcia. Jeśli stopy są szpiczaste, jak u insektów, to będą w narożnikach tego wielokąta. Jeśli mają inny kształt, to stanie się on częścią obrysu. Na przykład przy czworonożnym pająkopodobnym robocie i przy wszystkich nogach na ziemi, będziemy mieć czworokąt: A kiedy podniesiemy jedną nogę, uzyskamy trójkąt: Kiedy już mamy nasz wielokąt podparcia, to pozostaje nam znaleźć środek ciężkości naszego robota (uwaga — może się on zmieniać na skutek poruszania nóg czy innych elementów), poprowadzić z niego pionową kreskę aż do ziemi (zgodną z kierunkiem działania grawitacji) i sprawdzić, czy znajduje się ona wewnątrz naszego wielokąta. Jeśli tak, robot będzie stał. Jeśli nie, to znaczy że już się przewraca. Przy okazji, odległość tego punktu od najbliższego brzegu wielokąta podparcia jest dobrym wyznacznikiem stabilności robota — jego odporności na zewnętrzne siły. W przykładzie powyżej pionowy rzut środka ciężkości wypada dokładnie na brzegu trójkąta — zatem robot przewróci się od najdrobniejszego dotknięcia czy wibracji. Aby tego uniknąć, można przesunąć trzy nogi robota w kierunku tej, która ma zostać podniesiona zanim zaczniemy ją podnosić: To właśnie dlatego kroczące roboty często kiwają się na boki — przesuwają swój środek ciężkości, aby zawsze mieścił się w wielokącie podparcia. Stabilność dynamiczna Gdy chcemy, aby nasz robot poruszał się szybciej, a także potrafił chodzić z mniej niż trzema nogami na ziemi i bez rakiet śnieżnych, to musimy uwzględnić w naszych obliczeniach bezwładność. Jest wiele sposobów na zrobienie tego, ale niestety większość oznacza numeryczne rozwiązywanie skomplikowanych równań różniczkowych, co wymaga sporej mocy obliczeniowej. Istnieje jednak jedna dość prosta metoda nie wymagająca złożonych obliczeń, nazwana ZMP (zero-movement point). Czym jest ZMP? Pamiętacie ten punkt na ziemi bezpośrednio pod środkiem ciężkości robota? To właśnie jest ZMP w przypadku, kiedy inercja jest zerowa. W przypadku, gdy nie jest ona zerowa, punkt ten przesuwa się zgodnie z kierunkiem i siłą jej działania. Jest to po prostu punkt, w którym musielibyśmy się podeprzeć, żeby w danym momencie się nie przewrócić. Zatem wystarczy, że tak będziemy planować nasze ruchy, żeby ZMP nigdy nie znajdował się poza wielokątem podparcia na tyle długo, żeby robot się zdążył przewrócić, a wszystko będzie działać. No dobra, ale jak możemy wyznaczyć ZMP? Okazuje się, że jest na to kilka bardzo prostych sposobów. Jeśli mamy w stopach robota czujniki nacisku, to mierząc i uśredniając działające na nie siły jesteśmy w stanie wyznaczyć ZMP. Możemy też ZMP wyznaczyć przy pomocy akcelerometru, jeśli znamy środek ciężkość — wystarczy poprowadzić linię w kierunku wskazywanym przez niego, a tam gdzie przetnie podłogę będzie ZMP. Kinematyka odwrotna Aby mieć dobrą kontrolę nad tym co nasz robot robi i gdzie dokładnie stawia stopy, musimy opanować geometrię jego nóg i potrafić wyliczyć jak te nogi przesunąć żeby ustawiły się w danej pozycji. Takie obliczenia nazywane są kinematyką odwrotną i w przypadku nóg o dwóch lub trzech ortogonalnych stopniach swobody są relatywnie proste — wystarczy nam znajomość trygonometrii ze szkoły podstawowej. Cała sztuka sprowadza się do tego, aby współrzędne stopy móc przeliczyć na kąty w poszczególnych stawach nogi. Oczywiście dla każdej konfiguracji obliczenia będą inne, zatem nie będę się w nie tutaj bardzo zagłębiał. Oczywiście da się poradzić sobie z tym problemem bez obliczeń, po prostu zaszywając w programie poszczególne pozy naszego robota i przejścia między nimi. Niestety takie podejście nie pozwala nam modyfikować chodu w odpowiedzi na nierówny teren, dodatkowe siły, skręcanie czy zmianę pozycji ciała względem trasy — zatem daje naszemu robotowi niewiele przewagi nad zwykłym robotem na kołach. Układy współrzędnych Układ współrzędnych, w którym określana jest pozycja stopy względem ciała robota (a w zasadzie względem punktu przyczepienia nogi do tego ciała), to tylko początek. Oczywiście każda noga będzie miała swój. Ale jeśli chcemy naszego robota kontrolować jako całość (na przykład żeby przesuwać jego ciało celem odpowiedniego ustawiania środka ciężkości), to będziemy chcieli mieć drugi układ współrzędnych, wspólny dla wszystkich nóg — układ współrzędnych ciała. Następnie przydałoby się znać pozycję niejako środka robota, ignorującą przesunięcia ciała wynikające z balansowania i ruszania nogami — to, czym sterowalibyśmy przy pomocy zdalnego sterowania, na przykład. To układ współrzędnych wirtualnego pojazdu. No i wreszcie, jeśli nasz robot zapamiętuje mapę otoczenia, to wypadałoby mieć układ współrzędnych świata, w którym ten wirtualny pojazd się przesuwa. Przejścia pomiędzy tymi układami współrzędnych najłatwiej zrealizować poprzez mnożenie współrzędnych przez macierze przejścia pomiędzy bazami. W ten sposób trywialnie zaimplementujemy translację i rotację ciała robota. Chód Sam chód to prosta sprawa, choć oczywiście istnieje wiele wariacji na jego temat. Generalnie idea jest taka, że wszystkie nogi znajdujące się na ziemi przesuwają się do tyłu (najlepiej jednostajnie, choć można to też robić skokowo), a te najdalej wysunięte do tyłu są podnoszone i przestawiane do przodu kiedy tylko jest do tego okazja (na tyle szybko, żeby się nie skończył ich zakres ruchu do tyłu). W przypadku czworonogów istnieje optymalna kolejność takiego przestawiania (prawa-przednia, lewa-tylna, lewa-przednia, prawa-tylna) zapewniająca najlepszą stabilność, w przypadku dwunogów nie ma za bardzo wyboru, a sześcio-i-więcej-nogi mogą sobie pozwolić na dużo fantazji w tym zakresie. Statycznie stabilny chód u czworonogów jest jeden i nazywa się "creep" (skradanie się?) — polega na przestawianiu jednej nogi na raz. Gdy mamy stabilność dynamiczną, to możemy przejść do kłusu ("trot"), w którym przestawiamy dwie nogi na raz — po przekątnej, a nawet do galopu, w którym momentami tylko jedna noga dotyka ziemi (istnieją 4 wariacje tego chodu, w zależności od kolejności nóg). Jeśli mamy naprawdę szybki komputer i dobre czujniki (i silne aktuatory), to możemy nawet skakać... To tyle Tyle potrafię na ten temat napisać bez wchodzenia w szczegóły dotyczące konkretnych konfiguracji (humanoid, czworonóg, sześcionóg, etc.). Mam nadzieję, że jest to przynajmniej jakiś punkt startowy dla hobbystów projektujących swojego pierwszego robota kroczącego.
  27. 6 punktów
    Budżet każdego cubesata zawierającego podobne komponenty jest podobny. Ceny podzespołów dla nas i w innych krajach są podobne, koszty rakiety również. Nie mam dokładnie takich informacji, ale np. w Stanach buduje się cubesaty na każdym uniwersytecie więc być może nie jest to takie wielkie wydarzenie jak u nas. Są normy np. europejskie ECSS, które są nieaplikowalne do cubesatów i innych satelitów (komercyjnych) z tzw. "new space". Nieaplikowalne ze względu na wymiary, budżet i szereg innych powodów. Warto jednak przeczytać i wybrać z tych standardów rzeczy aplikowalne. Cały satelita powstał z elementów tzw. COTS, czyli tego co można kupić w sklepie. Jednak nie były to przypadkowe elementy: co tylko było dostępne było wybierane w wersjach hi-rel (np. kondensatory, które mają określony failure rate), komponenty z serii z rozszerzonym zakresem temperaturowym. Nie były używane obudowy typu BGA czy DFN, szczególnie w "busie" satelity (czyli kluczowych elementach jak układ zasilania, komputer pokładowy itd.). Część kluczowych komponentów ma redundancję. Jak najbardziej. Może przy tak krótkiej misji nie ma dużej obawy o TID, ale single eventy i spowodowane nimi latch-upy mogą się zdarzyć. Po pierwsze staraliśmy się wybierać elementy które już leciały i się spisały (tzw. flight heritage), po drugie elementy COTS często bywają testowane ze względu na odporność na promieniowanie (CERN robi dużo takich testów i publikuje te dane, ale nie tylko oni). Mikrokontroler w komputerze pokładowym (OBC) ma zewnętrzne pamięci SRAM a ich zawartość przechodzi przez FPGA który robi korekcję błędów "w locie" tak, aby właśnie bity zmienione przez promieniowanie nie zakłóciły pracy. To samo z kodem programu - przechowywany jest w 6. kopiach a bootloader robi głosowanie na 3. slotach i dopiero wtedy ładuje poprawny obraz (potrafi go też naprawiać i sklejać). Samo oprogramowanie OBC w trakcie robi tzw. scrubbing na pamięciach. Z układu zasilania: wszystkie linie zasilania mają zabezpieczenia nadprądowe tzw. latch-up current limitter (LCL) - jeśli któryś podsystem dostanie latchu-upa od promieniowania to zostanie zresetowany. Tam gdzie to potrzebne i osiągalne. Redundancja szczególnie potrzebna jest w systemie zasilania (np. są dwa mikrokontrolery), system rozkładający anteny (mikrokontroler + rezystory przepalający linkę "trzymającą" anteny w pozycji złożonej) też są zdublowane. Sam żagiel ma dwa rezystory oddzielnie sterowane dla redundancji. Dochodzi też redundancja na poziomie systemu - nawet jeśli OBC przestanie działać - automatycznie otwarcia żagla dokona układ OBC (który ma dwa mikrokontrolery, a każdy z nich steruje oddzielnym rezystorem zwalniającym żagiel). Są ścianki z aluminium + zasobnik na żagiel i akumulatory to całkiem dobry shielding. Dobre pytanie - staraliśmy się wzorować na innych (na ich sprawdzonych rozwiązaniach), ale jest to dosyć ciężkie. Mało konstrukcji, nawet studenckich jest udostępnionych. Będziemy chcieli ze swojego projektu udostępnić jak najwięcej, w jak najlepszej formie. Przynajmniej ze strony elektroniki i software. Dużo wiedzy wynieśliśmy z Centrum Badań Kosmicznych, przeglądy projektu robiła ESA. Jeśli chodzi o materiały to są wspomniane ECSS i pewnie dziesiątki innych publikacji/materiałów z których korzystaliśmy a teraz "na szybko" ich tytułów nie wyczaruję. Wrócę na pewno do tego tematu za jakiś czas (pewnie po misji).
  28. 6 punktów
    Nie samą maliną człowiek żyje Już na samym początku wspominałem o tym, że Raspberry Pi nie jest wcale ani jedyną, najlepszą, ani najtańszą platformą sprzętową dla wbudowanego Linux-a. Jej ogromnym plusem jest bardzo dobre wsparcie, ale nic nie stoi na przeszkodzie w używaniu innych płytek. I tutaj ważna uwaga - w bardzo podobny sposób możemy łatwo przygotować obraz systemu również dla innych platform. Yocto wykorzystuje tzw. warstwy - są to zestawy gotowych skryptów, jak dla mnie to takie moduły, czy biblioteki, ale ktoś wymyślił określenie warstwa więc będę się tego trzymać. W internecie znajdziemy całkiem sporo gotowych warstw, wiele osób przygotowuje własne - my też możemy, chociaż to chyba trochę bardziej zaawansowany temat. Co ważne warstwy pozwalają na oddzielenie części sprzętowej (BSP - Board Support Package) od reszty systemu. Więc zmieniając warstwę meta-raspberrypi na inną dostaniemy taki sam system (tzn. z takimi samymi pakietami), ale działający na innej platformie. Jakie platformy są wspierane? W sumie to prawie wszystkie - najlepiej do znajdowania warstw użyć wyszukiwarki: http://layers.openembedded.org/layerindex/branch/sumo/layers/ Wspomnę o kilku platformach, które moim zdaniem są warte uwagi: BeagleBone - jest domyślnie wspierana przez Yocto i włączona do dystrybucji Odroid (http://layers.openembedded.org/layerindex/branch/sumo/layer/meta-odroid/) - często wymieniane jako konkurencja malinki, na ogół wydajniejsze niż oryginał Xilinx (http://layers.openembedded.org/layerindex/branch/sumo/layer/meta-xilinx/) - tutaj znajdziemy wsparcie dla układów Zynq, czyli FPGA z Cortex-A9 Freescale (http://layers.openembedded.org/layerindex/branch/sumo/layer/meta-freescale/) - bardzo fajne procesory i płytki, trochę droższe ale z lepszą dokumentacją Intel (http://layers.openembedded.org/layerindex/branch/sumo/layer/meta-intel/) - yocto może też przygotować dystrybucję dla x86. Stary komputer może odzyskać drugą młodość jeśli potraktujemy go jako urządzenie wbudowane. Poza tym są wszystkie LattePanda i podobne (był też Edison, ale to już historia) Tegra (http://layers.openembedded.org/layerindex/branch/sumo/layer/meta-tegra/) - coś dla miłośników szybkich maszyn oraz GPU (albo hackerów Nintendo Switch) W nieco starszej wersji yocto mamy jeszcze większy wybór: Altera (http://layers.openembedded.org/layerindex/branch/rocko/layer/meta-altera/) - układy z FPGA oraz Cortex-A9, odpowiednik Zynq od Xilinx-a. Właśnie tej warstwy używałem przygotowując oprogramowanie dla mojego wyświetlacza paneli LED (https://forbot.pl/forum/topic/12015-wyswietlacz-z-paneli-led/) AllWinner (http://layers.openembedded.org/layerindex/branch/rocko/layer/meta-sunxi/) - to coś dla miłośników tańszych układów, znajdziemy je na wszelkiej maści OrangePi, BananaPi, NanoPi oraz Olinuxino Jeśli będzie zainteresowanie tematem Yocto, postaram się opisać nieco dokładniej możliwości jego wykorzystania z Raspberry Pi - ale większość omawianych możliwości można wykorzystać na innych platformach.
  29. 6 punktów
    Pojawiają się tutaj co jakiś czas dyskusje o kosztach naszego hobby i o porównywaniu cen w różnych sytuacjach. Sam ostatnio zacząłem sprzedawać swoje projekty na Tindie, więc postanowiłem napisać artykuł wyjaśniający dlaczego rzeczy nowe, niszowe i robione przez hobbystów są takie drogie, podczas gdy takie Raspberry Pi Zero można kupić za 50zł (i dwa razy tyle kosztu wysyłki). Przy okazji być może wyjaśni to też dlaczego tak wiele kickstarterów się nie udaje. Różnica pomiędzy projektem a produktem Większość z nas ma już jakieś tam doświadczenie w realizowaniu projektów elektronicznych. Wymyśliliśmy (lub skopiowaliśmy z noty katalogowej) schemat, zaprojektowaliśmy płytkę, wytrawiliśmy ją, zamówiliśmy próbki części, zlutowaliśmy wszystko, zaprogramowaliśmy, zdebugowaliśmy, pięknie nam działa, koniec. Czas otwierać szampana i zakładać stronę na kickstarterze, już wkrótce wszyscy hobbyści będą mogli korzystać z naszego wspaniałego nowego produktu, który kosztował nas dużo mniej niż podobne produkty dostępne w sklepach, a przecież wyprodukowaliśmy tylko jedną sztukę -- w masowej produkcji powinno być jeszcze tańsze, prawda? Tak właśnie miałem z moim shieldem. Udało mi się gdzieś kupić okazyjnie matryce ledowe, które wielkością pasują idealnie do D1 Mini i aż się proszą o shielda. Napisałem też ostatnio bilbiotekę do obsługi HT16K33, który bardzo łatwo taką macierzą steruje. Tylko dodać dwa oporniki do I2C i gotowe. Będę to sprzedawał za dolara od sztuki. Kilka miesięcy i 5 prototypów później już nie byłem taki pewien. Oczywiście, błędy, które popełniałem były głupie i wynikały z roztargnienia i zbyt dużej pewności siebie. W końcu to taki prosty projekt. Mimo to czas mija, części na kolejne prototypy kosztują. Kilka razy projekt porzuciłem, ale jakoś zawsze jednak do niego wracałem. W końcu na początku roku uzyskałem coś, z czego byłem w miarę zadowolony. (Muszę tu przyznać, że projekt rzeczywiście był wyjątkowo pechowy, no ale nie kontrolujemy tego i nigdy nie możemy zakładać, że wszystko się uda.) No dobra, to teraz czas rozpocząć produkcję "masową". Powiedzmy 40 sztuk -- powinno się sprzedać błyskawicznie, jak tylko ludzie to zobaczą, to na pewno się rzucą i wtedy będę mógł zrobić kolejną partię, 400 albo i 4000 sztuk. No dobra, to gdzie najlepiej zrobić 40 płytek? Zdecydowałem się na DirtyPCB z ich ofertą 10 (+/-1) płytek o wymiarach 5x5cm -- bo udało mi się wcisnąć w tym obszarze cztery swoje płytki, a pozwalają na panelizację. Poprawiłem kilka detali, wcisnąłem po 4 płytki w jeden gerber, zamówiłem. Miesiąc później nadal czekam na płytki -- piszę do nich o co chodzi, zawsze płytki w 2 tygodnie były -- a oni mi odpisują, że mają dużą kolejkę po chińskim nowym roku, do tego musieli zmienić wykonawcę, etc. Acha, jako bonus, zmienili ostatnio wygląd strony i od tego czasu nie pokazuje się obrys płytki na podglądzie. Niby drobiazg, ale będzie to istotne później. W międzyczasie zamówiłem macierze i czipy. Płytki są małe, więc użyłem w nich najmniejszej wersji HT16K33, z minimalną liczbą nóżek. Okazuje się, że trudno znaleźć je w większych ilościach i są droższe. No trudno, kilka centów na czipie mnie nie zbawi, a płytki już zamówiłem. No to teraz macierze. Okazuje się, że są dwa rodzaje -- ze wspólna anodą i ze wspólną katodą. Oczywiście w przypadku macierzy 8x8 nie ma tu absolutnie żadnej różnicy, bo obie wersje mają po prostu LED-y podłączone do kolumn i wierszy, ale różnią się one wyprowadzeniami. Zatem należy uważać co się zamawia -- oczywiście najtańsze oferty nie mają w opisie informacji o tym jakie mają wyprowadzania albo jakiego są typu -- nie będę ryzykować kupowania 40 macierzy, które się potem okażą złe. Zatem trzeba wziąć te droższe. Zazwyczaj są w paczkach po 10 sztuk, więc sobie wymyśliłem, że zamówię różne kolory i ludzie będą sobie mogli wybrać. Doskonale, ale wszystko, co nie jest czerwone, jest dwa razy droższe. No trudno. To pewnie w ramach promowania komunizmu. Wysyłka na szczęście darmowa, zamówione. Mniej więcej dwa tygodnie po tych zamówieniach, pracując nad innymi projektami zorientowałem się, że co prawda mam zapas oporników, ale nie aż tyle, żeby zmontować te wszystkie macierze. No to jeszcze zamówiłem oporniki, 500 sztuk na zapas. Przyszły macierze. Zamawiając nie zauważyłem, że wszystkie są od tego samego sprzedawcy, więc przyszły w jednej paczce, która przez to przekroczyła próg cła i dopłaciłem drugie tyle za cło (tu gdzie mieszkam płaci się cło i "opłatę manipulacyjną" za to, że sprawdzili co to jest i oclili, która wynosi często więcej niż samo cło). Kolejna kosztowna pomyłka. W tym momencie już wiedziałem, że za dolara ich sprzedawać nie będę. Przyszły w końcu płytki. Okazało się, że zrobiłem błąd w projekcie i otwór na środku płytki, który powinien rozdzielać panele, nie jest wycięty. Oczywiście zemścił się brak podglądu, ale ostatecznie to moja wina. Dwa dni zajęło mi powycinanie 40 płytek dremelem. To teraz składanie. Najpierw polutowałem do wszystkich płytek oporniki i czipy. Oczywiście przez nieuwagę na dwóch płytkach czipy przylutowałem odwrotnie. Pojawiły się pierwsze zamówienia. Polutowałem do końca zamówione egzemplarze, przetestowałem czy działają i... jak ja mam to wysłać? Potrzebuję kopert bąbelkowych. W domu znalazłem dwie, na razie wystarczy, ale trzeba kupić więcej. Poszedłem na pocztę, popatrzyłem na ceny kopert i stwierdziłem, że zamówię je z Chin. No ale trzeba najpierw wysłać zamówienia. Ustalając ceny sprawdziłem koszty wysyłki na stronie poczty, więc teraz całkiem pewnie podaje pani w okienku koperty i mówię, że chcę to wysłać. Pani mierzy grubość i mówi, że musi wysłać jako paczkę, cztery razy drożej. No trudno, płacę i wracam do domu. Zamówiłem koperty (oczywiście dziesięć razy taniej niż na poczcie) i dodałem do strony produktu informację o tym, że wysyłam z nieprzylutowanymi nóżkami, bo inaczej się nie mieści do koperty. Biorę się za lutowanie pozostałych macierzy. Polutowałem wszystkie kolory i zabieram się za sprawdzanie -- zrobiłem sobie testing rig, tak że dość prosto mogę podłączyć i odpalić prosty program zapalający wszystkie piksele. Wszystkie niebieskie sprawne. Wszystkie czerwone sprawne, tylko w jednym miejscu mostek z cyny do usunięcia. Sprawdzam białe -- sprawna co druga. Hmm. Patrzę na kilka macierzy, które mi zostało -- oczywiście oznaczenia góra/dół mają całkowicie losowo -- a to według nich je lutowałem. Odlutować tego teraz już nie ma jak, połowa do wyrzucenia. Przyszły koperty, pojawiło się więcej zamówień. Skończyły mi się piny -- używałem tych, które miałem w zapasie -- trzeba zamówić. Kończy mi się rolka cyny, grot lutownicy zaczyna wykazywać oznaki zużycia. Moja lutownica jest markowa i droga i takież są też do niej groty. Wysyłam to, co mam zrobione aż się nie skończą -- średnio 1-2 zamówienia tygodniowo. Więcej nie będę raczej tego robić. Wszystkie projekty udostępniłem na otwartej licencji -- może jakiś Chinczyk to weźmie i zacznie produkować taniej i z darmową wysyłką. Koniec końców, wyszło około $5 za sztukę, z około $2 za wysyłkę do tego. Czyli siedem razy więcej, niż szacowałem. Oczywiście nie wliczyłem w cenę własnej robocizny -- ani godzin spędzonych na projektowaniu i testowaniu, ani na składaniu tego, ani na bieganiu na pocztę i wysyłaniu. Siedzę i czekam aż płytki dotrą do klientów -- i boję się, że coś będzie nie tak i trzeba będzie oddawać im kasę albo wysyłać nowe. Duży może więcej No dobra, to jakim cudem możemy kupować te płytki za $2 z darmową wysyłką? Dlaczego chińscy producenci nie mają takich problemów? Powodów jest kilka: Po pierwsze, mają subsydiowaną przez rząd darmową wysyłkę i wszystkie części dostępne na miejscu bez cła. Mogą kupować te najtańsze części bez dokumentacji, bo po prostu sobie sprawdzą czy wyprowadzenia są dobre. Po drugie, produkują w naprawdę gigantycznych ilościach i mają hurtowe ceny. Dodatkowo potrafią wynegocjować sobie naprawdę dobre warunki. Po trzecie, nie robią w zasadzie żadnej kontroli jakości. To jest krok, który u mnie okazał się najbardziej kosztowny -- nie dlatego, że był czasochłonny, choć był, ale dlatego, że wadliwych produktów nie sprzedam -- a Chińczyk by sprzedał. Po czwarte, mają naprawdę dobrze ogarnięty cały proces, wszystko przygotowane z góry, robili to już wiele razy, więc wiedzą czego się spodziewać. U mnie wiele kosztów wynikało z tego, że coś przegapiłem albo zapomniałem -- tam, nawet jeśli coś takiego się na początku zdarzy, to te koszty znikną przy takiej skali. Po piąte, nie mają kosztów projektowania, bo to są w większości otwarte projekty, które ktoś już im zaprojektował. Nawet jeśli musi na to spojrzeć specjalista, to znowu koszt jego pensji znika przy tej skali. Czyli kupować tylko od Chińczyka? Z ekonomicznego punktu widzenia, wydaje się to logiczną decyzją -- w końcu pieniądze nie rosną na drzewach. Najlepiej więc projektować wszystko tak, żeby używało tanich chińskich modułów? Taka taktyka działa dobrze na krótką metę. Jednak jest jeden podstawowy problem -- oni rzadko projektują coś nowego, nawet kiedy to robią, to nie jest to zbyt długo wspierane. W tym samym czasie technika galopuje do przodu i pojawiają się nowe rozwiązania. Potrzebujemy nowych projektów i potrzebujemy społeczności wokół nich, które będą je wspierać. Zatem być może jednak warto kupić czasem taki "przedrożony" nowy produkt -- w ramach inwestycji na przyszłość.
  30. 6 punktów
    Witam, przedstawiam autonomicznego robota balansującego. Robot balansujący na Atmega 1284P 20MHz. Obsługuje komunikację oraz zmianę wsadu za pomocą bluetooth. Ponadto istnieje możliwość sterowania robotem za pomocą pilota IR, oraz zmiany nastawów regulatorów. Posiada system autonomicznej jazdy z wykorzystaniem 3 sensorów ultradźwiękowych. Delikatne ruchy robota w stanie spoczynku spowodowane są dużymi luzami w przekładniach silników. Robot radzi sobie bez problemów ze średniej wielkości nachyleniami podłoża. Sterowanie odbywa się poprzez aplikację na system android, która to wyświetla także podstawowe informacje o robocie (napięcie baterii, wielkość całki w regulatorze pochylenia itp). Tryb autonomicznej jazdy opiera się o trzy ultradźwiękowe czujniki odległości. W oparciu o ich wskazania, robot samoistnie podejmuje decyzje co do dalszej drogi. Jest to ostateczna wersja robota która posiada także prócz trybu autonomicznego, tryb zdalnego sterowania na odległość do 100 metrów. Zaimplementowany moduł auto diagnozy potrafi wykryć 32 ostrzeżenia i błędy, np od niskiego napięcia 12v 5v, po jego niestabilność, uślizg kół, luzy na piastach, opory toczenia i przekładni... itp.... itd... Uruchomienie poszczególnych funkcji robota odbywa się poprzez komendy terminala uart, lub wygodniej pilot ir. Wszystkie parametry robota wyświetlane są na 5 pulpitach 4 wierszowego wyświetlacza lub uproszczone w dedykowanej aplikacji na system android. __________ Komentarz dodany przez: Treker Witam na forum, następnym razem proszę pamiętać o zdjęciu w formie załącznika, które widoczne będzie później w katalogu robotów oraz na stronie głównej. W tym przypadku już poprawiłem
  31. 6 punktów
    W tym tygodniu mam dużo pracy i jeszcze nie udało mi się usiąść do myszy, ale ostatnio zdefiniowałem sobie problem przyspieszenia i dzisiaj zupełnie przypadkiem zapaliła mi się lampka w głowie: przyczepność i wynikający stąd poślizg to sprawa wtórna. To co istotne to II zasada dynamiki: F=m*a Czyli możliwości przyspieszania myszy zależą głównie od jej bezwładności (masy) i siły, czyli momentu silnika dzielonego przez promień koła. Żeby nie mielić na pusto wzorów, spróbujmy policzyć jaki moment powinien mieć silnik napędowy dla zadanego przyspieszenia, albo może lepiej z jakim przyspieszeniem mogę próbować rozpędzać mysz obecnym napędem. Moja mysz bez zasilania waży równiutko 100 g. Na razie jeżdżę z ciężkim pakietem 1600mAh o masie 102 g. Docelowo pakiet, powiedzmy 180mAh waży 20 g. Masa obecna to 202 g, docelowa120 g. Teraz siła. Silnik Pololu z przekładnią 10:1 ma moment 0,029 Nm. Średnica koła to 42 mm, stąd promień to 21 mm. Tak więc maksymalna siła na jednym kole przy pełnym wysterowaniu silnika to: F = M / r = 0,029 / 0,021 = 1,38 N Silniki są 2 więc mamy łączna siłę 2,76 N. Do tego dojdzie tarcie kulki podporowej, więc zaokrąglam siłę do 2,5 N. Teraz przyspieszenie dla obecnego i docelowego rozwiązania. a = F / m a1 = 2,5 / (9,81*0,202) = 1,26 m/s^2 a2 = 2,5 / (9,81*0,120) = 2,12 m/s^2 Gdybym zmienił przekładnię na 30:1 o momencie 0,059 Nm, to miałbym siłę na kole 2,8 N i łączną powiedzmy 5,4 N. Przyspieszenia to odpowiednio 2,73 m/s^2 oraz docelowo 4,59 m/s^2. Tutaj czuć ogień! Dla kompletu informacji warto podać jeszcze prędkości postępowe obu porównywanych napędów: P10:1 ma prędkość obrotową 3000 obr/min => 50 obr/s, więc prędkość liniowa to obrotowa razy obwód: 50 * 2 * Pi * 0,021 = 6,6 m/s P30:1 ma prędkość obrotową 1000 obr/min => 16,67 obr/s, więc prędkość liniowa to obrotowa razy obwód: 16,67 * 2 * Pi * 0,021 = 2,2 m/s Celem konkurencji jest najkrótsza eksploracja i najszybszy przejazd. Zakładając że eksploracja pozwala na jazdę komórka po komórce, więc robot musi rozpędzić się przez połowę komórki a w drugiej części hamować. Mając przyspieszenie i drogę można policzyć czas przejechania komórki dla obu napędów (10:1 i 30:1): t = sqrt( l / a) t10 = sqrt(0,18 / 2,12) = 0,29 s t30 = sqrt(0,18 / 4,59) = 0,20 s Tutaj widać że trzydziestka bije na głowę dziesiątkę. Szybkość przejazdu to trochę bardziej skomplikowana sprawa. Zróbmy to na jakimś przykładzie, tak aby przyjąć ilość odcinków o zadanej długości, np taki labirynt: ma 12 przejazdów po 1 komórce 3 po 2 komórki 4 po 3 5 po 4 2 po 5 1 po 11 komórek 1 po 12 komórek. Teraz trzeba wyliczyć jaki odcinek potrzebny jest do rozpędzenia się do maksymalnej prędkości. Wychodzę ze wzoru na czas rozpędzania do Vmax: t = v / a t10 = 6,6 / 2,12 = 3,11 s t30 = 2,2 / 4,59 = 0,47 s dochodzę do wzoru na drogę jaką pokona rozpędzając się do Vmax l = a * t^2 l10 = 2,12 * 3,11^2 = 20,5 m l30 = 4,59 * 0,47^2 = 1,01 m Już bez większego liczenia widać że napęd 10:1 aby się rozbujać potrzebuje 20 m i zupełnie nie nadaje się do tego typu robota. Napęd 30:1 rozpędzi się na maksa na drodze 6 komórek labiryntu i drugie 6 będzie hamował, więc w tym labiryncie tylko w jednym przejeździe przez chwilę osiągniemy maksymalną prędkość. To pokazuje że warto rozważyć nawet jeszcze wolniejszy napęd dający jeszcze większe przyspieszenie. W międzyczasie zrobiłem arkusz kalkulacyjny do przeliczenia 4 napędów: 10:1, 30:1, 50:1 i 100:1. Odcinki labiryntu podzieliłem na część w której robot się rozpedza i część z jaką jedzie z maksymalną prędkością. Policzyłem czasy pokonywania drogi przyspieszając, czas jazdy z maksymalną prędkością i łączny czas jazdy. Wyszło mi coś takiego: 10:1 = 6,59 + 0 = 6,59 s 30:1 = 4,6 + 0,06 = 4,66 s 50:1 = 2,77 + 4,01 = 6,77 s 100:1 = 0,73 + 18,97 = 19,7 s Wyniki oczywiście będą się zmieniały w zależności od masy i drogi labiryntu, ale dla zastałych warunków wyraźnie widać, który napęd jest optymalny.
  32. 6 punktów
    Cześć, Od jakiegoś czasu już się zbierałem do opisu konstrukcji. Hexapod, jak sugeruje nazwa, ma 6 nóg i chodzi . Powstał jako projekt 3-osobowego zespołu w ramach koła naukowego w ciągu ostatnich 4 miesięcy. Mechanika 12 stopni swobody, Hitec HS 645MG. Konstrukcja z blachy aluminiowej o grubości 3mm, elementy trzymające serwa z blachy aluminiowej 8mm. Od dołu podparcie na łożysku wkręconym w płytę korpusu. Masa konstrukcji 2100g. To chyba tyle. Całość konstrukcji wykonana przez nas na frezarce(dwuosiowej bez sterowania numerycznego i stołu obrotowego, więc łuki i fazy na ręcznym CNC ). Model 3D w Inventorze jest dość szczątkowy, takie minimum jakie bylo potrzebne do sprawdzenia czy to będzie działać. Żeby nie tracić czasu od razu przeszliśmy do fizycznego modelu 3D. Elektronika Całość układu sterowania opiera się o gotowe rozwiązania-na pokładzie jest Raspberry Pi i MiniMaestro. Układy komunikują się poprzez UART, z konwerterem poziomów po środku. Sterowanie W wielkim skrócie-robot rozwiązuje sobie równania różniczkowe, rzuca rozwiązania na kinematyke odwrotną, i tak w kółko. Serwa ustawiają się stosownie do wyliczonych pozycji. Informację o tym gdzie mają trafić wysyłamy przez UART. W tej chwili system sensoryczny sprowadza się do tego, że jest maszyna stanów, którą mogłby zarządzać sygnaly z czujników, tyle że czujników nie ma(jeszcze), jest za to bezprzewodowa klawiatura Robot może chodzic do przodu, do tyłu, i obracać się przez chodzenie jedną połową robota do przodu, drugą do tyłu. Zasilanie W robocie jest lipol 2S o pojemności 6000mAh. Do niego są 2 przetwornice na 5V. Jedna 5A do części logicznej Maestro i do Raspberry, druga na 9A na samo zasilanie serw. Podsumowanie Opis dość lakoniczny, bo skupiłem się na konkretach. Jeżeli będą jakieś pytania odpowiem. Robot w obecnym stanie pozostanie już niedługo, będzie trochę bardziej zaawansowany i mądrzejszy, ale o tym napiszę jak już taki będzie. Prace są w toku cały czas Zdjęcie robota: Filmik z chodzenia: Filmik z samego wiosłowania:
  33. 5 punktów
    Cyfrowa stacja lutownicza Jest to mój 2 prolekt po 12 letniej przerwie z elektroniką. Była to okazja do poznania Eagle oraz podstaw programowania mikroprocesorów. Obecnie wiele rzeczy bym poprawił i docelowo tak się chyba stanie. Działanie stacji oceniam bardzo pozytywnie. Obecnie mam 3 stacje lutownicze, więc już mogę coś na ten temat napisać ale to już dłuższy temat. Projekt polecam wszystkim, którzy mają niewykorzystane trafo 2x12V 60VA (minimum) oraz LCD1602 i procesor Atmega8. Są to chyba 3 najdroższe elementy (pomijając kolbę 907A, którą przez internet można kupić poniżej 30zł z kosztami wysyłki). Docelowo schemat podzieliłem na 2 zasadnicze części: 1. Płytka zasilająca 2.Płytka sterowania Wzory płytek w Eagle standardowo dostępne są w załączniku. A tutaj jeszcze foto gotowych płytek: Aby ułatwić możliwość wymiany procesora i wzmacniacza operacyjnego, zostały one umieszczone w podstawkach. Płytka sterująca oraz płytka zasilająca zostały połączone za pomocą złącza goldpin. Obudowa została wykonana z płyt meblowych oklejonych fornirem dębowym. Dodatkowo składałem dla znajomego CNC z chin i w ramach testów wykonałem panel przedni oraz tylni na tym CNC (materiał to 1,5mm blacha aluminiowa). Efekty pracy widać na poniższych zdjęciach: Zasilanie 230V trafia na gniazdo komputerowe oraz włącznik (pozyskane z zasilacza ATX). Następnie mamy bezpiecznik szklany i transformator toroidalny 50VA 2x12V. Transformator miał wymienione uzwojenia wtórne. Miałem transformator z tylko jednym uzwojeniem o napięciu 10,5V, więc od nowa zostały nawinięte uzwojenia 2x12V. Takie napięcia są wprowadzone zgodnie z zamieszczonym schematem na płytkę zasilającą. Zastosowałem najprostszą kolbę 907A z termoparą. Wykorzystałem dostępne w sieci oprogramowanie stacji lutowniczej RL-1 zawierające algorytm PID do sterowania grzałką. Konstrukcja nie jest pozbawiona wad: Obudowa nie jest dokładnie spasowana z panelami czołowym i tylnym (miała być tymczasowa, a wyszło jak zwykle). Słaby obieg powietrza w obudowie (pomimo tego faktu nic się nie przegrzewa przy długiej pracy. Oto film prezentujący rozgrzewanie grota od temperatury 38 stopni do 320 stopni: Już w 22 sekundzie grzałka osiąga temperaturę zadaną. Od 35 sekundy przykładam do grota cynę o grubości 0,7mm. Cyna zaczyna się topić ok. 50 sekundy. Temperatura grota została zestrojona ze wskazaniem stacji za pomocą termopary i procedury opisanej w dokumentacji stacji RL-1 (w załączniku AVT987). A to obecnie przeze mnie posiadane stacje lutownicze: Jak już wcześniej wspomniałem, wykonałbym kilka zmian. Najważniejsza to zmniejszenie wymiarów stacji. Trafo zajmuje 1/3-1/4 obudowy. Obecnie całość znalazłaby się na jednym PCB, wszystkie elementy SMD, cała stacja zmieściłaby się za LCD. Do tego trafo i wymiar całości zmniejszony minimum o połowę. Poza tym, prócz najdłuższego rozgrzewania i braku mocy przy lutowaniu dużych pól masy stacja działa nad wyraz dobrze. EAGLE_Moja stacja lutownicza.zip AVT987.pdf Cyfrowa_Stacja_Lutownicza_RL1 - do wgrania.zip Cyfrowa_Stacja_Lutownicza_RL1 - edytowalne oprogramowanie.zip Cyfrowa stacja lutownicza RL1.zip
  34. 5 punktów
    To mój pierwszy post na tym forum ale od razu chciałbym przedstawić zbudowanego przeze mnie robota. Mimo że to pierwszy post to odwiedzałem to i inne fora wielokrotnie w poszukiwaniu przydatnych informacji i wykorzystując jedynie „magiczny” guzik szukaj udało mi się rozwiązać większość problemów z budową. To dla tych którzy nie chcą i nie lubią szukać… Wracając jednak do robota to został on nazwany X-walker i jest czteronożnym robotem kroczącym o symetrycznej konstrukcji. Został zaprojektowany jako robot którego zadaniem będzie przejście po nieznanym terenie przy jednoczesnym zachowaniu równowagi i odpowiednim położeniu korpusu. Prace nad robotem aktualnie się zakończyły, aczkolwiek temat jest obszerny i wiele można jeszcze ulepszyć albo dodać, więc w przyszłości robot zostanie poddany kolejnym modyfikacją. 1.Budowa mechaniczna Konstrukcja mechaniczna robota została zaprojektowana przy użyciu programu Autodesk Inventor 2010. Program ten umożliwił stworzenie wirtualnego modelu robota oraz przetestowanie zależności mechanicznych występujących pomiędzy jego elementami. Dzięki temu wybrano optymalne wymiary poszczególnych części. Poniżej na rysunku 1 zaprezentowano projekt robota z programu Inventor (bez elektroniki oraz okablowania): Na materiał konstrukcyjny wybrano aluminium jako, iż posiada odpowiednią wytrzymałość, jest przy tym lekkie i nadaje się do obróbki za pomocą prostych narzędzi. Zaprojektowane elementy wycięto przy pomocy lasera z 1.5mm i 2mm arkuszy aluminium. Poniżej przedstawiono wycięte elementy: Dalszy etap prac polegał na odpowiednim ukształtowaniu niektórych części. Proces ten odbywał się ręcznie przy udziale odpowiednich kopyt wykonanych z drewna bukowego i stali. Następnie dokonano montażu elementów przy pomocy różnego rodzaju łączników śrubowych o średnicach od 2 do 4mm. Dodano także inne elementy, takie jak tulejki dystansowe czy części składowe stóp ze zintegrowanymi czujnikami stykowymi. Na kolejnym rysunku przedstawiono złożonego robota: Poniżej przedstawiono szczegóły budowy stopy: Napęd robota stanowi 12 serwomechanizmów Power HD 1201 o parametrach przedstawionych poniżej (dane producenta): - moment 12.2/13.2 kg/cm - prędkość 0.16/0.14 sec/60° - napięcia 4.8/6.0 V - waga 60 g - wymiary 40.7 x 20.5 x 39.5 mm Niestety niektóre dane obiegają od wartości rzeczywistych, szczególnie wartość momentu, ale co ciekawe nawet wymiary nie są zgodne z rzeczywistymi. Podsumowując, konstrukcja mechaniczna robota posiada kilka charakterystycznych cech: - zwarta i solidna konstrukcja - podwójne łożyskowanie wszystkich stawów - zintegrowane czujniki stykowe w stopach - całkowita rozbieralność konstrukcji – tylko połączenia śrubowe - możliwie najmniejsze wymiary przy zastosowaniu danych elementów wyposażenia robota - liczne otwory odciążające konstrukcję 2. Elektronika Część elektroniczna robota posiada budowę modułową. Każdy moduł zawiera mikrokontroler AVR i pełni odpowiednie dla siebie funkcje. Każdy posiada także odpowiednio multipleksowane wyprowadzenie ISP, co pozwala programować moduły podczas ich działania. Moduły stanowią odrębne jednostki elektroniczne i można ich używać oddzielnie nie koniecznie w robocie X-walker. Do komunikacji między sobą wykorzystują SPI. Takie rozwiązanie nie ogranicza w dalszej rozbudowie robota i pozwala stale dodawać nowe elementy i funkcje. Poniżej scharakteryzowano poszczególne moduły. 2.1. Moduł sterujący „BRAIN” Jest głównym modułem w robocie, zawiaduje działaniem pozostałych. Został oparty na mikrokontrolerze ATmega 16A z kwarcem 16MHz. Posiada wyprowadzone piny z magistralą I2C i SPI, wyświetlacz LCD oraz 2 dodatkowe przyciski na potrzeby przyszłych funkcji. Poniżej krótka charakterystyka: - arbiter magistrali SPI - komunikacja z akcelerometrem i żyroskopem poprzez I2C - Realizacja filtru Kalmana w celu wyznaczenia aktualnego pochylenia robota - obsługa wyświetlacza LCD - nadzorowanie pracy innych modułów - formowanie odpowiednich ramek danych do komunikacji z PC 2.2. Moduły sterowników serw Robot posiada dwa takie same moduły sterowników serw, każdy obsługuje 6 serwomechanizmów, czyli 2 nogi robota. Moduły także oparte są o mikrokontroler ATmega 16A na kwarcu 16MHz. Najważniejszymi funkcjami tych modułów jest oczywiście generowanie odpowiedniego sygnału PWM dla serwomechanizmów, ale także obsługa czujników stykowych i pomiar napięć na potencjometrach serw (dodatkowy przewód wychodzący z każdego serwa). Ta ostatnia cecha służy sprawdzeniu czy serwomechanizm jest rzeczywiście wychylony od taką wartość jaką wyznacza sterowanie, co jest przydatne w pracy przy dużym obciążeniu. Należy dodać, że sygnały analogowe z potencjometrów przed dotarciem do tych modułów przechodzą przez filtr analogowy. 2.3 Moduł nadawczo odbiorczy „BT_RX_TX” Moduł ten jest odpowiedzialny za obsługę dwóch modułów bluetooth, jednego wysyłającego a drugiego obierającego dane z komputera. Dane przychodzące są odpowiednio filtrowane. W module zastosowano mikrokontroler ATmega 8A oraz kwarc 14.745MHz odpowiedni do transmisji szeregowej. Standardowo w module instaluje się dwa moduły bluetooth BTM-222. Poniżej zdjęcie przedstawiające moduł zamontowany w robocie: 2.4. Moduł zasilający "POWER" Robot jest zasilany dwoma zestawami akumulatorów. Pierwszy większy zestaw (2x LiPo 1850 mAh 7.4V) zasila serwomechanizmy, drugi mniejszy (LiPo 850 mAh 7.4V) zasila układy elektroniczne. Moduł zasilający monitoruje wartości napięć poszczególnych akumulatorów a także mierzy prąd jaki zużywają napędy robota. Zajmuje się także stabilizacją napięć – 5V dla elektroniki i poprzez stabilizator impulsowy (niewidoczny na zdjęciach) 5.3V lub 6V dla serwomechanizmów. Moduł zasilający posiada budowany układ dźwiękowy sygnalizujący niski stan napięcia w akumulatorach. Zajmuje się także monitorowaniem temperatury w istotnych miejscach robota za pomocą magistrali 1-wire oraz czujników DS18b20. Te miejsca to: stabilizator impulsowy dla serw, stabilizator liniowy dla elektroniki, temperatura w serwomechanizmie „udowym”, temperatura otoczenia. Zdjęcie użytego zasilacza impulsowego oraz zdjęcie robota po zamontowaniu modułu "POWER". Widoczny radiator stabilizatora liniowego elektroniki: 2.5 Pozostałe moduły Moduł żyroskopu Zawiera żyroskop cyfrowy L3G4200D oraz kilka elementów elektronicznych niezbędnych do jego działania . Na zdjęciu widać poprawiony błąd na PCB. Praktyczniej było to zrobić w ten sposób niż zmieniać całą płytkę bo wiązałoby się to z ponownym lutowaniem obudowy LGA żyroskopu. Moduł akcelerometru Zawiera akcelerometr (i magnetometr) cyfrowy LSM303DLH oraz tak jak moduł żyroskopu kilka elementów elektronicznych niezbędnych do jego działania. IMU - interial measurmet unit Moduł IMU czyli tzw. interial measurmet unit złożony i zamontowany w całości wraz z konwerterami napięć dla sygnałów magistrali I2C Moduł filtrów analogowych RC (2 sztuki) Filtruje napięcia na potencjometrach serw aby można było je prawidłowo zmierzyć poprzez wbudowane w mikrokontrolerach przetworniki ADC 3. Sterowanie X-walker jest sterowany za pomocą komputera PC i odpowiedniej aplikacji. Zastosowanie dwóch modułów Bluetooth pozwoliło na szybkie przekazywanie danych w obu kierunkach i uzyskanie kroku sterowania na poziomie 40ms. Czas ten nie jest niestety gwarantowany z racji zastosowania protokołu Bluetooth, aczkolwiek robot porusza się płynnie i reaguje błyskawicznie na zmiany sterowania. W jednym cyklu sterowania od robota odbierane są odpowiednie dane, wyliczane jest sterowanie i dane ponownie wysyłane są do robota. Na ekranie komputera możemy obserwować dane generowane przez wszystkie moduły robota jak również aktualne położenie środka ciężkości robota względem jego stóp z naniesionym wielokątem podparcia (obraz poniżej) Po wybraniu odpowiednich ustawień chodu robota oraz prędkości poruszania się następuję połączenie z robotem. O tej pory możemy nim sterować: chód przód, tył, na boki oraz obroty w lewo prawo. Wszystkie inne „akcje” związane z chodzeniem po trudnym terenie robot podejmuje sam. Na filmach poniżej można więc zaobserwować jak przekłada nogę w celu znalezienia odpowiedniego miejsca do położenia jej bądź też ratuje się przed wywrotką po obsunięciu się którejś z nóg. Innych elementów prawdopodobnie nie widać na filmach a mianowicie robot dba cały czas o odpowiednie usytuowanie środka ciężkości tym samym zapewniając sobie stabilność. Każdorazowo dobiera odpowiednie przemieszczenia nóg wzdłuż wszystkich osi oraz przemieszczenie korpusu. Korpus robota jest pozycjonowany automatycznie za sprawa sterowników PID które wyliczają sterowanie na podstawie danych z żyroskopu i akcelerometru przetworzonych przez filtr Kalmana. Wysokość korpusu nad ziemią także jest ustalana przez odpowiedni algorytm. Dodatkowo robot pilnuje aby każda noga która w danej fazie chodu ma spoczywać, w przypadku utraty podłoża „znalazła” nowe poprzez systematyczne obniżanie jej. Opis powyżej przedstawia pokrótce sposób w jaki sterowany jest robot, aczkolwiek nie zawiera wszystkich szczegółów. Zostały wymienione tylko główne funkcje algorytmów sterujących. Zdaje sobie sprawę że opis ten może być ciężki do zrozumienia, ale nigdy nie miałem talentu do opisywania tego co robie, więc śmiało można pytać i będę się starał rozwiewać wątpliwości oraz uzupełnić opis w miarę możliwości. Na koniec jeszcze kilka zdjęć i filmy: Kinematyka odwrotna: Kontrola przechyłu korpusu: Chodzenie po nierównym terenie: Chodzenie po ruchomej równoważni: I jeszcze coś w HD, łażenie po kamyczkach:
  35. 5 punktów
    Dostępne na rynku oczyszczacze powietrza nie kosztują mało. Sam filtr, który wydaje się najważniejszym elementem kosztuje najczęściej nie więcej niż 1/3 oczyszczacza. Postanowiłem więc zbudować własny oczyszczacz. Oczywiście czas poświęcony na budowę też ma wartość, ale nie traktuje tego jako roboczogodziny a po prostu zabawę . W moim przypadku, koszt całości wyniósł około 300zł. Dla porównania, gotowy oczyszczacz Xiaomi to wydatek około 500zł, jesienią było to minimum ~650zł . Kupiłem filtr Xiaomi z wkładem węglowym, który jest nieco droższy niż zwykły, który montowany w fabrycznych oczyszczaczach. Użyty przeze mnie wentylator posiada według producenta wydajność 150m³/h co jest wartością 2x mniejszą niż fabryczny oczyszczacz. Jest to jednak w zupełności wystarczające. Mechanika Oczyszczacz składa się z filtra powietrza, wentylatora 200mm, łącznika filtra z wentylatorem i sterownika. Łącznik został wydrukowany na drukarce 3D. Wentylator to najtańszy wentylator 200mm jaki znalazłem w sklepie komputerowym. Elektronika Całość bazuje na płytce z ESP32. Na niej znajduje się shield prototypowy Arduino, a do niego są zamontowane kolejne elementy. Używałem głównie gotowych modułów. Starałem się w miarę możliwości nie lutować ich bezpośrednio do PCB tylko umieszczać na listwach kołkowych. Schematu niestety nie mam. Wszystko było lutowane na bieżąco w przypływach weny Planuje jeszcze wyprowadzić drugą szynę I2C i podłączyć do niej drugi barometr który będzie umieszczony w wewnętrznej części filtra. Będę mógł w ten sposób zbadać zależność różnicy ciśnień od obrotów wentylatora. Czujniki Jako czujnik pyłu zastosowałem GP2Y1010AU0F. Kluczem była niska cena. Niestety wymaga on dość dokładnego synchronizowania w czasie załączania diody LED i pomiaru napięcia wyjściowego. Z czym miałem duże problemy o czym napiszę niżej. Dodatkowo, jako że jest to czujnik analogowy, jego wyjście skaluje się względem napięcia zasilania. A tak się składa że o ile ESP32 jest zasilane ze stabilnych 3.3V, to czujnik jest zasilany z szyny 5V. Tutaj występuje wyraźny rozstrzał między zasilaniem z zasilacza (wtedy szyna 5V jest zasilana przez diodę która powoduje spadek napięcia) a zasilaniem przez USB. Staram się to kompensować dodatkowym pomiarem napięcia szyny 5V. Nie jest to idealnie, choć daje dużo. Prawdopodobnie czujnik nie skaluje swojego wyjścia idealnie liniowo z napięciem zasilania, stąd ten problem. Oprócz tego na płytce znajduje się czujnik wilgotności HDC1080 oraz ciśnienia BMP280. Oba mają wbudowane termometry, więc nie potrzeba dodatkowego. Teraz prawdopodobnie użyłbym BME280. Interfejs W sterowniku użyłem wyświetlacza OLED. Wyświetlane są na nim aktualne parametry, takie jak: temperatura, wilgotność, poziom zanieczyszczeń, moc wentylatora i inne. Wyświetlacz jest sterowany za pomocą interfejsu I2C. Obok wyświetlacz znajduje się enkoder. Użyłem gotowego modułu bo akurat nie miałem pod ręką tego typu enkodera z przyciskiem. Można nim regulować moc oczyszczacza oraz przełączać między trybami: "auto" i "manual". Oczywiście jak na 2019 rok przystało, oczyszczaczem można sterować też po WiFi :) Na ESP32 jest uruchomiony webserver. Panel webowy wygląda tak: W kodzie znajdują się funkcje które utrzymują stałą łączność WiFi z routerem. Dane dostępowe do znanych nam WiFi należy umieścić w pliku "wifi_credentials.json" i wgrać wraz z innymi plikami. Niestety hasła należy umieścić w formie tekstowej. Biblioteka micropythona do obsługi WiFi nie obsługuje haseł w wersji zahashowanej (PSK). W przyszłości może dopiszę bardziej ludzką formie wprowadzania haseł Sterowanie wentylatorem Z racji tego że użyłem najtańszego wentylatora o tej średnicy, posiada on tylko 3 pinową wtyczkę. Taki wentylator można sterować jedynie napięciowo. Wymyśliłem więc sposób na regulację PWMem napięcia wyjściowego przetwornicy impulsowej. Polega to na podkradaniu lub wprowadzaniu dodatkowego prądu do wyjściowego dzielnika napięcia. Schemat tego wygląda następująco: Zauważyłem że im mniejsza częstotliwość sygnału PWM, tym bardziej nieliniowa jest zależność Vout=f(PWM). Dlatego częstotliwość PWM została ustawiona na 312kHz. Aproksymacje tej funkcji stworzyłem robiąc pomiary Vout w zależności od danego wypełnienia PWM, a następnie w arkuszu kalkulacyjnym wyznaczyłem współczynniki funkcji liniowej. Współczynniki te są na sztywno zapisane w kodzie. Micropython Zdecydowałem się użyć micropythona ze względu na chęć nauki czegoś nowego. Niestety, jak okazało się w trakcie, posiada on wiele ograniczeń. Największą wadą jest używanie blokującego dostępu do interfejsów komunikacyjnych. Przez co np.: w trakcie odświeżania wyświetlacza nie można dokonywać pomiarów czujnika pyłu czy obsługiwać żądań serwera. Ne można też używać drugiego rdzenia ESP32. Przez co interfejs użytkownika chodzi wyraźnie wolno, i nie wygląda na uruchomiony na czymś tak mocnym Cały kod jest dostępny na GitHubie: https://github.com/Harnas/ESP32_Airpurifier
  36. 5 punktów
    O mnie Witam, Jestem Maciej - pracuje jako software architect (nie mam wykształcenia elektronicznego dlatego proszę o wyrozumiałość jeżeli chodzi o połączenia i rozwiązania - z tego też powodu w projekcie nie daje gotowego przepisu na zasilanie ) i żeby do końca nie zgnuśnieć po godzinach tworzę platformę RemoteMe. W platformie chodzi głównie o ułatwienie sterowaniem urządzeniami IoT poprzez internet - bez konieczności posiadania VPNa, publicznego IP. Po stronie RemoteMe tworzycie strony internetowe ( RemoteMe posiada hosting na Wasze pliki ) + zestaw bilbiotek (Javascript, RasbeprryPi (python), Arduino ESP ) które w łatwy sposób pozwolą na komunikowanie się z Waszymi urządzeniami. Co do protokołu to opracowałem własny (bardziej jest to konwencja przesyłu paczek niż protokół jako taki ) (działa przez sockety, websockety, wywoływania RESTowe) - umożliwia on przesył wiadomości do określonego urządzenia, i coś w rodzaju topic- subscribera ( u mnie się to nazwa"variables" zmienne ) Wasze urządzenia rejestrują się w RemoteMe po zarejestrowaniu, możecie do nich wysyłać komendy przez stronę internetową albo z innych urządzeń. Jednym z ostatnich featerów są "Out of the box projects" - polega to na tym, że jednym kliknięciem importujecie projekt na Wasze konto - oczywiście możecie potem wszytko zmieniać wedle własnych pomysłów - właśnie ostatnim takim projektem jest Samochód RaspberryPi z kamerką o którym w tym kursie. Projekt jest częściowo openSourcowy - bilbioteki Javascript, Python, api Restowe są openSource - sam kod serwera i program na RasbeprryPi jest zamknięty. Platformę tworzę sam - po godzinach i udostępniam za darmo O kursie Ten kurs – przedstawia budowę samochodu sterowanego przez przeglądarkę z wyświetlaniem obrazu z kamerki. Jest to dość specyficzny kurs (jak pisałem wyżej ) – całość oprogramowanie jest już zrobiona, a dodanie plików do własnego konta w RemoteMe sprowadza się do paru kliknięć. Po tak dodanym projekcie można własnoręcznie i dowolnie edytować wszystkie pliki źródłowe (strona WWW skrypt pythonowy) – zwłaszcza, że same pliki projektu nie są skomplikowane, a kod jest dość czytelny i samo opisujący się (mam przynajmniej taką nadzieję ) Na dole kursu opisana jest bardziej szczegółowo zasada działania samochodu. Jeżeli nie jesteście zainteresowani samą platformą RemoteMe to i tak myślę, że w kursie znajdziecie garść pomysłów na podobny projekt Kurs właściwy Na filmie działanie + krok po kroku wszystko z tego kursu. W poprzednim kursie pokazałem jak sterować pozycją kamerki i przechwytywać obraz na przeglądarkę tutaj i sterowanie kamerką tutaj . Teraz rozbudujemy ten projekt i zbudujemy samochód z napędem na 4 koła ( sterowany podobnie jak czołg – żeby skręcić prawa para kół musi się kręcić z inną prędkością niż lewa). Taki efekt otrzymamy na wideo też całość kursu – można zaglądnąć, gdy gdzieś utkniecie Części RaspberryPi z wifi ( np zeroW) link Podwozie z silnikami link Sterownik serwomechanizmów na I2C link Kamera do Rpi + taśma jeżeli potrzebna link Dwa SerwoMechanizmy kompatybilne z uchwytem kamerki kamery link Uchwyt na kamerkę z serwami link Mostek H TB6612FNG link Zasialnie – np akumlatory podłączone do przetwornicy – żeby uzyskać odpowiednie napięcie link Połączenia RaspberryPI steruje serwami poprzez moduł PWM i napędem przez ustawianie stanu pinów na mostku oraz dostarczając sygnału PWM poprzez ten sam moduł, który wysyła sygnał do serwomechanizmów. (Dzięki modułowi do generowanie sygnału PWM nie musimy tych sygnałów generować przez samo RaspberryPi – co jest dość problematyczne, poprostu przez I2C przesyłamy odpowiednie instrukcje do sterownika serw (poprzez bibliotekę pythonową dostarczoną przez adafruit), a ten generuje odpowiedni sygnał PWM dla serwo mechanizmów i do mostka H) Schemat połączeń: Poprzez magistrale I2C RPi steruje kontrolerem serwo mechanizmów, dwa ostanie wyprowadzenia kontrolera są podłączone do mostka H, gdzie wykorzystując sygnał PWM ustawiamy prędkość silników. Do mostka H są również podłączone piny RPi które stanami wysokim i niskim będą określać kierunek obrotu silników napędowych – po szczegóły odsyłam do dokumentacji układu TB6612FNG, równie dobrze można użyć mostka L298N lub podobnego. Zaprojektowałem płytkę PCB, którą możecie użyć pliki eagle,gerber itd tutaj plik pcb.zip Schemat płytki pokrywa się ze schematem powyżej. Wyprowadzenia płytki: Wejście sygnału PWM z kanałów 15 i 14 modułu PWM Wejście zasilania silników do poruszania się Zasilanie układów (PWM, RPi) koniecznie dokładne +5V Wyjście silników napędu, pierwsze dwa wyjścia do jednej pary silników kolejne dwa do drugiej Zasilanie serw i w tym przypadku silników napędu w moim przypadku ~6V (należy sprawdzić w specyfikacji serw i silników, jakie maksymalne napięcie można podłączyć) ZWORKA gdy zepniemy dwa piny napięcie z 5 będzie podawane też do zasilania silników napędu ZWORKA gdy jest podłączona zasilane jest RaspberryPI z połączenia 3 przed podłączeniem zworki należy dokładnie sprawdzić napięcia, żeby nie uszkodzić Najdroższego komponentu czyli właśnie malinki Wlutowujemy kabelki, bo nie będziemy korzystali z konwertera stanów Wlutowujemy kabelki, bo nie będziemy korzystali z konwertera stanów Oczywiście jest jeszcze potrzebne odpowiednie zasilanie, w moim przypadku 6v jako napięcie silników napędu i serw, oraz 5v dla RasbeprryPi i kontrolerów. Poniżej kilka zdjęć poglądowych całości samochodu: Programowanie Przed utworzeniem projektu skonfigurujcie kamerkę i komunikacje I2C używając raspi-config opisane tutaj. Ten projekt jest jednym z gotowych projektów, które możecie prosto zaimplementować kilkoma kliknięciami: KLIK - po zalogowaniu otworzy się projekt. Przejdźcie do zakładki “Build It” i podążajcie krokami, na końcu klik w “Build Project” i otrzymacie: Po kliknięciu “Get QR” pokaże się kod QR, który możecie zeskanować smartfonem, lub po prostu otworzyć stronę przyciskiem “Open” w przeglądarce na komputerze. Narazie nie radzę zmieniać pozycji kamery dopóki nie ustawimy pozycji serw – w niektórych przypadkach możecie uszkodzić swoje serwomechanizmy. Samochód powinien jeździć jak na filmie – może się zdarzyć, że skręca w złą stronę albo serwa są źle skalibrowane, poniżej w omawianiu kodu napisałem jak to naprawić. Omówienie tego, co się stało Jak zauważyliście, tworzenie projektu było mocno zautomatyzowane. Dlatego omówię teraz, co się dokładnie wydarzyło i jak modyfikować Wasz projekt. Przede wszystkim utworzyły się dwie zmienne (zakładka variables): Zmienna cameraPos przesyła pozycje kamery, drive pozycje joysticka. Obie są typem “Small int x2” oznacza to, że wartoscią zmiennej są dwie liczby integer. Strona internetowa zmienia nasze zmienne, a skrypt pythonowy te zmiany rejestruje i odpowiednio reaguje (jak rozwiniemy zmienne zobaczymy, że urządzeniem nasłuchującym na zmiany jest właśnie skrypt pythonowy). Zobaczmy jak wygląda kod Pythonowy (więcej o zmiennych tutaj) Python Skrypt pythonowy został automatycznie wgrany. Oczywiście możemy go podejrzeć i modyfikować ( żeby stworzyć nowy skrypt pythonowy np dla innych projektów zobacz tutaj) . Z informacji jakie teraz są Ci potrzebne to skrypt pythonowy to kolejne urządzenie w remoteMe jest zarządzalne przez skrypt (uruchomiony przez ./runme.sh) , do tego urządzenia możemy wysłać wiadomości, urządzenie reaguje też na zmiany zmiennych, które obserwuje i może te zmienne zmieniać. Żeby otworzyć skrypt pythonowy kliknij python.py i wybierz Edit : Wygląda on następująco. Poniżej omówię ciekawsze fragmenty import logging import socket import math import struct import sys import os os.chdir(sys.argv[1]) sys.path.append('../base') import remoteme import Adafruit_PCA9685 import time import RPi.GPIO as GPIO motorAIn1 = 25 # GPIO25 motorAIn2 = 8 # GPIO8 motorBIn1 = 24 # 24 motorBIn2 = 23 # 23 motors = [[motorAIn1, motorAIn2], [motorBIn1, motorBIn2]] motorsPWM = [14, 15] pwm = None; def motorForward(motorId): GPIO.output(motors[motorId][0], GPIO.LOW) GPIO.output(motors[motorId][1], GPIO.HIGH) def motorBackward(motorId): GPIO.output(motors[motorId][0], GPIO.HIGH) GPIO.output(motors[motorId][1], GPIO.LOW) def motorSoftStop(motorId): GPIO.output(motors[motorId][0], GPIO.LOW) GPIO.output(motors[motorId][1], GPIO.LOW) def setMotor(motorId, speed): if speed == 0: motorSoftStop(motorId) elif speed > 0: motorForward(motorId) elif speed < 0: motorBackward(motorId) speed=-speed logger.info("set speed {} for motor {} ".format(speed,motorId)) pwm.set_pwm(motorsPWM[motorId], 0, int(speed)) def onCameraPosChange(i1, i2): global pwm logger.info("on camera change {} , {}".format(i1, i2)) pwm.set_pwm(1, 0, i1) pwm.set_pwm(0, 0, i2) pass def onDriveChange(x, y): logger.info("on drive change x {} , y {}".format(x, y)) global pwm left=y right=y left+=x right-=x delta=(left+right)/2 left+=delta right+=delta # when your car doesnt drive as suppose try to swich right and left variable below # or remove add minuses next to 2 # another way is to switch cables conencted to motors setMotor(0, 2*left) setMotor(1, 2*right) pass def setupPWM(): global pwm pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(80) def setupPins(): global GPIO GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme for motor in motors: for pinId in motor: GPIO.setup(pinId, GPIO.OUT) try: logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%d.%m %H:%M', filename="logs.log") logger = logging.getLogger('application') setupPWM() setupPins() remoteMe = remoteme.RemoteMe() remoteMe.startRemoteMe(sys.argv) remoteMe.getVariables().observeSmallInteger2("cameraPos" ,onCameraPosChange); remoteMe.getVariables().observeSmallInteger2("drive" ,onDriveChange); remoteMe.wait() finally: pass Sterowanie silnikami: def motorForward(motorId): GPIO.output(motors[motorId][0], GPIO.LOW) GPIO.output(motors[motorId][1], GPIO.HIGH) def motorBackward(motorId): GPIO.output(motors[motorId][0], GPIO.HIGH) GPIO.output(motors[motorId][1], GPIO.LOW) def motorSoftStop(motorId): GPIO.output(motors[motorId][0], GPIO.LOW) GPIO.output(motors[motorId][1], GPIO.LOW) def setMotor(motorId, speed): if speed == 0: motorSoftStop(motorId) elif speed > 0: motorForward(motorId) elif speed < 0: motorBackward(motorId) speed=-speed logger.info("set speed {} for motor {} ".format(speed,motorId)) pwm.set_pwm(motorsPWM[motorId], 0, int(speed)) Funkcja setMotor dla motorId 1 lub 2 ustawia prędkość speed (może być ujemna). poprostu najperw na odpowiednich pinach ustawiamy odpowiednio stany (ruch do przodu do tyłu, hamowanie), a następnie w zależności od prędkości ustawiamy odpowiednio wypełnienie PWM korzystając ze sterownika serw. def onCameraPosChange(x, y): global pwm logger.info("on camera change {} , {}".format(x, y)) pwm.set_pwm(1, 0, x) pwm.set_pwm(0, 0, y) pass Funkcja setMotor dla motorId 1 lub 2 ustawia prędkość speed (może być ujemna). poprostu najperw na odpowiednich pinach ustawiamy odpowiednio stany (ruch do przodu do tyłu, hamowanie), a następnie w zależności od prędkości ustawiamy odpowiednio wypełnienie PWM korzystając ze sterownika serw. def onDriveChange(x, y): logger.info("on drive change x {} , y {}".format(x, y)) global pwm left=y right=y left+=x right-=x delta=(left+right)/2 left+=delta right+=delta # when your car doesnt drive as suppose try to swich right and left variable below # or remove add minuses next to 2 # another way is to switch cables conencted to motors setMotor(0, 2*left) setMotor(1, 2*right) pass Powyższa funkcja zostanie wywołana jak zmieni się zmienna drive – np po zmianie joysticka na stronie. x,y to po prostu współrzędne wychylenia joysticka (1024,1024) oznacza wychylenie maksymalnie do góry i w prawo. Na podstawie tych zmiennych wyliczamy prędkość lewej i prawej strony samochodu. Jeżeli samochód skręca, zamiast jechać do przodu, jedzie do tyłu zamiast do przodu: setMotor(0, Y2*left) setMotor(1, X2*right) Dajcie minusy w różnych kombinacjach (w miejsca X i Y) do czasu, aż samochód jedzie do przodu – gdy joystick jest wychylony do góry. (będzie to odpowiadać zamianą miejscami przewodów lewej strony dla miejsca Y i prawej strony dla miejsca X). Następnie, jeżeli prawa i lewa strony są zamienione (samochód skręca w złą stronę ), w funkcji powyżej zamieńcie left i right miejscami. def setupPWM(): global pwm pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(80) def setupPins(): global GPIO GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme for motor in motors: for pinId in motor: GPIO.setup(pinId, GPIO.OUT) Po prostu ustawiamy odpowiednie piny (te do sterowania mostkiem H) na wyjścia. I tworzymy obiekt do kontrolowania sterowania serw. (Uwaga żeby sterownik serw działał prawidłowo musimy włączyć komunikacje I2C używając raspi-config więcej tutaj ) remoteMe.startRemoteMe(sys.argv) remoteMe.getVariables().observeSmallInteger2("cameraPos" ,onCameraPosChange); remoteMe.getVariables().observeSmallInteger2("drive" ,onDriveChange); remoteMe.wait() Ustawienie RemoteMe i ustawienie jakie funkcję mają zostać wywołane, gdy zmienne do sterowania kamery i napędu zostaną zmienione. To tyle w samym skrypcie pythonowym, jak widzicie, nie jest on zbyt skomplikowany, po więcej informacji zapraszam tutaj Strona WWW Tak naprawdę zostały stworzone dwie strony WWW — jedna do kalibracji druga — strona do sterowania samochodem i wyświetlania obrazu z kamerki. Otwórzmy stronę do kalibracji: Otworzy się strona internetowa z dwoma suwakami. Ustawmy górny i dolny na środkową pozycję – kamera się poruszy- górny suwak powinien poruszać kamerę w osi x, dolny y. Jeżeli się tak nie dzieje – zamieńcie miejscami przewody serwomechanizmu. Następnie za pomocą suwaków ustalcie maksymalne wychylenie osi x i osi y dla mnie jest to: x : 298 – 830 i centralna pozycja. Ważne, żeby centralna pozycja byłą dokładnie pomiędzy przedziałem u mnie ((298+830) /2 = 564) y: 223 – 723 i podobnie centralna pozycja kamery w osi y powinna być w środku przedziału Zapiszmy liczby gdzieś w notatniku i otwórzmy do edycji stronę do sterowania samochodem: <camera autoConnect="true" showInfo="true" class="cameraView"></camera> <connectionstatus webSocket="true" directConnection="false" camera="true"></connectionstatus> <variable component="cameraMouseTrack" type="SMALL_INTEGER_2" style="display:block" name="cameraPos" xMin="298" xMax="830" invertX="true" yMin="223" yMax="723" invertY="true" requiredMouseDown="true" reset="true" onlyDirect="true"></variable> <div class="joystickButtons"> <div class="buttons"> <variable class="gyroscope" component="gyroscope" type="SMALL_INTEGER_2" name="cameraPos" label="Gyroscope Camera" orientationSupport="true" xMin="298" xMax="830" xRange="19" invertX="true" yMin="223" yMax="723" yRange="20" invertY="false" onlyDirect="true"></variable> <variable class="gyroscope" component="gyroscope" type="SMALL_INTEGER_2" name="drive" label="Gyroscope Drive" xMin="-512" xMax="512" xRange="19" invertX="false" yMin="-512" yMax="512" yRange="20" invertY="false" onlyDirect="true"></variable> <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect gyroscope" onClick="toggleFullScreen()">fullscreen </button> </div> <div class="joystickParent"> <variable class="joystick" component="joystick_simple" type="SMALL_INTEGER_2" name="drive" xRange="1024" yRange="1024" onlyDirect="true"></variable> </div> <div style="clear: both;"/> </div> Są to automatyczne komponenty do sterowania samochodem i wyświetlaniem obrazu wideo. Strona, którą otworzyliście zawiera już wszystkie komponenty potrzebne do sterowania waszym samochodem. Jedyne co trzeba zrobić to zmienić zakres ruchów serwo mechanizmów. xMin,xMax,yMin,yMax, zamieńcie na wartości jakie otrzymaliście na poprzedniej stronie z suwakami. Jeżeli chcecie stworzyć własną stronę ze swoimi komponentami najlepiej utworzyć ją od początku pokazane tutaj – pozwoli Wam to dodawać komponenty w przy pomocy kreatora, gdzie ustalicie potrzebne parametry, albo po prostu edytować źródła tej już utworzonej strony – wcześniej warto utworzyć kopię, gdyby coś poszło nie tak (albo skasować pliki i utworzyć projekt jeszcze raz – wtedy nie zapomnijcie wcześniej wykasować też zmienne) Po zmianie wartości x/y/Min/Max możemy otworzyć naszą stronę np w smartfonie, klikamy na index.html, ale tym razem wybieramy opcje get anymous link Następnie, klikamy ikonkę kodu QR, a kod, który się pojawi skanujemy smarfonem. Oczywiście sterowanie działa również poprzez internet – nie tylko w sieci lokalnej, jednak w niektórych przypadkach jest potrzebna dodatkowa konfiguracja więcej o niej tutaj Trochę szczegółów technicznych ( nie obowiązkowe ) RemoteMe serwuję stronę WWW do sterowania Waszym samochodem ( a dodatkowo Was loguje na Wasze konto – stąd token w linku otwieranym przez smartfon ) i uczestniczy w negocjowaniu tworzenia połączenia WebRTC. Połączenie webRTC jest to połączenie bezpośrednie (RaspberryPi – przeglądarka ( w niektórych przypadkach np za NATem jest potrzebny dodatkowo stun sewer)). Po stworzeniu połączenia webRTC stan zmiennych nie jest w ogóle wysyłany do remoteMe (bo pole “onlyDirect” w komponentach jest ustawione na true). Protokołem webRTC przesyłany jest też obraz, a że webRTC tworzy połaczenie point to point opóźnienie jest znikome. Program na RaspberryPi który odpalacie poleceniem ./runme.sh tworzy połączenie websocketowe z platformą RemoteMe oraz zarządza skryptem pythonowym (wysyła do niego wiadomości, przesyła wiadomości ze skryptu dalej do platformy etc ). Działanie skryptu pythonowego jest możliwe dzięki dodatkowym bilbiotekom RemoteMe (znajdują sie w folderze leafDevices/base/ ). Sama strona internetowa po websocketach łączy się do platformy RemoteMe (pozwalają na to skrypty javascriptowe zaimportowane w headerze pliku index.html ze ścieżek /libs/). Ułatwiają i ustanawiają komunikacje z platformą RemoteMe. Same komponenty wstawione w index.html typu : <variable component="**" W funkcjach pliku remoteMeComponents.js są zastępowane na “standardowe” i “bootstrapowe” komponenty htmlowe, dodatkowo do komponentów przypinane są eventy reagujące na akcje użytkownika i wysyłające odpowiednie komunikaty do skryptu pythonowego. Można podejrzeć jak remoteMeComponents.js zamienia i tworzy nowe komponenty – może to być interesujące gdy macie potrzebę stworzenia własnych komponentów, które RemoteMe nie pozwala dodać z kreatora. W większości przypadków akcje Waszych komponentów będą wykonywać zapis zmiennych w postaci RemoteMe.getInstance().getVariables() .setSmallInteger2("cameraPos",123,456,true); która wyśle do skryptu pythonowego informacje o zmianie zmiennej, podobnie sterujemy silnikami ustawiając odpowiednią zmienną. Podsumowanie Tworząc tej projekt chciałem pokazać Wam jak w łatwy sposób sterować Waszym samochodem z widokiem FPV. Projekt można rozbudowywać, lub zmieniać np, gdy korzystanie z innego mostka H niż ja. Zachęcam zatem do eksperymentowania ze źródłami projektu . Gdy jest to Wasz pierwszy projekt, zachęcam do zrobienia na początek projektu z mrugającą diodą i poczytanie dokumentacji na www.remoteme.org Pozdrawiam, Maciej
  37. 5 punktów
    Właśnie zaakceptowałem Twój opis, możesz go teraz zgłosić do akcji rabatowej umieszczając link w temacie zbiorczym. Dziękuję za przedstawienie ciekawego projektu, zachęcam do prezentowania kolejnych DIY oraz aktywności na naszym forum Świetny projekt, bardzo lubię takie klimaty! Tutaj dla porównania moje "analogowe" statystyki Forbota (liczba osób online + odsłony z całego dnia):
  38. 5 punktów
    Witam, od kiedy kupiłem swoje arduino (było to ze trzy lata temu) to chciałem zbudować frezerkę do płytek pcb. Obejrzałem w Internecie wiele projektów i w końcu postanowiłem zbudować swoją własną frezarkę :). Pochłonęła ona dużo pieniędzy i jeszcze więcej czasu. Swoje prace zacząłem od kupienia profili 25mmx 1.5mm x 2000mm (dwie sztuki) i kilkanaście kątowników. Wymierzyłem całą konstrukcję i zacząłem składać stelarz stołu a następnie go pomalowałem podkładem i czarną farbą matową. Gdy farba schła zamówiłem wsporniki wałków, wałki fi 12, łożyska oraz kupiłem skleję 10mm na stół. następnym krokiem było położenie blachy na stół żeby nie zniszczyć sklejki potem zacząłem składać oś Z z wałków fi 8 Kilkanaście dni później kontrukcja wyglądała następująco została postawiona brama, została ona wzmocniona zastrzałami z tyły oraz lewa i prawa strona bramy została połączona płaskownikiem stalowym 4mm x 20mm. Cała konstrukcja była bardzo solidna. Pozostało pomalowanie bramy na kolor czarny mat ale to dopiero w wakacje jak zrobi się ciepło Dzisiaj odbyły się pierwsze testy bezpieczeństwo przede wszystkim Całość wymaga oczywiście kalibracji oraz muszę kupić nakrętki bezluzowe na śruby trapezowe. Całość jest sterowana a pomocą GCode. Obszar roboczy to 40cm x 40cm. Elementy potrzebne do budowy to: 4 wałki fi12 (dwa na oś X i dwa na oś Y) 2 wałki fi8 8 wsporników wałków fi 12 4 wsporniki wałków fi 8 profile na stelarz blacha aluminiowa na oś Z trzy zestawy składające się z śruby trapezowej wraz z nakrętką, uchwytem nakrętki, łożyskami samonastawnymi, sprzęgła elastycznego (po komplecie na każdą oś) 3 silniki krokowe 3 mocowania silników arduino 3 sterowniki silnków krokowych CNC shield zasilacz 12V 4A frezy V 20 stopni komplet wierteł od 0.6mm do 1.5mm Potrzebujemy jeszcze silnik do wrzeciona, ja użyłem "pisaka" i dremela. Kosztów nie liczę gdyż nie chcę się załamać ale frajda z budowy była ogromna. Płytki pcb projektuje w Eaglu następnie tworzę gerbery które ląduję do programu flatcam. W tym programie ustawiam wymiary frezu, wierteł i generuje gcode który przesyłam do Arduino za pomocą programu source rabbit gcode sender. Ważna rzecz, przed zaladaowanie pliku drill do flatcamu musimy się upewnić ze każda współrzędna składa się z takiej samej ilości znaków jeśli nie to musimy dopisać odpowiednią ilość zer na początku (tzn po X lub Y ) następnie gdy załamujemy plik drill do flatcamu musimy zmniejszyć skalę tego pliku. Wchodzimy właściwości> scale i ustawiamy na 0.1
  39. 5 punktów
    O czymś podobnym myślałem praktycznie od chwili kupna drukarki. I pewnie dalej bym myślał, gdyby nie projekt na Majsterkowie, opisujący podobną (prostszą) konstrukcję. A i tak przymierzałem się do tego jak pies do jeża, zawsze cos mi przeszkadzało (a to nie potrafiłem rozwiązać problemu zasilania, a to miałem coś pilniejszego do roboty, a to nie miałem jakiegoś tam elementu...). Ale po zrobieniu mojej przystawki do OctoPrinta i (całkiem udanych) próbach druku w wielu kolorach - a co się z tym wiąże koniecznością ręcznej zmiany filamentu w odpowiednim momencie - potrzeba stała się raczej pilna. Zacząłem więc od sprecyzowania założeń. Monitorek miał przede wszystkim wyświetlać aktualne dane na temat wydruku (temperatury, stan drukarki, postęp). Jako że główną jego funkcją miało być zwrócenie uwagi na coś ważnego (np. konieczność zmiany filamentu czy wychłodzenie stołu wystarczające do zdjęcia wydruku) w czasie, kiedy byłem zajęty innymi Wielce Ważnymi Rzeczami (np. oglądaniem najnowszego odcinka przygód bohaterskiego Hannibala Smitha czy innego McGyvera) sygnalizacja powinna być głosowa. Jednocześnie najważniejsze parametry (temperatura i postęp) powinny być wyświetlane w czytelny sposób nawet dla krótkowidza bez okularów - czyli żadne nawet największe cyferki, jakiś pasek postępu w kontrastowych kolorach albo jakiś inny czytelny glif. Zasilanie akumulatorowe (na stoliku przy telewizorze nie mam jak podłączyć zasilacza), z możliwością podłączenia ładowarki. Nadałem więc urządzeniu roboczą nazwę OctoMon, wymęczyłem na forum że ktoś mi wreszcie wyoślił temat ładowarki (dzięki @marek1707!) i zabrałem się do konkretnego projektowania. Miałem już wyświetlacz, moduł ESP8266E i parę innych potrzebnych drobiazgów. Początkowo chciałem ESP umieścić na płytce podłączanej bezpośrednio do pinów wyświetlacza - niestety, jakbym ścieżek nie prowadził i tak jednostronna płytka wychodziła mi za duża. Postanowiłem więc dać sobie spokój, zastosować adapter i użyć po prostu płytki uniwersalnej. Ponieważ tego modelu wyświetlacza już uzywałem, eksperymenty z dźwiękiem też się powiodły (przynajmniej w zakresie wystarczającym do uruchomienia gadacza) - mogłem mieć pewność, że od strony programu nie będę już miał żadnych niespodzianek. Postanowiłem więc zaprojektować całą (niezbyt skomplikowaną zresztą) elektronikę. Jako że akurat w Botlandzie pojawił się moduł MAX9837A postanowiłem go wykorzystać jako DAC i wzmacniacz dźwięku. Niestety nie zdał egzaminu... ale o tym później. Zasilanie rozwiązałem w najprostszy chyba z możliwych sposób. Akumulator połączony z ładowarką, do tego przetwornica MT3608 ustawiona na 5V. Wyświetlacz i DAC zasilane bezpośrednio z 5V, ESP przez stabilizator LM1117, połączony z resztą świata jak na schemacie poniżej. Teoretycznie powinno to działać... ...No i już na wstępie pojawił się problem. Podłączony bezpośrednio (znaczy się kabelkami) do ESP i zasilany z USB moduł dźwiękowy pokazał co potrafi - czyli jak mi zepsuć dobry humor. Z powodów niewiadomych raz działał raz nie... a do tego owo niedziałanie powodowane było chyba fanaberiami motylków w Brazylii albo aktualna pogodą na Marsie. Doszedłem do wniosku, że USB to niespecjalnie dobry sposób zasilania, po prowizorycznym podłączeniu jakichś uczciwych 5V wydawało mi się, że działa. Postanowiłem więc sprawdzić wszystko później już na gotowym układzie. Może się to komuś wydać dziwaczne i ryzykowne... ale miałem w odwodzie sprawdzone rozwiązanie które co prawda dawało niższą jakość dźwięku, ale za to nie okazywało żadnych fanaberii Reszta elektroniki to praktycznie tylko połączenie tego wszystkiego do kupy - mogłem się więc zabrać za projekt obudowy. Nie chciałem się bawić w wymyślanie jakichś skomplikowanych kształtów, a więc obudowa została wydrukowana w kilku częściach i skręcona śrubkami M2. Początkowo urządzenie miało mieć jeden klawisz, ale okazało się, że mam wolne dwa piny GPIO, mogłem więc połączyć dwa. Płytę czołową postanowiłem umieścić pod kątem ze względu na wyświetlacz (który nie lubi jak patrzy się na niego lekko z boku, masz się gapić prosto i już!). Oprócz wyświetlacza miały tam się znaleźć głośnik i klawisze. W sumie więc górna część obudowy wygląda na projekcie tak: Otwory obok głośnika są przelotowe - od zewnątrz jest do nich przykręcona kratka mocująca i osłaniająca głośnik. Mocowanie klawiszy jest dopasowane do ratra płytki uniwersalnej (podobnie zresztą, jak mocowania płytki pod ESP8266). Cała reszta elektroniki oprócz DAC-a została umieszczona w dolnej części obudowy: Oprócz koszyka na akumulator są tam mocowania dla ładowarki, przetwornicy i małej płytki pod ESP. Po złożeniu cały układ wygląda tak: Niestety - po złożeniu wszystkiego w całość okazało się, że DAC nie bardzo chce ze mną współpracować. Co prawda wyczyniał swoje hece to dużo rzadziej, ale jednak. Postanowiłem więc wypróbować inny układ: wzmacniacz (wykorzystana połowa układu) oraz prosty filtr: Okazało się, że działa to całkiem znośnie - prawdopodobnie potrzebna by była jeszcze dodatkowa filtracja na zasilaniu (w głośniku słychać czasem ciche trzaski) ale bez tego już mogłem się obejść. Po złożeniu całość wygląda tak: I tu uwaga: ponieważ wątpię, aby ktoś kto chciałby zrobić to urządzonko miał dokładnie takie same elementy jak ja i identycznie spaczone poczucie estetyki - nie zamieszczam STL-i tylko plik dla OpenSCAD-a. Są w nim zawarte wymiary poszczególnych elementów i może być przydatny. No i kilka słów o programie. Program łączy się z serwerem OctoPrint i okresowo odpytuje o stan drukarki i (w przypadku gdy jest to drukowanie) o postęp. Oprócz podstawowych stanów sygnalizowanych przez serwer odróżniane są: Offline - drukarka jest wyłączona lub serwer nie odpowiada Rozgrzewanie stołu Rozgrzewanie dyszy Studzenie stołu - gdy po zakończeniu drukowania temperatura jest nie niższa niż 30°. Wciśnięcie pierwszego klawisza w trybie pauzy powoduje, że monitorek przestanie się odzywać. Bez tego co chwila będzie krzyczał że masz zmienić filament. W trybie studzenia powoduje przejście w tryb bezczynności. Wciśnięcie drugiego klawisza spowoduje podanie głosowo godziny. Dłuższe wciśnięcie pozwala na zmianę gadatliwości programu. Serwer WWW pozwala na zmianę wszystkich ważnych parametrów w dowolnej chwili. W trybie "drukowanie" wyświetlane są informacje o temperaturze dyszy i stołu, postępie w procentach oraz czasu dotychczasowanego i prognozowanego. Dodatkowo wyświetlane są: Adres IP monitora Bieżąca godzina Stan naładowania akumulatora Poziom gadatliwości (tylko wydarzenia/postęp/postęp i pozostały czas) Włączenie OTA Siła sygnału WiFi W trybie Offline monitor zachowuje się jak zegarek - wyświetla bieżące godzinę i datę Jeśli w czasie resetu urządzenia przytrzymamy pierwszy klawisz, startuje ono w trybie AccessPoint. Pod podanym adresem zgłasza się serwer WWW, gdzie można zapisać wszystkie potrzebne parametry. Jeśli w czasie resetu urządzenia przytrzymany drugi klawisz, startuje ono w trybie awaryjnym. W tym trybie nie będzie działać nic oprócz OTA. Przydatne, jeśli coś tak naknocimy w programie że nie będziemy mieli dostępu do OTA w normalnym trybie. Program został napisany z pomocą Arduino IDE. Biblioteka syntezy mowy jest na githubie. Pozostałe biblioteki instalowane były "po bożemu" poprzez managera bibliotek. Syntezator mowy to zwykły syntezator formantowy (użyłem w większości oryginalnego kodu D. Klatta z początku lat 80-tych), dostosowany kiedyś przeze mnie do języka polskiego. Dostosowanie nie jest może najlepsze - ale i syntezator Klatta nie jest mistrzem dykcji Kalibrację miernika poziomu akululatora należy przeprowadzić włączając opcję DEBUG w Octomon.h i podając w pliku wifi.cpp adres i port , na którym będziemy odbierać komunikaty UDP. Należy do wejścia przetwornicy podłączyć woltomierz, odczytać komunikat "Volts=..." i w pliku "display.cpp" w funkcji displayBattery() w linijce: ivolt = ivolt * 413 / 753; podstawić właściwe wartości (czyli napięcie akumulatora w setnych wolta oraz wartość odczytaną a przetwornika A/C). W moim przypadku jak widać woltomierz podał 4.13V a przetwornik zinterpretował to jako wartość 753 Aby program działał, należy w Arduino IDE ustawić zegar 160 MHz, tryb pamięci QIO oraz częstotliwość Flash 80 MHz. Dołączony programik bmconvert.py pozwala na zapisanie jako tablicę w C obrazka PNG. Obrazek powinien być zapisany w trybie indeksowanej palety kolorów bez przezroczystości, będzie przetworzony na skompresowaną w RLE tablicę, a do jego wyświetlenia należy użyć funkcji drawBitMap() z pliku display.cpp (lub analogicznej). Sprawdzony na Linuksie, ale powinien działać na wszystkim gdzie się da zainstalować Pythona 2.7 i PIL. Urządzenia używam od jakichś dwóch tygodni, na razie jest bardzo przydatne. octomon.zip
  40. 5 punktów
    Miniaturowy Tetris z pięcioma przyciskami, głośniczkiem Piezo i ekranem Oled 128×64. To wszystko przy zaledwie sześciu dostępnych GPIO jednodolarowego Digisparka/ATtiny85. Moja wersja kodu dodaje kilka ulepszeń, które znacząco zmieniają odbiór całej gry (opisane niżej), a koszt budowy całego zestawu wynosi około 15 zł. ATtiny Tetris Gold Multi Button obsługuje narastający poziom trudności (przyspieszanie opadania wraz z usuwaniem kolejnych linii), informację o klocku pojawiającym się w kolejnej turze, podpowiedź o pozycji klocka w dolnej partii planszy, pełną pseudo-losowość doboru klocków, dźwięki i temat muzyczny z oryginalnej gry. Poniżej mój filmik prezentujący ten układ w działaniu: W filmie można zobaczyć krótkie urywki z rozgrywki, proces instalacji szkicu w urządzeniu oraz pełny, pięciominutowy gameplay. Sprzęt Jakiś czas temu zainteresowały mnie klasyczne gry retro dla ATtiny85, ale w repo Attiny-Arduino-Games wszystkie były zaledwie dwu-przyciskowe. Tetris wymagał nieco więcej logiki, ale i tak obsługiwało się go przez naciskanie lub przytrzymywanie jednego z tylko dwóch przycisków, co generowało błędy i nie było zbyt wygodne. Z czasem jednak pojawiła się w repo wersja Tetris Multi Button, w której rozwiązano ten problem wykorzystując odpowiednią kombinację rezystorów i przycisków, dzięki czemu podłączono trzy przyciski pod jeden pin mikrokontrolera. Nie posiadam czystego ATtiny85, ale miałem na stanie Digisparka z tym chipem i postanowiłem złożyć to urządzenie. To chyba pierwsze nagranie wideo takiego zestawu - w sieci brak w sieci brak filmów i opisów wykonania pełnej, pięcio-przyciskowej wersji. Żeby się nie pogubić podczas montażu , korzystając z rozpiski pinów Digisparka i ATtiny85 przeniosłem dostarczony ze sketchem poniższy schemat: na lekko chaotyczną wersję graficzną dla stykowej płytki prototypowej i Digisparka zasilanego baterią 9V: a przy okazji też dla czystego ATtiny85 zasilanego baterią 3V: Poszczególne przyciski odpowiadają za: start nowej gry lub restart aktualnie rozgrywanej, włączenie/wyłączenie układu, obrót, przyspieszenie opadania, przesunięcie w lewo, przesunięcie w prawo. Przytrzymanie przycisku opadania i włączenie restartu gry aktywuje tryb ducha, a przytrzymanie przycisku opadania razem z przyciskiem obrotu podczas restartu ustawia trudny poziom gry, wypełniając dodatkowo błędnie klockami część planszy. Po aktywacji tych opcji grę należy uruchomić przyciskiem przyspieszonego opadania. Wersja na czystym ATtiny85 potrzebuje tylko 3V, bo sketch jest pisany dla obniżonego do 8MHz taktowania zegara. Wersję dla Digisparka zasilam poprzez pin VIN 9V baterią i przy takim poborze wystarczy jej na baaardzo długo. Wymagane do działania 5V przenoszę dodatkowym, pustym goldpinem na lewą stronę płytki prototypowej za pomocą dziesięciocentymetrowego przewodu połączeniowego żeńsko-męskiego. Po zlutowaniu powyższego układu w połączeniu z gołym ATtiny85 i po ubraniu go w miniaturowy brelok do kluczy, koszt (bez baterii) zamknąłby się poniżej 15 złotych. Na Aliexpress ATtiny85 kosztuje 0,80$, ekran Oled 128×64 1.80$, mały piezo buzzer 0,17$, a reszta części to już koszty groszowe. Tym sposobem otrzymujemy pełną grę sterowaną w identyczny sposób, jak w wielkich automatach Arcade lata temu, a do tego zasilaną malutką baterią 3V. Do zestawu zamiast białego ekranu można wybrać ekran niebieski lub żółto-niebieski, ale ponieważ ten ostatni jest dzielony na dwie różne części z odstępem, to nie prezentuje się zbyt atrakcyjnie (co widać na powyższym filmie) i polecam jednokolorowy odpowiednik. Potencjalny brelok mógłby wyglądać tak, jak na obrazku poniżej: Kod Zmiany w kodzie, których dokonałem, nie są duże, ale znaczące w odbiorze gry. Poniżej różnice między moją wersją, dostępną na GitHubie, a oryginałem gry dla ATtiny85: Dodałem losowość doboru klocków – domyślnie ATtiny Tetris generuje tę samą sekwencję klocków w każdej nowej grze, bo użyta funkcja random korzysta w kółko z tej samej tablicy liczb losowych. Programiści nie aktywowali randomSeed, ponieważ wszystkie piny w układzie są już podłączone. Moja wersja przesuwa tablicę liczb pseudo-losowych po każdym rozpoczęciu gry inkrementując seed do EEPROMu i aktywując w ten sposób pełną pseudolosowość doboru klocków (powtarzają się tylko pierwsze dwa). Grając w oryginalną wersję, do piątej linii miałem już ustalony optymalny schemat położenia klocków, przez co gra stawała się nudna. Teraz jest już poprawnie i mam świadomość, że wykorzystanie EEPROMu w randomSeedowaniu ograniczy liczbę rozgrywek do zaledwie 99000 (podana liczba uwzględnia już obecny w kodzie zapis najlepszych wyników również do EEPROMu). Na starcie gry dodałem fragment tematu muzycznego z oryginalnej gry Tetris z 1986 roku – domyślnie brak jakiejkolwiek muzyki w grze. Po wybraniu trybu ducha temat muzyczny jest nieco dłuższy. Dodałem dźwięk opadającego klocka (tylko podczas swobodnego spadania) oraz inny dźwięk dla klocka, który kończy opadanie. Domyślnie dźwięki w tej grze pojawiają się sporadycznie – tylko podczas usunięcia pełnej linii klocków oraz na zakończenie gry. Naprawiłem część błędnie wyświetlanych fontów na ekranie startowym Domyślnie wyłączyłem tryb ducha, który wyświetla podpowiedź o docelowej pozycji klocka. Tryb ducha można aktywować sposobem opisanym powyżej pod konfiguracją przycisków. Ze swoimi zmianami musiałem się zmieścić w sześciu procentach wolnej pamięci. Obecnie pozostaje już tylko 1% wolnego Projekcik jest dość interesujący i co najważniejsze, w pełni użyteczny, więc możliwe, że znajdą się osoby chcące zbudować taki układzik. Jako dodatek zamieszczam więc proces instalacji. Instalacja Kod zabiera blisko 100% pamięci ATtiny85, więc na Digisparku nie mieści się bootloader i nie można uploadować sketcha poprzez USB – należy więc skompilować hexa i wgrać go za pomocą programatora ISP. Jako programatora użyłem Arduino wg poniższego schematu: Na Arduino trzeba wgrać dostępny w przykładach Arduino IDE sketch ArduinoISP. Aby poprawnie skompilować tę wersję dla Digisparka należy w Arduino IDE zastąpić dodatkowy adres URL dla menadżera płytek od Digistump JSONem dla czystego ATtiny85, a następnie wybrać płytkę ATtiny25/45/85, procesor ATtiny85, zegar Internal 8MHz. Następnie z menu szkic eksportować skompilowany program, który zostanie wtedy umieszczony w katalogu źródła sketcha. Na koniec zostaje już tylko wgranie hexa na Digisparka poprzez Arduino programem avrdude. Poniżej przykładowe polecenie kopiujące (z fusami) wykonane na macOS, ale w innych systemach wygląda podobnie: /Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -pattiny85 -cstk500v1 -P/dev/cu.usbmodem14101 -b19200 -Uflash:w:/Users/username/Documents/ATtiny-Tetris-Gold/ATtiny-Tetris-Gold.ino.tiny8.hex -U lfuse:w:0xF1:m -U hfuse:w:0xD5:m -U efuse:w:0xFE:m Jak przebiega taki proces można obejrzeć na końcu powyższego filmiku. Poniżej też zdjęcie "programatora" i układu obok siebie. W filmie i na zdjęciach do włączania układu korzystam z przełącznika suwakowego SS22T25, ale lepiej sprawdził się przełącznik prosty ESP1010. Napięcia na przyciskach są istotne i podczas gry trzeba uważać aby nie dotykać rezystorów Ten problem wyeliminuje się po zlutowaniu układu. Najlepszy wynik gry jest również zapisywany w EEPROMie. Ponieważ głośniczek jest podłączony do pierwszego pinu Digisparka, to dodatkowo otrzymujemy LEDowe sygnały świetlne w momencie odtwarzania dźwięków. Po zakończeniu gry Tetris natychmiast przechodzi w tryb uśpienia z minimalnym poborem prądu, jednak do Digisparka dodałem przełącznik włączający/wyłączający zasilanie dla układu – wersja opierająca się wyłącznie na ATtiny85 nie wymaga wykonania tego kroku. Gra chodzi bardzo płynnie, co widać na powyższym filmie, gdy przytrzymuję przycisk przyspieszonego opadania dla kilku klocków pod rząd. Miniaturowy ATtiny Tetris Gold jest bardzo regrywalny (nie nudzi się) i to niesamowite, że udało się go upchnąć na tanim ATtiny85 przy zachowaniu tak dużej funkcjonalności. Serdecznie polecam montaż tego prostego układu. Powiększenia układów i trochę więcej informacji można znaleźć na moim blogu: http://jm.iq.pl/tetris
  41. 5 punktów
    Dzień dobry Nie będę zupełnie oryginalny i zrobiłem dwie stacje meteo. Chciałem poduczyć się trochę arduino i szukałem pomysłu na projekt przeglądając Botland znalazłem czujniki pyłu PM 2,5 i PM 10. Przez to, że temat smogu jest na czasie uznałem to za dobry pomysł by zweryfikować czy miejscowość w której mieszkam (wieś) jest od niego wolna. Zacząłem od kursów na Forbocie (vel wyświetlacz lcd) by załapać podstawy arduino i elektroniki. Były bardzo pomocne. Następnie chciałem przetestować niektóre czujniki i tak sprawdziłem Temperatura DS18B20 MCP9808 SHT 15 SHT 31 Wilgotność DHT 11 DHT 22 SHT 15 SHT 31 Przy wyborze też między innymi kierowałem się dokładnością pomiaru najlepiej ok 5% oraz możliwością pracy przy ujemnych temperaturach im mniej tym lepiej gdyż mrozy tu mogą sięgać -20C. Przy testowaniu tylko miałem problem z DHT11 i DHT22 - mianowicie nie podawał mi poprawnych danych (miałem obok kupny wilgotnościomierz i dane zupełnie nie pasowały do siebie ale opisałem to w innym poście na forum). Wybrałem MCP9808 gdyż uznałem, na czujnik temperatury gdyż wg moich obserwacji najlepiej się sprawdzał w różnych warunkach i wahaniach temperatury. Osobno tak samo wybrałem czujniki wilgotności tylko do tego celu tj. SHT31. Barometr widziałem, że polecany jest BMP180 więc na nim zostałem. Z programowaniem nie było problemu ze względu na biblioteki. Czujniki pyłu były małym wyzwaniem. Brak bibliotek. I śmigają na UART Trzeba operować na przykładowych kodach i rozumieć jak lecą bity. Ponadto trzeb zwracać uwagę na to że różne modele mogą mieć różny formę ramki danych przesyłanych. Przetestowałem 3 czujniki pyłu PMS5003 PMS5003 z detekcją formaldehydu Gravity Każdy z nich miał inaczej ramkę ukształtowaną. Ponadto czujniki zasilane są napięciem 5V a linia danych 3,3V Do tego należy dokupić konwerter poziomów logicznych by zadziałało to sprawnie. Do tego zestawu dokupiłem stacje meteo z wiatromierzem. Następnie chciałem aby stacja mogła być na zewnątrz i komunikować się z odbiornikiem w środku przez nRF24L01+. Warto brać moduł z zewnętrzną anteną oraz adapterem poprawia działanie modułu. Mając już na płytce w miarę temat ogarnięty chciałem najpierw testowo zrobić mobilny czujnik pyłu aby zrobić pierwsze przymiarki do lutowania i montażu. Lutowałem na płytkach prototypowych z cienkimi kablami. Nie był to dobry pomysł ale na daną chwilę dało się. Zamiast przylutowywać moduły na stałe lutowałem sloty do nich. Wolałem trochę poświęcić jakość wykonania na rzecz sytuacji w której mógłbym się pomylić. Nie mam rozlutotwnicy a standardowa lutownica i odsysacz słabo mi się sprawdzały. Specyfikacja mobilnego czujnika pyłu (główne moduły) Arduino Pro Mini 328 - 5V/16MHz SHT 15 (wilgotność i temperatura) PMS5003 (czujnik pyłu) Konwerter USB-UART FTDI FT232RL - gniazdo miniUSB (programator ew zasilanie poza bateryjne) Wyświetlacz LCD 4x20 znaków zielony Efekt był zadowalający wiec uznałem, że warto będzie spróbować wysyłać dane na stronę www. Do tego zadania zaprzęgłem malinkę z modułem nRF24L01+. Idea była taka aby: ->pomiar stacji ->wysłanie danych drogą radiową ->odebranie przez Ras Pi ->wysłanie danych na zewnętrzny bazę danych MySQL ->pobranie danych z bazy i wyświetlenie jej na stronie bazującej na wordpresie Główny problem był z liczbami zmiennoprzecinkowymi. Gdyż malinka odbiera surowe bity i nie chce ich prze konwertować na liczbę zmiennoprzecinkową. W każdym bądź razie wszelkie próby konwersji i operacji na bitach skończyły się komunikatem ze Python nie obsługuje przesunięć bitowych dla liczb zmiennoprzecinkowych. Do zastosowań domowych wystarczy mi pomiar do drugiego miejsca po przecinku (temperatura) więc po prostu każdą zmienna która miała część ułamkową mnożę na Arduino razy 100 i jak odbiorę na malince dzielę przez 100. O ile odbiór między arduino to linijka kodu to tu przy odbiorze suchej transmisji (już przy użyciu biblioteki ...... ) trzeba było bity ręcznie składać bo Arduino wysyła jedną zmienną w dwóch bajtach trzeba było używać operatorów bitowych by te bajty złączyć w jeden. Przed montażem należało wyznaczyć miejsce dla stacji. Z tego względu do stacji mobilnej dorzuciłem adapter NRF na który mogłem po prostu zamiennie testować wersje z zewnętrzną i wewnętrzną anteną. Syngał nadawał do malinki kolejne cyfry a obok miałem telefon z teamviwerem na którym patrzałem się co na konsoli wyświetliło. Jeśli był cykl 1 2 3 .... 11 12, tzn., że w miejscu w którym stałem jak nadawano cyfry 4 5 6 7 8 9 10 sygnał nie doszedł i nie należało go brać pod uwagę do montażu docelowej stacji meteo. Wiatromierz montowałem na chwycie antenowym. Średnica rur od stacji była mniejsza więc wkładając ją uzupełniłem całość pianką montażową by nie latało. Rezultat był taki, że moduł z wbudowaną anteną za oknem 3m tracił zasięg drugi miał sygnał spokojnie do ok 10m (nawet przez ściany). Po teście wysłania danych i odebrania jednej danej na wordpresie przytępiono do montażu stacji. Jej finalna konfiguracja to Arduino Pro Mini 328 - 5V/16MHz Konwerter USB-UART FTDI FT232RL - gniazdo miniUSB (programator i zasilanie) nRF24L01+ Stacja meteo dfrobot PMS5003 (czujnik pyłu) Gravity (czujnik pyłu) MCP9808 (temperatura) SHT 31 (wigotność) BMP180 (ciśnienie) Dorzuciłem dwa czujniki pyły by porównać ich działanie. Jako końcowy element została mi kwestia wyświetlenia danych na stronie www. Dzięki wtyczce do pisania skryptów php w wordpresie udało napisać moduł pobierania danych z bazy i jego wyświetlania. Wykresy były większym problemem. Darmowe wtyczki do wordpressa nie chcą pobierać danych z sql i są ciężko edytowalne preferują prace na .csv i najlepiej jakby je ręcznie przeładowywać. Finalnie użyłem do tego celu Google Charts (nota bene na których wiele darmowych wtyczek do wordpresa bazuje). Z racji, że nie jestem web-developerem było to moje pierwsze spotkanie z php oraz javascriptem na którym Google Charsty operują. Zmuszenie tego pracy odbyło się metodą prób i błędów ale efekt jest zadowalający. Mam wykresy z 24h, tygodnia i miesiąca. Problemy Kodowanie int w arduino i malince Ze względu za na sposób kodowania liczny int w pythonie ujemne wartości temperatury np -5C na arduino pokazywały na malince wartość 65531 C. Trzeba było dopisać fragment który usuwał ten błąd. Komunikacja L01+ Moduły te są bardzo wrażliwe na zmiany napięcia. Można do nich dokupić adapter do wpięcia który głównie ma stabilizator napięcia. Nawet nie zawsze on pomaga jeśli do niego pójdzie nie wystarczające napięcie. Widać to np. jak się rusza kable to migocze LED lub jest "ciut" jaśniejszy. Wtedy anteny nie mogą się dogadać. Potrafi się zdarzyć takie kuriozum, że w takiej sytuacji antena straci własny adres. Jeśli anteny nie są w stanie się dogadać należy bezwzględnie sprawdzić pewność zasilania. Błąd wysłania danych SQL Czasami kod w malince się zawiesi w oczekiwaniu na wysłanie danych do serwera SQL. Trudno mi powiedzieć jak dobrze temu zaradzić. Występuję to przy dłuższej pracy (tydzień, miesiąc) aczkolwiek jedyne co mi przychodzi do głowy to ustawić na Raspianie auto-restart systemu co 24h. Wycinanie dziur w plastikowej obudowie Próbowałem wycinać szlifierką modelarską ale zawsze plastik się topił. Po szperaniu w necie rozwiązaniem są albo nożyki do plastiku albo wycinarka włosowa do plastiku ale nie udało mi się tego przetestować. Niestety wycięcia wyglądają mało estetycznie ale trudno. Google Charts Przesyłanie danych z PHP do JavaScript tak aby Google bylo problemem. Wykresy nie łykną dowolnego formatu danych i nie wyświetlą błędy jeśli uznają, że format im nie pasuje. Co mógłbym zrobić inaczej? Gdybym miał robić update to zamiast komunikacji radiowej do malinki wydaje mi się bardziej rozsądne pójście w wyposażenie arduino w WIFI i wysyłanie bezpośrednio na serwer. Nie uczyniłem tak ze względu na to pisanie kodu komunikacji Arduino WIFI nie jest to pare linijek. Plus też kod do wysyłania do SQL który znalazłem też pewnie by zawierał trochę kodu. Więcej dłubania ale efekt powinien być bardziej zadowalający. Plany na przyszłość Jedyne co chce na dniach zrobić to poduczyć się Eagla i przenieść całość na płytkę drukowaną i zamówić ją np. JLCPCB. Wtedy wypnę moduły z tamtych płytek i przypnę je do zamówionej. Reasumując Stacja działa już ok 6 miesięcy. Bez problemowo. Jak widać na wykresie z ostatniego miesiąca (tj. 26.12.2018 - 25.12.2019), że normy dla smogu w mojej wsi były w paru dniach przekroczone (a mieszkam w centrum pomorskiego bez kopalni, ciężkiego przemysłu wokół). Gdyby dobrze opisać każdy etap pracy można by z tego zrobić osobny kurs Poniżej kody źródłowe Arduino Ras PI Wordpress pobieranie suchych danych Wordpress pobieranie danych i osadzenie ich na Google Charts //Autor Bartosz Jakusz. Można wykorzystywać komercyjnie. Proszę tylko podać autora kodu #include <math.h> #include <Wire.h> #include <Arduino.h> #include <Adafruit_BMP085.h> #include <SoftwareSerial.h> #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include "Adafruit_SHT31.h" #include "Adafruit_MCP9808.h"7 #define dataSize 16 #define PMS5003BufferSize 40 #define dustGravityBufferSize 32 Adafruit_BMP085 bmp; Adafruit_MCP9808 tempsensor = Adafruit_MCP9808(); Adafruit_SHT31 sht31 = Adafruit_SHT31(); // software serial #2: RX = digital pin 8, TX = digital pin 9 SoftwareSerial Serial1(4, 5); SoftwareSerial Serial3(8, 9); SoftwareSerial Serial2(3, 2); RF24 radio(10, 14); // CE, CSN const byte address[6] = "00001"; char col; unsigned int dustSensor25 = 0,dustSensor10 = 0; unsigned int PMS = 0,PM10 = 0, formalin = 0,CR1 = 0,CR2 = 0; float PMSTemp = 0, PMSHigro = 0; bool readErr = false, readErr25 = false; int dustSensorReadError = 0; unsigned int higherBit = 0, LowerBit = 0; unsigned char buffer_RTT[40]={}; //Serial buffer; Received Data char meteoDatabuffer[35]; int measurments [dataSize]; void readPMS(); void readPM25(); void readDustSensorUARTData(SoftwareSerial S, unsigned char *bufferData, int bufferSize); unsigned int mergeBitsToInt(unsigned char *bufferData, int startBit, int stopBit); void clearBuffer(unsigned char *bufferData); void calculateControlSum(unsigned int &CR1Var, unsigned int &CR2Var, unsigned char *bufferData, int bufferSize); void encageDustSensorReadError(); void printUARTRecievedData(); void readMeteoStation(); int transCharToInt(char *_buffer,int _start,int _stop); //char to int) void sendData(); void printSendedData(); void printDataBySensor(); void setup() { Serial.begin(115000); Serial.println("start"); Serial1.begin(9600); Serial1.setTimeout(1500); delay(2000); Serial2.begin(9600); Serial2.setTimeout(1500); delay(1000); Serial3.begin(9600); Serial3.setTimeout(1500); radio.begin(); radio.setPALevel(RF24_PA_MAX); radio.setDataRate(RF24_1MBPS); radio.setChannel(0x76); radio.openWritingPipe(0xF0F0F0F0E1LL); radio.enableDynamicPayloads(); radio.stopListening(); if (!bmp.begin()) { while (1) {} } if (!tempsensor.begin()) { while (1); } if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr while (1) delay(1); } Serial.println("Zakończony Init"); delay(2000); } void loop() { readPMS(); readPM25(); readMeteoStation(); printDataBySensor(); if(readErr == false && readErr25 == false) { //Serial.println("Wysyłam dane"); sendData(); //Serial.print("Wysłano dane: "); } delay(1000); } void readPMS() { Serial.println("Czujnik pm5003"); readDustSensorUARTData(Serial1, buffer_RTT, PMS5003BufferSize); calculateControlSum(CR1, CR2, buffer_RTT, PMS5003BufferSize); if(CR1 == CR2 && CR1 != 0) //Check { PMS = mergeBitsToInt(buffer_RTT, 12, 13); PM10 = mergeBitsToInt(buffer_RTT, 14, 15); formalin = mergeBitsToInt(buffer_RTT, 28, 29); PMSTemp = mergeBitsToInt(buffer_RTT, 30, 31) / 10; PMSHigro = mergeBitsToInt(buffer_RTT, 32, 33) / 10; readErr = false; } else { PMS = 4321; PM10 = 4321; formalin = 4321; encageDustSensorReadError(); } clearBuffer(buffer_RTT); } void readPM25() { Serial.println("Czujnik p, 25"); readDustSensorUARTData(Serial3, buffer_RTT, dustGravityBufferSize); calculateControlSum(CR1, CR2, buffer_RTT, dustGravityBufferSize); if(CR1 == CR2 && CR1 != 0) //Check { dustSensor25 = mergeBitsToInt(buffer_RTT, 6, 7); dustSensor10 = mergeBitsToInt(buffer_RTT, 8, 9); readErr25 = false; } else { dustSensor25 = 4321; dustSensor10 = 4321; encageDustSensorReadError(); } clearBuffer(buffer_RTT); } void readDustSensorUARTData(SoftwareSerial S, unsigned char *bufferData, int bufferSize) { S.listen(); while(!S.available()); while(S.available()>0) //Data check: weather there is any Data in Serial1 { col =S.read(); delay(2); if (col == 0x42) { bufferData[0]=(char)col; col =S.read(); delay(2); if (col == 0x4d) { bufferData[1]=(char)col; for(int i = 2; i < bufferSize; i++) { col =S.read(); bufferData[i]=(char)col; delay(2); } break; } } S.flush(); } } unsigned int mergeBitsToInt(unsigned char *bufferData, int startBit, int stopBit) { higherBit = buffer_RTT[startBit]; //Read PM2.5 High 8-bit LowerBit = buffer_RTT[stopBit]; //Read PM2.5 Low 8-bit return (higherBit << 8) + LowerBit; } void clearBuffer(unsigned char *bufferData) { for(int i = 0; i < 40; i++) { bufferData[i] = 0; } delay(100); } void calculateControlSum(unsigned int &CR1Var, unsigned int &CR2Var, unsigned char *bufferData, int bufferSize) { CR1Var = 0; CR2Var = 0; CR1Var =(buffer_RTT[bufferSize - 2]<<8) + buffer_RTT[bufferSize - 1]; for(int i = 0; i < bufferSize - 2; i++) { CR2Var += bufferData[i]; } } void encageDustSensorReadError() { dustSensorReadError = dustSensorReadError + 1; readErr = true; readErr25 = true; Serial.print("Błąd odczytu: "); Serial.println(dustSensorReadError); //printUARTRecievedData(); } void readMeteoStation() { Serial.println("Stacja meteo nasłuchuje"); Serial2.listen(); while(!Serial2.available()); while(Serial2.available()>0) //Data check: weather there is any Data in Serial1 { Serial.println("Start meteo"); for (int index = 0;index < 35;index ++) { if(Serial2.available()) { meteoDatabuffer[index] = Serial2.read(); if (meteoDatabuffer[0] != 'c') { //Serial.println("Transmisja w toku meteo"); index = -1; } } else { index --; } } } Serial.println("Koniec"); } int transCharToInt(char *_buffer,int _start,int _stop) { //char to int) int result = 0; int num = _stop - _start + 1; int tempArr[num]; for (int indx = _start; indx <= _stop; indx++) { tempArr[indx - _start] = _buffer[indx] - '0'; result = 10 * result + tempArr[indx - _start]; } return result; } void sendData(){ for(int z = 0; z < dataSize; z++) { measurments[z] = -1000; } //Meteo station measurments[0] = (int)(transCharToInt(meteoDatabuffer,1,3)); //wind directoin measurments[1] = (int)(transCharToInt(meteoDatabuffer,28,32) / 10.00); //pressure //measurments[2] = (int)(((transCharToInt(meteoDatabuffer,13,15) - 32.00) * 5.00 / 9.00) * 100); //temp *C //measurments[3] = (int)((transCharToInt(meteoDatabuffer,25,26)) * 100); //higro %RH measurments[2] = (int)((transCharToInt(meteoDatabuffer,5,7) / 0.44704) * 100); //avg wind speed 1 min (m/s) measurments[3] = (int)((transCharToInt(meteoDatabuffer,9,11) / 0.44704) * 100); //max wind speed 5min (m/s) measurments[4] = (int)((transCharToInt(meteoDatabuffer, 17, 19) * 25.40 * 0.01) * 100); // rain 1 hour (mm) measurments[5] = (int)((transCharToInt(meteoDatabuffer, 21, 23) * 25.40 * 0.01) * 100); // rain 24 hour (mm) //MCP9008 measurments[6] = (int)(tempsensor.readTempC() * 100); //SHT31 measurments[7] = (int)(sht31.readHumidity() * 100); measurments[8] = (int) (sht31.readTemperature()* 100); //PMS5003 //measurments[11] = PMSTemp * 100; //measurments[12] = PMSHigro * 100; measurments[9] = PMS; measurments[10] = PM10; measurments[11] = formalin; //PM2,5 Gravity measurments[12] = dustSensor25; measurments[13] = dustSensor10; //BMP180 measurments[14] = bmp.readPressure() / 100; //measurments[19] = (int) (bmp.readTemperature() * 100); measurments[15] = 666; int testMe = 0; for(int k = 0; k < 15; k++) { testMe += measurments[k]; } Serial.print("PRZYKLADOWA CHECK SUMA: "); Serial.println(testMe); radio.write(&measurments, sizeof(measurments)); printSendedData(); } void printSendedData() { Serial.println("Wysłano następujące dane:"); for (int i = 0; i < dataSize; i++) { Serial.print(measurments[i]); Serial.print(" "); } Serial.println(); } void printUARTRecievedData() { byte b; for(int i=0;i<32;i++) { b = (byte)buffer_RTT[i]; //buffer_RTT[i] = 0; Serial.print(b, HEX); Serial.print(" "); } Serial.print("CR1: "); Serial.print(CR1); Serial.print(" = "); Serial.println(CR2); } void printDataBySensor() { Serial.println(); Serial.println("MCP9808: "); Serial.print("Temperatura: "); float c = tempsensor.readTempC(); Serial.print(c); Serial.println("*C"); Serial.println(); Serial.println("SHT31: "); Serial.print("Wilgotność: "); Serial.print(sht31.readHumidity()); Serial.println("%RH"); Serial.print("Temperatura: "); Serial.print(sht31.readTemperature()); Serial.println("*C"); Serial.println(); Serial.println("BMP180: "); Serial.print("Temperatura: "); float bmpTemp = bmp.readTemperature(); Serial.print(bmpTemp); Serial.println("*C"); Serial.print("Ciśnienie: "); Serial.print(bmp.readPressure() / 100); Serial.println("hPa"); Serial.print("Teoretyczna wysokość: "); Serial.print(bmp.readAltitude(101100)); Serial.println("m.n.p.m"); Serial.println(); Serial.println("PMS5003:"); Serial.print("PM 2,5: "); Serial.print(PMS); Serial.println(" /25 ug/m3 "); Serial.print("PM 10 : "); Serial.print(PM10); Serial.println(" /50 ug/m3 "); Serial.print("Formaldehyd : "); Serial.print(formalin); Serial.println(" ug/m3 "); Serial.print("Temperatura: "); Serial.print(PMSTemp); Serial.println("*C"); Serial.print("Wilgotność: "); Serial.print(PMSHigro); Serial.println("%RH"); Serial.println(); Serial.println("PM 2,5 GRAVITY:"); Serial.print("PM 2,5: "); Serial.print(dustSensor25); Serial.println(" /25 ug/m3 "); Serial.print("PM 10 : "); Serial.print(dustSensor10); Serial.println(" /50 ug/m3 "); Serial.println(); Serial.println("STACJA METEO: "); Serial.print("Temperatura: "); c = (transCharToInt(meteoDatabuffer,13,15) - 32.00) * 5.00 / 9.00; Serial.print(c); Serial.println("*C"); Serial.print("Wilgotnosc: "); float metHigro = transCharToInt(meteoDatabuffer,25,26); Serial.print(metHigro); Serial.println("%RH"); Serial.print("Cisnienie: "); float pp = transCharToInt(meteoDatabuffer,28,32) / 10.00; Serial.print(pp); Serial.println("hPa"); Serial.print("Predkośc wiatru: "); float w = transCharToInt(meteoDatabuffer,5,7) / 0.44704; Serial.print(w); Serial.println("m/s"); Serial.print(" "); w = w * 3.6; Serial.print(w); Serial.println("km/h"); Serial.print("Max Predkośc wiatru: "); float m = transCharToInt(meteoDatabuffer,9,11) / 0.44704; Serial.print(m); Serial.println("m/s (ostatnie 5 minut)"); Serial.print(" "); m = m * 3.6; Serial.print(m); Serial.println("km/h (ostatnie 5 minut)"); Serial.print("Kierunek wiatru: "); Serial.print(transCharToInt(meteoDatabuffer,1,3)); Serial.println("C"); Serial.print("Opad (1h): "); float rain1 = transCharToInt(meteoDatabuffer, 17, 19) * 25.40 * 0.01; Serial.print(rain1); Serial.println("mm"); Serial.print("Opad (24h): "); float rain24 = transCharToInt(meteoDatabuffer, 21, 23) * 25.40 * 0.01; Serial.print(rain24); Serial.println("mm"); Serial.println(); } #Autor Bartosz Jakusz. Można replikować nawet w celach komercyjnych. Tylko umieścić autora kodu. import RPi.GPIO as GPIO from lib_nrf24 import NRF24 import time import spidev import struct import os import mysql.connector from mysql.connector import errorcode from datetime import date, datetime, timedelta GPIO.setmode(GPIO.BCM) pipes = [[0xE8, 0xE8, 0xF0, 0xF0, 0xE1], [0xF0, 0xF0, 0xF0, 0xF0, 0xE1]] radio = NRF24(GPIO, spidev.SpiDev()) radio.begin(0, 17) radio.setPayloadSize(32) radio.setChannel(0x76) radio.setDataRate(NRF24.BR_1MBPS) radio.setPALevel(NRF24.PA_MAX) radio.setAutoAck(True) radio.enableDynamicPayloads() radio.enableAckPayload() i = 0 j = 0 sucRate = 0 errRate = 0 totalRec = 0 try: while True: radio.openReadingPipe(1, pipes[1]) #radio.printDetails() radio.startListening() print(" ") print(datetime.now()) radio.print_address_register("RX_ADDR_P0-1", NRF24.RX_ADDR_P0, 2) radio.print_address_register("TX_ADDR", NRF24.TX_ADDR) j = 0 while not radio.available(0): j = j + 1 receivedMessage = [] radio.read(receivedMessage, radio.getDynamicPayloadSize()) radio.stopListening() print("Received: {}".format(receivedMessage)) string = "" floatBytes = [] indx = 0 while indx < 4: floatBytes.append(0) indx = indx + 1 measurments = [] indx = 0 mIndx = 0 tmpStr= "" tmpIndx = 0 crc = 0 if not receivedMessage: print("pusto wywalam sie") else: for n in receivedMessage: #print(tmpIndx) tmpIndx = tmpIndx + 1 floatBytes.insert(indx, n) if(indx >= 1): b1 = floatBytes[0] b2 = floatBytes[1] host = 0 host = b2 host = host << 8 host = host | b1 if(mIndx == 6): print("trt {}".format(host)) if(host > 65536 / 2): host = (65536 - host) * (-1) print("trti {}".format(host)) tmpVar = host / 100 print("trtf {}".format(tmpVar)) elif(mIndx >= 2 and mIndx < 5 or mIndx >= 7 and mIndx <= 8): tmpVar = host / 100 else: tmpVar = host indx = 0 measurments.append(tmpVar) mIndx = mIndx + 1 else: indx = indx + 1 totalRec = totalRec + 1 print(" ") if(host == 666): sucRate = sucRate + 1 print("Odebrano z sukcesem {}/{} transmisji".format(sucRate, totalRec)) try: print("Zaczynamy łacznie z baza") cnx = mysql.connector.connect(host='00.00.00.00',database='db') cursor = cnx.cursor() print("Połączono z baza") #zapytania SQL add_probeTime = ("INSERT INTO MeasrumentDateTime" "(time, date)" "VALUES (%s, %s)") add_MCP8006 = ("INSERT INTO MCP8006 " "(temperature, MeasrumentDateTime_ID) " "VALUES (%(temperature)s, %(timeID)s)") add_SHT31 = ("INSERT INTO SHT31 " "(humidity, temperature, MeasrumentDateTime_ID) " "VALUES (%(humidity)s ,%(temperature)s, %(timeID)s)") add_BMP180 = ("INSERT INTO BMP180" "(pressure, MeasrumentDateTime_ID) " "VALUES (%(pressure)s, %(timeID)s)") add_PMS5003 = ("INSERT INTO PMS5003" "(pm25, pm10, formaldehyd, MeasrumentDateTime_ID) " "VALUES (%(pm25)s, %(pm10)s, %(formaldehyd)s,%(timeID)s)") add_PMGravity = ("INSERT INTO PM25" "(PM25, PM10, MeasrumentDateTime_ID) " "VALUES (%(pm25)s, %(pm10)s, %(timeID)s)") add_meteoSation = ("INSERT INTO MeteoStation" "(windDirection, avgWindSpeedPerMinute, avgWindSpeedPerFiveMinutes, rainfallOneHour, rainfal24Hours, pressure, MeasrumentDateTime_ID) " "VALUES (%(windDir)s, %(avgWind)s, %(maxWind)s, %(rain1h)s, %(rain24h)s, %(pressure)s, %(timeID)s)") #Dodaj obecna godzine currentTimeAndDate = datetime.now() formatted_time = currentTimeAndDate.strftime('%H:%M:%S') currentDate = datetime.now().date() toSendSampleDate = (formatted_time, currentDate) cursor.execute(add_probeTime, toSendSampleDate) sampleTimeID = cursor.lastrowid #Wyslij do bazy MySql dane czujnik temp MCP8006Data = { 'timeID' : sampleTimeID, 'temperature' : measurments[6], } cursor.execute(add_MCP8006, MCP8006Data) #Wyslij do bazy MySql dane higrometr SHT 31 SHT31Data = { 'timeID' : sampleTimeID, 'humidity' : measurments[7], 'temperature' : measurments[8], } cursor.execute(add_SHT31, SHT31Data) #Wyslij do bazy MySql dane barometr BMP180 BMP180Data = { 'timeID' : sampleTimeID, 'pressure' : measurments[14], } cursor.execute(add_BMP180, BMP180Data) #Wyslij do bazy MySql dane czujnik pylu PMS5003 PMS5003Data = { 'timeID' : sampleTimeID, 'pm25' : measurments[9], 'pm10' : measurments[10], 'formaldehyd' : measurments[11], } cursor.execute(add_PMS5003, PMS5003Data) #Wyslij do bazy MySql dane czujnik pylu PM 2,5 Gravity PMGravityData = { 'timeID' : sampleTimeID, 'pm25' : measurments[12], 'pm10' : measurments[13], } cursor.execute(add_PMGravity, PMGravityData) #Wyslij do bazy MySql dane stacja meteo metStationData = { 'timeID' : sampleTimeID, 'windDir' : measurments[0], 'avgWind' : measurments[2], 'maxWind' : measurments[3], 'rain1h' : measurments[4], 'rain24h' : measurments[5], 'pressure' : measurments[1], } cursor.execute(add_meteoSation, metStationData) print("Wysylanie danych na serwer") cnx.commit() cursor.close() print("Wyslano do bazy pomyslnie dane") except mysql.connector.Error as err: if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: print("Something is wrong with your user name or password") elif err.errno == errorcode.ER_BAD_DB_ERROR: print("Database does not exist") else: print(err) else: cnx.close() time.sleep(14) else: print("BLAD TRANSMISJI: nie zgadza sie suma kontrolna") #errRate = errRate + 1 #print("Żle odebrano {}/{} transmisji".format(errRate, totalRec)) print(" ") print("------------------------------------------") #radio.closeReadingPipe(pipes[1]) #radio.stopListening() time.sleep(1) except KeyboardInterrupt: print(i) except: # this catches ALL other exceptions including errors. # You won't get any error messages for debugging # so only use it once your code is working print ("Other error or exception occurred!") finally: GPIO.cleanup() # this ensures a clean exit echo"Autor Bartosz Jakusz. Można wykorzystywać komercyjnie. Wsakazać tylko autora kodu. "; $mydb = new wpdb('usr_db','db','localhost'); $currentTime = $mydb->get_results("SELECT time, date FROM MeasrumentDateTime ORDER BY ID DESC LIMIT 1"); $tempData = $mydb->get_results("SELECT temperature FROM MCP8006, MeasrumentDateTime WHERE MeasrumentDateTime_ID = MeasrumentDateTime.ID ORDER BY MeasrumentDateTime.ID DESC LIMIT 1"); $higroData = $mydb->get_results("SELECT humidity FROM SHT31, MeasrumentDateTime WHERE MeasrumentDateTime_ID = MeasrumentDateTime.ID ORDER BY MeasrumentDateTime.ID DESC LIMIT 1"); $pressureData = $mydb->get_results("SELECT pressure FROM BMP180, MeasrumentDateTime WHERE MeasrumentDateTime_ID = MeasrumentDateTime.ID ORDER BY MeasrumentDateTime.ID DESC LIMIT 1"); $pms5003Data = $mydb->get_results("SELECT pm25, pm10, formaldehyd FROM PMS5003, MeasrumentDateTime WHERE MeasrumentDateTime_ID = MeasrumentDateTime.ID ORDER BY MeasrumentDateTime.ID DESC LIMIT 1"); $gravityData = $mydb->get_results("SELECT PM25, PM10 FROM PM25, MeasrumentDateTime WHERE MeasrumentDateTime_ID = MeasrumentDateTime.ID ORDER BY MeasrumentDateTime.ID DESC LIMIT 1"); $metStationData = $mydb->get_results("SELECT windDirection, avgWindSpeedPerMinute, avgWindSpeedPerFiveMinutes, rainfallOneHour, rainfal24Hours FROM MeteoStation, MeasrumentDateTime WHERE MeasrumentDateTime_ID = MeasrumentDateTime.ID ORDER BY MeasrumentDateTime.ID DESC LIMIT 1"); $avgkmPerHour = $metStationData[0]->avgWindSpeedPerMinute * 3.6; $maxkmPerHour = $metStationData[0]->avgWindSpeedPerFiveMinutes * 3.6; echo "<table>"; echo"<col width=50%>"; echo"<tr>"; echo"<th>Ostatni pomiar z: </th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th>".$currentTime[0]->time." </th>"; echo"<th>".$currentTime[0]->date." </th>"; echo"</tr>"; echo"</table>"; echo "<br>"; echo "<br>"; $dir = $metStationData[0]->windDirection; $dirName = ""; if ($dir < 45) { $dirName = "Północny"; } elseif ($dir >= 45 or $dir < 90 ) { $dirName = "Północno-Wschodni"; } elseif ($dir >= 90 or $dir < 135 ) { $dirName = "Wschodni"; } elseif ($dir >= 135 or $dir < 180 ) { $dirName = "Południowo-Wschodni"; } elseif ($dir >= 180 or $dir < 225 ) { $dirName = "Południowy"; } elseif ($dir >= 225 or $dir < 270 ) { $dirName = "Południowo-Zachodni"; } elseif ($dir >= 270 or $dir < 315 ) { $dirName = "Zachodni"; } else { $dirName = "Północno-Zachodni"; } echo "<table>"; echo"<col width=50%>"; echo"<tr>"; echo"<th>Temperatura: </th>"; echo"<th>".$tempData[0]->temperature."*C </th>"; echo"</tr>"; echo"<tr>"; echo"<th>Wilgotność: </th>"; echo"<th>".$higroData[0]->humidity."%RH </th>"; echo"</tr>"; echo"<tr>"; echo"<th>Ciśnienie: </th>"; echo"<th>".$pressureData[0]->pressure."hPa </th>"; echo"</tr>"; echo"</table>"; echo "<br>"; echo "<br>"; echo "<table>"; echo"<col width=50%>"; echo"<tr>"; echo"<th>Czystość powietrza: </th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th>PM 2,5 - norma 25ug/m3: </th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th>PMS5003: </th>"; echo"<th>".$pms5003Data[0]->pm25."ug/m3</th>"; echo"</tr>"; echo"<tr>"; echo"<th>Gravity: </th>"; echo"<th>".$gravityData[0]->PM25."ug/m3</th>"; echo"</tr>"; echo"</tr>"; echo"<tr>"; echo"<th><br></th>"; echo"<th><br></th>"; echo"</tr>"; echo"</tr>"; echo"<tr>"; echo"<th>PM 10 - norma 50ug/m3</th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th>PMS5003: </th>"; echo"<th>".$pms5003Data[0]->pm10."ug/m3 </th>"; echo"</tr>"; echo"<tr>"; echo"<th>Gravity: </th>"; echo"<th>".$gravityData[0]->PM10."ug/m3 </th>"; echo"</tr>"; echo"<tr>"; echo"<th><br></th>"; echo"<th><br></th>"; echo"</tr>"; echo"</tr>"; echo"<tr>"; echo"<th>Formaldehyd</th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th>PMS5003: </th>"; echo"<th>".$pms5003Data[0]->formaldehyd."ug/m3 </th>"; echo"</tr>"; echo"</table>"; echo "<br>"; echo "<br>"; echo "<table>"; echo"<col width=50%>"; echo"<tr>"; echo"<th>Stacja Meteo: </th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th>Kierunek Wiatru: </th>"; echo"<th>".$dirName."</th>"; echo"</tr>"; echo"<tr>"; echo"<th><br></th>"; echo"<th><br></th>"; echo"</tr>"; echo"<tr>"; echo"<th>Średnia prędkość wiatru (ostatnia minuta): </th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th> </th>"; echo"<th>".$metStationData[0]->avgWindSpeedPerMinute."m/s</th>"; echo"</tr>"; echo"<tr>"; echo"<th> </th>"; echo"<th>".$avgkmPerHour."km/h</th>"; echo"</tr>"; echo"</tr>"; echo"<tr>"; echo"<th><br></th>"; echo"<th><br></th>"; echo"</tr>"; echo"</tr>"; echo"<tr>"; echo"<th>Max prędkość wiatru (ostatnie 5 min)</th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th> </th>"; echo"<th>".$metStationData[0]->avgWindSpeedPerFiveMinutes."m/s</th>"; echo"</tr>"; echo"<tr>"; echo"<th> </th>"; echo"<th>".$maxkmPerHour."km/h</th>"; echo"</tr>"; echo"<tr>"; echo"<th><br></th>"; echo"<th><br></th>"; echo"</tr>"; echo"</tr>"; echo"<tr>"; echo"<th>Opad atmosferyczny</th>"; echo"<th></th>"; echo"</tr>"; echo"<tr>"; echo"<th>Ostatnia godzina: </th>"; echo"<th>".$metStationData[0]->rainfallOneHour."mm</th>"; echo"</tr>"; echo"<tr>"; echo"<th>Ostatnia doba: </th>"; echo"<th>".$metStationData[0]->rainfal24Hours."mm </th>"; echo"</tr>"; echo"</table>"; echo"Autor Bartosz Jakusz. Można wykorzystywać komercyjnie. Wsakazać tylko autora kodu. "; $mydb = new wpdb('usr_db','db','localhost'); $pm25DataPMS5003 = $mydb->get_results("SELECT time, date, round(avg(pm25), 0) as pm25PMSMonth FROM PMS5003, MeasrumentDateTime WHERE TIMESTAMP(date, time) > NOW() - INTERVAL 1 MONTH and MeasrumentDateTime_ID = MeasrumentDateTime.ID group by DAY(TIMESTAMP(date, time)) ORDER BY MeasrumentDateTime.ID"); $pm25DataGravity = $mydb->get_results("SELECT time, date, round(avg(PM25.PM25),0) as pm25GravMonth FROM PM25, MeasrumentDateTime WHERE TIMESTAMP(date, time) > NOW() - INTERVAL 1 MONTH and MeasrumentDateTime_ID = MeasrumentDateTime.ID group by DAY(TIMESTAMP(date, time)) ORDER BY MeasrumentDateTime.ID"); $tmpPM25 = []; $i = 0; $someRandData = 25; foreach ($pm25DataGravity as $obj) : array_push($tmpPM25, array(substr((string)$obj->date,5)." ".substr((string)$obj->time,0,-9), (float)$obj->pm25GravMonth, (float)$pm25DataPMS5003[$i]->pm25PMSMonth, (float)$someRandData )); $i++; endforeach; echo"<div id='pm25ChartMonth'></div>"; ?> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript"> var pm25 = <?php echo json_encode($tmpPM25); ?>; google.charts.load('current', {packages: ['corechart', 'line']}); google.charts.setOnLoadCallback(drawBasic); function drawBasic() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Last Hour'); data.addColumn('number', 'Gravity'); data.addColumn('number', 'PMS5003'); data.addColumn('number', 'Norma'); data.addRows(pm25); var options = { 'title':'Zaniczyszczenie PM 2,5 ostatni miesiąc', 'curveType': 'function', hAxis: { title: 'Godzina' }, vAxis: { title: 'um/m3' }, height: 500 }; var chart = new google.visualization.LineChart(document.getElementById('pm25ChartMonth')); chart.draw(data, options); } </script>
  42. 5 punktów
    Cześć W ramach organizowanej akcji postanowiłem opisać projekt, który wykonałem już jakiś czas temu. WPROWADZENIE Projekt to stacja meteorologiczna montowana na wyrzutni rakiet zaprojektowana i wykonana przeze mnie w ramach rekrutacji do Sekcji Rakietowej Studenckiego Koła Astronautycznego (działającego na Politechnice Warszawskiej). Wymagania wobec stacji: pomiar prędkości i kierunku wiatru, pomiar temperatury i ciśnienia, pomiar położenia oraz orientacji wyrzutni i kąta nachylenia ramienia, komunikacja bezprzewodowa z bazą, zasięg 500-700m, aplikacja na PC wyświetlająca i rejestrująca odbierane dane. ELEKTRONIKA Ogólny diagram sprzętowy wygląda następująco: Do realizacji 'mózgu' stacji wykorzystałem Arduino Pro Mini (zarówno w nadajniku, jak i odbiorniku). Komunikacja bezprzewodowa zrealizowana jest poprzez moduły NRF24L01+ ze wzmacniaczem mocy (w przeprowadzonych na poligonie testach bez problemu uzyskiwały zasięg 700m). Do pomiaru ciśnienia i temperatury zastosowałem moduł z układem BMP180. Pomiar prędkości i kierunku wiatru jest wykonywany przez zestaw stacji pogodowej. Do pomiaru kąta nachylenia wyrzutni zastosowałem moduł z układem MPU-6050. Położenie wyrzutni jest mierzone poprzez standardowy moduł GPS (NEO-7M-C firmy Waveshare). Urządzenie montowane na wyrzutni zasilane jest dwoma ogniwami litowo-jonowymi, a odbiornik jest zasilany przez komputer za pośrednictwem USB. Do generacji napięcia 5V w nadajniku wykorzystałem moduł przetwornicy D24V6F5 z Pololu. Z przeprowadzonych pomiarów wynika, że jedno ładowanie baterii pozwala działać stacji przez około 30 godzin. Schemat jednostki głównej: Ciekawą sprawą jest pomiar prędkości wiatru. Anemometr raz na obrót zwiera styk, a prędkość obrotowa jest proporcjonalna do prędkości wiatru (1Hz przekłada się na 2.4km/h). Mierząc więc okres pomiędzy kolejnymi krawędziami, można określić prędkość wiatru. Aby pomiar był możliwie dokładny, wykorzystałem przerwania. Jednak jak to z mechanicznymi stykami bywa, pojawiały się drgania styków: Aby zniwelować ten efekt zastosowałem dwie bramki NOT z przerzutnikami Schmitta i filtrem RC (o stałej czasowej około 1ms). Układ sprawia, że na pinie mikrokontrolera pojawiają się ładne, pojedyncze zbocza (czerwony to wyjście anemometru, a niebieski przebieg to sygnał podłączony do pinu mikrokontrolera): Na pokładzie zamontowany jest również magnetometr (znajdujący się poza główną obudową, w oddzielnej obudowie), który miał służyć do pomiaru azymutu wyrzutni (przy startach rakiet bardzo istotne są dwa kąty: azymut oraz nachylenie ramienia wyrzutni). Ostatecznie jednak nie został wykorzystany ze względu na problemy z kalibracją (magnetometr musiałby być za każdym razem montowany dokładnie tak samo na wyrzutni, co nie jest wykonalne). Odbiornik jest stosunkowo prostym urządzeniem: Zawiera tylko mikrokontroler (na module Arduino Pro Mini) oraz moduł radiowy. Komunikacja z PC wykonywana jest przez konwerter USB-UART. Odbiornik wyposażony jest też w diodę, która jest zapalana na chwilę w momencie odebrania pakietu. Bardzo to pomaga przy rozstawianiu stacji. Oba układy zmontowałem na płytkach prototypowych. OPROGRAMOWANIE Oprogramowanie projektu jest dość rozbudowane, gdyż składa się z dwóch projektów na systemy wbudowane (nadajnik i odbiornik) oraz oprogramowania na PC. Oprogramowanie nadajnika Kod napisany oczywiście z wykorzystaniem środowiska i bibliotek Arduino dla przyspieszenia developmentu Wykorzystałem dodatkowe biblioteki: MPU6050 (konfiguracja i odczytywanie danych z akcelerometru) HMC5883L (konfiguracja i odczytywanie danych z magnetometru) I2Cdev (wykorzystywane przez bibliotekę MPU6050) TinyGPS (parsowanie danych z GPS) RF24 (komunikacja z modułem radiowym) Adafruit_BMP085 (konfiguracja i odczytywanie danych z barometru) Oprogramowanie odbiornika Zadaniem programu uruchomionego na odbiorniku jest odczytanie danych z modułu radiowego i przerzucenie ich od razu na port szeregowy. Nic skomplikowanego. Kod na systemy wbudowane jest w repozytorium: https://github.com/Lukaszm94/rocketLauncherDAQ_embedded Oprogramowanie na PC Program do uruchamiany na PC służy do odbierania danych z odbiornika, wyświetlania ich i zapisywania do pliku CSV. Do zrealizowania powyższych zadań wykorzystałem język C++, framework Qt i bibliotekę Qwt. Kod znajduje się w repozytorium: https://github.com/Lukaszm94/RocketLauncherDataAcquisitionApp Na temat samej implementacji nie będę się rozpisywał. Kilka ciekawszych funkcji programu to wyznaczanie wartości średniej prędkości wiatru (z możliwością ustalenia z jakiego okresu ma być wyliczana średnia) oraz podmuchu (chwilowa maksymalna prędkość wiatru). Dodatkowo, jeżeli któryś sensor działa niepoprawnie (np. akcelerometr jest niepodłączony albo GPS nie ma fixa), to wartość z tego sensora jest wyświetlana w kolorze czerwonym. Widok okna programu: MECHANIKA Wszystkie obudowy i elementy mocujące zaprojektowałem w Autodesk Inventor i wykonałem z wykorzystaniem drukarki 3D. Na wyrzutni montowane są trzy urządzenia: jednostka główna, moduł kompasu i moduł akcelerometru. W czasie projektowania kierowałem się łatwością montażu w warunkach polowych (stąd np. zastosowanie nakrętek motylkowych do mocowania obejm) oraz zapewnienie możliwie wysokiej odporności na wodę. Render głównej obudowy: Render odbiornika: Nadajnik: Wnętrze nadajnika: Wnętrze odbiornika: Ciekawy patent, jaki mogę pokazać, to wykonanie złącz do świata zewnętrznego. Wykorzystałem złącza męskie KK254, które przylutowane są do odpowiednio wyciętej płytki prototypowej. W płytce są dwa otwory pod śruby M3, analogiczne otwory są w obudowie. Płytka jest mocowana od wewnątrz do ścianki urządzenia z wykorzystaniem dwóch śrub. Całość od zewnątrz wygląda elegancko i jest wytrzymała. Cała jednostka główna zmontowana: WNIOSKI I PODSUMOWANIE Projekt spełnia większość założeń i uważam, że został zrealizowany z sukcesem. Wykorzystany został już wielokrotnie na poligonie i w zasadzie za każdym razem system działał poprawnie. Jeśli chodzi o wady, to główny problem jaki zaobserwowałem, to uszkadzanie się modułów radiowych (konkretniej to wzmacniaczy mocy) w momencie włączenia urządzenia bez podłączonej anteny - co niestety zdarzyło się kilkukrotnie (przypadkowe włączenie). Drugi problem to brak pomiaru orientacji wyrzutni, związany z opisaną wcześniej kłopotliwą kalibracją. Przykładowy wykres uzyskany z wykorzystaniem stacji (na zawodach CanSatów w 2016 jeśli dobrze pamiętam): Krótki opis projektu jest też na mojej stronie internetowej: http://lukemeyer.me/rldaq.php Na koniec mogę pokazać ładne zdjęcie ze startu rakiety TuCAN (jak się dokładnie przyjrzycie, to widać stację zamontowaną na wyrzutni ). W projekcie TuCAN również brałem udział, zajmowałem się całością systemów elektronicznych w rakiecie. Jakby ktoś był zainteresowany, to mam mały opis na mojej stronie: http://lukemeyer.me/tucan.php
  43. 5 punktów
    Metod samodzielnego wykonywania płytek pcb jest wiele. Termotransfer - potrzebna dobra drukarka laserowa, fototransfer - też dobra drukarka, płytki światłoczułe lub własnoręczne pokrywanie takim lakierem, suszenie, naświetlanie itp. Testowałem naświetlanie i albo prześwietliło albo odwrotnie. Można frezować. Ale można też rysować. Oczywiście nie ręcznie, jak to dawniej bywało. Jako, że z cnc i budową urządzeń mam trochę do czynienia, postanowiłem zbudować sobie taką małą maszynkę. Większość materiałów miałem - aluminiowe płytki, kątowniki, silniki krokowe i szlifowane prowadnice ze starych drukarek, a także dostęp do własnej małej tokarko - frezarki cnc. Całość miała być "po taniości" i maksymalne wykorzystanie "przydasiów" . Początkowo użyłem kilku gotowych podzespołów, jak stolik krzyżowy (proxxon) i mechanizm napędu ze starego CD/DVD jako oś Z. Użyte silniczki mają 24 kroki/obrót, zasilane z 12 V. Ich sterowniki to DRV8825 . Koła zębate pod paski też wyrób własny - frezowanie ( aluminium i poliamid ), paski trzeba było nabyć. Całością steruje Arduino Uno i GRLB1.1. Problem pojawił się w momencie zainstalowania krańcówek. Jedna oś działała, reszta martwa. CNC Shield był projektowany pod GRLB-8, a nowsze wersje tego oprogramowania mają pozmieniane niektóre wyprowadzenia. Ale jest to opisane na stronie GRLB. Nic nie pomagało - wgrywanie softu, czyszczenie procka i jego EEPROM'u. Oczywiście kontrola przewodów i samych krańcówek. Do "przyzwoitego" połączenia przewodów z układem sterującym przydają się złącza BLS. Dopiero nowa Atmega328 - i teraz wszystko gra. Nie spodziewałem się wadliwego układu. W ferworze walki o działające krańcówki została wykonana optoizolacja na układzie LTV847 . Płytkę do tego wyrysowała maszyna już sama dla siebie. Ponieważ wszystko działało, można by tak zostawić. Jednak pole robocze było małe - 45 x 120 mm. Trochę pracy trzeba było włożyć - cięcie, frezowanie i toczenie elementów. Ale warto było, bo powstałą dość solidna konstrukcja - już tak przyszłościowo.Dorobienie śruby i nakrętki (żeliwo) z kasowaniem luzu, mocowania silnika i łożyskowania śruby dopełnia reszty. Oczywiście dokładne ustawienie na czujnik zegarowy i dokładnym kątomierzem równoległości oraz kątów. W efekcie obszar roboczy zwiększył się do 180 x 120 mm. Większych płytek chyba robić nie będę. Mocowanie pisaka umożliwia ruch góra/dół - taki luz bezpieczeństwa - z uwagi na czasem spotykane niezbyt "płaskie" laminaty, natomiast luz poprzeczny jest minimalny i wg. pomiarów nie przekracza 0,03mm. Można więc mówić o precyzji . Oczywiście kusi przeróbka. W pierwszym rzędzie zmiana silników na taki krokowiec. Obecnie używane mają cienką oś - 2 mm, która wygina się od naciągniętych pasków. Ich łożyska cierne też się od tego mocno wyrabiają jednostronnie. Drugi powód - mocniejszy silnik umożliwi większą szybkość pracy. Obecnie to 300 mm/min. Nowa oś Z ( mocniejsza ) i zwiększenie jej zakresu pracy oraz obniżenie stołu roboczego. Zamiast obecnego mazaka - bo tylko tyle ten mały silniczek dźwignie - można by założyć jakiś moduł lasera albo i głowicę drukującą ( 3D ). Albo i mały silnik jako wiertarkę. W chwili obecnej pisak daje ścieżkę szerokości 0,4 mm lub wielokrotność. Próby z cieńszą ścieżką nie wypadły na razie pomyślnie - za słabe krycie i potrafią zostać przetrawione - używam chlorku żelaza.
  44. 5 punktów
    Tym razem będzie nietechnicznie — to co tu opisuję, to wyłącznie moja własna prywatna opinia. Jeśli ktoś się nie zgadza, to zapraszam do dyskusji, jednak rezerwuję sobie prawo pozostania przy swoich wnioskach. Będzie o androidach, ale nie systemie operacyjnym dla telefonów, tylko o człekokształtnych robotach. Otóż uważam, że pomimo ich częstego pojawiania się w wiadomościach i na pierwszych stronach gazet, roboty tego typu są generalnie bezużyteczne poza bardzo wąską dziedziną zastosowań, jaką jest przemysł rozrywkowy. Jest tak z bardzo prostego powodu: humanoidalny kształt człowieka nie ma, z technicznego punktu widzenia, żadnych zalet, natomiast niesie ze sobą wiele nietrywialnych wyzwań. Zatem jeśli główną rolą naszego robota jest wyglądanie jak człowiek — po to, żeby stać na wystawie sklepowej i prezentować ubrania, iść w pochodzie, występować na scenie lub w filmie, bawić dzieci jako zabawka, czy zapewniać firmie dobrą prasę — to jak najbardziej ma sens nadanie mu właśnie takiego kształtu. W innych przypadkach nie ma to najmniejszego sensu, bo okazuje się, że wszelkie zalety takiego rozwiązania są tylko pozorne: 1. Zastępowanie ludzi w środowisku przystosowanym dla ludzi: używanie ludzkich maszyn i narzędzi, poruszanie się w mieszkaniach i biurach. Wydaje się, że to niezła racjonalizacja — jeśli dany robot ma zastąpić człowieka, to musi mieć możliwość sięgnięcia do wszystkich rzeczy, do których człowiek by sięgnął, wejścia w miejsce, w które człowiek może wejść i ogólnie robienia tego, co człowiek mógłby zrobić. Ale okazuje się, że można to osiągnąć bez kopiowania ludzkiego ciała. Co więcej, taki nie-człekokształtny robot będzie miał znaczącą przewagę, bo będzie mieć większą zwinność, lepszy zasięg, większą siłę i szybkość, nie mówiąc już o łatwiejszym sterowaniu. Roboty w rodzaju Robosimiania z łatwością mieszczą się wszędzie tam, gdzie człowiek, a są znacznie bardziej uniwersalne. 2. Interakcja z ludźmi. Wydawałoby się, że lepiej się będziemy czuć współpracując z czymś, co wygląda i zachowuje się tak jak my sami. Okazuje się, że wręcz przeciwnie. Im bardziej robot przypomina człowieka, tym bardziej obrzydliwy, wstrętny i straszny będzie się wydawał i tym gorzej przebiegać będzie interakcja. Zjawisko nosi nazwę "uncanny valley" i jest dość dobrze zbadane przez psychologów. Rozwiązaniem jest nadanie abstrakcyjnych lub komiksowych kształtów robotom, ale jeszcze łatwiej po prostu zaprojektować je tak, żeby ich kształt odpowiadał ich funkcji. 3. Wydajność energetyczna. Homo sapiens jest chyba najwydajniejszym biegaczem długodystansowym wśród zwierząt — potrafimy zagonić na śmierć konia. Nasz chód jest bardzo wydajny energetycznie — wybicie się z kostki pozwala na odzyskanie sporej części energii, która w innym przypadku zmarnowana by była na uderzeniu nogi w ziemię. Od dłuższego czasu próbujemy zbudować urządzenia, które by naśladowały ten chód. No ale przy całej tej wydajności tak naprawdę nic nie umywa się do transportu kołowego, który ma tą zaletę, że nie zużywa energii na ciągłą walkę z grawitacją. To między innymi dlatego wszystkie łaziki marsjańskie są na kołach, nawet jeśli mają pokonywać dość nierówny teren. Nawet jeśli kiedyś uda nam się zbudować dwunożne podwozie wzorowane na ludzkim chodzie, to przecież nie ma żadnego powodu dla którego jego górna część miałaby wyglądać jak człowiek. 4. Teleoperacja — w literaturze science fiction oraz filmach, szczególnie japońskich, często pojawia się pomysł robota sterowanego bezpośrednio ruchami człowieka. Pilot takiego robota, siedzący w jego wnętrzu lub w osobnym urządzeniu, jest zwieszony w specjalnej uprzęży (lub pływa w pojemniku ze specjalnym płynem) z sensorami, które każdy jego ruch przekładają na ruch robota. Robot jest przy tym często wielokrotnie większy i silniejszy od człowieka. Wydaje się oczywistym, że w takiej sytuacji najlepiej sprawdzać się będzie kształt kopiujący ludzkie ciało. W praktyce okazuje się jednak, że pomysł taki jest na dzień dzisiejszy praktycznie niemożliwy do zrealizowania w takiej postaci: utrzymywanie równowagi wymaga informacji zwrotnej, której nie mamy jak takiemu pilotowi przekazać. Być może kiedyś będziemy potrafili wpiąć się bezpośrednio w układ nerwowy pilota i w ten sposób sterować robotem, ale wówczas właściwie nie ma powodu, żeby nadal był on człekokształtny, a nie, na przykład, w kształcie goryla czy gibbona — przecież mamy nawet nerwy i odruchy potrzebne do sterowania ogonem! Na dzień dzisiejszy teleoperacja zazwyczaj ogranicza się do samych manipulatorów, czasem zamontowanych na ruchomej platformie — i to w zupełności wystarcza. Nawet nie mają na końcach ludzkich dłoni, tylko od razu narzędzia. 5. Seksboty. Bez komentarza — chyba tylko naprawdę zdesperowany nastolatek mógłby wpaść na taki pomysł. Podsumowując, w zasadzie nie ma żadnego powodu, aby budować praktyczne człekokształtne roboty. Jeśli ich wygląd nie jest celem samym w sobie, to warto zastanowić się nad projektem najlepiej przystosowanym do ich zadań, zamiast niepotrzebnie komplikować sobie życie próbując naśladować naturę.
  45. 5 punktów
    Cześć, Myślę że każdy kojarzy monitory, które mają wbudowane oświetlenie z tyłu. Zawsze uważałem to za fajny dodatek, jednak producenci często słono sobie za takie monitory liczą. Dlatego postanowiłem, że stworzę własną wersję w oparciu o Arduino i taśmę LED RGB i chciałbym się z Wami podzielić efektami mojej pracy. Zacznę od spisu niezbędnych materiałów: Arduino Nano (ja użyłem klona) Taśma LED RGB 12V Zasilacz 12V, minimum 1A 3 tranzystory MOSFET IRL540N 3 tact switche Przełącznik bistabilny suwakowy 3 rezystory 10k Listwa goldpin żeńska Płytka prototypowa Przewody Niezbędna będzie też lutownica (i oczywiście cyna), przydatny jest także pistolet z klejem na ciepło oraz płytka stykowa i pojedyncza dioda RGB ze wspólną anodą (i 3 rezystory 330R) w celu sprawdzenia czy układ działa poprawnie zanim zaczniemy lutować. Jak już mamy skompletowany cały zestaw możemy zabierać się do pracy. Na początek schemat układu: Całość ma działać w taki sposób, że po naciśnięciu przycisku jasność danego koloru wzrasta, a jeżeli przestawimy pozycję przełącznika to tym samym przyciskiem będziemy przyciemniać wybrany kolor. Natężenie światła będzie regulowane przez sygnał PWM na portach Arduino, które będą podłączone do bramek tranzystorów unipolarnych. Warto zacząć od złożenia całości na płytce stykowej w celu skontrolowania czy układ działa poprawnie. U mnie wygląda to tak: Oczywiście żeby dioda zaświeciła potrzebny jest program dla Arduino: #define oswietlenieG 10 //PWM do bramki tranzystorów sterujących oświetleniem (przez R 10k) #define oswietlenieR 11 // -//- #define oswietlenieB 9 // -//- #define przyciskG 3 //przycisk zmieniajacy natezenie B #define przyciskB 4 //przycisk zmieniajacy natezenie G #define przyciskR 5 //przycisk zmieniajacy natezenie R #define przycisk 2 //przelacznik do zmiany znaku "zmiany" int R=0; //jasność koloru czerwonego int G=0; //jasność koloru zielonego int B=0; //jasność koloru niebieskiego int zmiana=5; //wartość o jaką zmieni się natężenie przy pojedynczym kliknięciu void setup() { pinMode(przycisk,INPUT_PULLUP); //definiowanie pinów pinMode(przyciskR,INPUT_PULLUP); pinMode(przyciskG,INPUT_PULLUP); pinMode(przyciskB,INPUT_PULLUP); pinMode(oswietlenieR,OUTPUT); pinMode(oswietlenieG,OUTPUT); pinMode(oswietlenieB,OUTPUT); } void loop() { if(digitalRead(przycisk)==LOW) //sprawdzenie czy przełącznik jest w pozycji "on" { if(digitalRead(przyciskR)==LOW) //sprawdzenie czy przycisk do zmiany koloru czerwonego jest wciśnięty { R=R-zmiana; //zmniejszenie wypełnienia if(R<=0) R=0; delay(20); //niwelacja drgań styków } if(digitalRead(przyciskG)==LOW) { G=G-zmiana; if(G<=0) G=0; delay(20); } if(digitalRead(przyciskB)==LOW) { B=B-zmiana; if(B<=0) B=0; delay(20); } } else { if(digitalRead(przyciskR)==LOW) { R=R+zmiana; if(R>=255) R=255; delay(20); } if(digitalRead(przyciskG)==LOW) { G=G+zmiana; if(G>=255) G=255; delay(20); } if(digitalRead(przyciskB)==LOW) { B=B+zmiana; if(B>=255) B=255; delay(20); } } analogWrite(oswietlenieR,R); //ustawienie zadanego wypełnienia na pinie R analogWrite(oswietlenieG,G); // -//- G analogWrite(oswietlenieB,B); // -//- B } Jeżeli wszystko jest połączone poprawnie dioda powinna zmieniać kolor gdy naciskamy przyciski. Jak już wiemy, że nasz układ działa, możemy przejść do lutowania go na płytce prototypowej. Zacząłem od przylutowania listwy goldpin do której będziemy wpinać nasze Arduino. Co prawda powinno się zaczynać od małych elementów, jednak w ten sposób łatwiej jest określić gdzie mają się znajdować tranzystory. Kolejno na płytce pojawiły się rezystory oraz mosfety. Na koniec przylutowałem wyprowadzenia zasilacza, przewody które będą biegły do modułu z przyciskami i piny z taśmy LED. Trzeba pamiętać o podłączeniu zasilania do wejścia taśmy. Do tworzenia połączeń bardzo dobrze się nadają odcięte końcówki wyprowadzeń rezystorów. Gotowa płytka wygląda u mnie tak: (tył jest lekko ubrudzony, bo pokryłem całość klejem na ciepło i nie udało mi się usunąć całego do zdjęcia) Następnie stworzyłem moduł sterowania. Połączyłem każdy przycisk, oraz wyprowadzenie przełącznika do wspólnej masy a do poszczególnych przycisków dolutowałem przewody z płytki. Całość zamknąłem w tekturowym opakowaniu, które zalałem klejem na ciepło: Co prawda nie wygląda to zbyt ładnie, jednak przykleiłem to na bocznej ściance głośnika, więc nie jest to widoczne. Teraz jest dobry moment żeby przeprowadzić test całości, jeszcze zanim pokryjemy całość klejem na ciepło (ja popełniłem ten błąd że nie zrobiłem testu i miałem przez to dodatkową robotę z usuwaniem kleju jak okazało się że jeden z tranzystorów nie działa). Jeżeli wszystko jest tak jak powinno możemy przejść do przycinania taśmy na właściwą długość a następnie polutowania odpowiednich wyprowadzeń (ponownie przydatne są ucięte "nóżki" od rezystorów) tak żeby stworzyć prostokąt który będzie pasował do naszego monitora. Gdy taśma jest już gotowa warto ponownie zrobić test i jeżeli wszystko działa poprawnie "zaizolować" łączenia za pomocą kleju na ciepło a następnie przykleić taśmę do monitora. Ja moją dodatkowo dokleiłem za pomocą taśmy izolacyjnej, żeby się lepiej trzymała: Teraz wystarczy podłączyć taśmę do naszej płytki, wpiąć Arduino i całość powinna nam pięknie świecić: Mam nadzieję, że mój projekt się Wam spodoba i sami spróbujecie stworzyć takie oświetlenie, bo efekt jest naprawdę warty poświęcenia czasu. PS. Zamiast przycisków można by użyć np. modułu bluetooth albo odbiornika podczerwieni i dowolnego pilota od telewizora, ale ze względu na to, że sterowanie w moim przypadku znajduje się w łatwo dostępnym miejscu uznałem że byłaby to niepotrzebna komplikacja. Pozdrawiam ~Usohaki
  46. 5 punktów
    Hej koledzy i koleżanki;-) Ci którzy są dłużej obecni na Forbocie mnie już trochę znają, ale dla nowych użytkowników których sporo ostatnio, krótki rys historyczny. Moje zainteresownie elektroniką zaczęło się w październiku 2017 roku od jakiejś nudy przy kompie kiedy to przeglądając neta natknąłem się na kursy Forbota. Długo sie nie namyślając zamówiłem najpierw kurs elektroniki podstawowy i od strzału dodatkowy, no i oczywiście zestaw tablic. Jako, że mnie to strasznie wciągnęło, dalej poszło za ciosem: technika cyfrowa i oczywiście kurs arduino poziom pierwszy i drugi . Wciągnęło niesamowicie, chyba głównie dzięki temu, że autorzy kursu potrafili swoją wiedzę przekazać jasno, klarownie i przede wszystkim ciekawie. Dobra koniec tej łzawej historyjki pora na opis projektu. Mój system zbudowany jest z: Arduino MEGA, nodeMCU z esp8266, czujnik zanieczyszczeń powietrza PMS5003; ethernet Shield do wyżej wymienionego, czterech czujników temperaturyDS18B20, dwa czujniki temperatury i wilgotności typu DHT11, jeden DHT22, czujnik ciśnienia i temperatury BMP280 I2C, moduł zegarowy RTC1307 I2C, enkoder z przyciskiem, wyświetlacz LCD 20×4 I2C, dwie listwy diod programowalnych po 4 szt, czujnik deszczu, buzzer bez generatora, moduł 8 przekaźników; kilka dodakowych przekaźników, radiolinia PIN4 Proxima 2szt, przekaźnik czasowy PCM-04 Zamel; kilka krańcówek, bramki logiczne OR; żaróweczka neonka, fotorezystor, kupa przewodów, rezystorów, diod itp., tablet, telefon. Działanie: Układ mierzy temperaturę w dwóch miejscach w domu, na zewnątrz temperaturę w słońcu, przy gruncie i 1m nad gruntem w cieniu. Dodatkowo mierzy ciśnienie atmosferyczne, wilgotność zewnętrzną i wewnętrzną oraz temperaturę wody w CO. Od niedawna także poziom zanieczyszczenia powietrza (budowę urządzonka pomiarowego przedstawię w kolejnym artykule). Zapamiętuje również, najwyższe i najniższe wartości każdego z czujników wraz z datą zdarzenia. Funkcją dodatkową jest alarm wywoływany przy pierwszych opadach deszczu, a także (na wyraźne życzenie żony) alarm informujący kiedy pralka w piwnicy skończyła pracę. Jeśli kogoś interesuje ta ostatnia funkcja odsyłam do mojego tematu na Forbocie. Główną funkcją układu jest sterowanie pracą 8 przekaźników obsługujących min. bramę, furtkę, oświetlenie. Każdy z przekaźników jest sterowany niezależnie: -sygnałem z arduino idącym przez bramki OR do których dochodzą także -sygnały z zewnętrznych włączników naściennych -radiolini sterowanych pilotem, - no i oczywiscie aplikacją BLYNK z telefonu, tabletu... Dopiero sygnał za bramką OR idzie do przekaźnika oraz dodatkowo jako potwierdzenie wraca do arduino. Dioda led na obudowie tabletu informuje o włączeniu przekaźnika także, kiedy tenże jest włączony „poza arduino” przez włącznik naścienny bądź radiolinię. Informacja o tym fakcie wraca do arduino powodując odpowiednie zmiany zmiennych i na bieżąco aktualizując diody led i informacje wyświetlane na LCD 20×4 oraz wyświetlaczu telefonu i tabletu w kuchni na ścianie będącego "centrum sterowania" całością. Wszystkie dane z czujników są na bieżąco wyświetlane i przewijane na LCD 20×4 który to wyswietlacz stał się dodatkowym(po tablecie) i zainstalowałem go w obudowie szafki zawierającej najważniejsze elementy układu. Po wciśnięciu przycisku enkodera wchodzimy w menu opcje gdzie możemy na LCD20x4 sprawdzić najwyższy i najniższy odczyt każdego z czujników, datę tego odczytu oraz zresetować pamięć dla każdego odczytu i czujnika z osobna. Możemy również tym enkoderem sprawdzić w menu stan przekaźników i nimi sterować. Wciśnięcie enkodera jest sygnalizowane przez buzzer. Osobną sprawą jest BLYNK który miał służyć początkowo tylko do kontroli przez telefon nad przekaźnikami, ale po poznaniu jego możliwości, całkowicie zmieniłem założenia i teraz to tablet z zainstalowanym Blynkiem jest głównym wyświetlaczem i sterownikiem całego układu. Trochę bliżej na temat aplikacji BLYNK w moim systemie możecie przeczytać tu. Na tablecie mam podmenu: przekaźniki, czujniki, max i min, historia, alarmy. W menu przekaźniki sterujemy z tableta i telefonu, w dowolnym miejscu na świecie, przekaźnikami, otrzymując z powrotem informację o faktycznym włączeniu przekaźnika(zmiana koloru widgeta oraz wyświetlonego na nim napisu).Ta informacja pojawia się także kiedy przekaźnik zostanie włączony przez kogoś innego(przez włącznik ścienny, radiolinia lub drugie urządzenie:tablet lub telefon). Choć poprzez udostępnienie tokena do naszego projektu takich urządzeń może być więcej. Drugie menu w BLYNK-uto wyświetlanie danych z wszystkich czujników odświeżane co 1 min, oraz małe „diody led” migające i informujące o prawidłowej komunikacji apka-arduino MEGA i apka-ESP(czujnik jakości powietrza). Kolejne menu to ekran z rozwijanym podmenu na którym wyświetlone są nazwy wszystkich czujników i poprzez wybór któregoś z nich możemy sprawdzić(podobnie jak to było na LCD20x4), najniższą i najwyższą wartość datę tego zdarzenia i zresetować pamięć dla każdego czujnika osobno. Następne menu to historia, czyli wykresy. Ja mam ustawione wyświetlanie na wykresach historii odczytów ciśnienia atmosferycznego, wigotności, temperatury CO, temperatury zewnętrznej, oraz osobny wykres dla czujnika jakości powietrza. Ostatnie menu w BLYNK-uto alarmy. Po pojawieniu się na odpowiednim pinie arduino sygnału z czujnika deszczu lub sygnału o końcu pracy pralki, na wyświetlaczu LCD20x4 przestaje się przewijać informacja o dacie, godzinie i odczytach z czujników, a wyświetla się info o alarmie z odpowiednią treścią, albo o pralce albo o deszczu. Dodatkowo listwy diod led migają na niebiesko(pralka) lub na czerwono(deszcz). Po wciśnięciu enkodera, wyłączeniu na tablecie lub telefonie albo upływie ustawionego czasu alarm wyłącza się. Informacja o alarmie pojawia się jako notyfikacja także na tablecie i telefonie, w sposób wizualny i dźwiękowy, poprzez wybraną melodię z pamięci talefonu/tableta. Ostatnio dołożyłem dodatkowo obsługę przekaźników głosowo poprzez Google Assistant. Jeśli kogoś bliżej interesuje ta kwestia to zapraszam tutaj. Kolejną miłą opcją jest podpięty do tabletu poprzez bluetooth wzmacniacz klasy D z pilotem spięty z głośnikami zainstalowanymi w kuchni. Google assistant pozwala na bezdotykowe, głosowe włączanie ulubionego przeboju z YT, radia itp. Co do przekażnika czasowego i krańcówek i przeakźników to mają one zastosowanie przy sterowaniu bramą garażową i oświetleniem garażu. Bramą garażową steruję z przycisku naściennego, pilotów radiowych, telefonu, tabletu. Jednak dodatkowo jest założony przekaźnik czasowy który po uplywie zadanego czasu zamyka otwartą bramę niezależnie od systemu. Również włącznik naścienny jest niezależny, więc nawet jak by sytem padł(co się nie zdażyło za ostatnie12 miesięcy) mogę sterować bramą. Krańcowki zainstalowane przy bramie podają informację do Aruduino, a te wysyła info do Blynka który informuje mnie notyfikacją, gdziekolwiek bym nie był, że właśnie została otwarta lub zamknięta brama garażowa. Kolejną sprawą jest automatyka oświetlenia garażu. Zrobiona "analogowo" tzn. jesli świeci się lampa z czujnikiem ruchu przed garażem, a brama jest calkowicie otwarta, zapala się całe oświetlenie garażu. Co znakomicie ułatwia nocne parkowanie. Chyba tyle. Aktualnie pracuję nad stroną internetową(dziękuję wszystkim cierpliwym webmasterom z Forbota za pomoc) postawioną na RPi, która będzie pokazywać światu jakie to fajne powietrze mamy w Kryrach;-). W planach też pomiar siły i kierunku wiatru. Gdyby ktoś chciał poczytać o początkach tego projektu to tutaj, a cały worklog jest tu. Cały sketch sterujący arduino i Blynkiem tutaj. Teraz kilka zdjęć i filmów. Wnętrze szafki z Arduino i całym osprzętem, płytka główna przed i po tuningu: "Centrum": Kilka slajdów z BLYNK-a: Wzmacniacz i głośniki w kuchni: Jeden film mówi więcej niż tysiąc słów więc: Prototyp: Aktualny: LCD dodatkowy: Jeszcze LCD z dołożoną obsługą PMS5003: Działanie BLYNK-a i przekaźników: BLYNK, "centrum", google assistant: Google Assistant w praktyce: Dziękuję za poświęcony czas i pozdrawiam wszystkich. Lajkujcie, subskrybujcie bądzcie moimi followersami i co się tam jeszcze robi
  47. 5 punktów
    Witam! Chciałbym przedstawić wam moją konstrukcję, która stała się przedmiotem mojej pracy inżynierskiej. Mechanika: Konstrukcja mechaniczna w zasadzie oparta jest na 2 płytkach PCB. Do płytki głównej zamontowane są dwie kulki podporowe, a także silniki pololu o przekładni 1:10 co stanowi napęd robota. Z przodu zamontowana jest płytka z podstawą zawierająca uchwyty do czujników ultradźwiękowych. Taki sam uchwyt pod czujnik znajduje się również na 'ogonie' robota - jest on nie używany i został zamontowany eksperymentalnie. Na przedłużonej osi silników zostały zamontowane magnesy enkoderów magnetycznych co ilustruje poniższa fotografia. Elektronika: Sercem robota jest mikrokontroler AVR ATmega162, którego zadaniem jest sterowanie robotem w tym: obsługa enkoderów, sterowanie silnikami, odbiór informacji z mikrokontrolera slave nt. odległości mierzonych przez czujniki, realizację algorytmów sterowania, realizacja połączenia bluetooth, obsługa wyświetlacza LCD hd44780. Drugi mikrokontroler również AVR, ATmega328 realizuje tylko i wyłącznie obsługę czujników odległości HC-SR04. Pomiary normalizuje i wysyła interfejsem SPI do jednostki głównej ATmega162. Na pokładzie robota znajdują się również dwa enkodery magnetyczne AS5040 pracujące w pętli sterowania regulatora PI silników. Enkodery te pracują w trybie defaultowym czyli wyjście kwadraturowe, rozdzielczość 2x256. Silniki sterowane są poprzez mostek H L293. Komunikacją z robotem zajmuje się moduł bluetooth bt222 - czyli komunikacja jest przez UART mikrokontrolera. Główny mikrokontroler jest taktowany zewnętrznym kwarcem 16Mhz co przy takiej ilości obsługiwanych urządzeń i wykorzystywanych interfejsów było po prostu konieczne, z kolei mikrokontroler atmega328 jest taktowany zewnętrznym kwarcem jednak z powodu lepszej podstawy czasowej, która jest konieczna do dokładnych odczytów z czujników odległości. Na wyświetlaczu LCD są wyświetlane aktualnie mierzone wartości odległości czujników. Automatyka: Zostało wspomniane, że silnikami steruje algorytm regulatora PI. Aby obliczyć jego nastawy została przeprowadzona identyfikacja transmitancji. W tym celu wykorzystałem UART do przesyłania aktualnej prędkości silników oraz środowisko Matlab do wizualizacji danych na wykresie. Z wyliczeń wyszło, że silniki z zastosowanymi kołami mają transmitancję: G(s)=107/(0.19s+1) Po obliczeniu nastaw regulatora i zastosowaniu w praktyce okazało się, że można jeszcze troszkę dopieścić nastawy i ostatecznie wykresy odpowiedzi skokowej bez i z regulatorem wyglądają następująco: Software: Napisane w C w środowisku Eclipse. Umożliwia robotowi 3 tryby. Tryb avoid. W trybie tym robot ma za zadanie omijać przeszkody wykorzystując regulator rozmyty Takagi-Sugeno. Wykorzystuje w tym celu odczyty z czujników odległości. Tryb goal seeking. Robot podąża do celu czyli do odebranych przez bluetooth współrzędnych kartezjańskich podanych w [mm], zakładając, że miejsce od którego zaczyna lub dostał nowy zestaw współrzędnych, ma współrzędne 0,0. W trybie tym regulator Takagi-Sugeno ma za zadanie na podstawie zaimplementowanej odometrii oraz współrzędnych końcowych sterować robotem w celu osiągnięcia zadanego położenia. Problem algorytmu przedstawia ilustracja: Tryb avoid + goal seeking. Jest to połączenie dwóch wcześniej opisanych trybów. W trybie tym działają równocześnie obydwa wcześniej opisane algorytmy, jednak na wejście regulatorów PI sterujących silnikami jest podawany zbalansowany sygnał z obu algorytmów. Tzn w zależności od najmniejszej odległości od przeszkody mierzonej przez któryś z czujników jest obliczany procentowy udział wartości sterowania od dwóch algorytmów. Brzmi skomplikowanie ale takie nie jest. Najlepiej zobrazuje to wzór: V=K*Vg+(1-K)*Va gdzie V jest prędkością zadaną na regulator PI silnika, Vg jest prędkością wynikającą z algorytmu goal seeking, Va jest prędkością wynikającą z algorytmu avoid, K jest parametrem, który przyjmuje wartość z przedziału 0-1 w zależności od mierzonej minimalnej odległości do przeszkody. Robota wprowadza się w odpowiedni tryb za pomocą dwóch przycisków lub poprzez interfejs bluetooth. Odpowiednie tryby sygnalizują diody LED. W celu przesłania komendy zawierającej współrzędne celu najpierw należy wprowadzić robota w odpowiedni tryb, a następnie wysłać do niego wg stworzonego prze zemnie protokołu dane. Protokół wysyłania danych jest następujący: X±⌴⌴⌴Y±⌴⌴⌴& gdzie +- – znak współrzędnej, _ – wartość współrzędnej. Testy. Konstrukcja została przetestowana pod względem dokładności odometrii. Robot podczas licznych testów na bieżąco wysyłał swoje współrzędne, które w dalszej kolejności były obrabiane w środowisku Octave do przyjemnych w analizie wykresów. Przykładowy wykres drogi, którą pokonał robot na 'placu manewrowym' w trybie avoid: ... oraz rzut z góry na 'plac manewrowy': U góry pozycja początkowa, na dole końcowa robota. Cały ten obszar był dookoła ogrodzony ścianką. Słowa samokrytyki Co bym zmienił ? Czujniki. Ze względu na problematyczność wykrywania małych przeszkód lub gdy płaszczyzna przedmiotu uniemożliwia odbicie się fali ultradźwiękowej w stronę odbiornika. Zdarza się, że z powodu gubienia przeszkód robot po prostu w nie wpada. Najciekawsze fragmenty programu: Regulatory PI: //######################################## REGULATOR PRĘDKOŚCI ############################################ erra = vl-Va;//liczenie błedu prędkości errb = vp-Vb; if(ua<1023&&ua>-1023)Ca = Ca+(erra*dt);//całka błędu ua = kp*(erra + Ca/Ti);//regulator PI //P I if(ub<1023&&ub>-1023)Cb = Cb+(errb*dt);//całka błędu ub = kp*(errb + Cb/Ti);//regulator PI //P I if((ua<10)&&(ua>-10))ua=0; if((ub<10)&&(ub>-10))ub=0; motor_set(ua,ub);//ustawia sterowanie silników Regulator rozmyty Takagi-Sugeno trybu goal seeking: inline void PsiZ2Vlr(float *Psi, float *z, int16_t *vl,int16_t *vp) { float PSI[3]; float XL[6],XR[6]; float NR,FR,L,S,P,VL=0,VP=0,m=0; uint8_t i,k; ///////////////////////////////LICZENIE PRZYNALEŻNOŚCI////////////////////////////////// if(*z<=100)NR=-0.01*(*z)+1;else NR=0;//jak bardzo blisko jest cel if(*z<=100)FR=0.01*(*z);else FR=1;//jak bardzo daleko jest cel if(*Psi<=0)L=-0.3183*(*Psi);else if(*Psi<-M_PI)L=1;else L=0; if(*Psi<=0)S=0.3183*(*Psi)+1;else if(*Psi<-M_PI)S=0; else if(*Psi>M_PI)S=0;else S=-0.3183*(*Psi)+1; if(*Psi>=0)P=0.3183*(*Psi);else if(*Psi>M_PI)P=1;else P=0; /////////////////////////////////////TABLICA REGUŁ////////////////////////////////////// PSI[0]=L; PSI[1]=S; PSI[2]=P; //NR; XL[0]=-4000;XR[0]=4000; XL[1]=0;XR[1]=0; XL[2]=4000;XR[2]=-4000; //FR; XL[3]=-4000;XR[3]=4000; XL[4]=4000;XR[4]=4000; XL[5]=4000;XR[5]=-4000; /////////////////////////////obliczanie prędkości silników////////////////////////////// for(k=0,i=0;k<3;k++,i++)//pierwszy wiersz tabeli { VL+=NR*PSI[k]*XL[i]; VP+=NR*PSI[k]*XR[i]; m+=NR*PSI[k]; } for(k=0;i<6;k++,i++)//drugi wiersz tabeli { VL+=FR*PSI[k]*XL[i]; VP+=FR*PSI[k]*XR[i]; m+=FR*PSI[k]; } *vl=(int16_t)VL/m; *vp=(int16_t)VP/m; } Obsługa czujników odległości: //PRZERWANIE OD CAPTURE PIN ISR(TIMER1_CAPT_vect) { if( (TCCR1B & (1<<ICES1)) ) { LastCapture = ICR1;//jesli zbocze narastajace, zlap ICR1 } else { PulseWidth = ICR1 - LastCapture;//Jeśli zbocze opadajace oblicz PW pomiar=0;//wyzeruj flagę pomiaru } TCCR1B ^= (1<<ICES1);//Zmiana zbocza wyw. przerwanie } Mam nadzieję że robocik się podoba. W razie pytań proszę śmiało. Całości kodu nie udostępniam ze względu na prawa autorskie niektórych funkcji bibliotecznych. Co mogłem udostępniłem. Pozdrawiam was wszystkich !
  48. 5 punktów
    Czytam te wpisy kolegi @xirtt i coraz bardziej się zastanawiam, czy to jeszcze forum o robotyce, elektronice, czy już portal randkowy. Ciągle tylko o miłości i miłości... A biorąc pod uwagę, że na portalu prawie sami faceci, to nawet wolę nie zgadywać w którą stronę ten portal zmierza.
  49. 5 punktów
    @Treker a może to właśnie jest pomysł na "kolejny krok" portalu? Nie ograniczać się do samych kursów, ale przeprowadzać egazminy, czy testy i wydawać "certyfikaty"? Pewnie zabrzmi to bez sensu, ale może to pewien biznes-plan i kiedyś pracodawcy będą doceniali w CV ukończenie szkolenia Forbot-a? Co więcej odpowiednie egzaminy mogłyby ustalać rangę użytkownika na forum - co czasem oszczędzałoby pewnie wielu pytań.
  50. 5 punktów
    Myślę, że nie warto spierać się o takie głupoty - jako inny przykład definicji dystrybucji linuxa polecam wiki: https://pl.wikipedia.org/wiki/Dystrybucja_Linuksa Tutaj mamy nieco lepiej zdefiniowane kryteria, bo pisanie o paru ludziach to chyba kiepski pomysł - w każdej nietrywialnej firmie znajdziemy paru ludzi, niektórzy nawet pracują. Pobieranie i używanie też nie nadaje się zbytnio - jako ciekawostkę podam, że yocto ma manager pakietów, do wyboru .deb, .rpm, .ipk oraz .tar - nie opisuję tego, ale pakiety są automatycznie tworzone i wystarczy je umieścić na serwerze. A co do jednego użytkownika to faktycznie na RPi moja dystrybucja ma jednego użytkownika - natomiast systemy nad którymi pracuję zawodowo mają znacznie więcej użytkowników. Wszyscy pobierają pakiety i z nich korzystają np. oglądając telewizję, chociaż wcale nie widzą że na pokładzie dekodera działa linux... Więc zostawmy może te spory językowe w spokoju - yocto to w rzeczywistości zestaw skryptów, coś jak make. Pozwala na skompilowanie relatywnie dużego systemu, a czy nazwiemy go dystrybucją, firmware-m, czy androidem to zostawmy lingwistom. A jak już się czepiamy słówek - formalnie Linux to samo jądro... Cała reszta to właśnie dystrybucja, czyli zestaw oprogramowania bazujący na GNU. Dlatego niektórzy puryści nazywają takie cudo GNU/Linux, natomiast to co mamy w telefonach Android/Linux. Zawartość karty SD Wracając do głównego wątku, czyli możliwości pracy z linuksem nieco inaczej niż przez instalację Raspbiana. Ostatnio wygenerowałem obraz systemu poleceniem bitbake core-image-minimal. Jak łatwo się domyślić jest to minimalny działający obraz, możemy go uruchomić ale praca na nim nie będzie pasjonująca. Jednak zanim przejdziemy dalej chciałbym zatrzymać się przez chwilę nad tym co taki minimalny obraz zawiera - skoro jest mały to łatwiej zrozumieć jak to działa. Tutaj pierwsza uwaga - wbrew pozorom działa już całkiem sporo rzeczy. Zawdzięczamy to jądru systemu - mamy minimalny zestaw oprogramowania, ale jądro oraz większość sterowników jest już na miejscu. Jeśli podłączymy np. wyświetlacz zobaczymy że działa - nawet bez x serwera. Wspominam o tym żeby zwrócić uwagę na pewną nadmiarowość pełnych dystrybucji. Okazuje się że system wbudowany może używać znacznie mniej pamięci i innych zasobów niż pełna wersja "desktopowa". Na karcie SD znajdziemy podobnie jak w przypadku Raspbiana dwie partycje: Pierwsza ma rozmiar "aż" 40MB i typ FAT32. Druga to główny system plików, który zajmuje raptem 12MB. Na pierwszej partycji znajdziemy firmware dla GPU Malinki (za chwilę do tego wrócę), bootloadery oraz obraz jądra linuksa. Druga partycja to raczej minimalistyczny system plików - znajdziemy na nim (dość sporą) bibliotekę języka C oraz BusyBox, czyli program udostępniający podstawowe polecenia powłoki (https://busybox.net/about.html). Warto zwrócić uwagę na znaczny rozmiar katalogu lib - to właśnie domyślna biblioteka C tyle zajmuje. W urządzeniach wbudowanych są popularne jej zamienniki, jak chociażby uclibc (https://www.uclibc.org/) - nie tylko są mniejsze, ale często szybciej działają. W każdym razie taka optymalizacja pojednczych MB to temat na osobny wątek. Jak startuje system Celem moich być może zbyt długich wpisów jest pokazanie jak korzystać z u-boot-a, jednak niejako przy okazji chciałbym wyjaśnić miejsce bootloadera w procesie uruchamiania komputera. Zacznijmy od czegoś prostego co wszyscy znają, czyli mikrokontrolera. Powiedzmy ATmega328 - po włączeniu zasilania następuje reset procesora oraz wykonywany jest program z pamięci Flash. Adres gdzie zaczyna się program jest znany (nie jestem pewien jaki, ale to chyba mało istotne). Nowy mikrokontroler ma pustą pamięć Flash, więc przed pierwszym zaprogramowaniem procesor wykonuje tylko instrukcje NOP (https://www.microchip.com/webdoc/avrassembler/avrassembler.wb_NOP.html). Aby wgrać program konieczny jest sprzętowy programator - po zaprogramowaniu, program z pamięci Flash będzie wykonywany zaraz po załączeniu zasilania lub resecie procesora. Wszystko jest proste, ale wymaga dwóch istotnych elementów: pamieci flash oraz programatora. Konieczność posiadania programatora została elegancko rozwiązana w przypadku Arduino. Nowe mikrokontrolery są programowane za pomocą sprzętowego programatora i wgrywany jest do nich krótki program - nazywany właśnie bootloader-em. Przy kolejnych uruchomieniach procesora najpierw będzie zawsze działać bootloader. Wykona on sprawdzenie stanów odpowiednich pinów lub poczeka na dane przesyłane przez UART i jeśli wykryje odpowiednie sekwencje umożliwi programowanie pozostałej części pamięci flash. Natomiast podczas normalnej pracy urządzenia po prostu przekaże sterowanie do programu użytkownika. W pamięci flash przechowywane są więc dwa programy: bootloader oraz kod użytkownika. Jednak nie działają one równocześnie - bootloader rozpoczyna pracę, a następnie przekazuje sterowanie do głównego programu. Podobny schemat wykorzystywany jest w przypadku mikroprocesorów, chociaż jest nieco bardziej skomplikowany. Raspberry Pi jest pod tym względem nieco nietypowe - BCM2837 zawiera aż dwa procesory. Głównym wcale nie jest znany nam ARM, ale procesor graficzny, czyli VideoCore IV (https://en.wikipedia.org/wiki/VideoCore). Wiele osób takie rozwiązanie krytykuje, ale wcale nie jest ono aż tak nietypowe - spotkamy je również w świecie mikrokontrolerów, przykładowo przetworniki ADC mogą mieć wbudowany procesor (http://www.analog.com/en/products/aduc814.html), moduły radiowe często mogą wykonywać programy (http://www.ti.com/lit/ug/swru319c/swru319c.pdf), nawet popularny ESP8266 jest właściwie modułem radiowym który przypadkiem ma również procesor. Po załączeniu zasilania pierwszy startuje procesor graficzny, czyli VideoCore. Początkowy program jest zapisany w jego pamięci ROM - tutaj pojawia się pierwsza różnica między światem mikorkontrolerów i mikroprocesorów - ROM zamiast flash, to wbrew pozorom istotna zmiana. Jednak zasada jest identyczna - w ROM mamy bootloader, który wczytuje program. Różnica to liczba etapów. Na Arduino bootloader wczytywał od razu program główny, natomiast w przypadku mikroprocesorów najczęściej jest uruchamianych kilka bootloaderów, a dopiero na końcu właściwy program. Więc jako pierwszy uruchmia się bootloader zapisany w pamięci ROM - niewiele o nim wiadomo, większość producentów traktuje taki kod jako bardzo tajny. Ten bootloader potrafi obsługiwać karty SD oraz system Fat32. Stara się wczytać i uruchomić plik o nazwie bootcode.bin. Jak łatwo się domyślić, yocto pobrało odpowiedni plik z sieci i umieściło w obrazie, który nagraliśmy na karcie. Kolejny etap to wczytanie pliku start.elf. Nie jestem na 100% pewien, ale to chyba główny program dla VideoCore. Na naszej karcie znajdziemy jeszcze wersję start_x.elf z obsługą kamery RaspiCam oraz start_db.elf w wersji do debugowania (ale kodu i tak nie dostaniemy). Jest jeszcze plik start_cd.elf - nie wiem po co, może ktoś na forum wie do czego ta wersja służy? Pliki start.elf mają odpowiadajace im pliki z danymi, czyli fixup.dat, fixup_x.dat, fixup_db.dat oraz fixup_cd.dat. Wszystkie znajdziemy na naszej karcie SD - chociaż niepotrzebne możemy usunąć. Jeszcze dwa pliki są istotne dla uruchamiania malinki - config.txt oraz cmdline.txt. Oba są w formacie tekstowym, więc można użyć dowolnego edytora do ich zmiany. Pełnią funkcję ustawień, coś jak BIOS w stacjonarnym komputerze. Pierwszy jest bardzo rozbudowany, więcej o nim przeczytamy na stronie raspberrypi: https://www.raspberrypi.org/documentation/configuration/config-txt/README.md. Drugi zawiera parametry dla jądra systemu - używając u-boota nie będziemy musieli z niego korzystać. Teraz ostatnia i najważniejsza część - VideoCore ładuje z karty plik o nazwie kernel8.img do pamięci RAM oraz uruchamia rdzeń ARM tak aby wykonywał wczytany kod. Pewnie większość osób odgadnie, że kernel8.img to jądro systemu Linux - tak jest domyślnie, ale to wcale nie jest wymagane. Możemy napisać własny program, nazwać go kernel8.img i zostanie on uruchomiony bez Linux-a, czyli tak jak na Arduino. Jeśli lubimy takie ekstremalne rozrywki, polecam kurs programowania Raspberry Pi bez systemu operacyjnego: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/, jest nawet wersja dla języka C zmiast asemblera (ale to takie niesportowe : http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/. W naszym przypadku kernel8.img to wcale nie jądro linuksa - jądro znajdziemy w pliku Image. Natomiast kernel8.img to u-boot, czyli kolejny bootloader: https://www.denx.de/wiki/U-Boot Konfiguracja przygotowana przez yocto startuje więc u-boota, który dopiero uruchamia właściwego Linux-a. W kolejnych wpisach pokażę do czego się to może przydać - wspomnę tylko że możliwości są spore, a przede wszystkim możliwe jest pobieranie obrazu przez sieć. Więc karta SD może być używana jedynie na początku uruchamiania systemu, podczas gdy wszystkie pliki przechowamy bezpiecznie na serwerze lub stacji roboczej.
Tablica liderów jest ustawiona na Warszawa/GMT+02:00
×
×
  • Utwórz nowe...