Skocz do zawartości

Przeszukaj forum

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

  • 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
    • 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. Chciałem przedstawić wam mój projekt samochodziku "PiCar". To pojazd z funkcjami prostej jazdy autonomicznej opartej na wizji komputerowej, oraz zdalnego sterowania padem do konsoli (Xbox) z transmisją na żywo z kamerki pokładowej. Ponadto, ważnym elementem tego projektu jest moja własnoręcznie zaprojektowana płytka PCB, która reguluje napięcie płynące z baterii, zasila RPi 5, steruje silnikami i serwami i monitoruje napięcie baterii. Nazwa wzięła się z wykorzystania Raspberry Pi 5 jako komputera pokładowego. Na zdjęciu widać PiCar'a obok znacznika, który potrafi śledzić. Pod tym linkiem można znaleźć repozytorium tego projektu: https://github.com/ghemyn/picar Można tam zobaczyć pliki do których się odnoszę w tym poscie. Aby ułatwić czytanie, podzieliłem ten post na następujące sekcje: "Hardware - Płytka PCB" "Hardware - Silniki i serwa + koła" "Software - Autonomiczna jazda" "Software - Zdalne sterowanie" Hardware - Płytka PCB Powstała, aby pozbyć się osobno połączonych, niechlujnie wyglądających modułów i zastąpić je jedną dopracowaną płytką PCB. Osiągnęła swój cel ale obstawiam, że powstaną kiedyś kolejne wersje, które robią to lepiej Najważniejsze funkcję opisuję poniżej: Pliki projektowe płytki PCB można znaleźć w repozytorium tego projektu. Mikrokontroler CH32V003 jest głównym kontrolerem całej płytki PCB. Odpowiada za sterowanie sterownikami silników, generowanie sygnałów do serw i monitorowania napięcia baterii. Komunikuje się z Raspberry Pi 5 za pomocą magistrali I2C. Firmware jest napisany w C (w repo: /pwm_board/firmware/CH32V003A4M6), chociaż wersja znajdująca się na repozytorium jeszcze nie jest w pełni kompatybilna z tą nową płytką PCB. Przedtem CH32V003 było na innej płytce odpowiedzialnej tylko za sterowanie serwami. Napięcie wejściowe z baterii jest najpierw filtrowane przez kondensator low-ESR oraz ograniczane do 15 V za pomocą diody TVS SMBJ15A. Następnie układ MP2338 skutecznie obniża napięcie z zakresu 9–12,6 V do około 5,15 V, które jest podawane prosto do Raspberry Pi 5 poprzez kabel USB-C. Pin GND układu MP2338 jest połączony z szerokimi ścieżkami miedzi oraz przelotkami, żeby poprawić odprowadzanie ciepła z tak małego układu. Układ TB6612FNG jest wykorzystywany do sterowania oboma głównymi silnikami. Logika zasilania jest sterowana sygnałami PWM generowanymi przez mikrokontroler. Częstotliwość sygnału PWM może być regulowana z software'u o czym opowiadam więcej w sekcji "Hardware - Silniki i serwa". Płytka umożliwia jednoczesne generowanie czterech niezależnych hardware'owych sygnałów PWM. Serwa są zasilane napięciem 4,8 V generowanym przez drugi układ MP2238, skonfigurowany analogicznie do konwertera zasilającego RPi 5 (Oczywiście poza napięciem wyjściowym). Sekcja serw posiada 3-pinowe złącza dla każdego kanału, co ułatwia podpinanie i odpinanie kabli. Zrobiłem zapas kanałów, mimo że wykorzystuję tylko jeden, żeby zapewnić możliwość rozbudowy tego projektu w przyszłości, np. umożliwienia regulacji obrotu kamery w kilku osiach. Hardware - Silniki i serwa + koła Napęd tylnych kół PiCara realizowany jest przez dwa silniki DC N20-BT32 micro 100:1 320RPM - 9V sterowane dwukanałowym mostkiem H TB6122FNG. Umożliwia regulację prędkości za pomocą sygnału PWM generowanego przez wspomniany mikrokontroler CH32V003. Częstotliwość sygnału PWM może być regulowana z software'u, zależnie od tego czy użytkownik woli, żeby silniki były cichsze, czy żeby były mocniejsze. Im niższa częstotliwość, tym silniki pracują wydajniej, ale generują głośniejszy ton powstały przez przełączanie prądu. Skręt przednich kół realizowany jest za pomocą mikro-serwa, które przez prosty układ mechaniczny steruje kątem ich obrotu, dając efekt podobny, jak w samochodzie. Serwo jest sterowane sygnałem PWM o częstotliwości 50Hz również generowanym przez mikrokontroler. Przednie koła są przykręcone krótkimi śrubkami M3 do mocowań, które następnie wczepiają się do łożysk kulkowych, dokładnie tak, jak działają łączenia w LEGO technic. Bolec o odpowiedniej średnicy z przecięciami po bokach wchodzi w otwór łożyska i trzyma się wystarczająco mocno. Tylne koła są nasunięte na wały silników: Układ przedniego koła widziany w Fusion360: Użyte koła to Koła 60x8mm - czarne - Pololu 1420 Software - Autonomiczna jazda Autonomiczna jazda, póki co jest prostym algorytmem wizji komputerowej, który wyszukuje na obrazie z kamerki Raspberry Pi Camera HD v2 8MPx, specjalnego znacznika z trzema kluczowymi kolorami: czerwonym, zielonym i niebieskim. Obraz pochodzący z kamerki, jest najpierw filtrowany bilateralnie (Bilateral Filter), aby pozbyć się drobnych szczegółów i zakłóceń w późniejszym wyszukiwaniu znacznika. Następnie zmieniana jest gamma, żeby zwiększyć kontrast i powstały obraz jest binaryzowany, żeby SimpleBlobDetector z biblioteki OpenCV mógł wykryć trzy koła. Ostatecznie algorytm sprawdza czy koła znajdują się "wewnątrz" potencjalnie znalezionego znacznik - tzn. czy nie są przesunięte od uśrednionego środka o więcej niż o odchylenie standardowe. Jeśli nie są, to mamy pewność, że znacznik został znaleziony. Poniżej znajduje się wizualizacja, jak znacznik jest widziany przez algorytm: Kod jest dostępny na githubie Gdy znacznik jest znaleziony, pojazd jedzie do przodu i skręca tak, żeby środek znacznika znalazł się na środku widoku kamery. To w zupełności wystarczyło, aby efektywnie śledzić taki znacznik. Mam plan w przyszłości wykorzystać model wizji komputerowej "DepthAnythingV2", który oszacowuje głębię korzystając tylko z jednej kamerki w połączeniu z jednym czujnikiem ToF. Dzięki takiemu połączeniu będę w stanie uzyskać przybliżone (wystarczająco dokładne) informacje o odległości wszystkiego, co jest widoczne na przedniej kamerce. Te dane będę mógł wykorzystać do wykrywania kształtów po konturach i autonomicznego omijania przeszkód. Software - Zdalne sterowanie PiCar może być sterowany przez prosty interfejs webowy oparty na WebSocketach (interfejs znajduje się w repo: /frontend/index.html). Dostępne są dwa suwaki, jednak lepszą (i zdecydowanie fajniejszą) metodą sterowania jest gamepad (na przykład do XBox'a One), który strona wykrywa automatycznie. Przyspieszanie i hamowanie odbywa się za pomocą triggerów, a skręcanie lewym drążkiem analogowym. Interfejs wyświetla też obraz na żywo z kamery podłączonej do Raspberry Pi 5 z bardzo małym opóźnieniem (nie więcej niż 20ms). Strumień wideo jest udostępniony przez WebRTC, np. przy użyciu MediaMTX. Używany przeze mnie plik konfiguracyjny znajduje się w /car/mediamtx.yml. Po uruchomieniu transmisja z MediaMTX jest dostępna pod adresem ip raspberry_pi_5_ip:8889/rpi. Interfejs wygląda tak: Niezbyt atrakcyjny... Wiem. Podsumowanie Projekt nie jest w swojej finalnej postaci i obecnie jest w trakcie sporej aktualizacji jeśli chodzi o płytkę PCB, ale ciężko powiedzieć czy kiedykolwiek będzie gotowy bo zawsze będzie co poprawić Pliki ramy wydrukowanej na drukarce 3D, projekty płytek PCB, oraz kod można znaleźć na githubie w repozytorium projektu: https://github.com/ghemyn/picar/
  2. Pamiętacie grę Watch Dogs? Aiden Pearce jednym kliknięciem w smartfonie zmieniał świat wokół siebie. Choć rzeczywistość jest nieco bardziej skomplikowana, mój projekt ma być taką "namiastką" hakerskiego gadżetu w zasięgu nadgarstka. Chciałbym Wam przedstawić CyberWatch – zegarek oparty na ESP32-C3, który buduję z myślą o nauce etycznego hackingu i testowaniu podatności sieci. Płytka posiada Wi-Fi, Bluetooth i najważniejsze 16 pinów GPIO pomagających mi w tym projekcie. Z założenia ma być to płytka "hakerska" ale chciałbym żeby służyła przede wszystkim do bezpiecznego testowania urządzeń znajdujących się u mnie w domu, w garażu lub w piwnicy. Jednakże nie był bym sobą, gdyby projekt nie robił wielkiego wow dlatego poza funkcjami diagnostycznymi pojawią się również takie trochę utrudniające życie ludziom jak DDoS czy swego rodzaju Jamming. Na chwilę obecną jest to bardzo wczesny prototyp który tak naprawdę ma za zadanie sprawdzić czy 32-bitowy RISC-V (do 160 MHz) oraz 400kB SRAM, 384kb ROM oraz 4 MB Flash. są wstanie współpracować z Wi-Fi 2.4 GHz oraz Bluetooth 5.0. Stworzyłem to również dlatego że jestem ciekawy czy takie małe ESP jest już w stanie robić coś więcej niż tylko sterować domem, robotem czy odczytywać dane z czujników, czy to że te płytki są łatwo dostępne to jest wygoda czy problem. Jestem jeszcze ograniczony co do testów bo nie wgrałem na płytkę min. aktualizacji OTA dlatego też mój projekt chwilowo działa tylko po USB C, w przyszłości zamierzam dodać baterię. Całość będzie też bardziej rozbudowana niż na tym etapie może się wydawać ponieważ płytka dostanie też GPS i całą stronę HTML poświęconą wykresami i jakimś nazwijmy to "zapisem pomiarów". Zamierzam dodać też taki kluczyk nazwijmy go "Admin Mode" żeby płytka (w sumie to zegarek) był bez użyteczny gdy wpadnie w niepowołane ręce. Zapraszam do sekcji komentarzy, może ktoś wpadnie ja jakiś pomysł co można jeszcze wrzucić na taką płytkę, i jak to można jeszcze lepiej wykorzystać. Projekt wygląda mniej więcej tak:
  3. Cześć, Pracuję nad własnym komputerem opartym na Intel/AMD 8088. Na PCB mam: CPU Intel/AMD 8088 Układ U4: 74LS373 (latch danych) 2 moduły SRAM – jeden podłączony, drugi jeszcze nie Załączam obrazek schematu / wstępnego PCB, aby było widać, jak obecnie wygląda projekt. Prośba: Czy ktoś może sprawdzić mój schemat / PCB i zasugerować poprawki, najlepiej przygotować poprawioną wersję w EasyEDA? Zależy mi na stabilnym podłączeniu obu SRAM, poprawnym prowadzeniu linii danych i adresów, CE, OE i WE Jeśli ktoś ma czas, może przygotować poprawioną wersję PCB w EasyEDA i udostępnić plik Chcę też dodać gotową kość BIOS kompatybilną z Intel/AMD 8088. Czy ktoś może podpowiedzieć gdzie można kupić BIOS na EPROM/EEPROM/ROM gotowy do użycia, najlepiej od razu do włożenia w projekt? Będę bardzo wdzięczny za każdą radę, poprawkę schematu lub link do gotowej kości BIOS.
  4. Witam, właśnie ukończyłem mój projekt "Pochlaniacza" oparów lutowniczych , którego sercem jest płytka ESP32 . Spis elementów : Esp32 Mosfet logic-level Diody schotkyego Wentylator 12V Dioda led Moduł dźwiękowy arduino Wysiwetlacz OLED 128x64 2x przetwornica step up 2A 3x ogniwa 18650 Moduł ladowania TP4056 Na początek kilka słów o samym projekcie, jest to odpowiedź na nieustający problem oparow lutowniczych kumulujących się w niedużym garażu . Które po dłuższej sesji lutowania zaczęły naprawdę przeszkadzać w pracy , przy lutowaniu zazwyczaj obie ręce są zajęte z tąd pomysl na użycie czujnika dźwięku, reagującego na każde głośniejsze słowo. Parę bajerów w stylu wyświetlacza z animacja oraz diody sygnalizujacej podanie napięcia na bramkę tranzystora to jedynie środki stylistyczne . Dalej przechodząc do Budowy , zaczynając od sekcji zasilania 3 akumlatory 18650 zgrzane równolegle zabezpieczone przed nadmiernym rozładowaniem <2.5V z wyjścia układu zabezpieczającego TP , (który nie obsłuży dużych obciążeń jednak takie do 1A bez problemu znosi) więc z jego wyjść ( OUT ) podłączona jest reszta elementów przetwornica step up ustawiona na 5V zasilająca ESP z kabla typu C, Wyswietlacz OLED , oraz Czujnik dźwięku wszystkie masy elementów są polaczane na dodatnich wejściach przetwornic [5V,12V] są dane diody schotkyego w kierunku przewodzenia względem przetwornic w celu zapobiegniecia "cofniecia sie pradu" . ESP otrzymując sygnał z wyjścia out czujnika dźwięku podaje napiecie na bramkę tranzystora Mosfet która w pełni się otwiera dzieki użyciu tranzystora logic level o niskim napięciu przewodzenia bramki źródło zostało podpięte do masy przetwornicy step up 12V dren prosto do minusa wentylatora , między plusem a minusem wentylatora dioda schotykego pełniącą rolę diody flyback wszystko zostało zamknięte w obudowie hermetyczej 120x120x90mm czyli o wymiarach wentylatora który idealnie pasuje oraz filtra węglowego o tych samych rozmiarach wentylator zasysa dym i wypuszcza go w filtr weglowy który momentalnie pochłania cały dym , obudowa może nie jest zbyt estetyczna jednak spełnia swoje działanie i nie mam wobec niej większych wymagań. Pozdrawiam i czekam na opinie , i uwagi .
  5. Cześć, Chciałbym podzielić się projektem, który pochłonął mnie na ostatnie tygodnie – w pełni autonomiczny sterownik nawadniania do ogórków. Wszystko zaczęło się od prostego problemu: mam dość dużą działkę i zbiornik na deszczówkę, ale jest on oddalony od miejsca, które wymaga podlewania o jakieś 50 metrów, a do tego muszę pokonać różnicę wysokości około 3-5 metrów. Ręczne noszenie wody odpadało. Głównym założeniem było stworzenie urządzenia, które będzie w pełni konfigurowalne bez podłączania do komputera. Chciałem mieć możliwość zmiany harmonogramów podlewania, uruchamiania pompy ręcznie czy ustawiania pauzy w deszczowe dni, stojąc bezpośrednio przy urządzeniu. Wykorzystane moduły i komponenty Sercem projektu jest mikrokontroler Raspberry Pi Pico, a dokładnie Pico RP2040, programowany w MicroPythonie. Wybrałem go ze względu na dużą elastyczność i dwa niezależne porty I2C, co – jak się później okazało – było zbawieniem przy projektowaniu płytki PCB. Oto pełna lista kluczowych komponentów: Mikrokontroler: Raspberry Pi Pico Wyświetlacz: Ekran OLED 128x64 I2C (oparty na SSD1306) Zegar czasu rzeczywistego (RTC): Moduł DS3231 I2C podobny do tego (ostatecznie okazał się uszkodzony i projekt działa na wewnętrznym RTC Pico) Czujnik: Moduł AHT10 I2C do pomiaru temperatury i wilgotności powietrza ale równie dobrze może być AHT20 Moduł przekaźnika 1-kanałowy Element wykonawczy: Moduł przekaźnika 5V, sterujący pompą Interfejs użytkownika: 4 przyciski typu tact-switch (Góra, Dół, OK, Wstecz) System zasilania: Panel fotowoltaiczny 100W Regulator ładowania PWM 10A z wyjściami USB Akumulator żelowy 12V 18Ah Pompa: Membranowa pompa ciśnieniowa 12V 72W Droga od pomysłu do działającego urządzenia wymagająca. To mój pierwszy tak złożony projekt i nauczyłem się niesamowicie dużo, głównie na własnych błędach. Zaczęło się klasycznie – od prototypu na płytce stykowej. Plątanina kabli była ogromna, ale pozwoliła mi na napisanie i przetestowanie podstawowej wersji oprogramowania. Kod, napisany w MicroPythonie, rozrósł się do sporej maszyny stanów, która zarządza menu, harmonogramami i wszystkimi peryferiami. Kolejnym wyzwaniem było zaprojektowanie własnej płytki PCB w programie KiCad. To był mój debiut. Przejście od schematu do projektu ścieżek na jednej warstwie było jak rozwiązywanie trudnej łamigłówki. Każda ścieżka, która blokowała drogę innej, zmuszała do przemyślenia układu od nowa. Ostatecznie, aby ułatwić sobie życie, wykorzystałem oba porty I2C w Pico, co znacząco uprościło prowadzenie ścieżek. Płytkę wykonałem metodą termotransferu. Efekt końcowy moje ogórki.zip Po wielu wieczorach spędzonych na lutowaniu, debugowaniu i pisaniu kodu, powstało w pełni działające urządzenie zamknięte w szczelnym pojemniku na żywność. Sterownik realizuje wszystkie założone funkcje: Wyświetla aktualny status, czas i odczyty z czujnika. Uruchamia pompę zgodnie z dwoma, w pełni edytowalnymi harmonogramami. Pozwala na ręczne włączenie i wyłączenie pompy. Posiada funkcję pauzy na wybraną liczbę godzin na wypadek deszczu. Wszystkie ustawienia są zapisywane w pamięci Pico i nie giną po zaniku zasilania. W następnym roku na pewno użyję mocniejszej pompy Jestem świadomy, że użyłem dużo gluta ale jak wiecie, bez hot gluta nie ma DIY Zdjęcia z produkcji a w ZIPie finalny filmik
  6. Urządzenie które dzisiaj prezentuje powstało na prośbę mojego znajomego, jest liczydłem wskazującym za ile sekund zostanie zrobione zdjęcie. Sercem układu jest płytka black pill z mikrokontrolerem STM32F401 urządzeniem wyświetlającym matryca LED fotolicznik jest sterowany z zewnętrznego urządzenia a więc służy jedynie do wyświetlania czasu do zdjęcia. Schemat Schemat oraz płytka została zaprojektowana w edytorze pro.easyeda jest to wersja pierwsza, są tutaj drobne błędy które należałoby poprawić w kolejnych iteracjach: Ogólnie w tej wersji nie zostało wykorzystane zasilanie/podtrzymanie RTC, gniazdo usb oraz wyjścia OC z tranzystorów Q6...Q9 zostawiłem te elementy na poczet kolejnego projektu który będzie ich wymagał. W samym schemacie nie jest nic nadzwyczajnego ot kolejne stany na wejściach PC817 mają zmieniać zawartość wyświetlaną na matrycy. Program Oprogramowanie zostało napisane z bibliotekami HAL od ST. Program składa się z głównej pętli, która cyklicznie wywołuje funkcję dmd_proces(); do obsługi panelu użyłem biblioteki https://github.com/bjlli/DMD-for-STM32 ponieważ w plikach udostępnionych przez autora brakuje .ioc dla cubeMX dodaję tego konfiga na końcu artykułu. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) { //HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_2); scanDisplayBySPI(&hspi1); // HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2); } //int status; uint8_t first_transition = 2; uint32_t timer_first_trans; /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM3_Init(); MX_RTC_Init(); MX_SPI1_Init(); MX_WWDG_Init(); /* USER CODE BEGIN 2 */ //Write_Font_To_Flash(); HAL_TIM_Base_Start_IT(&htim3); //HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2); setFont(Arial_Black_14); //setFont(Arial_Black_14); DMD(1,1,OE_P10_GPIO_Port, OE_P10_Pin, SCLK_P10_GPIO_Port, SCLK_P10_Pin, A_P10_GPIO_Port, A_P10_Pin, B_P10_GPIO_Port, B_P10_Pin); HAL_GPIO_WritePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin,1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_WWDG_Refresh(&hwwdg); // Watch dog if(0 == first_transition) { dmd_proces(); } if(2 == first_transition){ timer_first_trans = HAL_GetTick(); first_transition = 1; setFont(SystemFont_5x7); drawString(0,0,"DMD",strlen("DMD"),0); drawString(0,9,"v1:25",strlen("v1:25"),0); } if((1 == first_transition) && (HAL_GetTick() - timer_first_trans) > 3000) { clearScreen(1); first_transition = 0; } } /* USER CODE END 3 */ } Program po restarcie wyświetla krótką informację na temat wersji i roku kompilacji, resetuje watchdog i wskakuje w wyżej wymienioną dmd_proces: #include "anim.h" #include "main.h" #include "dmd.h" #include "stdio.h" #include "stm32f4xx_hal.h" const uint8_t xPosChar[] = { 0,13,11,11,11,11,11,11,11,11,7,7,7,7,7,7,0 }; //0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 void dmd_proces(void) { // uint32_t x = HAL_GetTick(); static uint32_t licznik; licznik++; static uint32_t bounce_timer = 0; static uint16_t last_gpio_status = 0; static uint8_t bounce_test = 0; uint16_t pinStatus = GPIOA -> IDR; pinStatus &= 0x000F; if((last_gpio_status != pinStatus) && (0 == bounce_test)) { bounce_timer = HAL_GetTick(); bounce_test = 1; last_gpio_status = pinStatus; }else if((1 == bounce_test) && ((HAL_GetTick() - bounce_timer) > 10)){ if(pinStatus == last_gpio_status) { // stabilny clearScreen(1); uint8_t ctab = ~ pinStatus & 0x000F; char c = (char)ctab+'0'; if(ctab){ setFont(BIG_FONT); if(ctab < 10) { drawChar(xPosChar[ctab],0,c,0); }else{ char str[3]; drawString(xPosChar[ctab],0,itoa(ctab,str,10),strlen(str),0); } }else{ setFont(Arial_Black_16_ISO_8859_1); drawChar(0,-3,'F',0); drawChar(15,-3,'T',0); drawChar(7,3,'O',0); drawChar(23,3,'O',0); } HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin); }else{ last_gpio_status = pinStatus; } bounce_test = 0; } } Działanie polega na odczytaniu ćwiartki portu A sprawdzenia czy impuls nie był zakłóceniem i jeśli stan został potwierdzony - na wyświetlaczu pojawi się odpowiedni komunikat. Widać też że zależnie od tego co ma być wyświetlane zmieniam również wielkość fontów, dlatego napis "foto" jest innej wielkości niż cyfry które się wcześniej pojawiają. Te ogromne znaki liczbowe pobrałem z https://github.com/ekapujiw2002/ex4_jws_dmd/blob/master/lib/DMD/MyBigFont.h wypełniają maksymalnie przestrzeń roboczą panelu LED. Płytka i obudowa PCB została wykonana w warunkach domowych jako jednowarstwowa z montażem mieszanym przewlekanym i smd, połączenia brakujące - które normalnie zostałyby umieszczone na warstwie TOP wykonałem kynarem 0.4mm2 Ponieważ układ jest bardzo prosty obyło się bez wpadek i po montażu i sprawdzeniu pod kątem zwarć dał się uruchomić bez znaków dymnych. Obudowę dla pcb zaprojektowałem w fusion360 została wydrukowana z materiału PETG, zaś całość jest wbudowana w konstrukcję z blachy giętej malowanej proszkowo. Linki i źródła: https://sklep.msalamon.pl/produkt/stm32f401ccu6-dev-board/ https://tinyurl.com/4fm2bvx7 https://pro.easyeda.com/ https://github.com/bjlli/DMD-for-STM32 https://github.com/ekapujiw2002/ex4_jws_dmd/blob/master/lib/DMD/MyBigFont.h dmd01.zip
  7. Cześć! Mam pytanie związane z pomiarem napięcia baterii Li-Pol 3,7V przez ADC w ESP32, konkretnie pin IO12.Chciałbym, aby bateria była odłączany pinu IO12, kiedy ESP32 jest wyłączone (nie ma 3.3V). Robię to dlatego, ponieważ gdy ESP32 jest wyłączone to jak będzie widniało zasilanie na pinie IO12 to może nastąpić prądowy „backfeed", chyba że się mylę, co może uszkodzić esp32. Bateria jest podpięta do układu TP4056. Obecnie testuję układ z dzielnikiem 2×100k (B+ → 100k → IO12 → 100k → GND) oraz próbowałem użyć MOSFET-a 2N7000, żeby rozłączać napięcie z baterii, ale nie jestem pewien czy dobrze to robię. Pytanie: Jak najlepiej wstawić tranzystor (np. N-MOSFET THT, 2N7000), żeby: Gdy ESP32 ma 3.3V – pomiar napięcia baterii przez IO12 działa normalnie. Gdy ESP32 jest wyłączone – napięcie z baterii NIE trafia na IO12 (żeby nie zakłócać pomiaru, nie ciągnąć prądu przez dzielnik, itd.). Mój aktualny pomysł to: Czy to ma sens? A może da się to zrobić lepiej? Zależy mi na prostym i pewnym rozwiązaniu – może być z dodatkowymi elementami (pull-down, pull-up itp.). Z góry dziękuję za pomoc!
  8. Cześć! Nazywam się Mateusz (Mati) i jestem pasjonatem elektroniki oraz programowania. Tworzę różnorodne projekty, a w tym worklogu pokażę Wam, jak stworzyć mikrokomputer od podstaw. Projekt ten ma na celu edukację, ale także możliwość stworzenia zestawu, który będzie inspiracją dla innych twórców. Dla kogo jest ten projekt: Projekt skierowany jest do osób, które chcą nauczyć się, jak od podstaw zbudować swój własny mikrokomputer o funkcjonalnościach zbliżonych do popularnych platform, ale oparty o własne rozwiązania. Zawiera zarówno szczegóły techniczne, jak i wskazówki praktyczne. Idealny dla osób zainteresowanych elektroniką, programowaniem i tworzeniem własnych urządzeń. Cel projektu: Celem projektu jest stworzenie mikrokomputera, który będzie edukacyjnym narzędziem do nauki elektroniki i programowania. Będę dokumentować cały proces: od wyboru komponentów po montaż, projektowanie PCB, instalację systemu operacyjnego oraz tworzenie prostych aplikacji. Projekt jest otwarty – możecie śledzić postępy, zadawać pytania i dzielić się swoimi pomysłami! Spis treści: Etap 1: Wybór komponentów Wybór procesora Pamięć RAM i Flash Wyświetlanie, zasilanie, interfejsy itd. Etap 2: Projektowanie schematu Procesor Pamięć operacyjna Zasilanie Pamięć Flash Wyświetlanie(HDMI) Wi-Fi Pozostałe Poprawki i weryfikacja Etap 3: Projektowanie PCB Rozmieszczenie elementów Tworzenie połączeń oraz ścieżek Weryfikacja płytki i generowanie plików produkcyjnych Zamówienie prototypu płytki oraz elementów(możliwa opcja "PCB Assembly") Etap 4: Montaż i testowanie Montowanie komponentów na płytce Testowanie stabilności Etap 5: Oprogramowanie Inicjacja Uboot(lub inne) Konfiguracja Linuxa Instalacja systemu Implementacja podstawowych aplikacji (np. edytor tekstu, terminal) Etap 6: Finalizacja projektu Ostateczne testy i poprawki Podsumowanie Koszty, czas realizacji, plany rozwoju Oszacowanie czasu: Początkujący -> 1-2 miesiące Średnio zaawansowany -> 3-6 tygodni Zaawansowany -> 2-4 tygodnie Czas całkowity: 8–12 tygodni (3–4 miesiące) Oszacowanie kosztów: Procesor -> 15-50zł Pamięć RAM -> 15-30zł Pamięć Flash -> 20-50zł Pozostałe -> 50-100zł Koszt całkowity: 150–300 zł (zależnie od wybranych komponentów) Komponenty które najpewniej użyje w moim projekcie(każdy może dostosować dla siebie): Procesor: Allwinner H3(link) Pamięć RAM: 1GB(potem zostanie dobrany odpowiedni model) Pamięć Flash: NAND Flash 8GB(potem zostanie dobrany odpowiedni model) Reszta elementów: zostaną dobrane w późniejszym etapie Podsumowanie: Ten projekt ma na celu pokazanie procesu budowy mikrokomputera od podstaw. Będę dzielił się swoimi postępami, problemami i rozwiązaniami. Jeśli chcesz się dowiedzieć, jak stworzyć coś takiego, śledź ten temat! Na bieżąco będę informować o nowościach, dodając kolejne etapy realizacji projektu.
  9. Cześć! Planuję sprzedaż zestawów DIY do nauki lutowania, które zawierają: płytkę PCB (wykonaną w JLCPCB), elementy elektroniczne (rezystory, diody, buzzer itp.), obudowę z drukarki 3D, kurs i instrukcję online i fizyczną. Mam dylemat – chcę zamawiać płytki z pokryciem HASL z ołowiem, ponieważ są tańsze i dużo łatwiej się je lutuje. Jednak zastanawiam się, czy mogę legalnie sprzedawać takie zestawy w Polsce (np. przez Allegro), skoro dyrektywa RoHS ogranicza użycie ołowiu w elektronice. WAŻNE: To nie są gotowe urządzenia, tylko zestawy edukacyjne do samodzielnego montażu – przeznaczone głównie dla hobbystów i początkujących elektroników (nie dla dzieci). Kilka dodatkowych informacji: JLCPCB ma certyfikat RoHS, ale nie jestem pewien, czy dotyczy on wszystkich wariantów płytek (np. HASL z ołowiem). Nie planuję seryjnej produkcji urządzeń, tylko sprzedaż zestawów do nauki. Pytanie: Czy zestawy DIY też muszą spełniać wymagania RoHS? Czy ktoś ma doświadczenie lub zna konkretne przepisy, które regulują taką sytuację? Będę bardzo wdzięczny za każdą pomoc i ostrzegam z góry – sprzedaż ołowiu w elektronice w Polsce (bez spełnienia wymagań RoHS) może być nielegalna! Dlatego chcę to dobrze sprawdzić, zanim zacznę cokolwiek sprzedawać.
  10. Cześć wszystkim, chciałbym zaprezentować jeden z moich ostatnich projektów jest to zasilacz regulowany (stabilizowany) , którego ’sercem’ jest przetwornica AC/DC (zmienny-stały) 24.8V/4A, prąd płynący z przetwornicy AC/DC płynie do przetwornicy step-down gdzie można dowolnie go regulować przy użyciu potencjometru na zewnątrz obudowy. Z wejścia przetwornicy nr 1 prąd płynie do płytki mojej roboty wykonanej na laminacie jednostronnym, w której wkład wchodzi stabilizator 7812 ( do którego zamontowałem radiator), (oraz pastę która rozprowadza ciepło na cały radiator), 2 kondensatory elektrolityczne oraz 2 ceramiczne. Gdzie 24 V z przetwornicy redukowane są do 12V czyli znamionowego napięcia zasilania wentylatora którego zasilanie jest załączane przyciskiem umieszczonym na obudowie od strony prawej. Z wyjścia przetwornicy step-down prąd jest kierowany na gniazda bananowe z przodu obudowy. Zasilacz posiada na wejściu od strony zasilania całego układu z sieci , zabezpieczenie termiczne które przerywa obwód po przekroczeniu w środku obudowy 50°C , drugim zabezpieczeniem jest znany i lubiany wyłącznik nad prądowy 4A , który gdyby ktoś z czytelników nie wiedział, przerywa obwód w momencie przekroczenia przez odbiornik progu 4 amperów pobieranego prądu . Wszystkie łączenia zostały wykonane na konektorach dzięki czemu nie trzeba odlutowywać kabli gdy chcemy rozłączyć któryś z elementów. Niżej załączam schemat blokowy.. Oraz spis elementów... Obciążalności zasilacza w warunkach ‘bojowych’ nie testowałem, natomiast z żarówka samochodową o mocy 60W i 12V zasilania radził sobie bez większych problemów , a jak łatwo obliczyć 60W przy 12V napięcia zasilania oznacza 5A pobieranych przez żarówkę , co moim subiektywnym zdaniem jest wynikiem zadowalającym jak na pierwszy zasilacz. Poniżej wrzucam linki do 3 przykładowych elementów które zastosowałem ze sklepu BOTLAND https://botland.com.pl/bezpieczniki/11953-wylacznik-nadpradowy-termobimetaliczny-mr1-20a-5904422340544.html https://botland.com.pl/wentylatory-montazowe/3876-wentylator-12v-80x80x25mm-3-przewody-5904422349615.html https://botland.com.pl/zlacza-bananowe/6751-gniazdo-bananowe-al2437-czerwone-4mm-5szt-5904422334994.html
  11. Cześć wszystkim, chciałabym się z wami podzielić swoim projektem, który jest świetnym pomysłem na prezent dla waszej walentynki. Wykorzystuje on ESP32C3 Xiao, oraz został w całości skontruowany od zera na płytce prototypowej PCB. Poniżej znajduje się filmik przedstawiający działanie układu. Dzięki technice PWM, zyskujemy efekt bicia serca, gdzie nasza cyfrowa fala nasila ledy coraz większym duty cycle, oraz następnie po osiągnięciu maksymalnego nasycenia diod, maleje. Główne komponenty użyte w projekcie: Seeed Xiao ESP32-C3 - WiFi/Bluetooth - Seeedstudio 113991054 Rezystor justPi THT CF węglowy 1/4W 330Ω - 30szt. Dioda LED 5mm czerwona - 10szt. - justPi Praca przy projekcie: Myślę, że projekt ten jest świetną okazją dla początkujących majsterkowiczów, chętnych nauczenia się lutowania. Rozmiar komponentów jest na tyle duży, że daje swodobę w lutowaniu, oraz wybacza popełniane błędy, które łatwo usunąć, bez uszkadzania komponentów. Fajną opcją będą rezystory dobrane pod zasilenie jakim dysponujemy, w moim przypadku każda dioda posiada swój własny rezystor 330 ohm, który reguluje natężeniu prądu. Z uwagi na to że użyte zostały takie same diody, można by nagiąć lekko zasady oraz użyć tylko jednego rezystora w połączeniu równoległym, jednak należy uważać w tym przypadku na maksymalne natężenie płynące przez diodę. Bezpieczniejszą opcją jest zastosowanie diod w układzie równorzędnym, każda z jednym rezystorem. Niezbędna przy pracy okazała się mata silikonowa ze sklepu Botland, gdzie znajduje się w ofercie w super cenie. Czasem lepiej zachować tył modelu, podobnie jak tył choinki schowanym przed ludzkim okiem . Programowanie układu: Mikrokontroler z serii ESP32, esp32-c3 można zaprogramować przy pomocy Arduino IDE 2.0. Potrzebna do tego będzie biblioteka ESP32 AnalogWrite. Poniżej wklejam mój kod, który zlicza wartość nasycenia diod i na tej podstawie jest w stanie zwiększać, lub zmniejszać jasność diod w pętli. int led_pin = 10; int light_intensity = 0; void setup() { pinMode(led_pin,OUTPUT); } void loop() { if(light_intensity < 1){ for(int x = 1; x <= 255; x++){ analogWrite(led_pin,light_intensity); light_intensity++; delay(10); } }if ( light_intensity >254){ for(int x = 1; x <= 255; x++){ analogWrite(led_pin,light_intensity); light_intensity--; delay(10); } } } Filmik demonstacyjny na działanie układu: Ps. Jeśli polecacie jakieś lutownice w przystępnych cenach to doceniłabym wszelkie rekomendacje. Dziękuję za poświęconą chwilę na przeczytanie posta .
  12. Projekt zegarka opartego na GPS jako module czasu rzeczywistego. Po kilku testach układów DS1307 oraz DS3231 stwierdziłem, że nie są one wystarczająco precyzyjne; każdy z nich po jakimś czasie gubi parę minut. Testowałem układy zakupione w Polsce i w Chinach – każdy zachowywał tak samo, uje stąd pomysł na wykorzystanie modułu GPS jako źródła czasu rzeczywistego. Cena modułu GPS w Chinach to około 8 zł, więc porównywalnie do ceny układów DS. Zastosowanie LED-ów WS2812B 5V pozwala na tworzenie różnych animacji i wybór kolorów spośród 16 777 216 możliwości oraz wybór jasności 0–255. W ostatecznej wersji programu pozostałem przy jednym kolorze, który najbardziej mi odpowiada. Program umożliwia łatwą zmianę koloru i ilości użytych diod. Zastosowano 28 modułów LED WS2812B 8-bitowych tworzących wyświetlacze 7-segmentowe: LED-y 0–7 – segment a, 8–15 – segment b itd. Każde 8 LED-ów tworzy osobny wyświetlacz i jest podłączone do innego wyjścia Arduino. Podzielone są na dziesiątki godzin, godziny, dziesiątki minut i minuty oraz dwukropek, który jest zrobiony z dwóch diod LED WS2812B z taśmy LED. Ponieważ jasność diod LED w nocy może być oślepiająca, zastosowałem warunek, który zmienia jasność diod LED na 10 w godzinach 20–6. Można też całkowicie wyłączyć zegarek w tych godzinach. Minimalna jasność dobrze się sprawdza w nocy, w szczególności po przebudzeniu. Strefa czasowa jest ustawiona na stałe na +1 względem czasu UTC. Strefę czasową można zmienić za pomocą komunikacji szeregowej, wysyłając żądaną wartość. Program korzysta ze standardowych bibliotek NeoPixel oraz TinyGPS++. Całość przyklejona jest do plexy z podświetlania z zepsutego monitora. Podgrzana hotair aby była plastyczna do formowania w kształt V. Podłączenie jest tak proste, że nie potrzeba schematu. Całkowity koszt budowy zegarka około 50zł kupując części w chinach. Zachęca do wspierania Polskich sklepów takich jak botland. Opis programu: //wykorzystane biblioteki do obsługi GPS oraz ledów ws2812. #include <Adafruit_NeoPixel.h&gt; #include <TinyGPS++.h&gt; // Definicja segmentów ósemki (po 8 LED na segment) const uint8_t segments[8][8] = { {0, 1, 2, 3, 4, 5, 6, 7}, // Segment A {8, 9, 10, 11, 12, 13, 14, 15}, // Segment B {16, 17, 18, 19, 20, 21, 22, 23}, // Segment C {24, 25, 26, 27, 28, 29, 30, 31}, // Segment D {32, 33, 34, 35, 36, 37, 38, 39}, // Segment E {40, 41, 42, 43, 44, 45, 46, 47}, // Segment F {48, 49, 50, 51, 52, 53, 54, 55} // Segment G }; W tym miejscu można dowolnie zmieniać ilość zastosowanych ledów podzielonych na segmenty. // Mapowanie cyfr na segmenty (0 = wyłączony, 1 = włączony) const uint8_t digitMap[10][7] = { {1, 1, 1, 1, 1, 1, 0}, // 0 {0, 1, 1, 0, 0, 0, 0}, // 1 {1, 1, 0, 1, 1, 0, 1}, // 2 {1, 1, 1, 1, 0, 0, 1}, // 3 {0, 1, 1, 0, 0, 1, 1}, // 4 {1, 0, 1, 1, 0, 1, 1}, // 5 {1, 0, 1, 1, 1, 1, 1}, // 6 {1, 1, 1, 0, 0, 0, 0}, // 7 {1, 1, 1, 1, 1, 1, 1}, // 8 {1, 1, 1, 1, 0, 1, 1} // 9 }; Tworzenie mapy ledów tak, aby cały segment 8 LED był wykorzystywany jako jeden LED. uint8_t newBrightness = (hour >= 20 || hour < 6) ? 2 : 10;//Operator trójargumentowy działa w postaci: warunek ? wartość_jeśli_prawda : wartość_jeśli_fałsz; Sprawdzanie aktualnego czasu i dostosowywanie jasności zegara. // Funkcja wyświetlająca czas na wszystkich ósemkach void displayTime(int hour, int minute, int second) { displayDigit(strip1, hour / 10, strip1.Color(100, 100, 0)); // Dziesiątki godzin displayDigit(strip2, hour % 10, strip2.Color(100, 100, 0)); // Jedności godzin displayDigit(strip3, minute / 10, strip3.Color( 100, 100, 0)); // Dziesiątki minut displayDigit(strip4, minute % 10, strip4.Color(100, 100, 0)); // Jedności minut } Podział czasu na dziesiątki i jedności oraz wybór koloru. Zdjęcia projektu: Dla porównania zegarek oparty o DS1307 ustawiony 01.02.2025 równo z GPS, spieszy o około 1,5 minuty. Cały program można pobrać z Google dysku 7egment_ws2812b_gps_nano.zip Arduino nano LED WS2812B GPS
  13. Drogi Konstruktorze! Na pewno zdarzyła Ci się taka sytuacja: tworzysz układ na płytce stykowej. Wszystko jest ok, ale nagle ... które wyprowadzenie jest które? I liczysz: raz, dwa, trzy ... a potem drugi raz, żeby się nie pomylić, a czasem trzeci. Ale można inaczej - wystarczy nakleić na układ rozpiskę wyprowadzeń. I tu właśnie przychodzi z pomocą moja aplikacja. Możesz opisać piny układu całkowicie po swojemu, niekoniecznie zgodnie z kartą katalogową. Bez rejestracji, w pełni darmowo. Bez żadnego pobierania, wystarczy przeglądarka internetowa. Bez reklam. Po prostu tworzysz i drukujesz plik PDF. Jest także możliwość zapisania projektu, więc Twoja praca się nie zgubi. Zapraszam do testowania! Na razie wrzucam jako zajawkę, wkrótce pojawią się lepsze zdjęcia i zrzuty ekranu. Wszelki feedback mile widziany! https://stickers.js29a.info.pl/
  14. W tym projekcie chciałbym opisać krok po kroku proces podłączenia licznika samochodowego od Forda Galaxy do naszego Arduino. Potrzebne elementy: Zasilacz 12V Arduino Przewody męsko-żeńskie Licznik samochodowy Zestaw wskaźników od Forda Galaxy posiada 2 wtyczki - czerwoną oraz czarną. Nas w tym projekcie interesuje tylko czerwona wtyczka gdyż znajdują się w niej piny zasilające oraz dostarczające dane do silników krokowych w liczniku. Najpierw zajmijmy się zasilaniem. Do pinu 3 oraz do pinu 4 na liczniku wpinamy 2 przewody i podłączamy je do minusa na naszym zasilaczu a kolejne 2 przewody wpięte w pin 14 oraz w pin 15 podłączamy do +. Jako zasilacz może nam posłużyć zwykły zasilacz komputerowy kub jakikolwiek o napięciu 12V. Dalej zajmijmy się podłączeniem silniczków od wskazówek. obrotomierz - 10 pin prędkościomierz - 27 pin wskaźnik poziomu paliwa - 21 pin wskaźnik temperatury cieczy - 23 pin (pin 1 jest w lewym dolnym rogu wtyczki) Następnie przewody te wpinamy w wejścia cyfrowe do Arduino. W moim przypadku obrotomierz wpiąłem w wejście oznaczone 2, prędkościomierz w wejście nr 3, wskaźnik poziomu paliwa 4 a temp. cieczy w wejście 5. Jeżeli po podpięciu zasilania licznik zadziała (wskazówki ustawią się w położeniu 0 oraz włączy się podświetlenie) to możemy przejść do konfiguracji. Pobieramy oprogramowanie SimHub i instalujemy je. Po uruchomieniu programu przechodzimy do zakładki Arduino a następnie klikamy na zakładkę "My hardware". Wybieramy "Single Arduino" i klikamy "Open arduino setup tool". Następnie definiujemy w jakie wejścia wpięliśmy nasze wskaźniki. Wybieramy z jakiego arduino korzystamy (w moim przypadku jest to UNO) oraz wybieramy port komunikacyjny. Gdy wszystko mamy już zrobione klikamy Upload to arduino i czekamy aż program zostanie wgrany na Arduino. Jeżeli program wgrał się poprawnie przechodzimy do zakładki "Gauges" i kalibrujemy nasz licznik. Wartości liczbowe są indywidualne dla każdego licznika ale to co musimy ustawić do każdego licznika to MAX Tachometer RPM na 7 (jeżeli zakres na tarczy obrotomierza jest inny to podajemy maksymalną liczbę, jeśli jest to 5 to podajemy 5) oraz tachometer cylinders na 6. Warto zaznaczyć opcję "Always use tachometer full range" jednak jeśli sprawia ona problemy możemy ją wyłączyć. Resztę wartości musimy ustawić tak, żeby wskazówka poprawnie wskazywała położenie min i max. Niestety nie ma uniwersalnych wartości i prędkościomierz u mnie wskazuje poprawnie 240 km/h przy wartości 222 (speedo gauge maximum output) jednak w innym liczniku może być to wartość ciut większa lub mniejsza. Na samym końcu wybieramy grę w którą chcemy zagrać z zakładki "Games". Następnie uruchamiamy naszą grę i cieszymy się rozgrywką z naszym licznikiem. Ktoś mi może powiedzieć "Przecież można napisać kod", zgodzę się z tym tylko ja gram od ETS 2 przez Dirt 4 na Forzie kończąc. O wiele łatwiej jest jednym kliknięciem zmienić grę w simhubie niż pisać osobny kod eksportujący dane z telemetrii do Arduino. Jeżeli ktoś potrzebuje tylko licznika do jednej gry to ma to sens jednak w moim przypadku mija się to z celem. Koszt takiego licznika może zamknąć się w okolicach 50 zł. Możemy wykorzystać klona arduino (klon nano możemy kupić za mniej niż 15zł), a licznik możemy znaleźć na portalach aukcyjnych za ok 20zł. Jest to niedrogi i fajny bajer a na dodatek jest bardzo praktyczny. Poniżej znajdują się zdjęcia i gif pokazujący pracę urządzenia.
  15. Witam. Niedawno szukając pomysłu na projekt zobaczyłem, że mam wyświetlacz TM1637 i od razu wpadł mi do głowy pomysł na zrobienie licznika cyfrowego. Taki przyrząd dla zapominalskich, do liczenia. I tak oto powstało to: Cyfrowy Licznik Użyte komponenty/moduły: Attiny85 Moduł wyświetlacza TM1637 Tact switch (x3) Przełącznik Baterie AAA (x3) Zacząłem od napisania kodu i złożenia wszystkiego na płytce stykowej. Początkowo wszystko miało być zrobione na Arduino NANO, potem stwierdziłem że lepiej użyć czegoś tańszego i mniejszego czyli Attiny85. Przyciski miały działać w ten sposób: Lewy -> +1 Środkowy -> +10 Prawy -> RESET Rozkład działania przycisków licznika Cały kod udało mi się napisać dość szybko i nie jest on skomplikowany: #include <TM1637Display.h> #define CLK 3 #define DIO 4 TM1637Display display(CLK, DIO); int buttonState_1; int buttonState_10; int buttonState_reset; int licznik=0; void setup() { display.setBrightness(7); pinMode(0, INPUT); pinMode(1, INPUT); pinMode(2, INPUT); for(int i=0; i < 7; i++){ display.showNumberDecEx(8888, 0b01000000, true); delay(50); display.clear(); delay(50); } delay(500); display.showNumberDec(0); } void loop() { buttonState_1 = digitalRead(0); buttonState_10 = digitalRead(1); buttonState_reset = digitalRead(2); if(buttonState_1 == HIGH){ licznik++; display.showNumberDec(licznik); while(buttonState_1 == HIGH){ buttonState_1 = digitalRead(0); } } if(buttonState_10 == HIGH){ licznik+=10; display.showNumberDec(licznik); while(buttonState_10 == HIGH){ buttonState_10 = digitalRead(1); } } if(buttonState_reset == HIGH){ licznik=0; display.showNumberDec(licznik); while(buttonState_reset == HIGH){ buttonState_reset = digitalRead(2); } } if(licznik > 9999){ licznik=0; display.showNumberDec(licznik); } delay(50); } Na samym początku jest tzw. ,,test ledów" więc cały wyświetlacz mruga liczbami i znakami: 88:88, a później są same funkcje odpowiadające za wykrywanie czy przycisk nie został naciśnięty oraz za wyświetlanie danych liczb. Dobra dość gadania o kodzie, czas powiedzieć coś o obudowie. Obudowę robiło się bardzo przyjemnie. Robiłem ją jak zawsze w programie TINKERCAD, który jest bardzo prosty i przyjazny dla początkujących takich jak ja Obudowa licznika W moich poprzednich obudowach i projektach robiłem sam otwór na koszyk i tam go po prostu przyklejałem. Przyznam że nie wyglądało to estetycznie w ogóle. W tym projekcie koszyk był drukowany w raz z pokrywą całej obudowy, więc po wydrukowaniu trzeba było tylko włożyć odpowiednio blaszki i gotowe! Wydrukowana pokrywa obudowy wraz z koszykiem, blaszkami oraz bateriami Cała obudowa drukowała się ok. 3 godziny i pochłonęła 56g filamentu. Wszystko drukowało się bardzo ładnie, a tak wyglądał efekt: Wydrukowana obudowa Pozostało mi jeszcze wszystko polutować i upchać do środka, co okazało się najcięższym zadaniem... Na początku zlutowałem podstawkę (na Attiny85), tylko tutaj zrobiłem to trochę inaczej. Zamiast lutować kabelki do podstawki, zrobiłem coś co miało pełnić funkcje takiej jakby ,,płytki stykowej?" żeby było można wszystko w każdej chwili poprzepinać. Użyłem do tego żeńskich goldpin-ów i cały ten pomysł okazał się bardzo dobry. Wiadomo że wszystko będzie mniej wytrzymałe, bo w każdej chwili może coś się wypiąć, ale tu się to bardzo dobrze trzymało. Dodatkowo co chwilę musiałem coś wypinać/przepinać, więc ta metoda sprawdziła się tu idealnie Zlutowany, prawie gotowy projekt Okazało się, że obudowę jednak zrobiłem trochę za ciasną i upchanie tego wszystkiego do środka zajęło mi bardzo dużo czasu. Wiele elementów musiałem spiłować, kleić i robić wiele innych rzeczy, ale w końcu udało się to wszystko do środka włożyć i zamknąć obudowę: Obudowa i upchania do środka elektronika Test licznika jest na tym filmie: Czy będę go używał? Nie! Raczej jak już coś liczę to zapamiętuje to w głowie, więc taki przyrząd nie jest mi potrzebny. Zrobiłem go, bo innego pomysłu na projekt nie miałem. Dziękuje za przeczytanie tego DIY! Mam nadzieję że projekt się spodobał. Czekam na wasze opinie i uwagi! Pozdrawiam.
  16. Witam. Budowę auta na pilota planowałem już od dawna, ale nie wiedziałem jak się do tego zabrać. Dopiero niedawno gdy miałem okazje wykonać projekt z tego filmu, dowiedziałem się jak to zrobić. I tak oto powstało takie auto na pilota: Auto na pilota Użyte komponenty i moduły: Arduino UNO Moduł sterownika silników DC L293D Akumulatorki Li-Ion 18650 + koszyk Silnik DC z przekładnią + koła (x4) Odbiornik IR Rezystor 68Ω Kondensator 100µF Przełącznik I/O Pilot IR (ja użyłem ten pilot) Na samym początku musiałem zbadać kody które odbiornik odbiera po wciśnięciu danego przycisku na pilocie, więc napisałem i wgrałem taki kod: #include <IRremote.h> const int RECV_PIN = A0; void setup() { Serial.begin(9600); IrReceiver.begin(RECV_PIN, ENABLE_LED_FEEDBACK); Serial.println("Odbiornik IR gotowy."); } void loop() { if (IrReceiver.decode()) { Serial.print("Kod: "); Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); IrReceiver.resume(); } Okazało się, że odbiornik odbiera losowe sygnały gdy klikam ten sam przycisk. Problem rozwiązał ,,filtr na zasilaniu odbiornika". (problem szczegółowo opisywany i rozwiązywany jest w tym wątku): Ustaliłem sposób w jaki będą działać przyciski i zająłem się budową auta: Instrukcja obsługi pilota Auto budowałem w podobny sposób jak na filmie do którego linkowałem na początku tego opisu. Dlatego nie będę też opisywał tutaj tego jakie kroki wykonałem, żeby je zbudować. Lepiej zajrzyjmy do kodu. #include <IRremote.hpp> #include <AFMotor.h> AF_DCMotor motorM1(4); AF_DCMotor motorM2(3); AF_DCMotor motorM3(2); AF_DCMotor motorM4(1); const int RECV_PIN = A0; int speed=200; void setup() { IrReceiver.begin(RECV_PIN); motorM1.setSpeed(speed); motorM2.setSpeed(speed); motorM3.setSpeed(speed); motorM4.setSpeed(speed); } void loop() { if (IrReceiver.decode()) { if(IrReceiver.decodedIRData.decodedRawData == 0xBF40FF00){ // JAZDA W PRZÓD motorM1.run(FORWARD); motorM2.run(FORWARD); motorM3.run(FORWARD); motorM4.run(FORWARD); } if(IrReceiver.decodedIRData.decodedRawData == 0xE619FF00){ // JAZDA W TYŁ motorM1.run(BACKWARD); motorM2.run(BACKWARD); motorM3.run(BACKWARD); motorM4.run(BACKWARD); } if(IrReceiver.decodedIRData.decodedRawData == 0xF807FF00){ // SKRĘT W LEWO motorM1.run(FORWARD); motorM2.run(FORWARD); motorM3.run(BACKWARD); motorM4.run(BACKWARD); } if(IrReceiver.decodedIRData.decodedRawData == 0xF609FF00){ // SKRĘT W PRAWO motorM3.run(FORWARD); motorM4.run(FORWARD); motorM2.run(BACKWARD); motorM1.run(BACKWARD); } if(IrReceiver.decodedIRData.decodedRawData == 0xEA15FF00){ // STOP motorM3.run(RELEASE); motorM4.run(RELEASE); motorM2.run(RELEASE); motorM1.run(RELEASE); } IrReceiver.resume(); } } I tak jak widać po kodzie, sterowanie tym autem jest uciążliwe. W klasycznych autach na pilota, jak klika się przycisk (jazda w przód) to auto jedzie póki nie puścisz przycisku. Tutaj jak klikam przycisk, to auto jedzie do momentu w którym nie nacisnę innego przycisku, lub przycisku stop. Jak wie ktoś jak wykonać taki kod, który pozwoli sterować autem tak jak w klasycznych autach, to był bym wdzięczny jakby podpowiedział pod tym opisem. Podczas pisania kodu, napotkałem jeszcze jeden problem. Biblioteka AFMotor gryzła się z IRremote, przez co nie mogłem sterować silnikami M1 i M2, więc w kodzie mogłem używać tylko jednej z tych bibliotek. Rozwiązanie problemu też znajduje się w tym wątku: Na koniec najlepsza część, czyli filmik: Choć kod i schemat połączenia wszystkiego były wykonane przeze mnie to dużo inspirowałem się tym filmem. Dziękuje za przeczytanie całego DIY i z góry przepraszam, jeśli się je dziwnie czytało, ale zupełnie nie wiedziałem jak się do niego zabrać. Czekam z niecierpliwością na wasze uwagi. Pozdrawiam.
  17. Cześć! Ostatnio wpadłem na pomysł stworzenia lampki która będzie ładowana za pomocą panelu solarnego 6V/1W a dodatkowo będzie miała 2 ważne funkcje; zapalanie po nastaniu odpowiednich warunków w pokoju oraz wykrywanie ruchu. Głównym założeniem tego projektu ma być przede wszystkim nauka oraz sprawdzenie się pod względem wiedzy którą posiadam. Funkcje lampki które chciałbym aby miała: Samowystarczalność, ładowanie za pomocą panelu aby nie trzeba było pamiętać jej ładować. Mobilność urządzenia, może być zabrana wraz z dzieckiem gdziekolwiek będzie. Świecenie diody dopiero po zapadnięciu zmroku, a gdy wykryje ruch dioda ma świecić jaśniej. Z racji posiadanego zestawu elektroniki #1 oraz #2 Forbota chciałbym wykorzystać następujące elementy: Tranzystor BC546 x 2 Czujnik ruchu HC-SR501 Fotorezystor 5-10k Ohm Rezystory Komparator LM311 Potencjometr 5k Ohm Dodatkowo: Panel Solarny 6V/1W Moduł zarządzania energią z panelu solarnego Akumulator Li-on 3.7V 18650 (wykorzystuje takie do innych celów więc chciałbym użyć go i tutaj) Koszyczek na aku 18650 Poniżej zamieszczam schemat w postaci PNG oraz PDF. Z góry dziękuje za wszelkie odpowiedzi. Lampka_zmierzchowa.pdf
  18. Witam wszystkich czytelników. Zainspirowałem się w wakacje postem użytkownika @Krzysiek97, który przedstawił swoją kierownice do gier na bazie arduino leonardo: Kierownica PC - wersja 2. Z racji tego że lubię grać w gry wyścigowe i symulatory postanowiłem zbudować własną kierownicę z dodatkowymi akcesoriami. Nie chciałem przerabiać starej gotowej kierownicy do komputera, więc wpadłem na pomysł aby zbudować całe stanowisko. Materiał o tym stanowisku/ projekcie znajduję się na moim kanale na YT do którego was zapraszam Kierownica do komputera na bazie arduino Chciałem aby w tym stanowisko znajdowała się kierownica o kącie obrotu 900 stopni, sprzęgło, gaz, hamulec, 8 biegów + wsteczny (8 biegów ponieważ tyle mają niektóre samochody np. w Forza Horizon 4), hamulec ręczny, 2 joystiki (do sterowania maszynami w Farming Simualtor), button matrix 4x5 = 20 przycisków (przypisanych do rożnych akcji w grach) i zegary do wyświetlania prędkości i obrotów. Tak więc gdzieś w połowie lipca zacząłem szukać potrzebne części. Pierwszym problemem z którym się spotkałem była niewystarczająca ilość wejść w arduino leonardo. Ktoś na tym forum podsunął mi płytki Nucleo 64 na STM32, obawiałem się jednak czy programy które wcześniej znalazłem w internecie będą z nimi współpracować. Bawiłem się naco wcześniej arduino lecz nucleo nie stąd moja niepewność ponieważ zaczynałem dopiero wtedy zabawę z tym wszystkim. Zdecydowałem się jednak zostać przy arduino i zakupiłem 3 płytki, po jednej dla każdego programu który obsługuję inną część stanowiska, ponieważ i tak nie ma prgoramu który ogarnie wszystkie moje rzeczy na raz. A więc tak: Arduino Leonardo - program EMC Utility Lite (z początku korzystałem z RFR Whell Configuration elcz sprawiał on problemy) - obsługuję kierownicę, pedały, hamulec ręczny - Link do programu EMC, Jak zainstalować program Pierwsze Arduino Pro Micro - program MMJoy2 - obsługuję button matrix i 2 joysticki - Link do programu MMJoy2, Jak zainstalować program Drugie Arduino Pro Micro - program SimHub - obsługuję zegary/wyświetlacze - Link do programu SimHub Zamówiłem też 20 guzików (push button) 10 styczników krańcowych 2 Joysticki 2 wyświetlacze Tm1638, 1 wyświetlacz Max7219 (zamówiłem też sterownik silnika BTS7960 lecz na razie nie zakładałem FFB). Rzeczy które miałem w domu to: 2 potencjometry 10k Ohm, stycznik krańcowy ls-11s, kable kawałki plastiku, materiału i gumy. Za postawę stanowiska posłużyła mi deska rozdzielcza i fotel od mazdy mx-5 i kierownica od mazdy 626. Całość jest przyspawana do rurki i przykręcona do euro palety. Z racji tego że deska pochodzi z anglika to nie mogłem zamontować zwykłych zegarów w miejscu poduszki pasażera. Zamieszczam tutaj schematy podłączeń danych elementów: Drugim problemem który chce tu opisać, było przeniesienie/ zczytanie obrotu z kierownicy do arduino. Na początku chciałem wykorzystać enkoder optyczny z swojej starej drukarki, lecz gubił się on często i nie działał dokładnie, więc kupiłem enkoder inkrementalny 600ppr. Nie będę się już tak rozpisywał co jak i gdzie jest skręcone dlatego wszystko pokazane i omówione jest w filmiku do którego link jest na początku posta. Więc to jest dodatkowy materiał dla ciekawych. Podsumowując: koszt budowy stanowiska zamknął się dla mnie w kwocie 300zl, czas realizacji od pierwszego pomysłu do zbudowania całości i upewnienia się że wszystko jest sprawne to 6 miesięcy. Tak oto prezentuję się kierownica i jej działanie w grze Forza Horizon 4 Na koniec pytanie głownie do administratora, czy i kiedy będzie znowu dostępny konkurs Opisz elektroniczne DIY i odbierz 50 zł rabatu do Botland?
  19. Witam wszystkich! Mam na imię Paweł i od blisko 5 lat buduję swój własny procesor oparty o układy z rodziny 74 TTL. Do tej pory stworzyłem dwie iteracje projektu. Każda z tych dwóch iteracji składa się z płytki CPU i płytek potrzebnych do zbudowania prostego komputera w oparciu o te CPU. Do tej pory tworzyłem swój projekt hobbystycznie. Strona na której zamieszczałem opis i źródła nie była za bardzo nigdzie udostępniana i praktycznie tylko znajomi o niej wiedzieli. Ale nadszedł ten czas by się podzielić projektem z większą publiką WWW: https://xirx.net GIT: https://git.xirx.net lub mirror: https://github.com/demohpj Na stronie www na ta chwilę jest pełny opis XiPU w pierwszej wersji. XiPU_v2 będzie miał dopiero taki opis tworzony. Zapraszam też do zapoznania się działem download gdzie można ściągnąć emulator całego komputera i pobawić się z nim na żywo: Download: https://xirx.net/?s=download W obu wersjach miałem proste założenia: Używać układów 74 w wersji HCT (napięcie działania to 5V ale zapotrzebowanie prądowe jest o wiele mniejsze ze względu na bycie układami CMOS) Nie używać nic bardziej skomplikowanego niż ALU 181 Ograniczyć się maksymalnie do formatu A4 dla PCB 8 bitowa architektura z 16 bitowym adresowaniem pamięci 2 rejestry ogólnego przeznaczenia (A i B) i 2 rejestry dodatkowe pomocne przy używaniu adresów (X i Y) Obsługa 64 KB RAM (16 bitowa szyna adresowa) Taktowanie CPU minimum 1 MHz (by dało się go używać w jakiś sensownych scenariuszach) Szyna danych do komunikacji z zewnętrznym światem (8 bit IN oraz 8 bit OUT) Obsługa stosu Obsługa rozkazów: add, sub, inc, dec, shl, shr, push, pop, cmp, jmp Mikrokod zapisany na układach EEPROM Wymagania co do komputera: Ekran 320x240 z 4 bitową paletą i znakami 8x8 (w rzeczywistości zastosowany jest ekran LCD 640x480 z 8 bitową paletą) Prosty głośnik do odtwarzania tonów generowanych przez funkcję kwadratową (zmieniamy procent wypełnienia i częstotliwość) RS232 o prędkości 1200 bps Zegar RTC z podtrzymaniem bateryjnym Klawiatura QWERTY 4 diody LED (power, run, capslock, error) Komputer zasilany jest napięciem 7.5V przy maksymalnym prądzie 1A. Główną składową komputera oprócz CPU jest IO Board, który ma za zadanie pośredniczyć w komunikacji CPU ze światem. Jako układ sterujący zastosowałem STM32F072. Płytka posiada również pamięć typu flash o wielkości 2 MB do przechowywania plików i programów udostępnianych po szynie danych do CPU. W XiPU_v2 pamięć flash przechowuje również plik z systemem operacyjnym, który po starcie jest pobierany przez bootloader. Opis kluczowych właściwości XiPU: Częstotliwość zegara: 1 MHz Pamięć: 32 KB ROM + 64 KB RAM (dwie oddzielne przestrzenie adresowe, górne 32 KB RAM jest widoczne jako górna połówka ROM) Zewnętrzna szyna komunikacyjna: 8 bit IN, 8 bit OUT Rejestry: A, B, X, Y (wszystkie są 8 bitowe) Stos: 256 bajtów (tylko prosty push i pop) Adresowanie: Bezpośrednie lub jako adres w parze rejestrów Y:X Flagi procesora: C i Z (każda instrukcja używająca ALU powoduje zmianę tych flag) Mikrokod: 2 pamięci 32 KB EEPROM Arytmetyka: Tylko operacje na 8 bitowych danych System operacyjny: 32 KB EEPROM (zmiana wersji wymaga przeprogramowania układu) Opis kluczowych właściwości XiPU_v2: Częstotliwość zegara: 1 MHz Pamięć: 64 KB RAM (jedna przestrzeń adresowa, tylko pierwsze 2 KB pamięci jest przeznaczone dla BIOS w pamięci ROM) Zewnętrzna szyna komunikacyjna: 8 bit IN, 8 bit OUT Rejestry: A, B, X, Y (wszystkie są 8 bitowe) Stos: 4 KB, obsługa Frame Pointera (dostępny rejestr BP), dostępne instrukcje enter i leave, możliwe zaawansowane manipulowanie adresem wskaźnika stosu i bezpośredni dostęp do danych Adresowanie: Bezpośrednie lub jako adres w parze rejestrów Y:X, możliwe używanie dodatkowego przesunięcia dla adresów przechowywanych w Y:X Flagi procesora: C i Z (są dwie pary tych flag, jedna jest przeznaczona do widzenia przez następne instrukcje, druga jest ukryta i służy tylko do tymczasowego użytku podczas wykonywania specyficznych instrukcji) Mikrokod: 2 pamięci 32 KB EEPROM Arytmetyka: Operacje na 8 bitowych danych, dodatkowo wsparcie dla podstawowych instrukcji add/sub/inc/dec dla 16 bitowych danych w rejestrach Y:X System operacyjny: 2 KB EEPROM z BIOS (bootloader + podstawowe API dla IO), OS jest pobierany przez zewnętrzną szynę komunikacyjną z IO Board Do projektu użyłem następujących narzędzi: Geany - Tworzenie plików Makefile i asemblera. QtCreator - C++/Qt. Użyte do tworzenia aplikacji pomocniczych. Qt 5.12.4 - Biblioteka użyta do tworzenia aplikacji pomocniczych. GCC - kompilator C i C++ Keil uVision 5.37 - Kompilator i środowisko debugowe dla STM32F0 MCU. Make - Narzędzie do automatyzacji budowania. Doxygen 1.9.7 - Generator dokumentacji na podstawie kodu źródłowego. Proteus 8.10 - Symulator obwodów drukowanych. QCAD - Narzędzie do projektowania rysunków technicznych. DipTrace 4.2.0.1 - Narzędzie do projektowania PCB. AUTODESK Fusion - Narzędzie do projektowania modeli 3D do druku.
  20. Witam wszystkich! Po dłuższej nieobecności na formu chciałbym zaprezentować Wam kilka z moich najnowszych projektów przy okazji po krótce omawiając magistralę CAN bus. *** Wstęp *** Do tej pory opublikowałem dwa wpisy na forum opisujące budowę analogowych liczników samochodowych od Forda Galaxy oraz Audi A3 8L. Są to projekty niezwykle proste w budowie, wystarczy na określony pin podać 12V, masę lub sygnał z Arduino o określonej częstotliwości aby ożywić cały licznik i wszystkie wskazówki. Jednak ze względu na swoją prostotę projekty te posiadają liczne ograniczenia - przede wszystkim nie jesteśmy w stanie idealnie symulować zmiennej rezystancji czujnika poiomu paliwa oraz temperatury cieczy. Dodatkowo większosć kontrolek działa w logice 12V przez co nie można nimi sterować bezpośrednio z Arduino. Wszystkie te ograniczenia obchodzą liczniki, które do komunikacji wykorzystują magistralę CAN bus. *** Założenia projektu *** Projekt licznika miał być przede wszystkim uniwersalny i działać z szerokim wachlarzem gier - od ETS 2 gdzie prędkości obrotowe silnika wynoszą do 2500 RPM a prędkość rzadko kiedy przekracza 120km/h przez Framingi, BeamNG, Asseto Corsa na F1 kończąc gdzie silnik wkręca się powyżej 10.000 RPM a prędkości znacznie wykraczają za maksymalne wychylenie prędkościomierza licznika samochodowego. Licznik umożliwić ma nie tylko odczyt podstawowych parametrów prowadzonego pojazdu tj. obroty silnika, prędkość, temperatura cieczy, oleju czy poziomu paliwa ale także informować o stanie świateł, silnika czy nawet opon. *** Potrzebne materiały *** Arduino MCP2515 Zasilacz 12V (1A w zupełności starczy) Przewody połączeniowe *** Jak to działa? *** Do budowy projektu wykorzystałem dobrze znane większości z Was Arduino NANO wyposażone w USB-C. Dialog z licznikiem prowadzony jest poprzez moduł CAN MCP-2515 a całość zasila 12V zasilacz sieciowy. Całość umieściłem w małej obudowie wydrukowanej na drukarce 3D. Nie wgryzając się za bardzo w szczegóły techniczne - CAN bus to szeregowa magistrala danych wykorzystująca do komunikacji 2 przewody opisywane jako CAN-H oraz CAN-L. Jak łatwo się domyślić na przewodzie CAN-High panuje nieco wyższe napięcie niż na CAN-Low. CAN Bus jest magistralą działającą w sposób różnicowy czyli mierzy i porównuje napięcia na CAN-H oraz CAN-L. W ten sposób odczytywane są bity dominujące i recesywne tworąc ciąg zer i jedynek. Dla ułatwienia projektu nie oparłem o liczby binarne tylko znacznie przyjemniejsze dla oka - heksadecymalne. Ramka CAN wysyłana do licznika składa się z unikalnego identyfikatora (ID) oraz określonej ilości bajtów danych. Każdy bajt danych może przyjąć wartość od 0 do FF czyli decymalnych 255. Dla przykładu aby zapalić kontrolkę hamulca ręcznego w liczniku od Peugeota 407 muszę nadać ramkę o ID 128 a bicie zerowym nadać wartość 24HEX. Wygląda to mniej więcej tak: [ ID 128 0x24 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ]. Pod pozostałymi bitami kryją się kolejne kontrolki tj. kierunkowskazy, światła mijania, drogowe, przeciwmgielne oraz nielubiany przez kierowców check engine. Pod różnymi ID ramek można odnaleźć pozostałe funkcje licznika - sterowanie wskazówkami, podświetleniem, ustawianie przebiegu itd. Warto pamiętać, że niektóre liczniki po otrzymaniu zasilania będą pozornie wyglądać na martwe. Takie konstrukcje potrzebują tak zwanego sygnału przebudzenia, który "obudzi" licznik. Jeśli taki sygnał występuje to jest to pierwszy krok aby zacząć zabawę z licznikiem. *** Projekt licznika *** Do moich projektów wykorzystuję liczniki z samochodów Peugeot oraz Citroen. Magistrala CAN w obu markach jest bliźniaczo podobna i różnią się jedynie małymi szczegółami. Najważniejsze, że obie marki wykorzystują taką samą szybkość magistrali wynosząca 125Kbps. Do kontroli modułu MCP2515 wykorzystałem bibliotekę MCP2515.h. W pierwszej kolejności łączę moduł CAN z Arduino oraz podłączam magistralę wraz z zasilaniem do licznika. Należy pamiętać, że każdy licznik posiadać może swój własny indywidualny pinout. Powyżej można zobaczyć pinout licznika Citroen C3 I FL. Po podłączeniu wszystkich 4 przewodów wgrywam przygotowany wcześniej kod na Arduino. Warto zatrzymać się na chwilę przy kodzie i zastanowić się jak projektant tworzył licznik. Zespół projektujący licznik miał surowe dane - maksymalne obroty silnika 5200 RPM, maksymalna temp. cieczy 130℃, maksymalna temp. oleju 150℃, maksymalna prędkość 260km/h. Licznik przygotowany jest oczywiście na taki zakres danych z minimalnym zapasem jednak po przekroczeniu skali obrotomierza lub wskaźnika temperatury zaczną dziać się różne dziwne rzeczy. Wartości out of range są różnie traktowane przez liczniki - jedne ustawiają wskaźnik na "0", drugie wyłączają się a trzecie mogą się zawiesić. Dane z gier praktycznie zawsze będą wykraczać poza zakresy ustalone przez producenta więc trzeba przeanalizowaćkażdą grę z osobna i zastosować zabezpieczenia oraz skalowanie tak, aby wartości zawsze znajdowały się w akceptowalnym przez licznik zakresie. Kod musi brać także poprawkę na nieliniowość wskaźników temperatury - rzadko kiedy 1° obrotu silnika krokowgo będzie odpowiadał dokładnie takiemu samemu przyrostowi temperatury. Do przykładu - wskazówka temp. cieczy "zastyga" na 90℃ gdy faktyczna temperatura cieczy waha się od ~85-93℃. Dalszy wzrost temperatury będzie powodował niewielki wzrost wychylenia wskazówki. Jednak gdy temperatura niebezpiecznie wzrośnie to wskazówka momentalnie zwiększy swoją czułość i będzie wykonywać znaczny ruch co każdy 1-2℃. *** Dane z gier *** Po przetestowaniu kodu na "suchych" danych wpisanych "z palca" do kodu wypadałoby przestawić się na dane przesyłane z gier do licznika w czasie rzeczywistym. Za przygotowanie danych odpowiada aplikacja SimHUB współpracująca ze specjalnie napisaną przeze mnie formułą NCalc "obrabiającą" surowe dane z gier na zakresy liczbowe zaimplementowane w kodzie. Wygląd danych, którymi "karmię" kod Arduino przedstawiam poniżej. Jest to oczywiście wycinek danych ponieważ ogranicza mnie pole wyświetlające Raw result. *** Efekt końcowy *** Po wielu próbach i testach udało mi się ujarzmić prawie cały licznik. Wszytskie wskazania licznika: prędkość obrotowa silnika prędkość pojazdu poziom paliwa temp. cieczy temp. oleju wskaźnik biegów Kontrolki: hamulec ręczny kierunkowskazy światła mijania, drogowe, przeciwmgielne brak ładowania akumulatora niskie ciśnienie oleju rezerwa przegrzanie cieczy przebita opona przebieg nastawa tempomatu / aktualna prędkość pojazdu niskie ciśnienie w układzie hamulcowym (ETS2/ATS wykorzystując kontrolkę wody w filtrze paliwa) podniesienie osi (ETS2/ATS wykorzystując kontrolkę wyłączonej poduszki powietrznej pasażera) kończącego się czasu pracy (ETS2/ATS wykorzystując kontrolkę uszkodzenia wspomagania kierownicy oraz kontrolkę pasów bezpieczeństwa) przekroczonego limitu prędkości na drodze (ETS2/ATS wykorzystując kontrolkę usterki tempomatu (tylko Peugeot 407)) zbyt wysokich obrotów (ETS2/ATS wykorzystując kontrolkę trójkąta ostrzegawczego) retardera (ETS2/ATS wykorzystując kontrolkę świec żarowych) ekonomicznej jazdy (wykorzystując kontrolkę ECO) działanie ESP działanie ABS Działanie licznika w grach można zobaczyć na poniższych zdjęciach. *** Zbuduj sam własny projekt i odkrywaj tajniki CAN BUS! *** Z tego miejsca chciałbym gorąco zachęcić wszystkich zainteresowanych do spróbowania swoich sił i budowy własnego projektu z licznikiem opartym na magistrali CAN Bus. Elementy niezbędne do budowy projektu oraz same liczniki są bardzo tanie i projekt powinien spokojnie zamknąć sie w 100-150zł. Magistrala CAN grupy PSA jest bardzo dobrze opisana, obszerną dokumentację stanowiącą fundamentalny filar wiedzy można znaleźć pod TYM linkiem. Jeśli do wybranego przez Ciebie licznika nie ma żadnej dokumentacji to nic straconego, wystarczy napisać bardzo prosty generator losowych wartości bajtówki. Metoda ta nazywa się brute force i jest bardzo efektywna. Należy jednak korzystać z niej ostrożnie ponieważ istnieje niewielka szansa na zbrickowanie licznika. Eksperymentowanie z licznikiem oraz CAN Bus'em pozwoli Tobie także lepiej zrozumieć cały proces komunikacyjny, który finalnie zapala nielubiany check engine na liczniku. Za pomocą modułu MCP2515 możesz także podsłuchać co "szumi" w magistrali CAN Twojego samochodu. Jeśli rozszyfrujesz te dane to nic nie stoi na przeszkodzie abyś zaprojektował swój własny wyświetlacz doładowania, cyfrowy prędkościomierz czy wyświetlacz temperatury oleju w silniku. *** Wykorzystaj mój kod! *** Jeśli jednak nie czujesz się na siłach aby zbudować własny licznik to możesz bez problemu wykorzystać opracowane przeze mnie liczniki wraz z kodem na Arduino. Wszelkie informacje odnośnie budowy takiego projektu znajdziesz w poradniku na moim kanale:
  21. Miesiąc po skończeniu wstępnego kursu na Forbocie o arduino (w grudniu 2023), zacząłem myśleć jakim projektem się zająć. Na początku próbowałem robić różne proste rzeczy, ale gdy stwierdziłem, że kupię drukarkę 3D to pójdę o krok dalej i wrzucę się na głęboką wodę. I tak zaczęła się przygoda z tworzeniem kierownicy do simracingu na bazie kirownicy F1 z 2023 roku z bolidu mercedesa. W tym też momencie zacząłem się uczyć programów projektowych (fusion 360 itp) i szukać potrzebnych części. Na początku miała to byc prosta kierownica z 12 przyciskami. Ale gdy odkryłem bibliotekę joystick.h to stwierdziłem że idę na całość. Całość zajęła jakieś 1,5 mc. Lącznie z ogarnięciem drukarki która nie chciała współpracować. Znając podstawy dowiedziałem się że da się to zrobić na dowolnych arduino z ATmega32U4. Poniżej znajdziecie też trochę kodu. Na początku (co było złym pomysłem) próbowałem nauczyć się tworzenia płytek PCB nie wiedząc jeszcze jak połącze wszystko. (VCC pomyliłem z GND :D) Stwierdizłem, że zaprojektuje całość, ale nie wiedziałem dokładnie ile miejsca potrzebuje. Wersja miała zawierac tylko przyciski, joystick i 2-3 enkodery. testowo podpięte pod arduino. użyłem większych buttonów podświetlanych. Zostałem przy niebieskich i białych, bo pobierały najmniej pradu. Po przymiarkach stwierdziłem że robie full kierę z F1. Projekt to H005. całość robiona według instrukcji, ale z dużymi zmianami. Większe buttony, enkodery które miałem nie mieściły się. Inne pokrętła, no i całość na jednym arduino. Dodatkowo dokupiłem ekran Vocore 4,3 cala. Projekt był pod 4,0 więc przerobiłem obudowę pod niego. Na początku wpięte wszystkie buttony i enkodery, tak by skręcić całość bez tylnej pokrywy. wszystko sprawdzane 10 razy by nie musieć rozkręcać wszystkiego po złożeniu. Całość obklejona "carbonem" i opaskami do tenisa + tasma izolacyjna. Jeśli chodzi o okablowanie, użyłem płytek by moc na nich ogarnąć buttony i GND. Po podpięciu wszystkiego kabli było na tyle dużo że całość nie zamknęła się w obudowie. Musiałem ją pogrubić. Dodatkowo dodałem 7 way joystick, ale używam tylko 4 kierunkowy + przycisk. Nie starczyło wejść w arduino na więcej. - 12 wejść pod rotary enkodery, - 1 wejście pod 11 buttonów + joystick + manetki, - 2 wejścia pod 2x 12 pos switch, łącznie 52 buttony + ekran Manetki według projektu. Całość po skręceniu. Jedno pokrętło środkowe to potencjometr podpiety do VCC i rezystorem 330ohm by regulować podświetlenie. dodatkowo ekran podpięty na osobnym kablu usb. Same kable usb w środku wpięte do 7 din avaitor kabla, wszystko na jednym kablu z koncowka na 2x usb wpięte do PC. Sam ekran sterowany za pomocą SimHuba. i po naklejeniu naklejek. Po złożeniu całości wyszły problemy z bouncingiem enkoderów. Po dwóch dniach udało mi się rozwiązać problem bez użycia interrupt pinów. pierwsza zmiana to sposób sprawdzania 6 enkoderów. void read_encoder_1() { // Encoder interrupt routine for both pins. // if they are valid and have rotated a full indent Old_AB_1 <<=2; // Remember previous state if (digitalRead(PIN_A_1)) Old_AB_1 |= 0x02; // Add current state of pin A if (digitalRead(PIN_B_1)) Old_AB_1 |= 0x01; // Add current state of pin B encval_1 += enc_states[( Old_AB_1 & 0x0f )]; // Update counter_1 if encoder has rotated a full indent, that is at least 4 steps if( encval_1 > 3 ) { // Four steps forward Joystick.pressButton(12); set_rotary = 12; encval_1 = 0; } else if( encval_1 < -3 ) { // Four steps backward Joystick.pressButton(13); set_rotary = 13; // Update counter_1 encval_1 = 0; } } // Encoder value static const int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; // Lookup table Same buttony działają według tego schematu, podpiete pod jednym pinem sprawdzam wartość ograniczając każdy następny 1k rezystorem. Nie bawiłem sie w wyliczenia by było idealnie podzielone na 1023/ ilość buttonów. Po prostu sprawdzałem odczyt i wpisywałem zakresy z marginesem kilku %. Niby jest ograniczenie że nie możemy kliknąć więcej niz jednego przycisku, ale w moim przypadku jeśli klikniemy "wyzszy wartością" przycisk i pozniej kolejny, to dostajemy wieloklik, więc częściowo działa. Dodatkowo kod starałem się tak napisać by buttony do mommentu puszczenia były na stałe wciśnięte i by nie "migotały". //BUTTONS value_buttons = analogRead(A3); rotary12pos2 = analogRead(A1); rotary12pos = analogRead(A2); //Serial.println(value_buttons); if (value_buttons > 815 && value_buttons < 820) { // Joystick.pressButton(0); // delay(button_delay); setbutton = 0; //Serial.println("Button1"); //Serial.println(value_buttons); } else if (value_buttons > 764 && value_buttons < 770) { // Joystick.pressButton(1); // delay(button_delay); setbutton = 1; //Serial.println("Button2"); //Serial.println(value_buttons); } else if (value_buttons > 677 && value_buttons < 683) { // Joystick.pressButton(2); // delay(button_delay); setbutton = 2; //Serial.println("Button3"); //Serial.println(value_buttons); } else if (value_buttons > 507 && value_buttons < 515) { // Joystick.pressButton(3); // delay(button_delay); setbutton = 3; //Serial.println("Button4"); //Serial.println(value_buttons); } else if (value_buttons < 2) { //Joystick.pressButton(4); // delay(button_delay); setbutton = 4; //Serial.println("Button5"); //Serial.println(value_buttons); } else if (value_buttons > 849 && value_buttons < 855) { //Joystick.pressButton(5); // delay(button_delay); setbutton = 5; //Serial.println("Button4"); //Serial.println(value_buttons); } else if (value_buttons > 873 && value_buttons < 880) { // Joystick.pressButton(6); // delay(button_delay); setbutton = 6; //Serial.println("Button4"); //Serial.println(value_buttons); } else if (value_buttons > 891 && value_buttons < 898) { // Joystick.pressButton(7); // delay(button_delay); setbutton = 7; //Serial.println("Button4"); //Serial.println(value_buttons); } else if (value_buttons > 904 && value_buttons < 912) { // Joystick.pressButton(8); // delay(button_delay); setbutton = 8; //Serial.println("Button4"); //Serial.println(value_buttons); } else if (value_buttons > 956 && value_buttons < 960) { // Joystick.pressButton(9); // delay(button_delay); setbutton = 9; //Serial.println("Button4"); //Serial.println(value_buttons); } else if (value_buttons > 918 && value_buttons < 923) { //Joystick.pressButton(10); // delay(button_delay); setbutton = 10; //Serial.println("Button4"); //Serial.println(value_buttons); } else if (value_buttons > 951 && value_buttons < 958) { //Joystick.pressButton(11); // delay(button_delay); setbutton = 11; //Serial.println("Button4"); } else if (value_buttons > 968 && value_buttons < 971) { //Joystick.pressButton(50); // delay(button_delay); setbutton = 50; } else if (value_buttons > 964 && value_buttons < 968) { //Joystick.pressButton(51); // delay(button_delay); setbutton = 51; } else if (value_buttons > 933 && value_buttons < 942) { setbutton = -1; Joystick.setHatSwitch(0, 0); delay(button_delay); setbutton = -1; } else if (value_buttons > 927 && value_buttons < 932) { setbutton = -1; Joystick.setHatSwitch(0, 90); delay(button_delay); } else if (value_buttons > 945 && value_buttons < 952) { setbutton = -1; Joystick.setHatSwitch(0, 180); delay(button_delay); } else if (value_buttons > 940 && value_buttons < 949) { setbutton = -1; Joystick.setHatSwitch(0, 270); delay(button_delay); } //Serial.println(value_buttons); if(value_buttons == 1023){ Joystick.setHatSwitch(0, -1); Joystick.setHatSwitch(0, -1); Joystick.setHatSwitch(0, -1); Joystick.setHatSwitch(0, -1); Joystick.setButton(setbutton,0); for(int i =0; i<12; i++){ Joystick.releaseButton(i); } Joystick.releaseButton(50); Joystick.releaseButton(51); setbutton = -1; } Joystick.setButton(setbutton,1); Niestety przy stałym sprawdzaniu enkoderów i buttonów było to za wolne by enkodery wyłapywały każdy obrót. Stwierdziłem że przez 90% czasu działania kodu bede sprawdzał enkodery, a przez reszte buttony które nie potrzebują aż takiej precyzji. unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; static int counter = 0; static bool flag = false; if (counter < firstPartDuration / 1) { // rotary encoders read_encoder_1(); read_encoder_2(); read_encoder_3(); read_encoder_4(); read_encoder_5(); read_encoder_6(); // If count has changed print the new value to serial if(set_rotary != -1){ delay(70); Joystick.setButton(set_rotary, 0); set_rotary = -1; } } else if (counter < (firstPartDuration + secondPartDuration) / 1) { // CHECK BUTTONS // CHECK ROT SWITCH POS } Dzięki temu w dowolnym momencie poruszając enkoderami, działają idealnie, bez debouncingu, i za każdym razem gdy je przekręce. Co bym zmienił w kolejnej wersji? Na pewno zrobił płytkę PCB z wszystkimi komponentami by podpiąć tylko kable. Projekt który wykonałem jest poniżej. Sama płytka jest dość uniwersalna. I w zalezności co podepniemy to zadziała. Dodatkowo dodałbym rev light za jeden pin do którego jest podpięty 12 rot pos Porównujac z kupną DIY którą miałem do tej pory, jest to spoooory przeskok Sama kierownica jest bardzo wygodna. Wytrzymała już 10h jeżdzenia na 6Nm kierownicy TS-PC. Nic sie nie rozpada. Jest lekki flex bardziej przez problemy z projektem który w ogóle nie polecam składać bo jest to mordęga. Nowa Stara, kupiona na OLX
  22. Witam. Od wielu lat udzielam się na https://www.forumfajerwerki.pl Animowałem tam kilka projektów amatorskich systemów pirotechnicznych. W założeniach miały one spełniać funkcję edukacyjną i poprawić bezpieczeństwo fanów fajerwerków. Były nawet dosyć popularne, powstało kilka ich zmodyfikowanych wersji, ale miały też pewne ograniczenia, głównie związane z programowaniem uC. Pomyślałem, że Arduino rozwiąże te problemy i do nowego projektu wybrałem Arduino Nano Every. Płytka PCB została zaprojektowana w KiCad, a kod dla Arduino powstał w Arduino IDE. Hardware jest dostępny jako open source, a program sterujący tym systemem jest freeware. Pliki projektu dostępne są w repozytorium na GitHub https://github.com/pyrobox/knk1303ar1 Płytka PCB została zaprojektowana pod elementy THT aby ułatwić montaż i eksperymenty. Niektóre elementy z PCB nie zostały jeszcze uwzględnione w kodzie np. LoRa E32TTL100 czy Ra-02. Kod jest dosyć obszerny więc został podzielony na kilkanaście plików .cpp i zawiera mi.in.: - obsługę transmisji szeregowej, odbiór i nadawanie, po magistrali RS485 - obróbkę odebranych danych, w tym np. analizę stringa, kalkulację CRC - obsługę wyświetlacza LCD 2x16 z konwerterem I2C, w tym menu na 3 przyciskach - pomiar napięcia DC za pomocą modułu ADS1115 - sterowanie przekaźnikami poprzez rejestry przesuwające 74595 - zapis i odczyt ustawień do/z EEPROM Zastosowanie przekaźników zostanie pewnie uznane za rozwiązanie archaiczne ale uważam, że są one bezpieczniejsze w amatorskich projektach tego typu urządzeń. Poza tym zakładam, ze pojawią się modyfikacje projektu, w których przekaźniki zostaną zastąpione przez MOSFETy. To jest mój pierwszy i na razie jedyny projekt z Arduino. Pewnie pełno w nim fuszerek, ale prototyp działa więc dla mnie jest ok Wątek na forumfajerwerki.pl https://www.forumfajerwerki.pl/topic/9585-forumowy-projekt-opensource-systemu-pirotechnicznego/?do=findComment&comment=165880 Niestety dostęp do niego wymaga rejestracji na forum.
  23. Witam, piszę tu do was z prośbą o pomoc/radę w sprawie mojego mini projektu. Jestem początkującym w tworzenia elektroniki więc proszę o większą wyrozumiałość w kwestii specjalistycznego nazewnictwa. Celem projektu jest zamienienie podświetlenia przycisku zasilania na obudowie komputera na podświetlenie RGB zsynchronizowane z podświetleniem w obudowie. Sam przycisk ma trzy stany podświetlenia (świeci, mryga i nie świeci). Problem pojawia się, gdy chcemy “zsynchronizować” to z podświetleniem. Na płycie głównej mam trzy dostępne wyjścia: RGB, ARGB, POW-LED. (pin-out zamieszczam poniżej) RGB: 1 - 12v, 2 - G, 3 - R, 4 – B ARGB: 1 - 5v, 2 - Din, 3 - pusty, 4 - GND POW-LED: 1 - 5v, 2 – GND Początkowo zakładam nie korzystać z wyjścia ARGB z powodu większej złożoności tego rodzaju podświetlenia natomiast zostawiam tu informację o jego istnieniu. Schemat powinien realizować taką (pseudo) tablice boolowska: Legenda: IN – tablica stanów wejściowych OUT – tablica stanów wyjściowych PW – zasilanie 5v (POW-LED:1) LED – Czy podświetlenie obudowy się świeci? 12v – Czy na złączu RGB występuje zasilanie? PW LED – Czy przycisk się świeci? LED GRD – puszczenie “minusa” przez gniazdo RGB (RGB:2,3,4) PW GRD – puszczenie “minusa” przez gniazdo PW (POW-LED:2) Opis stanów: Nr.1 - PC włączony Nr.2 - PC wygaszony Nr.3 i 4 – PC uśpiony (przycisk mryga) Nr.5 - PC wyłączone Własnymi siłami doszedłem do takiego prototypu, ale nie jest on idealny. Nie spełnia bowiem przypadku Nr.2 z tablicy. Dostęp mam tylko do tego co jest podłączone do większej płytki stykowej (wyprowadzenia gniazd i diody). Mniejsza jest hipotetyczną implementacja sterowania oświetleniem na płycie głównej. Połączenie minusa pomiędzy płytkami jest nie potwierdzone (ale zakładam, że istnieje). Z braku istnienia modelu Diody RGB (wsp.Anoda) w programie użyłem trzech zwykłych na modelu. Napięcie 3v z baterii też jest umowne. Co do doboru rezystorów to jest to zrobione na oko (na razie) chodzi głównie o zasadę działania. Za wszelkie sugestie, pomysły i podpowiedzi będę bardzo wdzięczny. Ps. Niechciał bym używać w projekcie żadnych mikrokontrolerów typu Arduino itp.
  24. Cześć, przedstawiam projekt dla fanów drinków dla których zachowanie proporcji jest niezmiernie istotne. Postanowiłem, że robot będzie nalewał trzy różne substancje (jak na domowego barmana w zupełności wystarczy). Wykorzystałem w tym celu pompki membranowe, które są stosunkowo tanie, jednak warto użyć zaworów zwrotnych przy każdym z węży ponieważ "na postoju" nie są szczelne i ciecze powoli kapią z dysz robota. Przy innym projekcie zdarzyło mi się, że pompka była nieszczelna, więc w tym zamontowałem je w miejscu w którym ewentualny wyciek nie narobi szkód. We wcześniejszych konstrukcjach ustawiałem lanie zależne od zadanego czasu, jednak po testach (wspierając się wagą kuchenną) stwierdziłem, że odmierzane wartości nie są powtarzalne. Wtedy postanowiłem dodać wbudowaną wagę. Użyłem belki tensometrycznej do 1kg oraz wzmacniacza HX711. Robot zasilany jest zasilaczem wtykowym 12V a jego serce to Arduino Mega - ze względu na zapotrzebowanie na dużą liczbę wejść/wyjść. Do sterowania pompek użyłem gotowego Shielda - sterownika L293D – może sterować czterema silnikami DC i zajmuje mało miejsca w obudowie, a chciałem żeby konstrukcja była zwarta i jak najmniejsza. Początkowo użyłem wyświetlacza 2x16, jednak wyświetlane dane nie były tak przejrzyste, jakbym tego chciał więc zamontowałem wyświetlacz 4x16. Teraz każdy składnik ma swoją nieskróconą nazwę i ma swoją osobną linijkę. Wartości danych substancji ustawia się przy pomocy trzech potencjometrów. Wyskalowałem wartość każdego od 0 do 150g. W przypadku przekroczenia sumy trzech substancji powyżej 250g, zamontowane diody RGB świecą na czerwono (jest to tylko sygnał ostrzegawczy, nie blokuje nalewania). Diody te również „ubarwiają” proces tworzenia drinka (efekt widoczny na załączonym filmie). Po ustawieniu ulubionych proporcji wciskamy START i nalewanie odbywa się automatycznie, przed nalaniem każdego składnika waga samoczynnie się taruje. Można również korzystać z manualnego nalewania oraz tarowania, gdy stworzony drink nie spełnia wszystkich wymagań. Obudowę wydrukowałem na drukarce 3D. Składa się z wielu elementów, żeby był łatwiejszy dostęp do podzespołów oraz żeby pojedynczy wydruk krócej się drukował. Umieściłem z jednej strony okno rewizyjne żeby móc się w razie potrzeby podłączyć do Arduino. Części których użyłem do budowy robota: Arduino ATmega2560 - 1szt. wyświetlacz LCD 4x20 - Niebieski - ze sterownikiem kompatybilnym z HD44780 - QC2004A konwerter I2C do wyświetlacza LCD HD44780 wzmacniacz do belki tensometrycznej HX711 - 1szt. belka tensometryczna 1kg - 1szt pompa do cieczy 12V 110l/h - 7mm – 3szt moduł sterownika silnika L293 UNO MEGA shield - 1szt moduł diody RGB 5V - 2szt, wtyk DC 2,1/5,5mm z zaciskami skręcanymi – 1szt. gniazdo DC 2,1/5,5 do obudowy plastikowe -1szt. zasilacz wtyczkowy UMEC impulsowy 12V 30W 2,5A - 1szt. przełącznik kołyskowy 15x10mm – 1 szt przewody połączeniowe przycisk podświetlany - 1szt. przycisk okrągły monostabilny chwilowy czerwony - 4szt. potencjometr liniowy 1K – 3szt. .zawór zwrotny - 3szt. wężyk silikonowy 1,5m Oto kod, z którym się najdłużej męczyłem, ale działa #include <HX711.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <AFMotor.h> #define I2C_ADDR 0x3F #define start 52 #define manpom1 50 #define manpom2 46 #define manpom3 44 #define tara 48 #define redl 24 #define bluel 22 #define greenl 26 #define redr 30 #define bluer 28 #define greenr 32 HX711 waga; LiquidCrystal_I2C lcd(I2C_ADDR, 2, 1, 0, 4, 5, 6, 7); int led = 13; float ciezar; int ml1 = 0; int ml2 = 0; int ml3 = 0; int czasMigania = 250; int predkoscNalewania = 200; char odczyt[8]; AF_DCMotor pompa1 (3); AF_DCMotor pompa2 (2); AF_DCMotor pompa3 (1); void setup() { Serial.begin(9600); pinMode(start, INPUT_PULLUP); pinMode(manpom1, INPUT_PULLUP); pinMode(manpom2, INPUT_PULLUP); pinMode(manpom3, INPUT_PULLUP); pinMode(tara, INPUT_PULLUP); pinMode(redl, OUTPUT); pinMode(bluel, OUTPUT); pinMode(greenl, OUTPUT); pinMode(redr, OUTPUT); pinMode(bluer, OUTPUT); pinMode(greenr, OUTPUT); lcd.begin(20, 4); lcd.setBacklightPin(3, POSITIVE); digitalWrite(led, HIGH); lcd.setBacklight(HIGH); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Witaj!"); lcd.setCursor(0, 1); lcd.print("Chlapnij sobie!"); lcd.setCursor(13, 3); lcd.print("Kasztan"); delay(1000); pinMode(led, OUTPUT); waga.begin(A1, A2); waga.set_scale(419341.0 / 200.0); waga.tare(5); pompa1.setSpeed(predkoscNalewania); pompa2.setSpeed(predkoscNalewania); pompa3.setSpeed(predkoscNalewania); } void loop() { pomiar(); ekran(); if ((ml1 + ml2 + ml3) > 250) { czerwona(); delay(500); ciemno (); } else { ciemno(); } if (digitalRead(start) == LOW) { waga.tare(); ekran(); Serial.println("zeruje"); if (ml1 >= 0) { waga.tare(10); pomiar(); ekran(); Serial.println("nalewam promile"); while (ciezar <= ml1) { pomiar(); ekran(); pompa1.run(FORWARD); led1(); } pompa1.run(RELEASE); Serial.println("promile przerwa"); delay(100); if (ml2 >= 0) { waga.tare(10); pomiar(); ekran(); Serial.println("nalewam rozcienczacz"); while (ciezar <= ml2) { pomiar(); ekran(); pompa2.run(FORWARD); led2(); } pompa2.run(RELEASE); Serial.println("rozcienczacz przerwa"); delay(100); if (ml3 >= 0) { waga.tare(10); pomiar(); ekran(); Serial.println("nalewam kwas"); while (ciezar <= ml3) { pomiar(); ekran(); pompa3.run(FORWARD); led3(); } pompa3.run(RELEASE); Serial.println("kwaas przerwa"); delay(100); } } } waga.tare(); pomiar(); kolorowo(); ciemno(); } if (digitalRead(manpom1) == LOW) { pompa1.run(FORWARD); led1(); } else { pompa1.run(RELEASE); } if (digitalRead(manpom2) == LOW) { pompa2.run(FORWARD); led2(); } else { pompa2.run(RELEASE); } if (digitalRead(manpom3) == LOW) { pompa3.run(FORWARD); led3(); } else { pompa3.run(RELEASE); } if (digitalRead(tara) == LOW) { waga.tare(10); } } void pomiar() { ml1 = analogRead(A5); ml1 = map(ml1, 1020, 0, 0, 150); ml2 = analogRead(A4); ml2 = map(ml2, 1020, 0, 0, 150); ml3 = analogRead(A3); ml3 = map(ml3, 1020, 0, 0, 150); ciezar = waga.get_units(); dtostrf(ciezar, 5, 0, odczyt); } void ekran() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("1.Alkohol:"); lcd.print(ml1); lcd.setCursor(0, 1); lcd.print("2.Dodatek:"); lcd.print(ml2); lcd.setCursor(0, 2); lcd.print("3.Kwas:"); lcd.print(ml3); lcd.setCursor(0, 3); lcd.print("Waga:"); lcd.print(odczyt); lcd.print("g"); Serial.println(ml1); Serial.println(ciezar); } void ciemno() { digitalWrite(redl, LOW); digitalWrite(greenl, LOW); digitalWrite(bluel, LOW); digitalWrite(redr, LOW); digitalWrite(greenr, LOW); digitalWrite(bluer, LOW); } void czerwona () { digitalWrite(redl, HIGH); digitalWrite(greenl, LOW); digitalWrite(bluel, LOW); digitalWrite(redr, HIGH); digitalWrite(greenr, LOW); digitalWrite(bluer, LOW); } void zielona () { digitalWrite(redl, LOW); digitalWrite(greenl, HIGH); digitalWrite(bluel, LOW); digitalWrite(redr, LOW); digitalWrite(greenr, HIGH); digitalWrite(bluer, LOW); } void niebieska () { digitalWrite(redl, LOW); digitalWrite(greenl, LOW); digitalWrite(bluel, HIGH); digitalWrite(redr, LOW); digitalWrite(greenr, LOW); digitalWrite(bluer, HIGH); } void kolorowo () { digitalWrite(redl, HIGH); delay(czasMigania); digitalWrite(greenl, HIGH); delay(czasMigania); digitalWrite(bluel, HIGH); delay(czasMigania); digitalWrite(redr, HIGH); delay(czasMigania); digitalWrite(greenr, HIGH); delay(czasMigania); digitalWrite(bluer, HIGH); delay(czasMigania); delay(500); } void led1 () { digitalWrite(redl, HIGH); digitalWrite(greenl, HIGH); digitalWrite(bluel, LOW); digitalWrite(redr, HIGH); digitalWrite(greenr, HIGH); digitalWrite(bluer, LOW); } void led2 () { digitalWrite(redl, LOW); digitalWrite(greenl, HIGH); digitalWrite(bluel, HIGH); digitalWrite(redr, LOW); digitalWrite(greenr, HIGH); digitalWrite(bluer, HIGH); } void led3 () { digitalWrite(redl, HIGH); digitalWrite(greenl, LOW); digitalWrite(bluel, HIGH); digitalWrite(redr, HIGH); digitalWrite(greenr, LOW); digitalWrite(bluer, HIGH); } Link do filmu:
  25. import cv2 import pytesseract import time from pytesseract import Output def extract_license_plate(image_path): image = cv2.imread(image_path) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0) edges = cv2.Canny(blur, 100, 200) contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10] plate_text = None for contour in contours: peri = cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, 0.018 * peri, True) if len(approx) == 4: x, y, w, h = cv2.boundingRect(approx) roi = image[y:y + h, x:x + w] plate_text = pytesseract.image_to_string(roi, config='--psm 8 --oem 3 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') return ''.join(filter(str.isalnum, plate_text)) return "no text detected" cap=cv2.VideoCapture(0) try: while True: ret, frame = cap.read() if ret: cv2.imwrite('/home/marek/tablica.png',frame) print("Image saved") text = extract_license_plate('/home/marek/tablica.png') else: print("fail") if text is not None: print(f"Extracted Text: {text}") time.sleep(5) except Exception as e: print(f"An error occurred: {e}") finally: cap.release() print("Camera released.") Pracuję nad projektem systemu służącego do automatycznego otwierania bramy, w momencie rozpoznania przez kamerę z Raspberry Pi, numerów tablic rejestracyjnych zapisanych w pliku tekstowym. Jestem dość zielony w jakiekolwiek programy związane z systemami wizyjnymi i mocno posiłkowałem się ChatemGPT 4, wrzuciłem do chatu zdjęcia przypominające docelowy obraz z kamery i kazałem mu pod to napisać program. Program działa prawie idealnie kiedy zczytuje tablice z gotowych zdjęć, jednak gdy zdjęcia pochodzą z kamery i pokazuje przed nią dokładnie to samo zdjęcie tylko wydrukowane, program nie rozpoznaje żadnych znaków. Pytanie gdzie może leżeć problem, czy wpływ na to ma zbyt niska jakość obrazu z kamerki (używam kamery ZeroCam z przejściówka do Raspberry PI 3A+) , potencjalnie zły kąt zdjęcia przed kamerka czy może jakiś błąd w kodzie? Testuje działanie na załączonym obrazku Z góry dziękuje za pomoc, ewentualny namiar do kogoś kto mógłby pomóc :))
×
×
  • Utwórz nowe...