Skocz do zawartości

Przeszukaj forum

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

  • 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

  1. Słowo wstępu Jeśli chodzi o tworzenie własnych PCB, zawsze (oprócz zapachu lutownicy) w powietrzu zawsze wisi trochę magii... Eksplozja kreatywności kończy się urządzeniem, które będzie służyć do rozwiązania konkretnego problemu i ułatwi życie. W naszym starym mieszkaniu miałem gniazdka elektryczne sterowane za pomocą radiowej częstotliwości 433MHz, kontrolowane przez ESP8266. Jednak teraz, gdy zbliżamy się do kolejnych kamieni milowych w naszej wspólnej drodze z moją wspaniałą żoną, w mojej głowie zrodziła się pewna idea i postawiłem sobie wyzwanie, aby zbudować własną Bramkę Zigbee. Chciałbym mieć pełną kontrolę nad urządzeniami, kontrolę nad przepływem między Zigbee a internetem oraz powiadomienia głosowe w jednym urządzeniu. Szczegóły techniczne Pierwszy krok, znany również jako MVP, polegał na stworzeniu urządzenia, które działa jako proxy Ser2Net (zdalny port szeregowy) i potrafi obsługiwać wbudowaną integrację ZHA w Home Assistant poprzez protokół EZSP. Urządzenie miało docelowo również obsługiwać powiadomienia dźwiękowe i posiadać wbudowany czujnik temperatury. Wszystkie kroki zakończyły się powodzeniem. 😇 Design funkcjonalny opiera się o następujące układy: ESP32S3 - główny procesor aplikacyjny ze wsparciem USB oraz WiFi. EFR32MG1 (w postaci modułu Ebyte E-180) - Zigbee Network Co-processor (NCP). MAX98357A - Wzmacniacz i kodek audio I2S. Ponadto na płytce zamontowane są: filtr wejściowy zasilania oparty na dławiku ferrytowym w konfiguracji LC, celem filtracji ewentualnych sygnałów RF. układ ograniczający prąd do 1A (~1.5A peak), dodatkowo działający jako soft-start (zapobiega tzw. inrush current, co w przypadku USB jest ważne). regulator napięcia 3.3V (low noise, ultra-low dropout). Software oparty jest o ksIotFrameworkLib a aplikacja składa się z kilku komponentów: AudioPlay - komponent odpowiedzialny za obsługę audio, w tym sterowanie częstotliwością CPU (dekodowanie wymaga 240MHz a bazowo jest 80MHz). Ser2Net - komponent pośredniczacy w komunikacji między HomeAssistant a procesorem sieci Zigbee. TempSensor - komponent odpowiedzialny za pomiary temperatury. Funkcjonalności takie jak zarządzanie połączeniem WiFi, komunikacja MQTT czy konfiguracja parametrów są dostarczane poprzez framework. Galeria multimediów Linki: Strona projektu na hackaday.io
  2. Cześć! Robię ramkę do zdjęć. Podobne tematy widziałem u nas na forum epaper 7.5" Waveshare. W końcu udało mi się wysterować wyświetlacz, napisałem własną bibliotekę dla ESP-IDF do rysowania kształtów, tekstów i grafik i działa bardzo dobrze: Ale... Chcę teraz zrobić opcję wgrywania zdjęć przez internet. Na razie zrobiłem captive portal odpalany ukrytym dotykowym przyciskiem do wprowadzania danych do WIFI. Ale po podłączeniu do WiFI chciałbym żeby była na tym odpalona strona do wgrywania zdjęć. Widziałem ten przykład i jest super: File upload server ESP-IDF. Chcę też funkcje takie jak na stronie do skalowania i ditheringu zdjęć: https://doodad.dev/dither-me-this/ Bez fajerwerków - stałe 800x480 + wybór algorytmu ditheringu. Znam się średnio na tematach webowych, ale ostatnio coraz częściej muszę więc trzeba to przebrnąć. Zatem mój pomysł jest taki: Skalowanie i dithering w JS wykonywanym na urządzeniu użytkownika, żeby mógł sobie zrobić podgląd zdjęcia. Upload przetworzonej grafiki tak jak jest to w przykładzie serwera plików - jakiś REST POST. Tak jak w przykładzie lista nazw plików przesłanych na serwer. Z plikami JS jest przykład tu Restful server w którym jest cały projekt frontendu w VUE. Przykład wygląda bardzo obiecująco: Btw. Jakby ktoś miał problem z ziarnistością obrazu na Epaper 7.5" V2 800x480 od Waveshare to polecam ten temat. Problem leży w złych parametrach podanych w przykładach od producenta. Meh...
  3. Problem: Po aktualizacji nie można połączyć się z ESP32 w trybie AP. Rozwiązanie: przed pierwszym uploadem programu trzeba skasować zawartość flash. Dla Arduino1.8.19 w menu trzeba wybrać "Erase All Flash Before Sketch Upload" (musi wskazywać "Enabled"). Dla esptool uruchomić z opcję erase_flash. UWAGA! To skasuje CAŁĄ zawartość pamięci (a więc również preferencje i pliki). Jeśli nie możemy sobie na to pozwolić, trzeba wrócić do wersji 2.0.13 Dopisane po chwili: Cos ta wersja 2.0.14 niespecjalnie się sprawdza, ja wróciłem do 2.0.13 i będę czekał na rozwój wydarzeń, z tego co się zdążyłem zorientować problem jest znany i wynikł z przejścia na nową wersję esp-idf.
  4. Przeglądając listę devkitów Espressifa trafiłem na wariant "RUST". Pierwsze myśl - czym to się różni od innych devkitów, bo trochę drogie 112zł na oficjalnym Ali. Opis sugeruje że są przykłady dla komponentów na płytce: Idąc dalej trafiam na repo ze schematem. Ciekawe, że ta płytka nie ma konwertera USB-UART tylko bezpośrednie podłączenie do USB-C. Najwyraźniej bootloader obsługuje USB. Ale to raczej nie czyni jej wyjątkowo "Rust" bo w repo wymienione są inne devkity. Podlinkowane są też są okazjonalne kursy. Patrząc na kolejne repo od esp-rs jest rozwijana implementajca ESP-IDF. Są narzędzia dla cargo np monitor. Jest też książka podobna do dokumentacji Rust w mdbook: Z opisu wynika że są jakieś 2 gałęzie projektu, jedna zgodna z std druga nie. Książka jest niekompletna, ale widać że coś się nabudowuje. Dział na oficjalnym forum jest dość pusty (samo forum jest dość puste) Ktoś coś robił w tym temacie i może podzielić się swoim doświadczeniem?
  5. Pisałem niedawno, że marzyłem kiedyś i takim przenośnym urządzeniu, które czytałoby mi książki w czasie spaceru czy jazdy pociągiem. I to nie audiobooki, ale zwyczajne ebooki. Cóż - kilkanaście lat temu było to raczej mało realne. Minęły lata (kilkanaście jak wspomniałem), realia się zmieniły, i chociaż rzadziej wychodzę na spacery czy wsiadam do pociągu - postanowiłem zrealizować swoje marzenie. Co prawda jakieś pierwotne założenia sobie poczyniłem, jednak pozostały z nich tylko dwa: rozmiar nie przekraczający paczki papierosów i ESP32 WROVER jako serce urządzenia. Miałem w planach kartę microSD - ale po drodze stwierdziłem, że na moim ESP mam jakieś 8MB flasha do dyspozycji na FatFS, książka po skompresowaniu zajmuje nie więcej niż pół mega, czyli kilkanaście książek powinienem zmieścić bez dodatkowych urządzeń typu czytnik kart. Kilka problemów musiałem rozwiązać zanim zabrałem się do jakiejkolwiek roboty. Najważniejsza była klawiatura: musiała być intuicyjna (tak żebym nie musiał wyciągać urządzenia z kieszeni żeby znaleźć klawisz pauzy), a jednocześnie odporna na jakieś "samoczynne" wciskanie klawiszy w kieszeni. Postanowiłem umieścić ją razem z gniazdem słuchawek i wyłącznikiem na górnej (najkrótszej) ścianie obudowy; pozwoli to na bezwzrokowe obsługiwanie czytaka, a jednocześnie jest nikłe prawdopodobieństwo że klawisz sam się wciśnie. Trochę musiałem pokombinować z ilością klawiszy (początkowo miało ich być 13, ale po ograniczeniu do 9 okazało się, że wszystkie potrzebne funkcje są dostępne). Trochę kombinowania - i wyszło mi coś takiego: Dla porównania wielkości - moje pudełko na papierosy. Jest to oczywiście tylko próbny wydruk, ale wszystkie klawisze są wlutowane do płytki, a gniazdo słuchawek jest już na swoim miejscu. Drugą niemniej ważną sprawą był rozmiar aplikacji. Tego się obawiałem najbardziej - bo o ile tworząc microlenę mogłem sobie pozwolić na dość duże uproszczenia z uwagi na przewidywalność stosunkowo krótkich komunikatów (vide "poziomica") - o tyle tutaj musiałem zastosować pełne słowniki i wzorce rozpoznawania zwrotów. Dodatkowo microlena nie miała modułu rozpoznawania czasowników - tu musiałem go stworzyć praktycznie od nowa (wersja pecetowa korzysta albo z Morfologika, albo z wbudowanego kilkunastomegabajtowego słownika czasowników). I tu niespodzianka - wszystkie dane potrzebne do przetworzenia tekstu z książki na zapis fonetyczny zmieściły się w ok. 800 kB. Co prawda analizator morfologiczny nie jest tak dokładny jak w wersji PC, ale wystarczający aby nie było rażących błędów prozodii. Przynajmniej słuchając przez pół godziny przygód Anastazji Kamieńskiej nie zauważyłem błędów (poza kompletnie popsutą odmianą liczebników, ale to kwestia błędów w programie, a nie niewystarczających danych). Tak więc testowa aplikacja, zawierająca prowizoryczny serwer www (do uploadu i ogólnie manipulowania "księgozbiorem") oraz syntezator ma ok. 1.8 MB. Ponieważ nie przewiduję jakichś "flashożernych" procedur powinienem zejść poniżej 3 MB. Biorąc pod uwagę zajmujące nieco ponad 5 MB próbki głosu potrzebne Mbroli do syntezy - powinienem móc połowę z 16 MB pozostawić na FatFS. Opiszę jeszcze klawiaturę urządzenia (w trybie odtwarzania): Klawisze po lewej stronie (piątka): dwa klawisze regulacji głośności klawisz pauzy dwa klawisze regulacji prędkości Klawisze po prawej stronie (romb) która godzina/stan baterii (krótkie lub długie wciśnięcie) dwa klawisze przeskoku o zdanie/akapit w tył lub do przodu gdzie jestem? (tytuł, rozdział, akapit) W trybie pauzy można przeskoczyć o akapit lub rozdział lub (poprzez długie naciśnięcie klawisza "pauza") przejść do stanu "stop" (tu jeszcze nie mam opracowanego znaczenia klawiszy). Ponieważ urządzenie będzie miało wbudowany zegarek - wybrałem moduł zawierający pamięć EEPROM, w której mam zamiar trzymać zarówno wszystkie ustawienia programu, jak i informacje o aktualnie czytanej książce (rozdział/akapit/offset). Cóż - zobaczymy co będzie dalej 🙂 Na pewno opiszę efekty moich bojów z wbudowanymi w ROM funkcjami kompresji/dekompresji, muszę tylko doprowadzić ten fragment kodu do postaci umożliwiającej publiczne pokazanie go bez narażania się na inwektywy oraz skrobnąć parę słów opisu typu "dlaczego tak a nie inaczej". Aha: program jest pisany pod Arduino, tak że być może ktoś wykorzysta jakieś jego fragmenty. Postaram się publikować co ciekawsze kawałki. Jeśli ktoś miałby jakieś sugestie - jestem bardzo ciekaw, bo na tym etapie mogę jeszcze dużo zmienić. Stay tuned!
  6. - na rynku jest dużo oferowanych modułów typu Open-smartWatch. - mnie zainteresował moduł z wyświetlaczem IPS 240x240 GC9A01 w brzydkiej obudowie zegarka na rękę, 4 przyciski, bateria w środku. - zestaw części obejmuje: ESP32-pico-D4: 2x240MHz, 320KB RAM DS3231MZ GC9A01 240x240 16bit TFT display (round) BMA400 Accelerometer + Pedometer MCP73831 LiPo Charger CH340E USB Serial TPS2115A switch PWR - dwa stabilizatory 3V3 typu XC6209 oraz baterię Li-Po 400mAh. - do tej pory udało się uruchomić planetarium, grę Tetris, zegarek analogowy oraz małą stację pogodową. - zegarek okresowo poprzez WiFi łączy się z internetem i pobiera dane pogodowe oraz czas z serwera NTP do synchronizacji modułu DS3231MZ . - "zegarek" do połączenia z AP WiFi może pobierać login, hasło z trzech telefonów lub też z pamięci SPIFFS. - w planie była (jest) możliwość podania loginu, hasła z APK na telefonie przez BT ale program obsługujący BT plus program "matka" nie mieści się w zainstalowanym w tym module flashu 4MB. - będę jeszcze nad tym pracował zwłaszcza że był na githubie projekt z wifi, BT SPP na flashu 4MB autor zmienił rozmiary partycji oraz napisał program switcha na wifi-BT (nie na BLE). - konto i zawartość konta znikneła.
  7. Dzisiaj taki faktycznie mały projekcik, zrealizowany (nie licząc czasu druku) w dwa popołudnia. Od pewnego czasu chodzi za mną małe, przenośne ustrojstwo oparte na RPi, czyli taka przenośna linuksowa konsolka. No - ale sama konsolka byłaby za nudna, warto by było coś tam ciekawego zainstalować... nawet się nie zastanawiałem, i wybrałem emulator VICE. Trochę miałem problemów, ale całość ładnie ruszyła (ekran ST7789 320x240, dźwięk I2S, nad zasilaniem jeszcze się namyślam), ale jeśli już emulacja C64 to przydałby się jakiś joystick (na podłączonej mini-klawiaturze od biedy da się pisać, ale o graniu można zapomnieć). Kupno raczej nie wchodziło w grę, poza tym konsolka ma być mała, a taki Quickshot byłby pewnie co najmniej tak duży jak ona... a chciałem żeby to był0o naprawdę małe, ale jednocześnie używalne. Tak więc trzeba było zajrzeć do swoich rupieci. I co przydatnego znalazłem: Wemos LOLIN32 Lite Joystick analogowy Waveshare (PSP1000) Akumulator 1200 mAh I oczywiście jakieś pstryczki, przełączniki i tym podobne drobiazgi, Zacząłem oczywiście od sprawdzenia sposobu komunikacji joysticka z konsolką. Od razu założyłem, że nie ma tam być żadnych kabli - najprostsze było połączeniu BLE. Po kilku próbach doszedłem do wniosku, że joystick będzie po prostu udawać drugą klawiaturę i użyję klawiszy które nie są zmapowane na klawiaturę C64. No i po paru próbach wyszło mi coś takiego: Urządzenie sprawdza się nadspodziewanie dobrze, przynajmniej w prostych grach. Jedynym problemem były ostre krawędzie w pierwszej wersji obudowy, utrudniające wygodne trzymanie. Kod jest krótki (niecałe 200 linii) więc zamieszczam go w całości: #include <BleKeyboard.h> #include <Bounce2.h> BleKeyboard bleKeyboard("BlueShot-I"); const uint8_t led_pin = 33; const uint8_t key1_pin = 27; const uint8_t key2_pin = 26; const uint8_t fire_pin = 25; const uint8_t x_pin=39; const uint8_t y_pin=36; Bounce AfButton=Bounce(), TfButton=Bounce(), FiButton=Bounce(); bool autoFire=false; uint32_t fireDelays[]={220, 150, 100, 70, 50, 500, 330}; const int fireDelayCnt = sizeof(fireDelays) / sizeof(fireDelays[0]); int fireDelayNo = 0; uint32_t fireTimer; uint32_t ledTimer; void setup() { Serial.begin(115200); pinMode(led_pin, OUTPUT); digitalWrite(led_pin,1); pinMode(fire_pin, INPUT_PULLUP); AfButton.attach(key1_pin, INPUT_PULLUP); TfButton.attach(key2_pin, INPUT_PULLUP); FiButton.attach(fire_pin, INPUT_PULLUP); AfButton.interval(30); TfButton.interval(30); FiButton.interval(10); bleKeyboard.begin(); ledTimer = millis(); } int keys[2][5]={ {KEY_NUM_8, KEY_NUM_2, KEY_NUM_4, KEY_NUM_6, KEY_NUM_0}, {KEY_NUM_SLASH, KEY_NUM_ASTERISK, KEY_NUM_PLUS, KEY_NUM_MINUS,KEY_NUM_PERIOD}}; uint8_t keySet=0; uint8_t lastKeys,thisKeys; int autoFirePos(int fire) { static int lastFire = 0; static bool fireState = false; if (!fire) { lastFire=0; return 0; } if (!lastFire) { fireTimer = millis(); fireState=true; lastFire = 1; } else if (millis() - fireTimer >= fireDelays[fireDelayNo]) { fireState = !fireState; fireTimer=millis(); } return fireState; } int xRead(int pin) { int i,sum; for (i=sum=0;i<32;i++) sum+=analogRead(pin); return sum /32; } #define BIT_JU 1 #define BIT_JD 2 #define BIT_JL 4 #define BIT_JR 8 static uint8_t dirbits[]={ BIT_JR,BIT_JR+BIT_JD, BIT_JD, BIT_JD+BIT_JL, BIT_JL, BIT_JL+BIT_JU, BIT_JU, BIT_JU+BIT_JR}; int readDirection() { int x=xRead(x_pin)-1800; int y=xRead(y_pin)-1800; int w=sqrt(x*x+y*y); if (w < 900) return 0; float a = atan2(y,x) * (4.0/PI) + 4.0625; w=(int)a; return dirbits[w & 7]; } void addKey (KeyReport *kr, uint8_t key) { int i; if (key >= 136) key -= 136; else if (key >= 128) { kr->modifiers |= 1 << (key & 7); return; } for (i=0;i<6;i++) if (!kr->keys[i]) { kr->keys[i] = key; break; } } enum { LEDCTL_NONE=0, LEDCTL_AUTOFIRE, LEDCTL_KEYSET}; uint8_t ledStatus; uint8_t ledControl=0; uint32_t ledControlTimer; void loop() { TfButton.update(); AfButton.update(); FiButton.update(); if (AfButton.rose()) { if (AfButton.previousDuration() > 400) { keySet = 1 - keySet; ledControl = LEDCTL_KEYSET; ledControlTimer = millis(); } else autoFire = !autoFire; } if (TfButton.fell()) { if (ledControl == LEDCTL_AUTOFIRE) fireDelayNo = (fireDelayNo + 1) % fireDelayCnt; else ledControl=LEDCTL_AUTOFIRE; ledControlTimer = millis(); } bool afToLed=false; if(bleKeyboard.isConnected()) { int i,fr; KeyReport kr; thisKeys=0; memset((void *)&kr,0,sizeof(kr)); thisKeys=readDirection(); fr=!FiButton.read(); if (fr) ledControl = LEDCTL_NONE; if (autoFire) { if (fr) afToLed = true; fr=autoFirePos(fr); } if (afToLed) ledStatus = fr; else ledStatus = millis() - ledTimer <= 50; if (fr) thisKeys |= 1<<4; if (thisKeys != lastKeys) { for (i=0; i<5; i++) if (thisKeys & (1<<i)) addKey(&kr,keys[keySet][i]); lastKeys = thisKeys; bleKeyboard.sendReport(&kr); delay(10); } } else { ledStatus = millis() - ledTimer >= 100; } uint32_t delta ; switch(ledControl) { case LEDCTL_KEYSET: delta = (millis() - ledControlTimer)/150; if (delta >= 24) ledControl = LEDCTL_NONE; else { static uint8_t pls[2][8] = { {1,0,1,1,1,0,0,0}, {1,1,1,0,1,0,0,0}}; ledStatus = pls[keySet][delta & 7]; } break; case LEDCTL_AUTOFIRE: delta= millis() - ledControlTimer; if (delta >= 3000) ledControl = LEDCTL_NONE; else { delta /= fireDelays[fireDelayNo]; ledStatus = delta & 1; } break; } digitalWrite(led_pin, ledStatus); if (autoFire) { if (millis() - ledTimer >= 500) ledTimer = millis(); } else { if (millis() - ledTimer >= 1000) ledTimer = millis(); } } Potrzebne biblioteki: stara dobra Bounce2 i ESP32-BLE-Keyboard. Fragment pliku sdl-vicerc dla c64: KeySet1North=264 KeySet1East=262 KeySet1South=258 KeySet1West=260 KeySet1Fire=256 KeySet2North=267 KeySet2East=269 KeySet2South=268 KeySet2West=270 KeySet2Fire=266 Ciekawsze możliwości: Autofire (oczywiście włączany na żądanie) z regulowaną częstotliwością (7 możliwości od 1 do 10 Hz), zsynchronizowany z przyciskiem fire (tzn. wciśnięcie fire od razu oddaje pierwszy strzał) Możliwość przełączenia zestawu klawiszy (w praktyce przy odpowiednim skonfigurowaniu x64 pozwala to na szybkie przełączanie portów). Pojedyncza dioda w czytelny sposób podaje stan połączenia BLE, włączenie i częstotliwość autofire oraz numer zestawu klawiszy. Schematu nie podaję bo jest trywialny - praktycznie wszystko wynika z kodu. Będę chciał tam jeszcze jakoś zmieścić gniazdo DB9 (żeby można było Quickshota podłączyć albo inną stalową wajchę), w programie to dołączenie raptem paru linijek w funkcji readDirection. Jakby ktoś miał jakieś pomysły - bardzo proszę o komentarz.
  8. Projekt z gatunku "pilnych" - czyli trzeba rzucić wszystko i się tym zająć... Założenia: ma to odtwarzać empeszcze przez BT albo kontrolnie przez wbudowany głośniczek ma być łatwy w obsłudze (baaaaardzo łatwy) kilka trybów pracy, m.inn. spektakl (czyli po każdym numerze robi stop i przeskakuje do następnego) odczyt albo wszystkich plików mp3 (przesłuchanie) albo tylko konkretnych (nazwy rozpoczynające się od ciągu cyfr i podkreślnika lub myślnika) odczyt muzyki z pendrive (montowany read-only automatycznie) i ogólnie jeszcze innych parę ważnych rzeczy które wyjdą w praniu No i najważniejsze: zrobiony z tego co leży w szufladzie. Na razie wyszło mi coś takiego: RPi Zero W do grania, gadania z ustrojstwami po BT i czytania pendrive ESP32 do obsługi klawiatury, wyświetlacza i ogólnie całej logiki Komunikacja obu przez port serial Co już mam: Spatchowaną bibliotekę mpg123 do Pythona (dodane funkcje seek i tell) udane pożenienie ze sobą i2s, pulseaudio i bluetooth (walka z regulacją głośności dla i2s to temat na powieść) automontowanie pendrive oraz powiadomienie głównego programu na RPi że takowy został zamontowany prowizoryczny programik odtwarzacza mp3 (na mpg123 i pyao) jeszcze bardziej prowizoryczny do obsługi BT (w sumie wrapper do bluetoothctl - nic bardziej sensownego nie znalazłem). szkieletowy program na ESP32 (rdzeń 0 zajmuje się na razie wyłącznie wyświetlaczem, rdzeń 1 to cała reszta, zobaczymy co z tego wyjdzie) zmontowane wszystko (razem z modułem DS3231, eeprom się przyda bo karta jest montowana ro w overlay) na płytce uniwersalnej, Zobaczymy co z tego wyjdzie - konstrukcja zapowiada się ciekawie. Teraz kompletuję przyciski do klawiatury (chyba mi kilku zabraknie, ale może da się z czegoś wylutować). Jakby ktoś miał jakieś pomysły to na tym etapie bardzo chętnie się zapoznam 🙂
  9. Enbio Technology - Potrzebujemy do pomocy średniodoświadczonego programistę embedded, najlepiej który ma doświadczenie w STM32 i ESP32 w rozwiązaniach komercyjnych, albo przynajmniej w projektach wykonanych profesjonalnie, przetestowanych, nieawaryjnych. Dobrze mieć wiedzę w temacie IoT, najlepiej z MQTT i Azure IoT Hub. Praca hybrydowa: zdalnie / biuro + warsztat R&D w Rumii (Pomorskie, tuż obok Gdynii). Zarobki: do 10k brutto. Projekty które robimy to autoklawy parowe z dostępem do internetu. Pracujemy nad nowymi technologiami, a urządzenia, po wdrożeniu będą pracować w krajach na całym świecie. Duża zaleta tej pracy - możliwość prześledzenia projektu od początku do końca i napisanie własnego programu - jest to świetna okazja do nauki. Praca nie ogranicza się do jednego projektu. W tym momencie jest jeden produkt wymagający utrzymania (STM32F4), drugi w trakcie realizacji i trzeci do którego szukamy programisty. Będą też kolejne. W przypadku zainteresowania podam szczegóły.
  10. Witam, czy ktoś z was ogarnia obsługę wyświetlacza GC9A01 240x240 ? Wymyśliłem sobie fajny projekcik jednak nie mam zielonego pojęcia o programowaniu takowego wyświetlacza. Ktoś mógłby pomoc ?
  11. https://github.com/rkalwak/WeatherStation Wygodniej mi podlinkować do Githuba, gdzie mogę prościej aktualizować i przechowywać obrazki. Wiem, że aplikacja pokazuje trochę głupoty - rozłączyłem coś przenosząc. Stacja pogodowa: Z Arduino i zaraz potem ESP32 bawię się już ponad dwa lata. W sumie to zacząłem bardziej z https://www.nanoframework.net i tam portowałem kilka bibliotek, bo C++ to jest dla mnie epoka kamienia łupanego 😛 Padł pomysł, żeby zrobić sobie pogodynkę na bazie ESP32 zaprogramowaną w C# przez NanoFramework. W międzyczasie poznałem Suplę i zacząłem od rolet na SRW-01 a potem na zaprogramowaniu ESP przez GUI-Generic i się zaczęło... Doszedłem do momentu że dopisałem sobie "Kanał ogólnego przeznaczenia", umiem to zbudować ale ze względu na absolutny brak dokumentacji nie umiem tego uruchomić w Dokerze i się poddałem... Chciałem też napisać komunikację z Supla w C# ale z braku czasu odpuściłem. Prędzej czy później to zrobię... Poczytałem trochę co będzie potrzebne, kupiłem niekompletna stacje Sainlogic WS3500 na A****** i tak powstało to cudo, które niedlugo zawiśnie na płocie 😄 Funkcjonalności: * 2x temperatura, * wilgotność, * ciśnienie atmosferyczne, * siła i kierunek wiatru, * ilość opadów, * pomiar napięcia baterii, Części: * niekompletna stacja Sainlogic WS3500 - bez tabletu i zasilacza -> nie można jej skonfigurować, ale nieuszkodzona, wyrwana za 100zł 😄 * ESP32 DevKit * HDC1080 - czujnik wilgotności i temperatury * MS5611 - czujnik ciśnienia * DS18B20 - czujnik temperatury przy gruncie * LTR390 - czujnik UV i natężenia światła wbudowany w stację, użyty jako ten drugi * AS5600 - enkoder magnetyczny, zastąpił czujnik kierunku wiatru w stacji * czujnik Halla - zastąpil czujnik siły wiatru w stacji , ten od czujnika opadów został * 2 baterie 18650 LiPo i koszyk * lx-lifc1-n - Moduł BMS z ładowarką do akumulatorów Li-ion 2S z USB typu C i obsługą QC, możliwość ładowania z USB albo panelu. * przetwornica step-down * panel fotowoltaiczny dający 7V i ok. 1W wbudowany w stację Schemat i sposób działania ESP32 jest wyciągnięte do zewnętrznej puszki wraz z zasilaniem, ze względu na rozmiar stacji, po prostu się w niej nie mieści. Użyłem 12 żyłowego, 2 metrowego przewodu telefonicznego do połączenia płytki w stacji z tą w puszce. Wykorzystałem panel fotowoltaiczny z kupionej stacji do ładowania akumulatorków, jednak jest za słaby aby w pełni naładować 2 akumulatorki i co najwyżej wydłuża czas pracy na bateriach, który bez panelu wynosi ponad dobę pracy non stop. Stacja wykorzystuje bibliotekę SuplaDevice do komunikacji z Supla i robi to co 10 sek. Problemy 1. Brak schematów do stacji Sainlogic WS3500 i opisów na płytkach Metodą prób i błędów wymyśliłem jak wykorzystać niektóre wbudowane czujniki. LTR390 po wyjęciu i zobaczeniu oznaczeń pinów podpiąłem do ESP i puściłem skaner I2C a potem po adresie znalazłem czujnik, po dobraniu biblioteki zadziałał 😄 Niestety ten sam manewr nie zadziałał z czujnikiem temperatury i wilgotności. Mimo, że wygląda jak AHT XX i ma właściwy adres I2C nie działa z żadną biblioteką do tych czujników. Czujnik Halla dla opadów zadziałał. Doświadczalnie trzeba było dobrać jego pojemność. Czujnik Halla dla siły wiatru najpierw działał a potem przestał... Kupiłem inny i działa, ale obserwując dane w Supli, muszę poprawić obliczanie prędkości wiatru. Po kilku godzinach czytania okazało się, że kierunek wiatru jest zrealizowany przez dwa czujniki Halla i coś jeszcze, ale nie rozkminiłem tego... Kupiłem za to enkoder magnetyczny, który podaję kąt w stopniach - idealnie. 2. Zasilanie Pierwsza opcja: 1 akumulatorek 18650 i LDO na 3.3V, owszem ESP się uruchomi, ale z Wifi już się nie połączy przy obciążeniu wszystkimi czujnikami. Użyłem AMS1117 jako LDO. Druga opcja: 2 akumulatorki 18650 i przetwornica StepDown ustawiona na 5V, podane na VIN pin. Działa, ale chyba marnuje możliwości akumulatorków. Dodatkowo dwa akumulatorki to za dużo aby naładować z małego panela dającego max 7V, więc chyba skończy się to większym panelem 😄 Trzecia opcja: zasilanie z USB - nie mam póki co dobrego miejsca, żeby stacja wisiała na rozsądnej i dostępnej wysokości i był bezpieczny i wygodny dostęp do prądu. Czwarta opcja: czytałem, że ESP32 DevKit może przyjąć do 12V na VIN pin, podłączył bym bezpośrednio baterie, ale jakoś się nie odważyłem jeszcze, ktoś próbował? 3. Dokładność pomiarów ADC w ESP32 jest trochę słabe, pomiar napięcia akumulatorków jest "mniej więcej", wahania rzędu 0.3V. HDC1080 się bardzo grzeje w obudowie radiacyjnej i generalnie w południe pokazuje głupoty w stosunku do DS18B20 wiszącego luźno w cieniu, aczkolwiek wilgotność pokazuje nieźle co jest dziwne. Więc muszę to przemyśleć. Siła wiatru zdecydowanie będzie lepiej oprogramowana bo nie znając możliwości wiatraczka błądzę w obliczeniach. 4. Supla i jej możliwości Niestety Supla nie ma jeszcze generycznego kanału, któremu można przypisać jednostkę lub kanału stacji pogodowej przewidującego więcej parametrów więc niektóre pomiary musiały zostać przepchnięte przez kanał temperatury, np. napięcie akumulatorków czy kierunek wiatru jako kąt z zakresu 0-360 względem północy. Plany na przyszłość - Pewnie większy panel fotowoltaiczny. - Pomiar napięcia z panelu. - Pomiar poboru prądu przez ESP - mam już moduł INA219 obczajony 😄 - Własne płytki zamiast breakout boardów, a przynajmniej ta zewnętrzna. - Pomiar zanieczyszczenia powietrza (SDS0111). - Po przekroczeniu ustawionej godziny przechodzić na tryb "deep_sleep" i budzić co 15 min na minutę aby pomiar wiatru i deszczu był choć trochę użyteczny. Następnie rano o ustalonej godzinie budzić się aby pracować do wieczora w celu wydłużenia pracy na akumulatorkach. - Albo w Supli pojawi się kanał ogólnego przeznaczenia, który będzie wspierał dane, które mogę wysłać albo zgłosze PR ze zmianami 😄
  12. Ten artykuł jest częścią serii "Tworzenie interfejsu sieciowego z wykorzystaniem ESP" #1 - część 1 (właśnie to czytasz) #2 - część 2 ESP32 czy też ESP8266 na dobre już zagościło w wielu warsztatach domowych majsterkowiczów. Większość obecnych projektów z wykorzystaniem ESP skupia się wokół dorzucenia do niego garści czujników, podłączenia do baterii i wybudzania go od czasu do czasu, aby wysłać dane o wykonanych pomiarach do naszego serwera. Czasem zdarza się, że nasze urządzenie pobiera pewne dane z zewnątrz i je wykorzystuje, np. budzik czas z serwera NTP, czy stacja pogodowa, informacje o pogodzie z wybranego serwisu. Co w sytuacji kiedy chcemy kontrolować nasze urządzenie lub obserwować jego stan z poziomu przeglądarki, a nie posiadamy Raspberry Pi, czy innej opcji, na której moglibyśmy mieć własny serwer? Co jeżeli zastosowanie dodatkowego serwera jest po prostu nieadekwatne do naszego celu? W tym artykule postaram się: omówić najpopularniejsze rozwiązania pokazać jak uruchomić serwer www ESP32 stworzyć prostą stronę www do naszych zadań wykonać interakcje strona-ESP w postaci: kontroli portu GPIO wyświetlanie wyniku pomiaru z ADC pobieranie pliku z pamięci ESP/karty SD Ten artykuł bierze udział w naszym konkursie! 🔥 Na zwycięzców czekają karty podarunkowe Allegro, m.in.: 2000 zł, 1000 zł i 500 zł. Potrafisz napisać podobny poradnik? Opublikuj go na forum i zgłoś się do konkursu! Czekamy na ciekawe teksty związane z elektroniką i programowaniem. Sprawdź szczegóły » Wszystkie powyższe rzeczy postaram się zobrazować w jak najprostszy i przejrzysty sposób. Poruszany temat jest niewątpliwie bardzo złożony i niestety nie jest możliwe aby wszystkie informacje zawrzeć w jednym artykule. Temat wymaga zarówno znajomość obsługi samego ESP, HTML, JavaScriptu czy też CSS, zaś znajomość protokołów sieciowych również byłaby mile widziana. Tutaj będą jedynie ukazane podstawy jak to wszystko ze sobą połączyć. Pokazane metody z pewnością nie będą należeć do najbardziej optymalnych rozwiązań, mają jedynie na celu ukazanie koncepcji i zachęcenia do dalszej analizy tego zagadnienia. Wszystkie kody będą skomentowane. W treści będę również odsyłał do dodatkowych materiałów, które dokładniej opisują poszczególne zagadnienia oraz tam gdzie można zdobyć więcej wartościowych informacji. Ale w jakim celu? Część z osób może zadać pytanie po co uruchamiać serwer na ESP, wiąże się to z dużym poborem energii, pomiary najlepiej z wielu czujników wysyłać w jedno miejsce, to dużo pracy itd. Inni zaś, od razu stwierdzą, że to jest to czego oni potrzebują. Jako że nie widzę większego sensu pisania długich wywodów na temat dlaczego warto, dlaczego nie, kiedy tak, kiedy nie. Przedstawię poniżej dwa praktyczne przykłady i możliwości takich realizacji które pozwolą samemu ocenić te aspekty. Pierwszym przykładem jest zdalny interfejs drukarki 3D. Dzięki niemu możemy zdalnie uruchomić drukarkę, wysyłać do niej pliki, uruchamiać druk, obserwować parametry druku, dostosowywać je, konfigurować drukarkę i wiele innych. Zostało to zrealizowane na ESP8266 i projekt jest dostępny pod tymi linkami Duet WiFi Server oraz Duet Web Control Drugi przykład jest to interfejs do sterowania lampką/oświetleniem LED. Z poziomu przeglądarki możemy ustawiać różne efekty świetlne, barwę, jasność, konfigurować urządzenie. Więcej o tym projekcie można dowiedzieć się tutaj Aircookie WLED Co będzie nam potrzebne? Podstawowa znajomość platformy ESP oraz programowania w Arduino w tym obsługa SPIFFS lub kart SD Płytka z ESP32 (wszystko powinno być kompatybilne z ESP8266) Zainstalowana biblioteka Async Web Server Dodatkowo: Znajomość języka angielskiego – dodatkowe odnośniki Płytka stykowa, potencjometr, fotorezystor czy cokolwiek sobie wymyślicie aby urozmaicić sobie temat 🙂 Zrozumienie tematu również ułatwi znajomość podstaw HTML oraz JavaScriptu. Jako że wymagane są już podstawowe umiejętności odnośnie obsługi ESP oraz Arduino, pominę kwestie instalacji biblioteki, omówienia zagadnień struktury programu czy też obsługi peryferiów. Z czym to się je? Podstawowa koncepcja naszego projektu opiera się na tym, iż na ESP uruchamiamy serwer, który na zapytanie klienta (klient czyli nas - naszej przeglądarki) zwraca odpowiednie pliki lub wykonuje pewne operacje. W ten sposób możemy poprosić ESP aby zwrócił nam plik HTML zawierający naszą stronę, przeglądarka ją odbierze, a my będziemy się mogli cieszyć widokiem naszej witryny. W ten sposób możemy wyróżnić pierwszy ze sposobów interakcji z naszym ESP, czyli z wykorzystaniem metod HTTP. W uproszczeniu, metody są to pewnego rodzaju „komunikaty” czego oczekujemy od naszego serwera. Przykładowo, wysyłamy zapytanie „GET” – oznacza że chcemy coś od serwera i ma on nam to dać, zapytanie „POST” – oznacza że chcemy coś dać od siebie. Każde nasze zapytanie będzie skutkować odpowiedzią (lub jej brakiem 🙂 ). Odpowiedzi posiadają swoje kody, które mają różne znaczenie – to daje nam dodatkowe możliwości interakcji. Wiedząc co oznacza dany kod możemy przykładowo stwierdzać czy dostaliśmy odpowiedź, czy wyświetlić jakiś błąd, lub stwierdzić że coś nie istnieje (każdemu znane 404). Najprostszym użyciem tych zapytań jest po prostu wykorzystanie odpowiednich struktur w HTML z stosownymi atrybutami. Metodę „POST” możemy wykorzystać przy tworzeniu formularza. Wadą tego rozwiązania jest fakt tego iż będzie to skutkować przeładowaniem strony przy każdej tego typu akcji. Inną opcją jest wykorzystanie pomocy Java Scriptu który będzie służył jako nasza „trzecia ręka” wykonująca te operacje w tle. Rozwiązanie to nazywa się AJAX (z angielskiego Asynchronus JavaScript and XML) i na nim się głównie skupimy w tym artykule. Drugą powszechną opcją jest skorzystanie z WebSocket. Jest to sposób ciągłej komunikacji między klientem a serwerem. Polega ona na nawiązaniu „kontaktu” z serwerem i zapytaniem go czy jest chętny na „pogawędkę”. Metoda ta idealnie się nadaje do wymiany ciągów informacji na żywo. Przykładowo potrzebujemy ciągłego odczytu z przetwornika ADC – można stwierdzić „wirtualny port szeregowy”. Oczywiście moglibyśmy zrealizować to samo zadanie z wykorzystaniem wcześniej wspomnianych metod, ale wykorzystanie metody HTTP wiąże się z całym procesem, wysłania zapytania, otrzymania odpowiedzi, co w skali procesora trwa wieki (np. jedno zapytanie kilkadziesiąt – set ms). Tutaj nie mamy tego problemu, gdyż nasze połączenie ciągle trwa i sobie rozmawiamy. W przypadku gdy nie zależy nam na ciągłym podglądzie (np. odświeżanie informacji raz na pół minuty) możemy spokojnie zadowolić się wykorzystaniem AJAX i metod HTTP. Ponadto warto nadmienić iż korzystanie z WebSocketów jest zarówno korzystne dla serwera jak i klienta ze względu na minimalną ilość przesyłanych danych (ograniczenie tego co jest nam w rzeczywistości zbędne). No to zaczynamy! Na wstępie warto nadmienić że pracujemy wewnątrz sieci lokalnej. Jeżeli połączymy się z naszym WiFi, inne urządzenia z tej samej sieci będą miały dostęp do naszego serwera. Bez stosownej konfiguracji sieci (jak i czasem ograniczeń narzuconych przez naszego dostawcę internetowego) nie będziemy mieć dostępu do naszego urządzenia z dowolnego miejsca na świecie. Na początek zacznijmy od tego czym jest nasza biblioteka i dlaczego ona. Otóż umożliwia ona komunikację asynchroniczną, co pozwala nam na posiadanie więcej niż jednego połączenia w danej chwili i działa poza pętlą loop(). Aby się nie rozpisywać na temat innych zalet i możliwości zainteresowanych dogłębną analizą odeślę tutaj. Uwaga dla użytkowników ESP8266! Biblioteka od obsługi WiFi definiuje się jako: #include <ESP8266WiFi.h> Zaś obsługa SPIFFS: #include <FS.h> Ponadto w poniższej pętli while() potrzebne jest opóźnienie, aby zapobiec uruchamianiu się watchdoga while (WiFi.status() != WL_CONNECTED){ delay(1000); } Powyższe uwagi będą zawarte w komentarzach kodów. Uruchamiamy serwer! #include <Arduino.h> #include <WiFi.h> //ESP8266 //#include <ESP8266WiFi.h> #include <SPIFFS.h> //ESP8266 //#include <FS.h> #include <ESPAsyncWebServer.h> #define SSID "nazwa sieci" #define PASS "hasło sieci" AsyncWebServer serwer(80); //utwórzmy obiekt serwera na porcie 80 void setup() { Serial.begin(115200); //zainicjujmy port szeregowy WiFi.begin(SSID, PASS); //połącz z naszą siecią wifi while (WiFi.status() != WL_CONNECTED){ //poczekajmy aż ESP połączy się z naszą seicią //delay(1000); //dla ESP8266 } Serial.printf("\nAdres IP:"); Serial.println(WiFi.localIP()); //wypisz adres IP naszego ESP przez port szeregowy //tutaj odbywa sie obsługa zapytań serwer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/" typu GET, request->send_P(200, "text/plain", "Witaj! :)"); //odpowiedz mu kodem 200, danymi tekstowymi, o treści "Witaj! :)" }); serwer.begin(); //zainicjujmy nasz serwer } void loop() { } W powyższym kodzie widzimy następujące etapy, łączymy się z naszą siecią WiFi, ESP zwraca nam przez port szeregowy swój adres IP w naszej sieci. Będzie on nam potrzebny do wpisania w pasku przeglądarki w celu połączenia się z serwerem. Następnie tworzymy funkcję która obsługuje konkretne zapytania, w naszym przypadku po otrzymaniu zapytania GET pod adresem „/” – można to określić jako „folder główny” serwera, tak samo jak w komputerze mamy dysk np. „D:\” – odeśle klientowi odpowiedź o kodzie 200 (oznacza to „ok” – więcej o kodach tutaj) i zawartości typu tekstowej (są to typy MIME, mówią one przeglądarce co jej chcemy przekazać – więcej o typach MIME tutaj). Rezultatem, po wpisaniu w pasek przeglądarki adresu IP naszego ESP, jest strona. Tworzymy prostą stronę Jako że celem tutaj nie jest nauka HTML czy też CSS, ograniczyłem stronę do absolutnego minimum, potrzebnego do naszych zabaw. Tutaj też, odeślę do wartościowego źródła gdzie można znaleźć wiele wartościowych informacji odnośnie HTML, JavaScript, CSS oraz innych. Nasza strona będzie się składać z pola tekstowego gdzie wyświetlimy wartość odczytaną z ADC, dwóch przycisków do włączania i wyłączania diody oraz przycisku pobierania pliku z naszego ESP. <!DOCTYPE html> <html> <head> <title>Strona</title> <meta charset="UTF-8"/> </head> <body> <p id="pomiar">Wartość:</p> <button id="on">Włącz</button> <button id="off">Wyłącz</button><br> <button id="download">Pobierz obrazek</button> <script> </script> </body> </html> Kluczowe podczas tworzenia takiej strony jest nadawanie unikalnego ID każdemu elementowi, ułatwi to współpracę z JavaScriptem. Gdy już mamy przygotowaną stronę musimy ją wgrać do SPIFFS. Stąd będziemy wysyłać plik HTML jako odpowiedź dla klienta. Analogicznie można te pliki wgrać na kartę pamięci i z delikatną modyfikacją kodu serwować z niej pliki. #include <Arduino.h> #include <WiFi.h> //ESP8266 //#include <ESP8266WiFi.h> #include <SPIFFS.h> //ESP8266 //#include <FS.h> #include <SPIFFS.h> #include <ESPAsyncWebServer.h> #define SSID "nazwa sieci" #define PASS "hasło sieci" AsyncWebServer serwer(80); //utwórzmy obiekt serwera na porcie 80 void setup() { Serial.begin(115200); //zainicjujmy port szeregowy SPIFFS.begin(); //zainicjujmy system plików WiFi.begin(SSID, PASS); //połącz z naszą siecią wifi while (WiFi.status() != WL_CONNECTED){ //poczekajmy aż ESP połączy się z naszą seicią //delay(1000); //dla ESP8266 } Serial.printf("\nAdres IP:"); Serial.println(WiFi.localIP()); //wypisz adres IP naszego ESP przez port szeregowy //tutaj odbywa sie obsługa zapytań serwer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytania pod adresem "/" typu GET, request->send(SPIFFS, "/index.html", "text/html"); //odpowiedz plikiem index.html z SPIFFS (można to zmienić na kartę SD) //zawierającym naszą stronę będącą plikem tekstowym HTML }); serwer.begin(); //zainicjujmy nasz serwer } void loop() { } Teraz po wpisaniu adresu IP naszej strony w pasek przeglądarki ukaże się nam prosta strona. Pora na działanie! Na pierwszy ogień weźmiemy obsługę LED. W tym celu konieczne będzie dorzucenie trochę JavaScriptu do naszej strony document.getElementById("on").onclick = function () { //po nacisinięciu elementu o ID "on" const zapytanie = new XMLHttpRequest(); //wyślijmy zapytanie GET, pod adresem /on zapytanie.open("GET", "/on"); zapytanie.send(); }; document.getElementById("off").onclick = function () { //po nacisinięciu elementu o ID "off" const zapytanie = new XMLHttpRequest(); //wyślijmy zapytanie GET, pod adresem /off zapytanie.open("GET", "/off"); zapytanie.send(); }; Kod ten sprawdza czy któryś z przycisków został naciśnięty, a jeżeli został wysyła stosowne zapytanie do naszego serwera. Finalnie kod strony przedstawia się jak poniżej. <!DOCTYPE html> <html> <head> <title>Strona</title> <meta charset="UTF-8"/> </head> <body> <p id="pomiar">Wartość:</p> <button id="on">Włącz</button> <button id="off">Wyłącz</button><br> <button id="download">Pobierz obrazek</button> <script> document.getElementById("on").onclick = function () { //po nacisinięciu elementu o ID "on" const zapytanie = new XMLHttpRequest(); //wyślijmy zapytanie GET, pod adresem /on zapytanie.open("GET", "/on"); zapytanie.send(); }; document.getElementById("off").onclick = function () { //po nacisinięciu elementu o ID "off" const zapytanie = new XMLHttpRequest(); //wyślijmy zapytanie GET, pod adresem /off zapytanie.open("GET", "/off"); zapytanie.send(); }; </script> </body> </html> Ponadto w sekcji setup() naszego kodu ESP musimy dodać obsługę nowo powstałych zapytań. serwer.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/on" typu GET, digitalWrite(LED, LOW); //zapal diodę request->send(200); //odeślij odpowiedź z kodem 200 OK }); serwer.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/off" typu GET, digitalWrite(LED, HIGH); //zgaś diodę request->send(200); //odeślij odpowiedź z kodem 200 OK }); Co daje nam w rezultacie kod jak poniżej. Ważne aby wszystkie zapytania były przed funkcją serwer.begin() #include <Arduino.h> #include <WiFi.h> //ESP8266 //#include <ESP8266WiFi.h> #include <SPIFFS.h> //ESP8266 //#include <FS.h> #include <SPIFFS.h> #include <ESPAsyncWebServer.h> #define SSID "nazwa sieci" //nazwa sieci #define PASS "haslo sieci" //hasło sieci #define LED 22 //numer pinu gdzie mamy podłączoną diodę AsyncWebServer serwer(80); //utwórzmy obiekt serwera na porcie 80 void setup() { Serial.begin(115200); //zainicjujmy port szeregowy SPIFFS.begin(); //zainicjujmy system plików pinMode(LED, OUTPUT); //ustawmy naszeg pin jako wyjście WiFi.begin(SSID, PASS); //połącz z naszą siecią wifi while (WiFi.status() != WL_CONNECTED){ //poczekajmy aż ESP połączy się z naszą seicią //delay(1000); //dla ESP8266 } Serial.printf("\nAdres IP:"); Serial.println(WiFi.localIP()); //wypisz adres IP naszego ESP przez port szeregowy //tutaj odbywa sie obsługa zapytań serwer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytania pod adresem "/" typu GET, request->send(SPIFFS, "/index.html", "text/html"); //odpowiedz plikiem index.html z SPIFFS (można to zmienić na kartę SD) //zawierającym naszą stronę będącą plikem tekstowym HTML }); serwer.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/on" typu GET, digitalWrite(LED, LOW); //zapal diodę request->send(200); //odeślij odpowiedź z kodem 200 OK }); serwer.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/off" typu GET, digitalWrite(LED, HIGH); //zgaś diodę request->send(200); //odeślij odpowiedź z kodem 200 OK }); serwer.begin(); //zainicjujmy nasz serwer } void loop() { } Teraz możemy zaobserwować działanie naszego kodu. Odczyt ADC Teraz pora na odczyt wartości z przetwornika analogowo-cyfrowego. Tym razem nasz skrypt będzie automatycznie, z pewnym interwałem czasowym (500ms), wysyłał zapytanie do serwera. setInterval(function () { const zapytanie = new XMLHttpRequest(); zapytanie.open("GET", "/adc"); zapytanie.send(); zapytanie.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { document.getElementById("pomiar").innerHTML = "Pomiar:" + this.responseText; } }; }, 500); Powyższy fragment powinien znaleźć się w pliku .html w sekcji <script>, tak jak poprzednio. Serwer w odpowiedzi będzie zwracał wartość z ADC w postaci tekstu, zaś JavaScript, w tle będzie nam podmieniał wartości na stronie uzyskane w odpowiedzi od serwera, bez konieczności przeładowania. W kodzie ESP wystarczy że dodamy taki fragment kodu do sekcji setup() przed funkcją serwer.begin(). serwer.on("/adc", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/off" typu GET, String wartosc = String(analogRead(ADC)); //wykonaj pomiar ADC i zapisz do Stringa request->send(200, "text/plain", wartosc); //odeślij odpowiedź z kodem 200 OK i odczytem z wartością }); Na powyższej animacji widać jak zmieniają się wartości. W konsoli przeglądarki (przycisk F12 powinien nam ją uruchomić w większości przeglądarek) można obserwować wszystkie zapytania wymieniane między klientem a serwerem. Jest to bardzo przydatne narzędzie do „debugowania” kiedy coś nie chce do końca z nami współpracować. Powyższe zadania możemy zrealizować również w inny sposób, poprzez wywołanie naszej funkcji z poziomu funkcji obsługi zapytań. Przykład obsługi ADC przedstawiałby się w następujący sposób. #include <Arduino.h> #include <WiFi.h> //ESP8266 //#include <ESP8266WiFi.h> #include <SPIFFS.h> //ESP8266 //#include <FS.h> #include <SPIFFS.h> #include <ESPAsyncWebServer.h> #define SSID "nazwa sieci" //nazwa sieci #define PASS "hasło sieci" //hasło sieci #define ADC 34 //numer pinu potencjometru AsyncWebServer serwer(80); //utwórzmy obiekt serwera na porcie 80 String odczyt_ADC() { return String(analogRead(ADC)); } void setup() { Serial.begin(115200); //zainicjujmy port szeregowy SPIFFS.begin(); //zainicjujmy system plików pinMode(LED, OUTPUT); //ustawmy naszeg pin jako wyjście WiFi.begin(SSID, PASS); //połącz z naszą siecią wifi while (WiFi.status() != WL_CONNECTED){ //poczekajmy aż ESP połączy się z naszą seicią //delay(1000); //dla ESP8266 } Serial.printf("\nAdres IP:"); Serial.println(WiFi.localIP()); //wypisz adres IP naszego ESP przez port szeregowy //tutaj odbywa sie obsługa zapytań serwer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytania pod adresem "/" typu GET, request->send(SPIFFS, "/index.html", "text/html"); //odpowiedz plikiem index.html z SPIFFS (można to zmienić na kartę SD) //zawierającym naszą stronę będącą plikem tekstowym HTML }); serwer.on("/adc", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/off" typu GET, request->send(200, "text/plain", odczyt_ADC()); //odeślij odpowiedź z kodem 200 OK i odczytem z wartością }); serwer.begin(); //zainicjujmy nasz serwer } void loop() { } Pobieranie pliku Na koniec zajmiemy się pobieraniem pliku z naszego serwera. W celu pokazania jak korzystać z typów MIME przedstawię jak pobrać obrazek z naszego prostego serwera. Do naszej ESP pamięci wgramy poniższy obrazek. W tym celu musimy dodać fragment skryptu do naszej strony. document.getElementById("download").onclick = function () { //po nacisinięciu elementu o ID "download" location.href = "/download"; //przekieruj pod /download }; Podobnie jak uprzednio dodajemy go do naszej sekcji <script></script>. Działa on podobnie jak poprzednie włączanie i wyłączanie diody, lecz w normalnej sytuacji, takie działanie spowodowałoby przekierowanie pod ten adres /download. Ponieważ w kodzie programu ustawimy atrybut pobierania. Będzie to skutkowało wyskoczeniem okna pobierania. serwer.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/off" typu GET, request->send(SPIFFS, "/Lenna.png", "image/png", true); //odeślij odpowiedź w postaci pliku png o nazwie obrazek.png z SPIFFS i umożliwij pobranie (true) }); Jak widzimy musimy wskazać skąd nasz plik ma zostać pobrany (SPIFFS, może to być również karta SD), następnie wskazujemy dokładną lokalizację naszego pliku, jego rodzaj (MIME) oraz ustawiamy atrybut pobierania jako true. W efekcie uzyskujemy pobieranie naszego pliku. Zachęcam do sprawdzenia rezultatu po zmienieniu atrybutu pobierania na false. Poniżej zamieszam finalne wersje programu Arduino oraz kodu strony HTML. #include <Arduino.h> #include <WiFi.h> //ESP8266 //#include <ESP8266WiFi.h> #include <SPIFFS.h> //ESP8266 //#include <FS.h> #include <SPIFFS.h> #include <ESPAsyncWebServer.h> #define SSID "nazwa sieci" //nazwa sieci #define PASS "hasło sieci" //hasło sieci #define LED 22 //numer pinu gdzie mamy podłączoną diodę #define ADC 34 //numer pinu potencjometru AsyncWebServer serwer(80); //utwórzmy obiekt serwera na porcie 80 void setup() { Serial.begin(115200); //zainicjujmy port szeregowy SPIFFS.begin(); //zainicjujmy system plików pinMode(LED, OUTPUT); //ustawmy naszeg pin jako wyjście WiFi.begin(SSID, PASS); //połącz z naszą siecią wifi while (WiFi.status() != WL_CONNECTED){ //poczekajmy aż ESP połączy się z naszą seicią //delay(1000); //dla ESP8266 } Serial.printf("\nAdres IP:"); Serial.println(WiFi.localIP()); //wypisz adres IP naszego ESP przez port szeregowy //tutaj odbywa sie obsługa zapytań serwer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytania pod adresem "/" typu GET, request->send(SPIFFS, "/index.html", "text/html"); //odpowiedz plikiem index.html z SPIFFS (można to zmienić na kartę SD) //zawierającym naszą stronę będącą plikem tekstowym HTML }); serwer.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/on" typu GET, digitalWrite(LED, LOW); //zapal diodę request->send(200); //odeślij odpowiedź z kodem 200 OK }); serwer.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/off" typu GET, digitalWrite(LED, HIGH); //zgaś diodę request->send(200); //odeślij odpowiedź z kodem 200 OK }); serwer.on("/adc", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/off" typu GET, String wartosc = String(analogRead(ADC)); //wykonaj pomiar ADC i zapisz do Stringa request->send(200, "text/plain", wartosc); //odeślij odpowiedź z kodem 200 OK i odczytem z wartością }); serwer.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){ //na otrzymane od klienta zapytanie pod adresem "/off" typu GET, request->send(SPIFFS, "/Lenna.png", "image/png", false); //odeślij odpowiedź w postaci pliku png o nazwie obrazek.png z SPIFFS i umożliwij pobranie (true) }); serwer.begin(); //zainicjujmy nasz serwer } void loop() { } <!DOCTYPE html> <html> <head> <title>Strona</title> <meta charset="UTF-8" /> </head> <body> <p id="pomiar">Wartość:</p> <button id="on">Włącz</button> <button id="off">Wyłącz</button><br> <button id="download">Pobierz obrazek</button> <script> document.getElementById("on").onclick = function () { //po nacisinięciu elementu o ID "on" const zapytanie = new XMLHttpRequest(); //wyślijmy zapytanie GET, pod adresem /on zapytanie.open("GET", "/on"); zapytanie.send(); }; document.getElementById("off").onclick = function () { //po nacisinięciu elementu o ID "on" const zapytanie = new XMLHttpRequest(); //wyślijmy zapytanie GET, pod adresem /off zapytanie.open("GET", "/off"); zapytanie.send(); }; setInterval(function () { const zapytanie = new XMLHttpRequest(); //wyślijmy zapytanie jak poprzednio zapytanie.open("GET", "/adc"); zapytanie.send(); zapytanie.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { document.getElementById("pomiar").innerHTML = "Wartość:" + this.responseText; } }; }, 500); document.getElementById("download").onclick = function () { //po nacisinięciu elementu o ID "download" location.href = "/download"; }; </script> </body> </html> Podsumowanie Bardzo się cieszę że dotrwałeś do tego momentu! Jak wspomniałem na początku, przedstawione rozwiązania są najprostszymi, niekoniecznie zgodnymi ze sztuką rozwiązaniami. Starałem się w kodach programów ograniczyć wszystkie zbędne fragmenty i uprościć do absolutnego minimum – czego często brakuje w poradnikach z internetu, co skutkuje utrudnioną analizą działania programu. Pokazane sposoby mają na celu jedynie wprowadzenie do koncepcji tematu, zachęcenia do pracy oraz poznawania możliwości rozwiązań sieciowych, o których można by było pisać całe książki. Zarówno komunikacja z wykorzystaniem Websocketów czy tworzenie samej strony którą widzi klient – czyli strony internetowej – mogłaby zająć czas na oddzielne artykuły. W drugiej części artykułu omówię w teoretyczny sposób (bez gotowych rozwiązań programowych) jak z wykorzystaniem ESP oraz dostępnych technologii i bibliotek rozwiać takie problemy jak: konfigurowanie urządzenia z poziomu przeglądarki przeglądanie i zarządzanie plikami w pamięci ESP provisioning i co to oraz po co to właściwie jest M. S.
  13. Hej, zwracam się do Was z prośbą i radą jaki protokół do komunikacji miedzy różnymi mikrokontrolerami najlepiej użyć do mojego wymyślonego projektu. To zaczynając od pomysłu. Chciałem stworzyć kontroler główny, który będzie miał komunikację 2 kierunkową z urządzeniami podłączonymi do niego: mniej więcej tak ja na tym schemacie: Z Założenia chcę, aby urządzenia łączyły się ze sobą kablowo najprawdopodobniej skrętką 8 żyłową(2 lub 4 przewody chciałbym poświęcić na zasilania, reszta na komunikację) a odległość maksymalna to będzie 20m, Dane przesyłane miedzy nimi nie będą duże( najprawdopodobniej string o długości max 30 znaków lub char do identyfikacji typu wiadomości i int16) a częstotliwość komunikacji raz na 1s z każdym urządzeniem wystarczy. Chciałbym także aby te podłączenia można było robić w trakcie używania urządzenia a ich wykrywanie było na zasadzie "do portu 3 zostało coś podłączone" i po przez różnego rodzaju wiadomości urządzanie będzie rozpoznawało z czym konkretnie się połączył. Dodatkowo chciałbym aby można było podłączyć różne mikrokontrolery, takie jak STM32, ESP oraz Arduino. Jest Modbus, SPI, I2C, CAN, UART itd... Ale co najlepiej do takiego zastosowania by się nadało? Wiem, że każdy wybór ma swoje plusy i minusy i zdaję sobie sprawę, że muszę pójść na jakieś kompromisy. Moim wstępnym pomysłem było wykorzystanie do tego RS-485. Tylko nie miałem z nim nigdy styczności i nie jestem przekonany, że się sprawdzi. Dlatego chcę waszej opinii i porady, co byście do takiego zastosowania użyli, a może już ktoś robił coś podobnego i ma w tym doświadczenie.
  14. Wczoraj zacząłem coś tam bazgrać po półtora miesiąca przerwy i chcąc użyć wskaźnika jako argument funkcji napotkałem problem braku inkrementacji wartości na którą wskazuje ten wskaźnik... pomyślałem sobie że być może ja coś źle zapamiętałem lub ESP32 nie obsługuje takiego wyrażenia, no ale raz dwa do neta zajrzałem i wychodzi że wszystko jest ok składniowo, na pro mini taki sam problem... ktoś wie czemu? int x; fun(&x); void fun(int *z) { *z++; Serial.print(x); } Powyższy kod daję zero... natomiast takie coś.. *z += 1; daje już oczekiwany rezultat...
  15. https://botland.com.pl/wyswietlacze-do-arduino/4464-wyswietlacz-dotykowy-lcd-tft-rev-21-28-320x240px-spi-z-czytnikiem-microsd-shield-dla-arduino-waveshare-10684-5904422352608.html?fbclid=IwAR2Hht_LptyxYgvWfRCcs2hXsaxTBfCIVZZ_2bvxIhDw3aLOmWfBDs7vRUw Witam, Chciałbym zapytać czy ktoś może pracował z tym wyświetlaczem i podpinał go do ESP 32? Bo nie wiem czy są gotowe biblioteki współpracujące z tym mikrokontrolerem a wyświetlaczem, (które działają) Ewentualnie czy ktoś, może mi podpowiedzieć jakieś dostępne alternatywy bo na ekranie dotykowym mi nie zależy, tylko nie na wielkości.
  16. Dzisiaj znów coś software-only: biblioteczka do prostej komunikacji UDP, taka po prostu konsola udp. Działa na obu ESP. Na pececie do komunikacji można użyć netcata (Linux, cygwin, pewnie Mac też), załączonego programu ardumon.py (Linux), i prawdopodobnie Ncat (Windows, nie mam jak sprawdzić). Biblioteczka jeszcze nie skończona, ale obiecałem koledze @SOYER że wrzucę 🙂 Można zacząć testować ESPUdpConsole.zip - feedback mile widziany.
  17. Swego czasu postanowiłem - dla oszczędności kasy i miejsca w obudowie - przerzucić się na proste moduły (typu ESP32-WROOM lub ESP12E). Na pierwszej doświadczalnej płytce miałem wszystkie elementy potrzebne do podłączenia konwertera USB-UART, ale w docelowych urządzeniach (np. czytak) absolutnie nie były one potrzebne. Postanowiłem stworzyć sobie taki własny pseudo-standard gniazda programowania i zrobić przejściówkę do popularnego konwertera HW-417. Nie będę się za dużo rozpisywał, napiszę tylko kilka rzeczy: Schemat całości to po prostu fragment ESP32 Dev Kit. Układ sprawdzony, działa zarówno z ESP32 (WROOM, WROVER) jak i ESP8266 (ESP-12E). Nie próbowałem robić żadnej specjalnej płytki, użyłem kawałka płytki uniwersalnej i części wyciągniętych z szuflady. Gniazdo programowania ma dodatkowy pin 3.3V. W tej chwili nie jest nigdzie podłączony, ale w planach mam przeróbkę płytki tak, aby można było podłączyć się albo do +5V z USB, albo do zewnętrznego zasilacza. Na zdjęciu widać, że wtyczka programatora jest ośmio- a nie sześciopinowa. Po prostu czytak ma dwa dodatkowe piny przeznaczone do podłączenia +5V do ładowania akumulatora (i bardzo się cieszę że to przewidziałem, bo z modułu ładowarki odpadło mi gniazdo USB). A ośmio[inowa żeńska wtyczka pasuje do sześciopinowego gniazda. Gniazdo do podłączenia ma 7 pinów, mimo iż sam konwerter ma sześć. Siódmy pin służy do podłączenia sygnału RTS. Niestety - wersja esptool-ftdi umożliwiająca wykorzystanie pinów DTR/CTS zamiast DTR/RTS nie jest rozwijana, a jakoś nie bardzo miałem czas żeby sprawdzić czy da się jakoś połączyć kod aktualnej wersji (CTS/RTS) z taką trochę zapomnianą gałęzią 😞 Zdjęcie kiedyś pokazywałem, ale dla przypomnienia jeszcze raz (na zdjęciu widać przewód łączący dolutowany do HW-417 pin RTS z przejściówka). Przejściówka sprawdza się zarówno przy programowaniu ESP32, jak i ESP8266. Ponieważ przewidziana jest do współpracy z esptool - powinna działać z Arduino IDE, PlatformIO jak i różnymi wynalazkami (jak mój "pyrduino"). Przyciski RESET i BOOT są tak na wszelki wypadek - esptool i tak steruje sygnałami RTS i DTR potrzebnymi do zresetowania płytki i/lub przejścia w stan uploadu.
  18. - brakowało mi zawsze przy lutowaniu podgrzewacza oraz urządzenia do lutowania amatorskiego w technologii rozpływowej. - dopiero po pojawieniu się artykułu na temat użycia Uyue 946 do budowy amatorskiego podgrzewacza zdecydowałem się za to zabrać. - na razie zmontowałem układ do podania zadanej temperatury, czyli taki mały profile dla lutowania ołowiowego (PB) oraz bezołowiowego (LF). - zrzuty z programu poniżej. - w zasadzie w zakupionym Uyue 946 są wszystkie elementy, pozostało tylko wyrzucić użyty procesor i dołożyć esp32 Lolin 32 oraz wyświetlacz OLED 2.4". - długo się zastanawiałem czy raczej nie kupić MHP30 ale on nie ma profili lutowania i pole 30 x 30 mm jest zbyt małe do prac. - teraz czeka mnie dobranie parametrów do kontrolera PDI i określenie wydajności temperaturowej Uyue, do roboty. - przepraszam za jakość zrzutów ale z programu dostaje *.xbm i muszę konwertowac na *.jpg.
  19. Jakiś czas temu zakupiłem sobie ESP32 CAM, niestety nie umiałem dla niej znaleźć jakiegoś sensownego zastosowania. Przeleżała z pół roku a może i więcej, aż wpadłem na pomysł zrobienia foto-pułapki. I tak oto powstała: Po mojej posiadłości często biegają dzikie zwierzęta takie jak: sarny, bażanty, dziki i zające. Te ostatnie to raczej szkodniki ale lecimy z tematem dalej. Założenia: Zapis zdjęć na karcie SD Wysyłka zdjęć na FTP Wysyłka zdjęć na maila jakiś czujnik temperatury praca możliwie jak najdłużej z jednej baterii wspomaganej panelem PV Po ogarnięciu softu na biurku podłączeniu czujnika PIR wszystko ładnie działało. Za zasilanie odpowiada jedno ogniwo 18650, przetwornica podnosząca napięcie do 5V i mały panel PV 6V 167mA. Jak widać powyżej kamera jest przylepiona klejem dwuskładnikowym, tak by uniknąć uszkodzenia tasiemki. Wszystko zostało umieszczone w obudowie po NanoStation Loco M5. Która została dostosowana do zamontowania panelu PV, czujnika PIR oraz kamery. Poniżej etap pasowania elementów. Został również wydrukowany daszek oraz uchwyty dla szyby która osłania kamerę od deszczu. Obudowa Została dodatkowo pomalowana na czarno - ale chyba będę jej robić jakieś malowanie taktyczne, lub pójdzie w ruch “termoglut” i trzcina żeby się lepiej wtapiała w otoczenie. Pierwsze wyjście w teren i klapa, wszystkie zdjęcia były przejaśnione. Po kilku próbach okazało się że kamera potrzebuje 2s! aby dostosować czas ekspozycji, (lekka tragedia bo przy zajączkach to już go może dawno nie być w kadrze) oczywiście w warsztacie wszystko działało jak należy. Następnym nietrafionym pomysłem okazało się wysyłanie zdjęć na maila, trwa to stosunkowo długo a co za tym idzie zużycie energii jest większe, co doprowadziło do rozładowania baterii po 2 dniach. Konieczne było zrezygnowanie z wysyłki zdjęć na maila. W tej chwili kamera działa bez ładowania już 5 dni. Przykładowe zdjęcia z kamery poniżej: Trapi mnie jeszcze jeden problem mianowicie jeśli na zdjęciu jest więcej szczegółów np: cały kadr trzciny lub trawy, to obraz jest obcinany tak około 100-200px z dołu. Nie jest to chyba problem buforu w ESP bo przy kompresji ustawionej w sofcie na 10 zdjęcia zajmują 384KB jeśli zwiększę kompresje zdjęcia zajmują mniej a obraz i tak jest obcinany. Oprócz zdjęć wyzwalanych czujnikiem ruchu, procesor budzi się co 30 min wykonuje zdjęcie i wysyła je na FTP. To aby mieć pewność że bateria nie uległa rozładowaniu. A i jest jeszcze nieszczęsny czujnik temperatury DS18B20, nie było łatwo go tam upchać bo okazało się że wszystkie piny na płytce są wykorzystywane i jedyny wolny pin który mogę wykorzystać to pin serial RX, co niesie za sobą konieczność wypięcia czujnika w razie chęci przeprogramowania układu. Lista wykorzystanych elementów: ESP32-CAM AI-Thinker Przetwornica step-up 5V wraz z modułem ładowania ogniw 18650 Koszyk na ogniwo 18650 Czujnik PIR Mini panel PV 6V 167mA Antena 2.4 Ghz Podsumowując, działa aczkolwiek widać pewne ograniczenia tego układu chociażby czas jaki kamera potrzebuje na uruchomienie się. Z ciekawostek do ESP32 została podłączona zewnętrzna antena, gdzie przetestowany zasięg to około 200 m :), ale pewnie to też zasługa tego że łącze się do AP który mam wystawiony na dworze. Kodu programu pozwolę sobie w tej chwili nie udostępnić bo mam tam niezły bałagan, a jeszcze staram się uporać z obcinaniem fotek, za jakiś czas na pewno go zamieszczę.
  20. Witam...tak sobie czytam o pamięciach na ESP32 i kilku rzeczy nie jestem pewien...np. mamy funkcję która ma działać w przerwaniu, czyli void IRAM_ATTR fun() Czy wszystkie stałe znajdujące się w tej funkcji muszą być umieszczone w ram'ie? Za pomocą np. DRAM_ATTR ______________________________________ Mamy dane które chcemy zachować po głębokim śnie, więc używamy RTC_DATA_ATTR a jest też inny atrybut który robi to samo (tak mi się wydaje po lekturze) czyli RTC_NOINIT_ATTR czy można to stosować zamiennie? I czy napewno obie wersje robią to samo? Chętnie też poczytam o innych atrybutach często stosowanych i wręcz koniecznych do prawidłowego działania, jeśli się wam cos nasuwa😉
  21. Mocne postanowienie: na podstawie doświadczeń z lalkami zrobić coś, co pozbawione jest błędów poprzednich konstrukcji 🙂 Robot początkowo miał być czarownicą, ale okazało się, że dzieci w przedszkolu negatywnie reagują na postacie tego typu (młodsze się wręcz boją czarownicy czy czarodzieja), dlatego ma być to kolejny Krasnolud. Tym razem nie Tolkienowski mieszkaniec podziemi, a sympatyczny Krasnal mieszkający w lesie, z ładną czerwona czapeczką i miłym dla oka szlafroczkiem. Ponieważ sprawę podwozia mam na razie nie do końca rozwiązaną, postanowiłem, że będzie to stary Krasnolud, jeżdżący w fotelu na kółkach. Takie rozwiązanie zwalnia mnie z konieczności ukrywania kół napędowych, a jednocześnie pozwala na użycie większych i tańszych silników (NEMA 17, kupione po 7 PLN na Allegro). Ponownie chcę użyć akumulatora Parkside (bardzo dobrze sprawdził się w poprzednim Krasnoludzie), tym razem nie kombinuję z EasyDriverami tylko wstawiłem stare dobre A4988. Zostawiam sobie jednak możliwość zastosowania TMC 2209 (o ile eksperyment pokaże, że detekcja zatrzymania silnika będzie działała poprawnie). Na razie mam złożone podwozie: Silniki które kupiłem miały założone zębatki na wałach, dlatego taka a nie inna konstrukcja kół napędowych. Teoretycznie mają półtora ampera na cewkę, na sterownikach ustawiłem na razie 0.7A a i tak są za mocne. Ale dokładniej będę mógł ustawić dopiero na zakończenie. I tu ciekawostka: koła wyposażone w łożyska 6mm miały być osadzone na wspólnej osi. Niestety, okazało się że gwintowany (podobno M6) pręt który mam ma jakieś 5.4mm średnicy i nie bardzo chciał współpracować z łożyskami. Użyłem pojedynczych śrub wymontowanych ze starej kanapy (jak dobrze sobie zostawić takie drobiazgi). A co z resztą? Głowę mam w połowie gotową. Dzisiaj powinny przyjść serwa HD1440A (zależy mi zarówno na wymiarach, jak i najmniejszym możliwym poborze prądu). W sumie jest tu pięć serw: po jednym HD1370A umieszczonych wewnątrz gałki ocznej, jedno do pionowego wspólnego ruchu oczu, jedno do skłonu głowy (uczciwe cięgło a nie jakieś wydumane zębatki) i jedno do obrotu (tym razem przekładnia zębata 1:2, sprawdziła się bardzo dobrze w poprzednich konstrukcjach). Jak tylko uda mi się zamontować serwa wrzucę jakąś ładną fotkę. Ręce - a właściwie ręka, bo tylko prawa ma być w pełni animowana. Zrobiłem bardzo ambitne założenie sześciu stopni swobody, zobaczymy co z tego wyjdzie. Serwa do napędu ręki mam. Kombinuję jeszcze z jakimś wyhamowaniem oscylacji na głównym serwie barkowym, być może uda mi się to osiągnąć programowo tylko musiałbym dodać jakieś sprzężenie zwrotne... no cóż, zobaczymy co z tego wyjdzie. Jeśli nic, zawsze mogę skorzystać ze sprawdzonego rozwiązania (ograniczenie prędkości ruchu serwa). No i oczywiście "drobiazgi": żyroskop/akcelerometr, kamera (do patrzenia na twarz rozmówcy), czujnik odległości (tym razem nie tylko do wykrywania przeszkód ale również do ustalania zbieżności oczu), syntezator mowy i takie tam różności. Zdalne sterowanie na razie poprzez UDP (ESP32 pracujący w trybie AP_STA, czyli z możliwością zarówno podłączenia do domowej sieci WiFi jak i do pracującego w trybie STA sterownika). Pozwala mi to na odłożenie zaprojektowania sterownika na sam koniec i sterowanie na razie prostą aplikacją na pececie. No cóż - sam jestem ciekaw co mi z tego wyjdzie 🙂
  22. - przyszedł czas na dokończenie zeszłorocznego projektu zegarka na RGB ringu z 60 diodami rgb. - projekt zawiera esp32 WEMOS Lolin 32, akumulator Li-Po 400 mAh, czujnik temperatury BME280, czujnik światła BH1750, mp3 odtwarzacz DFPlayer oraz czujnik IR model TSOP31256 , OLED 2.4" SSD1309, WS2812 RGB w kształcie ringu z 60 ledami RGB. - na razie mam wszystko "doklejone" do tarczy zegara analogowego 26 cm i patrzę jak to ustawić aby było optymalnie dla mnie. - czas jest pokazywany na ringu RGB przez pojedyncze piksle , czerwony godzina, zielony minuta, niebieski sekundy, zaznaczone są także znaczniki czasu co 15 minut w kolorze żółtym. - jest jeszcze wahadło w kolorze zielonym biegające od 0 piksla do 59 i z powrotem, czas "obiegu" to 1 sekunda. - jako sterownik IR użyłem popularnego sterownika NEC IR do Car IR. - sterownik IR reguluje głośność muzyki, wybiera katalogi i pliki do odtworzenia, zatrzymuje wahadło, restartuje cały system. - na wyświetlaczu OLED pokazuję czas, numer pliku i katalogu do odtwarzania, wilgotność, temperaturę oraz ciśnienie barometryczne, siłę światła lux. - pętla obsługi RGB pracuje na core1, reszta programu na core 0. - program komunikuje się z serwerem NTP za pośrednictwem Wi-Fi, dwa razy dziennie. - problemy jakie mam obecnie to mruganie diod RGB podczas pracy wahadla oraz zbyt duże świecenie diod RGB w trybie nocnym. - aktualizacja programu nie jest wykonywana w trybie OTA, ponieważ esp32 Lolin 32 ma tylko 4MB flasha a program obecnie zajmuje 1.6MB. - program podaje aktualny czas głosowo co 15 minut, próbki są pobierane z karty SD na DFPlayer. - poniżej zdjęcia z aktualnego stanu prac.
  23. Używam esp32-cam i chciałbym zapisywać dane z czujnika na kartę SD. Niestety, ale gdy wysyłam dane komendą file.println w pętli loop, to albo plik jest pusty, albo plik zawiera dane tylko tak jakby po jednym przejściu pętli.
  24. No cześć, kilka miesięcy wzlotów i upadków, kłótni z żoną i w końcu jest .... ESPoBOT 🙂 Robot gąsienicowy RC z kamerą FPV i chwytakiem. Sterowanie oparte o ESP32-wroom 32D. Zacząłem od Arduino, ale z uwagi na problemy z komunikacją dwustronną NRF24L01, przesiadłem się na ESP32. Napędem są 2 silniki 9Vdc z przekładnią 87:1 na podwoziu gąsienicowym z regulacją prześwitu, kontrolowane przez sterownik oparty o układ TB6612. Prędkość silników regulowana płynnie w zakresie 0-30cm/s (1km/h). Robot wyposażony w chwytak umożliwiający chwycenie detalu, podniesienie/opuszczenie z użyciem 3 serw. Kontrola zaciśnięcia chwytaka zrealizowana poprzez pomiar prądu serwa. Regulacja prędkości serw. Zainstalowana kamera 1200TVL do przekazywania obrazu fpv 5.8GHz na telefon, PC lub wyświetlacz AV. Zasięg nadajnika do 500m. Robot wyposażony w oświetlenie LED RGB. Całość zasilana z akumulatora LiPo 1800mAh 11,1V 20C i zabezpieczona bezpiecznikiem polimerowym 4A. Dodatkowo akumulator zabezpieczony programowo przed rozładowaniem. Komunikacja dwustronna z padem na częstotliwości 2.4GHz (ESP-NOW) i zasięgu do 250m. Pad wyposażony w 2 joysticki, 6 guzików, potencjometr, enkoder oraz wyświetlacz OLED 128x64 do wyświetlania parametrów urządzenia. Zasilany z akumulatora 9V 650mAh USB.
  25. Hej, próbuje wysłać przez kolejkę na FreeRTOS strukturę wraz z rozróżnieniem dwóch tasków wysyłających i jednym odbierającym. Tak wygląda mój kod: #include "queue.h" typedef int taskProfiler; typedef enum { eSender1 = 0, eSender2, }DataSource_t; typedef struct { uint8_t ucValue; DataSource_t eDataSource; }Data_t; static Data_t xStructToSend[2] = { (100, eSender1), (50, eSender2) }; QueueHandle_t xQueue; taskProfiler senderTaskProfiler = 0; taskProfiler receiverTaskProfiler = 0; void setup() { // put your setup code here, to run once: Serial.begin(115200); delay(5000); Serial.println(xStructToSend[1].ucValue); xQueue = xQueueCreate(3, sizeof(Data_t)); xTaskCreate(vSenderTask, "Sender Task 1", 8192, &(xStructToSend[0]), 2, NULL); xTaskCreate(vSenderTask, "Sender Task 2", 8192, &(xStructToSend[1]), 2, NULL); xTaskCreate(vReceiverTask, "Receiver Task", 8192, NULL, 2, NULL); } void vSenderTask(void *pvParameters) { BaseType_t xStatus; const TickType_t xTicksToWait = pdMS_TO_TICKS(100); Data_t xReceivedStructure; memcpy(&xReceivedStructure, &pvParameters, sizeof(pvParameters)); while(1) { xStatus = xQueueSend(xQueue, pvParameters, xTicksToWait); if(xStatus != pdPASS) { Serial.println("Could not send to the Queue"); } Serial.println(xReceivedStructure.ucValue); } } void vReceiverTask(void *pvParameters) { Data_t xReceivedStructure; BaseType_t xStatus; while(1) { xStatus = xQueueReceive(xQueue, &xReceivedStructure, 0); if(xStatus == pdPASS) { if(xReceivedStructure.eDataSource == eSender1) { Serial.print("This is from Sender1: "); Serial.println(xReceivedStructure.ucValue); } else { Serial.print("This is from Sender2: "); Serial.println(xReceivedStructure.ucValue); } } else { Serial.println("Could not receive data from the queue"); } } } void loop() { // put your main code here, to run repeatedly: } W "setup()" linia "Serial.println(xStructToSend[1].ucValue);" zwraca mi wartość 0 chociaż teoretycznie powinna 50. Tak samo dzieje się w tasku wysyłającym w linii "Serial.println(xReceivedStructure.ucValue);". Wyglada jakby od samego początku była zła inicjalizacja wartości zmiennych w wysyłanej strukturze. Sam task Receiver zwraca wartość 152 lub 160. Jaki błąd został popełniony w tym kodzie i w jaki sposób prawidłowo mogę zainicjalizować zmienne w strukturze? Z góry dziękuje za pomoc. Pozdrawiam
×
×
  • 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.