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


TempX

  1. Taki mały projekcik - coś dla bezwzrokowców. Czyli nie tylko dla niewidomych i słabowidzących, ale również dla tych, którzy nie mają ochoty albo możliwości gapienia się na wyświetlacz... Czyli coś w rodzaju wypasionego termometru albo (jak kto woli) mini-stacji pogodowej. Ale zacznę może od genezy projektu. Szukając pewnego sprzętu do domu natrafiłem na osobę poszukującą mówiącego termometru pokojowego. Ktoś tam rzucił jakimiś linkami... z ciekawości zajrzałem. No i oczywiście pierwszy do Altix. Termometr co prawda niedrogi, ale za yi jak zwykle w tej firmie "kłopoty ze stanem magazynowym". Kolejne ceny wyglądały raczej mało zachęcająco... Jako że taki "gadający termometr z prognozą pogody" stanowi integralną część mojego "wygodnego domu" zacząłem zastanawiać się, czy coś podobnego (tylko bez tej "wygodnodomowej" otoczki) mogłoby się komuś przydać. No i po dłuższym zastanowieniu wyszło mi coś takiego: W moim przypadku sprawdza się to idealnie, tak że pewnie znaleźli by się zainteresowani... Przede wszystkim musi być to urządzenie DIY. Z uwagi na możliwości zastosowania różnych podzespołów raczej nie byłoby możliwe zaprojektowanie PCB czy obudowy - poza tym urządzenie powinno być możliwe do zbudowania przez początkującego adepta sztuki elektroniki (z możliwością wsadzenia tego na płytkę stykową włącznie). Dodatkowo wszystkie elementy muszą być dostępne w handlu, a przede wszystkim tanie! Wybrałem ESP32 jako "serce" urządzenia. Powodów było kilka, ale najważniejsze było to, że mam dobrze przetestowany syntezator mowy właśnie na ESP. Również ceny modułów są atrakcyjne. Jednocześnie nie mogę wymagać umiejątności użerania się z wersjami bibliotek (które lubią gryźć się albo z definicją płytki, albo ze sobą). Co prawda źródła programu dla Arduino powinny być dostępne, ale warto zadbać o to, aby ktoś kto nie ma zielonego pojęcia o programowaniu mógł wrzucić soft na płytkę i skonfigurować całość. Tak że wymagana by była równioeż wersja binarna, możliwa do prostego załadowania z pomocą esptool (Linux, Mac) czy FlashTool (Windows). Z wstępnych założeń wyszło mi coś takiego: Trzy typy komunikatów: Najkrótszy to tylko godzina i temperatura. Dłuższy to godzina, data, temperatura oraz dodatkowe parametry zależne od możliwości zastosowanych podzespołów (np. ciśnienie i wilgotność) Najdłuższy to ten sam co dłuższy, ale wzbogacony o dane ściągnięte z Internetu Postanowiłem wykorzystać serwis open-meteo.com. Tak więc zgodnie z możliwościami serwisu dane muszą zawierać bieżące warunki pogodowe oraz skróconą prognozę pogody. Uznałem, że rozwiązanie które mam w domu powinno się sprawdzić - czyli prognoza na dziś i jutro, lub po którejś godzinie na jutro i pojutrze. Konieczna jest też możliwość ustawienia wszystkiego co się da za pomocą terminala serial - po to, aby nie było trzeba robić jakichś zależności w czasie kompilacji. Jeśli chodzi o elektronikę, uznałem, że podstawową płytką będzie ESP32 DevKit. Ma wystarczającą ilość pamięci (zarówno RAM jak i Flash), wszystkie potrzebne interfejsy a co ważniejsze - jest tania i dostępna. Konieczny jest również jakiś wzmacniacz I2S - czyli znów najtańsza opcja: MAX98357. Dla niewtajemniczonych: monofoniczny dekoder I2S zawierający wzmacniacz mocy do 3W. Cena jest również zachęcająca, z dostępnością nie ma problemu. Do tego jeden przycisk (dwa to o jeden za dużo), jakiś zasilaczyk 5V o mocy wystarczającej na zasilenie wzmacniacza - i to wszystko. Jako czujniki postanowiłem dopuścić następujące: W pomieszczeniu - BMP180, BMP280, DS18B20. Na zewnątrz - DHT22, DHT11, DS18B20 z możliwością bezprzewodowego połączenia. Oczywiście można nie podłączać któregoś z urządzeń - w najprostszym (najtańszym) przypadku można zastosować tylko DS18B20 do pomiaru temperatury w pomieszczeniu, czas oraz warunki bieżące dla lokalizacji pobierać z Internetu. DHT11 oczywiście nie powinien być stosowany, ale po prostu taki mam 🙂 Jednocześnie w razie potrzeby byłbym w stanie dorobić BME280 jako czujnik wewnętrzny (jak to słusznie @mkwiatkowski zauważył, odczyt wilgotności może być potrzebny przy pracującej klimatyzacji). Dodatkowym wyposażeniem może być zegarek DS3231 (jeśli istnieje możliwość utraty połączenia z Internetem). Można również dodać detektor IR aby sparować urządzenie z dowolnym pilotem. Prace zacząłem już jakiś czas temu, ale nie chciałem nic pisać dopóki nie uzyskałem pewności, że zadanie jest wykonalne. W tej chwili działają wszystkie moduły, urządzenie sobie gada, coś tam mierzy, nawet serwer www wystawia do bieżących ustawień... Tylko pytanie: czy ktoś to wykorzysta? Czy przypadkiem nir planuję zrobienia kawału dobrej, nikomu niepotrzebnej roboty? Bo co prawda pisząc program musiałem rozwiązać kilka dość interesujących (z punktu widzenia Arduinowo-ESPowego programisty) problemów, ale więcej nie przewiduję, a czego trzeba to już się nauczyłem 🙂 I dla zachęty: plik mp3 z prognozą pogody (nagrany na pececie, ale to taki sam syntezator jak na ESP32): meteo.zip Prosiłbym o wypowiedzi czy dalsza praca ma sens. czy mam sobie darować i zająć się czymś bardziej pożytecznym. A może jakieś pomysły?
  2. Hej, walczyłem teraz kilka dni z uruchomieniem modułu PN532 podłączonego do ESP32 niestety nieudało mi się ich zainicjować mimo korzystania z dedykowanej biblioteki oraz kilku modułów(trzech) PN532 oraz innych ESP32(też trzech). Wiem że aby komunikacja SPI była uruchomiona trzeba załączyć odpowiednie zwory lub przyciski, u mnie to pierwszy w dół drugi w górę: Wersja biblioteki to 1.3.3, a podłączenie to: PN532_SCK -> (18) PN532_MOSI -> (23) PN532_SS -> (32) PN532_MISO -> (19) Znalazłem na Internecie aby zmienić bitrate z 1MHz do 100KHz nic nie pomogło, tak samo dodanie . delay(10); w funkcji : bool Adafruit_PN532::sendCommandCheckAck Gdzie indziej znalazłem aby dodać na zasilanie kondensator 47uf dalej z tym samym skutkiem. Jako programu testowego używam przykładu z biblioteki dla SPI oto kod: **************************************************************************/ /*! @file readMifareClassic.pde @author Adafruit Industries @license BSD (see license.txt) This example will wait for any ISO14443A card or tag, and depending on the size of the UID will attempt to read from it. If the card has a 4-byte UID it is probably a Mifare Classic card, and the following steps are taken: Reads the 4 byte (32 bit) ID of a MiFare Classic card. Since the classic cards have only 32 bit identifiers you can stick them in a single variable and use that to compare card ID's as a number. This doesn't work for ultralight cards that have longer 7 byte IDs! Note that you need the baud rate to be 115200 because we need to print out the data and read from the card at the same time! This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards This library works with the Adafruit NFC breakout ----> https://www.adafruit.com/products/364 Check out the links above for our tutorials and wiring diagrams These chips use SPI to communicate, 4 required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! */ /**************************************************************************/ #include <Wire.h> #include <SPI.h> #include <Adafruit_PN532.h> // If using the breakout with SPI, define the pins for SPI communication. #define PN532_SCK (18) #define PN532_MOSI (23) #define PN532_SS (32) #define PN532_MISO (19) // If using the breakout or shield with I2C, define just the pins connected // to the IRQ and reset lines. Use the values below (2, 3) for the shield! #define PN532_IRQ (2) #define PN532_RESET (3) // Not connected by default on the NFC Shield // Uncomment just _one_ line below depending on how your breakout or shield // is connected to the Arduino: // Use this line for a breakout with a SPI connection: Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); // Use this line for a breakout with a hardware SPI connection. Note that // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin. // Adafruit_PN532 nfc(PN532_SS); // Or use this line for a breakout or shield with an I2C connection: // Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); void setup(void) { Serial.begin(115200); while (!Serial) delay(10); // for Leonardo/Micro/Zero Serial.println("Hello!"); nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (!versiondata) { Serial.print("Didn't find PN53x board"); while (1) ; // halt } // Got ok data, print it out! Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX); Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC); Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC); Serial.println("Waiting for an ISO14443A Card ..."); } void loop(void) { uint8_t success; uint8_t uid[] = {0, 0, 0, 0, 0, 0, 0}; // Buffer to store the returned UID uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) // Wait for an ISO14443A type cards (Mifare, etc.). When one is found // 'uid' will be populated with the UID, and uidLength will indicate // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); if (success) { // Display some basic information about the card Serial.println("Found an ISO14443A card"); Serial.print(" UID Length: "); Serial.print(uidLength, DEC); Serial.println(" bytes"); Serial.print(" UID Value: "); nfc.PrintHex(uid, uidLength); if (uidLength == 4) { // We probably have a Mifare Classic card ... uint32_t cardid = uid[0]; cardid <<= 8; cardid |= uid[1]; cardid <<= 8; cardid |= uid[2]; cardid <<= 8; cardid |= uid[3]; Serial.print("Seems to be a Mifare Classic card #"); Serial.println(cardid); } Serial.println(""); } } W kodzie sprawdzałem różnego konstruktora tej klasy, zawsze z takim samym skutkiem: Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); Adafruit_PN532 nfc(PN532_SS); Czy ktoś się napotkał z takim problemem i go rozwiązał ? Ja już nie mam pomysłów co może być nie tak, oraz jak to naprawić. Poniżej załączam logi z włączonego debugowania PN532DEBUG : Hello! Sending : 0x0, 0x0, 0xFF, 0x5, 0xFB, 0xD4, 0x14, 0x1, 0x14, 0x1, 0x2, 0x0, TIMEOUT! Sending : 0x0, 0x0, 0xFF, 0x2, 0xFE, 0xD4, 0x2, 0x2A, 0x0, TIMEOUT! Didn't find PN53x board
  3. - gdzieś na forum znalazłem program obslugujący strtok_r do dzielenia tekstu wg separatorów. - sam podprogram dzielenia tekstu działa i wyświetla poprawnie tekst na TFT zapisywany w tablicy. - ta sama tablica w pętli loop jednak nie chce się wyświetlać dając błąd o przekroczeniu bufora 256 znaków w OpenFontRender. - jedna tablica DX raz się wyświetla, drugi raz już nie, coś chyba nagrzebałem, tak jakby brakowało w tablicy znaku NULL na końcu. - proszę o pomoc bo nie daje rady z tym problemem. char* DX[10]; void testChar() { char *str; char sz[] = "Prognoza na jutro. Niewielki deszcz. "; char *p = sz; char *del = "."; // separator int indeks = 0; // ------------------------------------- while ((str = strtok_r(p, del, &p)) != NULL) { DX[indeks] = str; ofr.printf("%s\n", DX[indeks]) // tu wyswetla poprawnie indeks += 1; } } // .... loop if (millis() > czas) { Serial.println("."); tft.fillScreen(TFT_BLUE); testChar(); for(wiersz = 0; wiersz < 6; wiersz++) { ofr.setCursor(50, 20 * wiersz); //ofr.printf("%s\n", DX[wiersz]); // tutaj blad ! } czas = millis() + 10000; }
  4. 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 😄
  5. Tak jak w tytule plus dodatkowe pytanie, wytłumaczę na podstawie kodu. Mam pamięć która przechowuje parametry transmisji zapisane jako csv (świadomie zrezygnowałem z JSON) następnie po zainstalowaniu systemu plików i odnalezieniu tego z parametrami "reg1.txt"[będzie .csv] robię dwie rzeczy: zliczam ile jest linii(wierszy) w pliku i przesyłam kolejne wiersze do funkcji dekodującej. while ((d = readdir(dh)) != NULL) { printf("DIR %s\n", d->d_name); if(0 == (strcmp(d->d_name,"reg1.txt"))) { FILE * f = fopen("/usb/reg1.txt", "r"); char line[128]; int l = 0; if(mdbTask != NULL){ vTaskSuspend(mdbTask); while(fgets(line, sizeof(line), f)) //where sizeof(buf) is the length of //line you anticipate reading in. { //do something with buf here; //The input of fgets will be NULL as soon //as its input fp has been fully read, then exit the loop l++; } decode_csv(NULL,l); FILE * f = fopen("/usb/reg1.txt", "r"); // printf("test1\n"); while(fgets(line, sizeof(line), f)) //where sizeof(buf) is the length of { decode_csv(line, 0); } Pierwsze otwarcie pliku ma na celu zliczenie linii, jest to później potrzebne gdyż stosuję dynamiczną alokację pamięci. Problem był kiedy chciałem przesłać do funkcji "decode_csv" kolejne linie z pliku. Poradziłem sobie przypisując ponownie wskaźnik file * f nie jestem pewien czy to prawidłowe rozwiązanie? Ewentualnie czy istnieje inny sposób na zliczenie wierszy w pliku tekstowym? Poniżej plik na którym testuję U1,1,4,2,0,1,V I1,1,4,2,6,1,A P1,1,4,2,18,1,W
  6. Często pojawia się konieczność użycia pakietu płytko w konkretnej wersji. Szczególnie dla ESP32, gdzie różne wersje pakietów mogą działać inaczej, a wersje maior w ogóle nie są ze sobą kompatybilne - jest to wręcz niezbędne. Artuino IDE oczywiście pozwala zainstalować dowolną wersję pakietu, ale tylko jedną konkretną, a proces instalacji wcale nie jest taki szybki. Dodatkowo jeśli dokonaliśmy jakichś zmian w katalogu pakietu (w moim przypadku to dodanie nowych układów partycji i modyfikacja boards.txt) zaczyna być to niespecjalnie wygodne... Postanowiłem więc zrobić prosty przełącznik wersji. Działa dla ESP32, ale można go oczywiście zmodyfikować tak, aby działał dla dowolnych płytek. Rozwiązanie jest niestety linux-only, ale po drobnych zmianach (ścieżki, polecenia powinny działać tak samo) powinno ruszyć na Macu. A na pewno nowoczesny Windows pozwoli na zrobienie podobnego przełącznika... pozwoli, prawda? Kod jest stosunkowo prosty: #!/bin/bash #położenie docelowego pakietu ESP32 dstitem=${HOME}/.arduino15/packages/esp32 #tu są różne wersje srcdir=${HOME}/.arduinoESP32 if [ -n "$1" ]; then if [ "$1" = "off" ] ; then #przygotowanie do instalacji rm ${dstitem} echo "Gotowy do instalacji nowej wersji" exit 0 fi if [ "$1" = "show" ] ; then if a=$(readlink ${dstitem}) ; then basename $a else echo "Brak skonfigurowanej wersji" fi exit 0 fi # parametr to numer wersji src=${srcdir}/$1 if [ ! -d ${src} ] ; then echo "Brak wersji $1" else ln -sfn ${src} ${dstitem} echo "Ustawiona wersja $1" fi else #bez parametrów listuje zawartość katalogu ls ${srcdir} fi Jak tego użyć? Trzeba utworzyć plik o zawartości jak wyżej (ja nadałem mu nazwę espversion) i nadać mu prawa do wykonywania. Skrypt najlepiej utworzyć w katalogu gdzie przechowujemy własne polecenia (np. ~/bin/). Następnie trzeba sobie stworzyć katalog, który będzie zawierał wszystkie wersje pakietów. Ja utworzyłem do tego celu katalog ~/.arduinoESP32. Następnie należy kolejno zainstalować potrzebne wersje, a po instalacji przenieść zawartość pakietu do odpowiedniego miejsca. Przykładowo: po instalacji wersji 3.0.4 należy wykonać coś w stylu: mv ~/.arduino15/packages/esp32 ~/.arduinoESP32/3.0.4 Pamiętać należy, że przed jakąkolwiek próbą instalacji nowej wersji należy usunąć link ~/.arduino15/packages/esp32 - jeśli tego nie zrobimy, wersja zostanie nadpisana! Mamy więc teraz następujące możliwości: Listowanie dostępnych wersji: espversion Pokazanie która wersja jest aktualnie wybrana: espversion show Przygotowanie do instalacji nowej wersji (usunięcie linku): espversion off Zmiana wersji: espversion <numer_wersji> Tak więc teraz można sobie zmieniać wersje w locie, np: espversion 2.0.17 włączy wersję 2.0.17, o ile taką mamy przygotowaną. Pamiętać równie należy, że przy przełączaniu wersji Arduino IDE powinien być wyłączony! Jeśli ktoś korzysta z mojego pyrduino, należy przed kompilacją wydać polecenie: ardu -clean I to tyle. Przyjemnego przełączania życzy ethanak
  7. Mam do wykonania logger parametrów pewnego urządzenia, wymaganie jest między innymi takie aby po włożeniu pamięci pendrive logowanie zaczynało się automatycznie. Logger buduję w oparciu o esp32s3 który ma wsparcie sprzętowe USB msc, aby zapoznać się z komponentem udostępnionym przez espressif korzystam i ich przykładu https://components.espressif.com/components/espressif/usb_host_msc https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb/host/msc Urządzenie ma być bezobsługowe, czyli użytkownik wkłada pamięć -> esp sprawdza czy istnieje folder ze specyficzną nazwą powiązaną z jego MAC adres, jeśli taki istnieje to tworzy w tym folderze plik z bieżącą datą i czasem oraz zaczyna zapisywanie danych. -> jeśli folder nie istnieje to musi go założyć i przejść powyższe kroki, ścieżkę buduję w taki sposób: uint8_t chipid[6]; esp_efuse_mac_get_default(chipid); char makedir[128]; sprintf(makedir,"/usb/LOGGER_%02X%02X%02X%02X%02X%02X",chipid[0], chipid[1], chipid[2], chipid[3], chipid[4], chipid[5]); bool directory_exists = stat(makedir, &s)==0; if (!directory_exists) { if (mkdir(makedir, 0775) != 0) { ESP_LOGE(TAG, "mkdir failed with errno: %s", strerror(errno)); } } Następnie plik z oznaczony aktualnym czasem np: 22082024_1444.csv i do niego zapisuje kolejne rekordy danych. Sprawa która mnie zastanawia to właśnie ten moment kiedy ktoś podejdzie i wyjmie pendrive z urządzenia, log będzie co sekundę, można liczyć że akurat pendrive zostanie wyjęty pomiędzy kolejnymi zapisami, ale co jeśli trafi akurat w moment dodawania wpisu do pliku? Można w programowy sposób na to zareagować lub muszę wykombinować jakiś mechanizm aby plik został poprawnie zamknięty przed wyjęciem pamięci z gniazda?
  8. - poniżej interfejs do odczytu parametrów stacji Xiaomi z odczytem wilgotności i temperatury oraz stanu baterii zasilającej. - stacja Xiaomi pracuje na BLE 4.0, z M5Stack Core 0 zapewnia zasięg około 8 - 10 metrów. - w M5Stack wbudowano screen capture oraz shutdown. - aby korzystać z czujników, należy adres MAC jednego z czujników wpisać do linii [516] programu i skompilować cały projekt. - załączono także pliki binarne oraz adres programu do wgrywania do flasha esp32. Xiaomi_M5Stack_core_4.zip
  9. Jako że przydałby się mi teraz oscyloskop to w sieci znalazłem coś takiego... https://github.com/BojanJurca/Esp32_oscilloscope/ , pasuje mi taka opcja bo dane są wyświetlane przez neta na stronie a pod ręką mam akurat wolne esp32, a inne projekty na esp32 operują na wyświetlaczach o rozmiarach których akurat nie mam...tylko że kompletnie nie wiem jak się za to zabrać, nie widzę nigdzie przykładów 🤔 ktoś coś pomoże??
  10. Cześć:) Planuję budowę urządzenia opartego o esp32 oraz moduł gsm SIM800. Zadaniem urządzenia ma być zebranie kliku prostych informacji z czujników (stan niski/wysoki), przesłanie ich przez gsm na serwer, a następnie uśpienie esp32 i SIM800 na 5 min. Całość musi być zasilana z baterii AA. Najważniejsze w projekcie jest to, by jak najrzadziej wymieniać baterie. W dokumentacji technicznej wyczytałem, że moduł SIM800 potrzebuje nawet 2A w piku. Zastanawiałem się czy w związku z tym, musze stosować przetwornicę o wydajności 2A (która jest dość droga), czy mogę zastosować przetwornicę np. 1A, ale przed uruchomieniem modułu gsm ładować kondensatory, z których sim800 pobierałby energię. Czy w moich rozmyślaniach jest sens? Czy muszę się pchać w drogą przetwornicę 2A? Jeżeli tak to jaką polecacie?
  11. Cześć. Mam za zadanie odczytanie parametrów licznika DRS - 100 - 3P -MOD lub jego inna nazwa LUMEL NMID30-1 oto instrukcja tego licznika https://www.lumel.com.pl/resources/Pliki do pobrania/NMID30-1/NMID30-1_instrukcja_obslugi_Modbus.pdf Do tego celu postanowiłem skorzystać z przykładu modbus od espressif: https://docs.espressif.com/projects/esp-modbus/en/latest/esp32/master_api_overview.html#modbus-api-master-overview Problem polega na tym że różne próby wypełnienia tablicy deskryptorów nie przynoszą oczekiwanych parametrów. Chcę na początek odczytać rejestr przechowujący napięcie pomiędzy L1 i N wypełniam tablicę jak poniżej: const mb_parameter_descriptor_t device_parameters[] = { // { CID, Param Name, Units, Modbus Slave Addr, Modbus Reg Type, Reg Start, Reg Size, Instance Offset, Data Type, Data Size, Parameter Options, Access Mode} // { CID_INP_DATA_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 30000, 2, // INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4, OPTS(0,0,0), PAR_PERMS_READ }, { CID_INP_DATA_0, //CID STR("Data_channel_1"), //Par Name STR("Volts"), //Unit MB_DEVICE_ADDR1, //DEV ADDR '1' // MB_PARAM_HOLDING, MB_PARAM_INPUT, // Modbus Reg Type 0, // Reg Start 2, // Reg Size INPUT_OFFSET(input_data0), // Instance Offset PARAM_TYPE_FLOAT, // data type 'float' // PARAM_TYPE_FLOAT_BADC, // PARAM_TYPE_FLOAT_DCBA, // PARAM_TYPE_U32, 4, // Data Size OPTS( 0,0,0), // nd PAR_PERMS_READ_WRITE_TRIGGER },// nd Kod z którego korzystałem pochodzi z przykładów espressif https://github.com/espressif/esp-idf/tree/master/examples/protocols/modbus/serial/mb_master I (498) MASTER_TEST: Start modbus test... I (518) MASTER_TEST: Characteristic #0 Data_channel_1 (Volts) value = -4266057265024839188480.000000 (0xe3674370) read successful. I (1018) MASTER_TEST: Alarm triggered by cid #0. I (1018) MASTER_TEST: Destroy master... I (1018) main_task: Returned from app_main() Elektrycznie komunikacja jest sprawna gdyż podczas łączenia licznik wskazuje ikonę słuchawki oraz podłączenie "śledziem" modbus - usb również wskazuje na prawidłową komunikację, mam to przetestowane. Niestety dalsze działania, skomunikowania tego z esp nie dają efektów. W programach na PC często jest zaznaczenie "float swapped" co to oznacza?
  12. Kilka dni temu płytka przestała być wykrywana przez komputer, po czym platformio wyrzucało błąd mówiący, że COM nie istnieje lub Permission error 13. Udało mi się to naprawić i kod ładuje się po ręcznym wejściu do bootloadera (boot hold i reset press) . Bez problemu ładuje na płytkę każdy program, natomiast większe programy jak serwer WWW z DNS i powiadomieniami na ekranie OLED nie działają na nim. Jedyne, co zadziałało, to wyświetlanie prostego tekstu na ekranie OLED. Podsumowując jest upload succes ale tylko mniejsze programy dzialaja, po wgraniu wiekszego plytka nie dziala.
  13. 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.
  14. Swego czasu pokazywałem tu już joystick do Vice. Powiem tak: sprawdził się, idealny do grania w podróży czy w barze. Niestety - ma swoje wady. Przede wszystkim analogowy joystick nie daje "wyczucia". Poza tym zmiana konfiguracji wymagałaby przekompilowania programu - postanowiłem zrobić jego następcę. Tak więc przedstawiam: BlueShot-II Założenia były proste: Pełnowymiarowy mechanizm wraz z dwoma przyciskami Fire Symulowanie wciśnięć konkretnych klawiszy na klawiaturze BLE (najprostsza i chyba najlepsza forma emuuacji joysticka dla emulatora Vice) Prosty w obsłudze autofire Możliwość szybkiej zmiany podstawowych parametrów (port, zestawy klawiszy, parametry startowe autofire itp) Możliwość zaprogramowania kilku presetów. Zasilanie z akumulatora z możliwością podłączenia kabla USB do naładowania I co najważniejsze - jak najniższa cena. O konstrukcji mechanicznej nie ma co się rozpisywać. To zwykły chiński mechanizm i dwa typowe przyciski. Zresztą - jeśli ktoś będzie bardzo chciał (w co wątpię) mogę opublikować pliki stl i scad. Ciekawsza natomiast jest elektronika. Sercem urządzenia jet płytka ESP32 - Lolin32 Lite. Ponieważ ma możliwość podłączenia akumulatorka, na pokładzie ma ładowarkę a przede wszystkim cena poniżej 20 PLN z dostawą następnego dnia jest raczej atrakcyjna - wybór był chyba naturalny. Do programowania służą trzy klawisze: PORT - krótkie wciśnięcie pokazuje który port symuluje w danej chwili joystick. Przytrzymanie powyżej pół sekundy to zmiana portu AUTOFIRE - krótkie wciśnięcie to włączenie/wyączenie autofire, przytrzymanie to zmiana okresu (od 100 to 1000 msec). PROGRAM - krótkie wciśnięcie zmienia bieżące parametry, przytrzymanie włącza edycję głównych opcji. Dwie diody służą do pokazania stanu. Dioda AUTOFIRE pali się cały czas jeśli autofire jest wyłączony, migocze jeśli autofire jest włączony zgodnie z ustawionym okresem. Dioda BLE pali się jeśli joystick jest połączony z hostem, migocze z częstotliwością 1 HZ jeśli nie. Trzecia możlliwość (krótkie błyski raz na sekundę) oznaczają pracę w trybie Serial (o tym później). Dodatkowo mały wyświetlacz OLED 128x32 służy do wyświetlania różnych ważnych informacji - np. bieżącego portu, stanu autofire - oraz jako monitor przy programowaniu. Do elektroniki dochodzi jeszcze mała pamięć EEPROM (nie chciałem ryzykować, bo zapisy mogą być dość częste i poleganie na bibliotece Preferences mogłoby - choć to mało prawdopodobne - skończyć się smętnie). Ponieważ pamięć typu 24C01 kosztowała mnie poniżej złotówki - po prostu podkleiłem ją (obudowa SOT-8 jest raczej płaska) kropelką pod spodem Lolina i przylutowałem kynarem do pinów. Jako że ESP32 pozwala na dużą dowolność jeśli chodzi o przydział pinów - postarałem się, aby te podłączone do konkretnych elementów znalazły się obok siebie (np. joystick i klawisze Fire podłączone są do sześciu kolejnych pinów ESP, podobnie reszta). Zresztą - układ połączeń (no, ciężko to nazwać schematem ale powinno być zrozumiałe) wygląda tak: Wyjaśnię od razu jedną rzecz. Ponieważ gniazdo akumulatora jest umieszczone dość niewygodnie, podlutowałem po prostu przewody akumulatora bezpośrednio do płytki, w tym miejscu: Teoretycznie powinienem w ogóle usunąć gniazdo akumulatora - ale po pierwsze w niczym mi ono nie przeszkadza, a możliwe jest jego wysłonięcie odpowiednio modyfikując obudowę. Wracając do pinów - takie rozmieszczenie pozwoliło mi po prostu wlutować gniazda bezpośrednio do płytki, bez konieczności projektowania i trawienia PCB. Szerokość obudowy jest wystarczająca, aby można było zastosować takie gniazda kątowe. Przejdę więc do programu. Przełączenie za pomocą klawiszy Port lub Autofire powoduje zapis do EEPROM -u (po starcie ostwarzany jest ostatni stan). Możliwości bieżących ustawień są następujące: Port - 1 lub 2 Autofire - włączenie / wyłączenie Autofire mode - still (działa cały czas) lub press (strzelanie seriami) Autofire period - okres powtarzania: 100, 150, 200, 250, 300, 400, 500, 650, 800 lub 1000 msec Swap fire - zamiana Fire i Fire2 (jeśli Fire2 jest w zestawie klawiszy) Keyset1 - wybrany jeden z siedmiu zaprogramowanych zestawów (Numpad i sześć programowalnych) dla portu 1 Keyset2 - to samo dla portu 2 Dirs - 8 lub 4 kierunki. W trybie 4 kierunków pozycje pośrednie nie (np Up-Right) nie są przekazywane, w ich miejsce jest przekazywana ostatnia z pozycji (w tym przypadku Up lub Right). Name - jedna z dwóch nazw pod którymi przedstawia się joystick. Copy from - skopiowanie ustawień z jednego z 5 programowapnych presetów. Wciśnięcie klawisza PROGRAM spowoduje zapisanie opcji do EEPROM-u. Wciśnięcie Fire2 oznacza anulowanie operacji. Możliwości ustawień głównych opcji to: Keyset (1 lub 2): ustawienie klawiszy przypisanych do joysticka. Można ustawić 4 (tylko podstawowe kierunki) lub 8 (również kierunki pośrednie). Jeśli pośredni kierunek nie będzie ustawiony, joystick zasymuluje wciśnięcie dwóch klawiszy (np. Up i Right). Jeśli Fire2 nie będzie zaprogramowany, będzie działać po prostu jak równoległy przycisk Fire. Name (1 lub 2) - możliwość ustawienia obu nazw. Maksymalna długość to 15 znaków (litery, cyfry, podkreślnik, myślnik, spacja) Preset (1 do 5) - predefiniowany zestaw opcji. Opcje są identyczne jak w bieżących ustaawieniach, tyle że zamiast "skopiuj z presetu" jest "skopiuj bieżące ustawienia". Dodatkowo istnieje możliwość zaprogramowania nazwy presetu (max 4 znaki). STORE - zapisanie do EEPROM-u CANCEL (lub Fire2) anulowanie operacji. Klawisze Port i Autofire mają jeszcze jedną funkcję: wciśnięcie obu na ponad pół sekundy spowoduje przejście wyświetlacza i mikrokontrolera w stan uśpienia. Przydaje się to przy ładowaniu akumulatora (wyłącznik musi być w pozycji "włączony") - mikrokontroler i wyświetlacz praktycznie w porównaniu z prądem ładowania nie pobierają prądu. Wyjście ze stanu uśpienia poprzez wciśnięcie Fire. Mógłbym na tym zakończyć: kompletny kod jest w załączniku, potrzebne są dodatkowe biblioteki dla Arduino: Bounce2 (z managera bibliotek) ESP32-BLE-Keyboard (z githuba: https://github.com/T-vK/ESP32-BLE-Keyboard) I2C-EEPROM (z managera bibliotek) Adafruit_SSDF1306 i Adafruit_GFX (z managera bibliotek) Skompilowany program zapewne będzie działać, ale można działanie poprawić. W tym celu należy: z biblioteki Bounce2 skopiować do folderu szkicu pliki Bounce2.h i Bounce2.cpp W pliku Bounce2.cpp odkomentować linię: //#define BOUNCE_WITH_PROMPT_DETECTION Najlepiej zrobić to przed pierwszą kompilacją programu, aby builder Arduino nie próbował użyć biblioteki z cache. Powinno to poprawić szybkość reakcji joysticka. Niestety - jest tu pewna niedogodność: nie można podłączyć joysticka do komputera, który nie ma BlueTooth. Oczywiście jedną z opcji jest dokupienie dongla, ale przynajmniej w przypadku Linuksa znalazłem rozwiązanie. Uruchomiony na Linuksie programik joyport.py zamieni przychodzące przez serial numery klawiszy na odpowiednie kody i "wstrzyknie" je do kolejki zdarzeń. Jako parametr można podać urządzenie (np. /dev/ttyUSB0) lub identyfikator USB (prawdopodobnie będzie to 1A86:7523). Joystick wwykryje uruchomienie drivera i odpowiednio zareaguje - zasygnalizuje błyskami diody podłąćzenie Serial, wyśle przez bluetooth informację "wszystkie klawisze puszczone" i dopóki driver będzie uruchomiony, nie będzie przekazywać nic na bluetooth. Do uruchomienia programu potrzebne są moduły python3-serial i python3-evdev (nie są instalowane domyślnie, ale można je doinstalować np. przez apt). I to by było na tyle. Źródła programu i program w załączniku: vicestk.zip W razie pytań jestem do dyspozycji - ale teraz muszę kończyć bo Giana czeka! 🙂
  15. 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
  16. 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...
  17. 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.
  18. 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?
  19. 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!
  20. - 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.
  21. 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 🙂
  22. 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.
  23. 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 ?
  24. 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.
  25. 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.
×
×
  • 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.