Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'micropython'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - DIY
    • Projekty - DIY roboty
    • Projekty - DIY (mini)
    • Projekty - DIY (początkujący)
    • Projekty - DIY w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie

Kategorie

  • Quizy o elektronice
  • Quizy do kursu elektroniki I
  • Quizy do kursu elektroniki II
  • Quizy do kursów Arduino
  • Quizy do kursu STM32L4
  • Quizy do pozostałych kursów

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Imię


Strona

Znaleziono 6 wyników

  1. Wstęp Od poprzednich właścicieli mieszkania dowiedziałem się, że w piwnicy zdarzają się kradzieże. W związku z tym postanowiłem zbudować fotopułapkę na złodzieja: urządzenie, które po wykryciu ruchu robi zdjęcia i wysyła je na serwer. Serwer natomiast powiadamia mnie mailowo (z załączonymi zdjęciami) o wykryciu ruchu. Finał tej historii był taki, że... nie zdążyłem. Jakiś miesiąc przed ukończeniem projektu było seryjne włamanie, którego także padłem ofiarą 😕 Wracając do meritum: Hardware - ESP32-CAM - Arduino Pro Mini (klon) - moduł czujnika ruchu PIR HC-SR501 - moduł czytnika RFID MRFC522 - akumulator żelowy 6 V 4,5 Ah - obudowa Kradex Z2AW - przetwornica mini step-down 360 - Raspberry Pi 4 (serwer) Zasilanie W piwnicy nie ma gniazdka, więc założyłem, że zasilanie będzie akumulatorowe. Nie chciałem kombinować z wpinaniem się w oprawę oświetleniową i ryzykować oskarżenie o kradzież prądu. Gdybym nawet miał dostęp do prądu, to i tak dobrze byłoby zastosować akumulator buforowy. No może uprościłoby to projekt o tyle, że ESP, które jest nadrzędnym modułem urządzenia, mogłoby pracować w sposób ciągły, bez usypiania. Napięcie akumulatora obniżane jest do 3,3 V przez małą, tanią, chińską przetworniczkę step-down i... w zasadzie tyle. Komunikacja Miałem to wielkie szczęście, że w piwnicy łapie mi zasięg domowego WiFi. Dzięki temu odpadło kombinowanie z LoRa czy GSM. ESP "gada" z serwerem z wykorzystaniem socketów TCP. Schemat działania ESP jest w trybie deepsleep z którego budzi się co 2 godziny w celu zaraportowania napięcia akumulatora, albo od przerwania wywołanego sygnałem z czujnika ruchu. Jeśli wybudzenie wywołał czujnik ruchu, ESP w pętli robi zdjęcia i wysyła je do serwera w mieszkaniu. Wszelki zapis na karcie SD odpadał już w założeniach, bo złodziej może urządzenie zniszczyć albo po prostu zabrać ze sobą. Zdjęcia przesłane na serwer są już bezpieczne. Wyjście z pętli następuje w dwóch przypadkach: gdy czujnik PIR przestanie wykrywać ruch, albo gdy obecność zostanie zautentyfikowana przez przyłożenie tagu RFID do czytnika. Serwer ma następujące zadania: stanowi sprzętowy watchdog układu - kontroluje, czy ESP skomunikuje się przynajmniej raz na 4 godziny oraz oczywiście wysyła powiadomienia mailowe o detekcji. Powiadomienia mailowe są dwa - pierwsze zawsze po wykonaniu dwóch zdjęć (chyba że wcześniej nastąpi autentykacja), kolejne to już transfer wszystkich zdjęć jakie urządzenie zdążyło wykonać i przesłać do wyjścia z pętli. Jeśli uwierzytelnię się przez zeskanowanie breloka RFID, to drugi mail ze zdjęciami nie jest wysyłany - obrazki usuwane są z serwera. Jaką rolę ma w tym Arduino, skoro wszystko ogarnia ESP? Prostą, zabrakło mi pinów w ESP, żeby podłączyć wszystkie peryferia 🙂 czytnik RFID komunikuje się po SPI, więc zabiera ich sporo. Arduino jest interfejsem, który odczytuje i przechowuje UID odczytanego tagu, a na żądanie (otrzymane z ESP przez Serial), podaje tę wartość. Dodatkowo mierzy napięcie baterii (również w odpowiedzi na komendę Serial) oraz daje akustyczny sygnał buzzerem, gdy odczyta tag. Nie bawiłem się nawet w usypianie Arduino. Jest ono podłączone do masy przez tranzystor i ESP załącza je sobie przy starcie i wyłącza gdy nie jest już potrzebne. Ciekawym problemem, który pojawił się pod koniec realizacji projektu było fałszywie pozytywne wzbudzanie czujnika ruchu, gdy ESP wybudzało się "z timera". W Internecie były dziesiątki wątków sygnalizujących ten problem z modułem HC-SR501. Dwa największe tropy to było zasilanie (spory pobór prądu przy starcie ESP, gdy łączy się z WiFi) oraz sam sygnał WiFi. To drugie było łatwiejsze do zdebugowania i okazało się od razu celnym strzałem. Pomogło stworzenie ekranu z folii aluminiowej wokół tylnej części modułu PIR. W montażu wspomagałem się drobnymi elementami, które sam projektowałem i drukowałem w 3D - panel przedni, tylna pokrywa PIR, uchwyt montażowy baterii, ramka montażowa czytnika RFID. Żeby było trochę druciarstwa to w niektórych miejscach wspomógł mnie hot-glue i... sznurek. Oprogramowanie ESP32-CAM - Micropython Raspberry Pi (serwer) - Python Arduino - C++ (Arduino) Jeśli ktoś jest zainteresowany, mogę upublicznić repozytorium na Githubie. Jeszcze tego nie zrobiłem, bo musiałbym wyczyścić kod z danych osobistych, a najlepiej przenieść te zmienne do oddzielnego pliku. Zdjęcia front wnętrze bonus - jednooki Project Manager Wydawało mi się że mam gdzieś zdjęcie z zamkniętą obudową, ale nie znalazłem. W sumie wygląda to prawie jak oryginalna obudowa, bo oprócz wystających z panelu frontowego obiektywu kamery i czujnika ruchu, na zewnątrz nie ma żadnych elementów. fot. Kradex
  2. [Przydługa osobista historia] Będąc uczniem nieistniejących już gimnazjów, zapragnąłem dowiedzieć się, jak działa tranzystor. Artykuły na wikipedii niewiele mi tłumaczyły, dlatego sięgnąłem do archiwów Elportalu i zacząłem czytać stare artykuły z Elektroniki dla wszystkich". Było to dość trudne do zrozumienia, ale czytałem w kółko, aż coś załapałem. Próbowałem coś tam majstrować przy elektronice, ale moje zrozumienie tematu było słabe. Elektroniki cyfrowej nawet nie próbowałem, bo uważałem, że to "kolejny krok" po elektronice analogowej, a tej jeszcze nie ogarniam. Przełomem była rada mojego wujka, który zasugerował mi, żebym spróbował, bo obwody są prostsze i nie wymagają tak wielu obliczeń. Spróbowałem, spodobało mi się i posiadając już pewną wiedzę, postanowiłem zbudować linefollowera. To był rok 2010, więc Arduino nie było jeszcze w powszechnym użyciu, więc oparłem swój projekt o Atmegę 8 zaprogramowaną w BASCOM. Projekt niestety upadł, ponieważ liczne problemy z elektroniką (pierwsza samodzielnie wytworzona płytka-podstawka do programatora szwankowała), mechaniką (problem z osadzeniem kół) i ograniczony budżet zniechęciły mnie do zabawy. Początki jednak wrzuciłem na to forum i o dziwo temat się zachował! Potem porzuciłem trochę elektronikę i nauczyłem się podstaw programowania (Turbo Pascal :)), ale na studiach (niezwiązanych z elektroniką), kupiłem klona Arduino i wróciłem do zabawy. Później bawiłem się trochę drukiem 3D, do czego zachęcił mnie przypadkowo (służbowo) poznany doktorant pracujący w GIGu i robiący badania wytrzymałościowe wydruków. Do tej pory sądziłem że to musi być strasznie skomplikowane 🙂 Ostatnio miałem ochotę zrobić "coś elektronicznego", ale nie miałem pomysłu. Nie byłem zbyt wielkim fanem odtwarzania tutoriali. Wolałem sam rozwiązać jakiś problem. Przypomniało mi się jednak o mojej próbie z linefollowerem sprzed 10-laty i uświadomiłem sobie, że nawet jeśli pomysł będzie odtwórczy, to jego realizacja na pewno będzie tylko moją inwencją, a przez problemy które na pewno się pojawią, wiele się nauczę. Dostępność i ceny części do amatorskich konstrukcji poprawiły się tak bardzo, że nie zatrzymam się na problemach, które powstrzymały mnie 10 lat temu. Popularne stały się płytki rozwojowe, które były tanie i do programowania wymagały jedynie kabla USB. Napęd, koła i baza robota jest do kupienia w internecie za mniej niż 40 zł. Można się będzie skupić na prawdziwych wyzwaniach. [Część techniczna] Jako że w tym roku zainteresowałem się Pythonem, a potem poznałem jego wersję na mikrokontrolery, postanowiłem, że projekt będzie oparty o ESP32 (devkit) i zaprogramowany w Micropythonie właśnie. Będzie to świetna okazja żeby nauczyć się czegoś spoza ekosystemu Arduino. Na pewno w Micropythonie pisze się szybciej, ale wykonuje się wolniej, ponieważ jest językiem wyższego poziomu niż C. Powinna to częściowo zrekompensować platforma sprzętowa o wydajności i pamięci znacznie większej niż Arduino Uno. Jak wyjdzie? Zobaczymy. Drugi ważny komponent - mostek H to moduł oparty na TB6612FNG. Byłem bliski odruchowego zamówienia popularnego L293D, ale nie byłem pewny czy tanie zespoły napędowe nie będą wymagały większej mocy aby poruszyć kołem, a spore spadki napięć na tym, jakby nie patrzeć, starym scalaku pogorszą sprawę. Na szczęście chwilę poszperałem i znalazłem ten fajny, niewiele droższy, ale oparty już o MOSFETy moduł. Wykrywanie linii pozostawiłem jednak klasycznemu rozwiązaniu jakim są CNY70. Pora przerwać tę ścianę tekstu pierwszym zdjęciem: Zdj. 1. Główne elementy zakupionego zestawu. Bardzo szybko uporałem się z jego złożeniem. Od razu po tym pojawiły się proste dylematy. ESP32 przyszło z wlutowanymi goldpinami, ale chciałbym je mieć odwrotnie. Przelutowywać, czy na samym początku połączyć w mniej wygodnej pozycji? Próba wylutowania kilkunastopinowej listwy okazała się trudna, więc porzuciłem ją, nie chcąc ryzykować uszkodzenia płytki. Złożyłem pierwszą wersję na zwykłych du pont cables, napisałem prosty kod do obsługi silników i dość szybko udało się zakręcić kołami 🙂 W międzyczasie przełożyłem ESP na dwie małe płytki stykowe, żeby łatwiej tworzyć i zmieniać połączenia. Pierwsze rozczarowanie związane z Micropythonem to brak bibliotek do obsługi klasycznego Bluetooth, jedynie BLE, które jest sporo bardziej skomplikowane w obsłudze. Postanowiłem na tym etapie nie tracić czasu na opanowywanie BLE i dokupiłem poczciwy moduł HC-05. Plusem Micropythona okazał się dostęp do konsoli i możliwość wgrywania programów przez WiFi (usługa nazywa się WebREPL). Działa to jednak średnio gdy byłem już na etapie testów jednego czujnika i chciałem wysyłać jego odczyty co mniej niż 500 ms, widocznie procedura łączenia trwa dość długo i była zakłócana przez ciągle wysyłane dane. Pomogło wysyłanie ich przez inny UART, do którego wpiąłem się najpierw przez zwykły konwerter USB-UART, a potem zastąpiłem HC-05. Robot w tej chwili nie ma mocowań płytek, bo po sprawdzeniu, czy da się sterować kołami, zajmuję się samymi czujnikami, więc robot sobie stoi, a ja grzebię w elektronice i oprogramowaniu. Jak będzie miał jeździć to na pewno zamocuję te płytki i kable. Tak to wygląda w tej chwili: Zdj. 2, 3, 4 Wygląd robota - stan 09.12.2020 Dla czujnika bez problemu udało się dobrać próg wykrywania czarnej linii. Przy małej odległości od dobrze refleksyjnej powierzchni mam odczyty z ADC nawet poniżej 100, a przy zwiększeniu tej odległości lub skierowaniu transoptora na czarną taśmę izolacyjną, spokojnie dobijam napięciem do maksymalnego zakresu ADC (4095). Jeden problem z głowy. Na tę chwilę zakodowałem linię jako odczyt powyżej 1000. Żeby przetestować szybkość działania bez obciążania UARTów dużą ilością danych, zaprogramowałem gaszenie i zapalanie wbudowanego w płytkę LEDa przy zmianie wartości poza progową. Pojawił się ciekawy problem. Kiedy ESP było podłączone do komputera przez USB i stamtąd brało zasilanie, wszystko działało. Po odłączeniu i zasilaniu z baterii świeciła się dioda Power, ale program nie wykonywał się, bo kiedy zmieniałem położenie czujnika względem różnych powierzchni, dioda sygnalizacyjna nie świeciła. Byłem przekonany, że układ ciągnie momentami za duży prąd i mikrokontroler resetuje się. Byłem zaskoczony, ponieważ ubiegłej nocy wymieniłem baterie ze zwykłych ogniw cynkowo-węglowych na alkaliczne żeby uniknąć takich kłopotów.. Jednak na pinie Vin miałem spadki do nawet 3,7V. Zacząłem mierzyć rezystancję wewnętrzną zestawu ogniw i wyszło mi coś takiego: Pobór prądu przez układ (bez pracujących silników, bo ich nie używałem na tym etapie) z podłączonym HC-05 wynosił około 140 mA. Przyjmując Rw baterii na poziomie 5 omów, przy tym poborze prądu powinienem mieć spadek do ok. 5,4 V, wciąż więcej niż z USB. Nie ma co wierzyć statycznym pomiarom, w takim układzie mogą być jakieś piki, które będzie można wyeliminować kondensatorem, więc sięgnąłem po oscyloskop i sprawdziłem napięcie przy nóżce Vin. Napięcie było poniżej 5V, a okresowo spadało jeszcze nawet o prawie 1,2 V! Podczas pomiarów rezystancji baterii nie udało mi się uzyskać takiego spadku nawet pobierając z układu 350mA. Powtarzając kilkukrotnie pomiary, wpiąłem się sondą nieco bliżej baterii. Tam napięcie było w porządku. Skoro przy pinie są duże spadki, a kabelek dalej już nie to... KABELEK Co mogło być z nim nie tak? Spróbowałem zmierzyć rezystancję i aż Wam to nagrałem. Coś w obszarze zaciśnięcia kabla na pinie musi być nie tak, bo nic nie wypada, a rezystancja wariuje. Co najciekawsze, wynik pomiaru pływa nawet gdy kabel leży nieruchomo! Miał ktoś z Was taką sytuację? Wymieniłem kabelek na inny i jak ręką odjął. Tak to jest jak człowiek szuka przyczyn daleko, a rozwiązanie jest banalne. Plan na najbliższe dni: Zdecydować, jak rozmieścić czujniki. Na pewno na początek w linii prostej, ale 4, czy 5, sąsiadująco, czy w odstępach, wszystkie sąsiadująco, czy tylko centralne, a może wszystkie w odstępach, jakie te odstępy? Warianty można mnożyć, może popatrzę na rozwiązania użytkowników forum, jeśli macie jakieś propozycje, to chętnie wysłucham. Jak będzie decyzja to zlutuje je na płytce uniwersalnej 20x80 i będę ją musiał jakoś przymocować. Prawdopodobnie wydrukuję wysięgnik trzymający płytkę. W grę jednak wchodzi też wydrukowanie sensorotrzymacza, który pozwoli na swobodne przesuwanie transoptorów i dobór najlepszej konfiguracji. Podsumowanie 09.12.2020: Wiem, rozpisałem się, ale... miałem ochotę się tym podzielić i tyle 🙂 Historiografię wyraźnie oznaczyłem więc jak ktoś chce pominąć to widać gdzie zaczyna się część techniczna. Chętnie wysłucham konstruktywnej krytyki, sugestii i odpowiem na pytania związane z robotem i Micropythonem, bo uważam że język ten zasługuje na większą popularność, również w polskim DIY.
  3. Dziś pierwszy mój samodzielny wpis: jak wysterować trójkolorowy wyświetlacz ePaper z Raspberry Pico. Przykłady są przeprowadzane na czarno-biało-czerwonej matrycy GDEW075Z09 (zestaw WaveShare 13505, matryca z płytką kontrolera SPI w formie shielda na Raspberry Pi), ale tak samo programuje się czarno-biało-żółtą matrycę GDEW075C21 (zestaw WaveShare 14229). Teoria Wyświetlacze typu e-papier w najczęstszej formie nazywają się wyświetlaczami elekroforetycznymi i działają tak: Wyświetlacz zawiera miliony miniaturowych, przezroczystych kapsułek zawierających dwa lub trzy pigmenty zawieszone w oleju. Cząsteczki pigmentów są naładowane elektrycznie (w wyświetlaczach dwukolorowych - dodatnio i ujemnie, w trójkolorowych słabo i silnie dodatnio i ujemnie) Kapsułki są umieszczone pomiędzy przezroczystą elektrodą wspólną u góry a matrycą elektrod indywidualnych na dole. Jeden piksel składa się z wielu kapsułek (są one dużo mniejsze od jednej elektrody) i widać to pod dużym powiększeniem. Zmieniając napięcie na elektrodach indywidualnych można wypychać pożądane pigmenty w kierunku górnej części wyświetlacza, wtedy piksel zmienia kolor. W 3-kolorowych jest trudnej, bo dwa pigmenty poruszają się razem (czarny i kolorowy), ale z różnymi prędkościami i trzeba sztuczek, żeby te kolory finalnie rozdzielić - więcej w tym artykule. Napięcia sterujące są dość wysokie (jak na współczesną elektronikę), rzędu ±7-15V i wyświetlacz pozostawiony "pod napięciem" przez dłuższy czas może ulec uszkodzeniu (jak burn-in w OLED czy plaźmie). Pamiętaj, żeby po każdym odświeżeniu przełączyć kontroler w stan power-down. Kontroler Matryce można kupić w formie zestawu z shieldem dla Raspberry Pi (testowałem z Pi0W i Pi3). Płytka shielda ma pod spodem styki do standardowego łącza GPIO-40, ale ma też osobne gniazdo SPI do używania z innymi komputerami nadzorczymi. I właśnie to gniazdo zostało wykorzystane do podpięcia się do Raspberry Pico. W zestawie z shieldem jest nawet odpowiedni kabel z żeńskimi końcówkami do podpięcia pod szpilki. Shield jest uniwersalny (do wszystkich "gołych" matryc ePaper sprzedawanych przez WaveShare), należy tylko odpowiednio na nim ustawić mikroswitche. Interfejs elektryczny Shield jest wyposażony w standardowy, jednokierunkowy port SPI (matryca ma co prawda łącze dwukierunkowe, ale część odbiorcza nie jest "przepuszczana" przez shield), kilka sygnałów sterujących (CS, CD, RST) oraz jeden monitorujący (BUSY). Zasilany jest jednym napięciem 3.3V. Przykładowy kod zakłada następujące połączenia (kolorowe kable na dole powyższego zdjęcia, licząc od lewej): BUSY -> GP6 (pin 9 Pico) RST <- GP1 (pin 2 Pico) DC <- GP0 (pin 1 Pico) CS <- GP5/SPI0)CSn (pin 7 Pico) CLK <- GP2/SPI0_SCK (pin 4 Pico) DIN <- GP3/SPI0_TX (pin 5 Pico) GND -- GND (pin 38 Pico) VCC -- 3V3_OUT (pin 36 Pico) Protokół Do wyświetlacza możemy przesyłać ciągi komend opcjonalnie uzupełnionych o dane. O tym, co jest transmitowane, decyduje stan linii DC. Sekwencja wysłania komendy wygląda tak: Wysterować linię DC na stan niski (komenda), Wysterować linię CS na stan niski, Przesłać bajt komendy Wysterować linię CS na stan wysoki, Jeżeli komenda wymaga danych, to później następuje taka sekwencja: Wysterować linię DC na stan wysoki (dane), Wysterować linię CS na stan niski, Przesłać bajty danych Wysterować linię CS na stan wysoki, Na końcu trzeba próbkować linię BUSY, stan wysoki sygnalizuje zakończenie operacji. Dokumentacja jawnie wskazuje, że należy "zdjąć" na chwilę CS po komendzie, jednak zaobserwowałem, że nie ma to wpływu na działanie wyświetlacza. Program przykładowy skonstruowany jest zgodnie z dokumentacją. Inicjalizacja Proces inicjalizacji wyświetlacza zawiera dużo czarnej magii: poszczególne rejestry dla poszczególnych matryc muszą być ustawione konkretnie, bo producent tak mówi - bez głębszego wyjaśniania. Dotyczy to szczególnie zależności czasowych i konfiguracji układu konwersji napięcia. Ma być tak, bo inaczej zepsujesz matrycę. Sekwencja komend konfiguracyjnych w przykładowym programie jest dostosowana do konkretnych dwóch matryc - parametry dla innych należy ściągnąć z przykładowych programów na wiki WaveShare'a. Aktualizacja Matryca ma wbudowaną pamięć obrazu i jeżeli chcemy zmienić jej zawartość, musimy przesłać cały nowy obraz. Po przesłaniu nowej ramki wydaje się polecenie odświeżenia, które pierw czyści cały ekran, a następnie na podstawie zawartości pamięci "pompuje" odpowiednie piksele. W przypadku opisywanych matryc cały cykl trwa bolesne 15 sekund. Matryce dwukolorowe mają możliwość częściowego odświeżenia prostokątnego okienka - trwa to około 1/3s. Niestety, żadna matryca trójkolorowa nie ma takiej funkcjonalności. Zasilanie Aby uniknąć uszkodzenia materiały matrycy, należy bezwzględnie wydawać polecenie wyłączenia zasilania po każdym odświeżeniu. Program """ Driver do wyświetlaczy GDEW075Z09 (czarno-biało-czerwony) i GDEW075C21 (czarno-biało-żółty), występujących odpowiednio w zestawach WaveShare 13505 i 14229 Copyright (c) 2021 Paweł Kraszewski Bazuje na pracy: Copyright (c) 2017 Waveshare Copyright (c) 2018 Mike Causer MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ class EPaper_GDEW075Z09: from micropython import const EPD_WIDTH = const(640) EPD_HEIGHT = const(384) COMMAND = const(0) DATA = const(1) def __init__(self, spi, cs, dc, rst, busy): """ Inicjalizacja wyświetlacza :param spi: Skonfigurowany interfejs SPI :param cs: Pin do sygnału wyjściowego ~CS (chip select) :param dc: Pin do sygnału wyjściowego DC (data/command) :param rst: Pin do sygnału wyjściowego ~RST (reset) :param busy: Pin do sygnału wejściowego ~BUSY (gotowość wyświetlacz) """ import framebuf self.spi = spi self.cs = cs self.dc = dc self.rst = rst self.busy = busy self.cs.init(self.cs.OUT, value=1) self.dc.init(self.dc.OUT, value=0) self.rst.init(self.rst.OUT, value=0) self.busy.init(self.busy.IN) self._setup_pixel_lut() # Format framebuf.GS2_HMSB to grafika w 4 odcieniach szarości. Tablica # LUT przetwarza kolory 0, 1, 2 i 3 odpowiednio na biały, # czerwony/żółty, czarny, czarny (tak, dwa czarne) # Bajt tablicy obrazu to spakowane 4 piksle, dlatego wymaga 1/4 bajtów # Bufor pamięciowy self.buf = bytearray(self.EPD_WIDTH * self.EPD_HEIGHT // 4) # Framebuffer (operacje graficzne, itd) self.fb = framebuf.FrameBuffer( self.buf, self.EPD_WIDTH, self.EPD_HEIGHT, framebuf.GS2_HMSB ) def _wait_for_ready(self): from time import sleep_ms while self.busy.value() == 0: sleep_ms(100) def _setup_pixel_lut(self): """ Funkcja wypełnia tablice do szybkiej transformacji obrazu w formacie 2:2:2:2 (bajt zawiera cztery pikele po dwa bity każdy) na dwa bajty w formacie 4:4 4:4 (piksele po cztery bity, ale tylko 3 kombinacje dają sensowny wynik, kolory czarny, biały i czerwony/żółty) """ LUT = [3, 4, 0, 0] self.lut_high = bytearray(256) self.lut_low = bytearray(256) for i in range(0, 256): p1 = LUT[(i >> 6) & 3] p2 = LUT[(i >> 4) & 3] p3 = LUT[(i >> 2) & 3] p4 = LUT[(i >> 0) & 3] self.lut_high[i] = (p2 << 4) | p1 self.lut_low[i] = (p4 << 4) | p3 def _send_command(self, command, data=None): """ Funkcja wysyła komendę (z linią DC=0) za którą występują opcjonalne dane (z linią DC=1) :param command: komenda wyświetlacz :param data: opcjonalne dane dla komendy """ self.dc(self.COMMAND) self.cs(0) self.spi.write(bytearray([command])) self.cs(1) if data is not None: self.dc(self.DATA) self._send_raw_data(data) def _send_raw_data(self, data): """ Komenda wysyła surowe dane :param data: dane """ self.dc(self.DATA) self.cs(0) self.spi.write(data) self.cs(1) def _send_pixel_data(self, data): """ Komenda wysyła bufor wyświetlacza w formacie 2:2:2:2 przeliczając kolory według prekalkulowanych tablic LUT :param data: framebuffer """ self.dc(self.DATA) self.cs(0) for quad_pixel in data: self.spi.write(bytearray([ self.lut_low[quad_pixel], self.lut_high[quad_pixel] ])) self.cs(1) def setup(self): """ Inicjalizacja wyświetlacza. Poprawne dla modułów GDEW075Z09 (czarno-biało-czerwony) i GDEW075C21 (czarno-biało-żółty), występujących odpowiednio w zestawach WaveShare 13505 i 14229 """ import ustruct self.hard_reset() # Power setting self._send_command(0x01, b'\x37\x00') # Panel setting self._send_command(0x00, b'\xCF\x08') # PLL Control self._send_command(0x30, b'\x3A') # VCM DC Setting self._send_command(0x82, b'\x28') # Booster soft start self._send_command(0x06, b'\xC7\xCC\x15') # VCOM and data interval setting self._send_command(0x50, b'\x77') # TCON setting self._send_command(0x60, b'\x22') # SPI flash control self._send_command(0x65, b'\x00') # TCON resolution self._send_command(0x61, ustruct.pack(">HH", self.EPD_WIDTH, self.EPD_HEIGHT)) # FLASH mode self._send_command(0xE5, b'\x03') # Temp calibration self._send_command(0x41, b'\x00') # Power on self._send_command(0x04) self._wait_for_ready() def hard_reset(self): """ Twardy reset wyświetlacza (zeruje wszystkie rejestry), impuls niski sygnału ~RST przez 200ms i dodatkowe 200ms czekania """ from time import sleep_ms self.rst(0) sleep_ms(200) self.rst(1) sleep_ms(200) def update(self): """ Aktualizuje zawartość wyświetlacza na podstawie bieżącej zawartości framebuffera. Dla opisywanych wyświetlaczy trwa to ~10s :( """ # Start pixel transmission self._send_command(0x10) # Pixels self._send_pixel_data(self.buf) # Stop pixel transmission self._send_command(0x11) # Display refresh self._send_command(0x12) self._wait_for_ready() def power_down(self): """ Wyłączenie zasilania wyświetlacza (zawartość oczywiście pozostaje na ekranie) """ # Power off self._send_command(0x02) self._wait_for_ready() # Deep sleep self._send_command(0x07, b'\xA5') def get_framebuffer(self): """ Zwraca klasę framebuf.FrameBuffer() do rysowania na buforze :return: framebuf.FrameBuffer() """ return self.fb def get_size(self): """ Zwraca rozmiar wyświetlacza w pikselach :return: (width,height) """ return self.EPD_WIDTH, self.EPD_HEIGHT def demo(): from machine import Pin, SPI # Konfiguracja pinów zgodnie z artykułem sck = Pin(2) miso = Pin(4) mosi = Pin(3) dc = Pin(0) cs = Pin(5) rst = Pin(1) busy = Pin(6) spi = SPI(0, baudrate=20000000, polarity=0, phase=0, sck=sck, miso=miso, mosi=mosi) # Podpięcie pod wyświetlacz e = EPaper_GDEW075Z09(spi, cs, dc, rst, busy) # Inicjalizacja e.setup() # Pobranie rozmiaru wyświetalcza w pikselach w, h = e.get_size() # Pobranie instancji klasy FrameBuffer do rysowania fb = e.get_framebuffer() # Przypisanie kolorów black = 2 red = 1 white = 0 # Wypełnienie białym kolorem fb.fill(white) # Ramki for i in range(0, 40, 4): fb.rect(i, i, w - 1 - 2 * i, h - 1 - 2 * i, black) fb.rect(i + 2, i + 2, w - 1 - 4 - 2 * i, h - 1 - 4 - 2 * i, red) # "Szachownica" for x in range(12): for y in range(12): c = (red, black, white)[(x + y) % 3] fb.fill_rect(50 + x * 20, 50 + y * 20, 19, 19, c) # Tekst fb.text('RED', w // 2, h // 2, red) fb.text('BLACK', w // 2, h // 2 + 16, black) # Wysłanie bufora do matrycy i polecenie odświeżenia e.update() # Bardzo, BARDZO ważne! Wyłączenie zasilania e.power_down() if __name__ == "__main__": demo() Miłej zabawy! A, skryptu można używać jako biblioteki w swoich programach. Jak zapiszecie na Malince jako "epaper.py" to z własnego skryptu użyjecie tego przez "from epaper import EPaper_GDEW075Z09" PS. Niebawem to samo, tylko w C++. A potem inne peryferia: OLED monochromatyczny, OLED kolorowy i LCD kolorowy, w wersjach pierw Python, potem C++.
  4. from machine import Pin, UART import utime keyb = bytearray(4) mouse = bytearray(7) UART1 = UART(1, baudrate=115200, bits=8, parity=None, stop=1) button1 = machine.Pin(7, machine.Pin.IN, machine.Pin.PULL_UP) button2 = machine.Pin(6, machine.Pin.IN, machine.Pin.PULL_UP) keyb = [0xFE,0x04,0x00,0x00,0x00] #mouse = [0XFD,0x05,0x02,0x00,0x00] while True: if button1.value() == 1: keyb[3]=(0x00) elif button1.value() == 0: keyb[3]=(0x1b) if button2.value() == 1: keyb[4]=(0x00) elif button2.value() == 0: keyb[4]=(0x1d) UART1.write(bytes(keyb)) utime.sleep(0.09) #print(bytes(keyb)) Mam taki problem, chciałbym wysłać do buforu tablice hexów po naciśnięciu przycisku dany element w tablicy jest nadpisany . Nie znalazłem nic o buforze protokołu UART w sieci dlatego powstał taki kod, który podmienia jeden element po naciśnięciu przycisku i wysyła poprawnie raport, ale drugi if nie działa i powoduje nadpisanie całego raportu i reset połączenia. Nie wiem czy dla tak prostej operacji muszę zagłębić się w topologię fifo i DMA ?
  5. Cześć Minęło już sporo czasu odkąd kolega deshipu opublikował bardzo ciekawy i inspirujący artykuł traktujący o Micropython. https://forbot.pl/forum/topic/8588-micropython-na-esp8266/?tab=comments#comment-88039 Przez ten czas spora część entuzjastów elektroniki, programowania, majsterkowiczów no i czytelników Forbota wszak, zaznajomiła się przynajmniej na przyzwoitym poziomie z możliwościami zastosowania mikroprocków AVR w swoich projektach. Powstawały przy tym mniej lub bardziej udane konstrukcje, które cieszyły, zaskakiwały i rozwijały twórczo, cokolwiek to oznacza. Jeśli w tym czasie miałem jakiś niedosyt, czy poczucie, że czegoś tu jeszcze brakuje, że można zrobić coś lepiej, coś zmienić lub rozbudować, to tylko z korzyścią dla siebie i dla nas samych, bo chyba nie piszę tu tylko o sobie, prawda? Podstawowy moduł Arduino R3, jakkolwiek bardzo przydatny i udany projekt z czasem zrobił się ciut niewystarczający. Brakowało komunikacji, ta szeregowa, I2C czy SPI to za mało. Apetyt rośnie w miarę jedzenia. Przydałby się Ethernet (powstawały nakładki z modułem Ethernet, samodzielne moduły np. Arduino Yun), przydałaby się sieć WiFi (np. WiDo moduł WiFi WG1300). Jeśli dysponujesz wolnym czasem i kwotą około 30 zł. do wykorzystania, to proponuję zakupić jeden z dostępnych modułów, opartych na ESP32 / ESP8266 i zacząć zabawę z alternatywnym IDE, jakim jest Thonny (z wbudowanym Pythonem), zamiast IDE z Arduino i gcc. Jest w internecie sporo gotowych poradników i rozwiązań opartych na programowaniu modułów ESP za pomocą IDE Arduino, natomiast stosunkowo niewiele można znaleźć o Micropythonie. Znam C i C++(przynajmniej z czasów kiedy wręcz obowiązkową pozycją była "Symfonia C++" Grębosza), poznanie i przyswojenie innych języków, C#, Javy czy shell-a Bash nie sprawia mi szczególnych trudności. Czas zatem zabrać się za Pythona i poznać dla niego konkretne zastosowania praktyczne. Język Python jest stosunkowo prosty i wręcz intuicyjny, sprawia, że można w miarę szybko opanować jego podstawy przynajmniej w zakresie zastosowań do programowania mikrokontrolerów. Mikropython z kolei jest własnie tym czego potrzebujemy. To minimalny, niezbędny podzbiór języka Python, gdzie umieszczono szereg narzędzi i modułów do sterowania i komunikacji z mikrokontrolerami. Przyznaje, że początkowo dość sceptycznie podchodziłem do Pythona, ze względu na wcześniejsze przyzwyczajenia co do deklaracji typów dla obiektów w C, zmiennych tablic i w ogólności składni, a tutaj jest dużo prościej i przejrzyściej, przynajmniej w tym zakresie jaki akurat jest mi potrzebny na tym etapie. Nie chciałbym przy tym rozpoczynać dyskusji na temat wyższości jednego języka nad drugim. Kieruje się tylko chęcią poznania nowego języka i alternatywnych narzędzi dla programowania mikrokontrolera. Micropython to minimalny podzbiór... tylko tyle ile jest niezbędne i tylko tyle aby zostawić dla nas jak najwięcej miejsca w pamięci takiego procka. Tak, micropython flashujemy (wgrywamy)na nasz procek i cały system wraz z szeregiem niezbędnych modułów i poleceń. Trochę to przypomina znaną już malinkę (raspberry pi), gdzie instaluje się jedną z dystrybucji linuxa i mamy tam pełnoprawny system operacyjny w dużym pudełku zapałek. Micropython i ESP32/8266 w dużym uproszczeniu przypomina nieco dystrybucję minilinux z wbudowanym micropythonem. (czy ten osioł przypomina nieco kurę? CK Dezerterzy) 🐴 Jak zacząć? Sporo się zmieniło na plus przez te kilka lat istnienia micropythona. W necie można znaleźć kilka wartościowych poradników jak zainstalować (flashować) procesory... większość zaczyna od instalacji Pythona, potem niezbędnych narzędzi (pip, esptool, ampy, potem jakiegoś środowiska/edytora IDE dla Pythona), co w konsekwencji robi się nieco flustrujące. Dobra wiadomość jest taka, że nie musimy już tego wszystkiego robić. Wystarczy pobrać i zainstalować Thonny IDE dla Pythona. Thonny w wersji 3.2.7 pobierzemy stąd: https://www.downloaddrivers.info/download-thonny-3-2-7/ , przewijamy okno w dół i mamy niebieski odnośnik: Rozpakowujemy pobrane archiwum zip i instalujemy program. Przy instalacji warto ustawić skrót do aplikacji na pulpicie. Na chwilę obecną dysponuję modułem ESP-WROOM-32, dostępnym np. w https://botland.com.pl/pl/moduly-wifi/8893-esp32-wifi-bt-42-platforma-z-modulem-esp-wroom-32-zgodny-z-esp32-devkit.html?search_query=esp32&results=65 , ale nic nie stoi na przeszkodzie aby wykorzystać dowolny moduł oparty na ESP32/8266. Na tym etapie dobrze jest wybrać taki z wbudowanym gniazdem USB, bowiem będziemy mogli bezpośrednio wpinać go do naszego komputera i programować/komunikować się z modułem w locie. Podpinamy nasz moduł kablem USB (powinien wykryć nasz moduł i przypisać do niego nr portu COM). Odpalamy Thonny IDE, i z menu wybieramy Uruchom->Wybierz Interpreter: a tam MicroPython (ESP32) i wybieramy nasz rozpoznany port COM. Następnie musimy pobrać obraz naszego systemu, aby wgrać go do naszego ESP32. Wchodzimy na stronę http://micropython.org i pobieramy z zakładki Download najbardziej odpowiedni obraz dla naszego modułu. Dla nas jest to Generic ESP32 Module i poniżej z listy Firmware with ESP-IDF v3.x wybieramy najlepiej najnowszą stabilną wersję (ja wybrałem esp32-idf3-20200902-v1.13.bin, czyli tą stabilna, bez słowa unstable w nazwie). Po pobraniu pliku obrazu .bin klikamy w Thonny na opcję menu Uruchom->Wybierz Interpreter ... i tam w pole : Otwórz okno dialogowe instalacji lub aktualizacji MicroPython... następnie wybieramy port i ścieżkę z naszym pobranym właśnie plikiem .bin. Klikamy Install Po chwili powinna rozpocząć się procedura flashowania naszego modułu. Uwaga... jeśli program zgłosi niepowodzenie uruchom ponownie Install przytrzymując na chwilę przycisk Reset w naszym module. Po flashowaniu zamykamy aktywne okno. Resetujemy ponownie moduł, zaś w polu Powłoki mamy znak zachęty naszego micropythona: >>> To oznacza, że możemy zacząć zabawę z micropythonem. Okno Thonny składa się z 2 głównych okien - okno powłoki i okno edytora. W górnym oknie możemy tworzyć/edytować skrypty Pythona, a w dolnym - i tu niespodzianka mamy dostęp do powłoki shell naszego micropythona. 😄 Czym szczególnym wyróżnia się ta powłoka? Ano możemy bezpośrednio komunikować się z naszym modułem i wydawać mu polecenia do wykonania, niejako adhoc, czyli w locie!!! Nie trzeba tak jak w Arduino najpierw kompilować całego programu aby zobaczyć w monitorze portu szeregowego "Hello World".... tutaj po prostu po znaku zachęty >>> napisz: print('Hello World') ... i tyle - poniżej otrzymasz odpowiedź z ESP32 😀 Dobra... nie masz pewności czy aby procek odpowiada (bo może to robić sam Thony), więc zrób to: wpisz po znaku zachęty po kolei te linie:(po każdej daj Enter) import machine led = machine.Pin(2, machine.Pin.OUT) led.on() led.off() Będziesz teraz zapalał i gasił wbudowaną diodę Led. Powłoka zapamiętuje wpisane wcześniej polecenia, więc możesz klawiszami strzałka góra/dół wracać do nich, bez konieczności ponownego wpisywania z palucha poleceń. Więcej o możliwościach Thonny doczytasz w Necie. Na chwilę obecną wystarczy zaznajomić się z możliwościami powłoki Micropythona. Planuję kolejny post w tematyce mikropythona, gdzie umieszczę swoje zmagania z tym nowym i dla mnie tematem. W szczególności ciekawy jest proces bootowania (uruchamiania) takiego ESP z wgranym micropythonem, do czego służą pliki boot.py i main.py , jak dodać i wgrać do procka własny skrypt/moduł .py do struktury katalogów i jak z niego korzystać. Kolejne tematy, z którymi ostatnio byłem za pan brat, (całość za pomocą micropythona - czyli alternatywa do tego co już można zrobić za pomocą Arduino IDE) : podpięcie do sieci WiFi, server i klient pobranie akt. czasu (RTC, time, utime) korzystanie z Telegram Bot przy pomocy micropythona i modułu urequests tryb głębokiego uśpienia (deep sleep mode) dla jednego (ext0) i wielu pinów (ext1) własny moduł/biblioteka użytecznych funkcji Pozdrawiam i zachęcam do zabawy z micropythonem, nie zaszkodzi 🍺 Wielkie dzięki dla kol. deshipu !
  6. 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
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.