Skocz do zawartości

Przeszukaj forum

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

  • 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 - roboty
    • Projekty - DIY
    • Projekty - DIY (początkujący)
    • Projekty - 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


Strona

Znaleziono 6 wyników

  1. W końcu się zebrałem i złożyłem ustrojstwo do kupy więc niniejszym chwalę się pierwszym projektem nadającym się do chwalenia Projekt oparty o F401CCU6, sterowanie za pomocą trzech przycisków. Wyświetlacz 1.8" na ST7735S (ten z kursu). Funkcje: Dalmierz (moduł TF-Luna) z funkcją ciągłego i pojedynczego pomiaru Poziomica (MPU6050) z możliwością ustawienia "zera" użytkownika Pomiar temperatury i wilgotności (DHT11) Latarka (WS2812B) świecąca kolorem białym, czerwonym lub zielonym Ustawienia - zmiana jasności, tryb jasny/ciemny, zmiana jednostek Najwięcej pracy było oczywiście z tworzeniem interfejsu użytkownika. Ikonki brałem z http://flaticon.com przy czym musiałem je dodatkowo edytować żeby dobrze się prezentowały na wyświetlaczu. Ponadto musiałem robić po dwie wersje - dla trybu jasnego i ciemnego. Zasilanie - bateria 9v 6f22 zamknięta w obudowie. Dodatkowo dorobiłem płytkę ze stabilizatorami napięcia na 5V i 3.3V, na której dodatkowo umieściłem bufor cyfrowy dla diod programowalnych. Obudowa to ceownik aluminiowy z panelem drukowanym na drukarce 3D. Ogólnie jestem dość zadowolony z efektu ale jest kilka mankamentów: Zielony przycisk mi odstaje Wyświetlacz muli na napisach. Pasowałoby zrobić swoją bibliotekę bo ta, z której korzystałem jest średnio optymalna ale uznałem, że szkoda roboty.0 Pobór energii jest za wysoki, również po wyłączeniu urządzenia. Tu by konieczna była rozbudowa płytki zasilającej bo obecnie bateria padnie najprawdopodobniej po kilku dniach (jeszcze nie dobiłem do limitu). Spaghetti w obudowie w pewnym momencie bałem się, że nie dam rady tego tam upchnąć ale skracanie kabli załatwiło temat. Na ten moment jeszcze nie bawiłem się w rysowanie płytek więc jest jak jest. Pewnie nie będę już przy tym dłubał bo zaczynając od etapu gdzie nie wiedziałem jak podłączyć programator do BlackPilla spędziłem przy tym aż nadto czasu Pora zacząć coś nowego
  2. 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 ?
  3. Posiadam wyświetlacz TFT do arduino (kontroler ili9486, biblioteka MCUFRIEND_kb) z arduino działa bardzo dobrze, lecz ja chcę go użyć z esp32. Używam wyświetlacz wraz z wemos d1 uno esp32. Wyświetlanie grafiki działa dobrze lecz gdy chce użyć ekranu dotykowego to odczytuje dotyk lecz nie reaguje na klawisze, które są wyświetlane na ekranie (na arduino działają). A by odczytywało dotyk i dobrze działał wyświetlacz to połączyłem kablami tak jak na poniższym obrazku (bez tego zielonego kabla nie odczytuje dotyku). Dodam też, że kalibracja ekranu działa dobrze poza jednym rogiem ekranu. Poniżej kod jaki wgrywam do esp różni się od tego co wgrywam do arduino tylko pinami od dotyku. #include <MCUFRIEND_kbv.h> MCUFRIEND_kbv tft; // hard-wired for UNO shields anyway. #include <TouchScreen.h> #include <stdint.h> #include "TouchScreen.h" char *name = "Please Calibrate."; //edit name of shield const int XP=27,XM=15,YP=4,YM=14; //320x480 ID=0x1581 const int TS_LEFT=925,TS_RT=85,TS_TOP=949,TS_BOT=72; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); TSPoint tp; #define MINPRESSURE 200 #define MAXPRESSURE 1000 int16_t BOXSIZE; int16_t PENRADIUS = 1; uint16_t ID, oldcolor, currentcolor; uint8_t Orientation = 0; //PORTRAIT // Assign human-readable names to some common 16-bit color values: #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF void show_Serial(void) { Serial.println(F("Most Touch Screens use pins 6, 7, A1, A2")); Serial.println(F("But they can be in ANY order")); Serial.println(F("e.g. right to left or bottom to top")); Serial.println(F("or wrong direction")); Serial.println(F("Edit name and calibration statements\n")); Serial.println(name); Serial.print(F("ID=0x")); Serial.println(ID, HEX); Serial.println("Screen is " + String(tft.width()) + "x" + String(tft.height())); Serial.println("Calibration is: "); Serial.println("LEFT = " + String(TS_LEFT) + " RT = " + String(TS_RT)); Serial.println("TOP = " + String(TS_TOP) + " BOT = " + String(TS_BOT)); Serial.println("Wiring is always PORTRAIT"); Serial.println("YP=" + String(YP) + " XM=" + String(XM)); Serial.println("YM=" + String(YM) + " XP=" + String(XP)); } void show_tft(void) { tft.setCursor(0, 0); tft.setTextSize(1); tft.print(F("ID=0x")); tft.println(ID, HEX); tft.println("Screen is " + String(tft.width()) + "x" + String(tft.height())); tft.println(""); tft.setTextSize(2); tft.println(name); tft.setTextSize(1); tft.println("PORTRAIT Values:"); tft.println("LEFT = " + String(TS_LEFT) + " RT = " + String(TS_RT)); tft.println("TOP = " + String(TS_TOP) + " BOT = " + String(TS_BOT)); tft.println("\nWiring is: "); tft.println("YP=" + String(YP) + " XM=" + String(XM)); tft.println("YM=" + String(YM) + " XP=" + String(XP)); tft.setTextSize(2); tft.setTextColor(RED); tft.setCursor((tft.width() - 48) / 2, (tft.height() * 2) / 4); tft.print("EXIT"); tft.setTextColor(YELLOW, BLACK); tft.setCursor(0, (tft.height() * 6) / 8); tft.print("Touch screen for loc"); while (1) { tp = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (tp.z < MINPRESSURE || tp.z > MAXPRESSURE) continue; if (tp.x > 450 && tp.x < 570 && tp.y > 450 && tp.y < 570) break; tft.setCursor(0, (tft.height() * 3) / 4); tft.print("tp.x=" + String(tp.x) + " tp.y=" + String(tp.y) + " "); } } void setup(void) { uint16_t tmp; tft.reset(); ID = tft.readID(); tft.begin(ID); Serial.begin(9600); show_Serial(); tft.setRotation(Orientation); tft.fillScreen(BLACK); show_tft(); BOXSIZE = tft.width() / 6; tft.fillScreen(BLACK); tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED); tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW); tft.fillRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, GREEN); tft.fillRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, CYAN); tft.fillRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, BLUE); tft.fillRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, MAGENTA); tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE); currentcolor = RED; delay(1000); } void loop() { uint16_t xpos, ypos; //screen coordinates tp = ts.getPoint(); //tp.x, tp.y are ADC values // if sharing pins, you'll need to fix the directions of the touchscreen pins pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); // we have some minimum pressure we consider 'valid' // pressure of 0 means no pressing! if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE) { // most mcufriend have touch (with icons) that extends below the TFT // screens without icons need to reserve a space for "erase" // scale the ADC values from ts.getPoint() to screen values e.g. 0-239 // // Calibration is true for PORTRAIT. tp.y is always long dimension // map to your current pixel orientation switch (Orientation) { case 0: xpos = map(tp.x, TS_LEFT, TS_RT, 0, tft.width()); ypos = map(tp.y, TS_TOP, TS_BOT, 0, tft.height()); break; case 1: xpos = map(tp.y, TS_TOP, TS_BOT, 0, tft.width()); ypos = map(tp.x, TS_RT, TS_LEFT, 0, tft.height()); break; case 2: xpos = map(tp.x, TS_RT, TS_LEFT, 0, tft.width()); ypos = map(tp.y, TS_BOT, TS_TOP, 0, tft.height()); break; case 3: xpos = map(tp.y, TS_BOT, TS_TOP, 0, tft.width()); ypos = map(tp.x, TS_LEFT, TS_RT, 0, tft.height()); break; } // are we in top color box area ? if (ypos < BOXSIZE) { //draw white border on selected color box oldcolor = currentcolor; if (xpos < BOXSIZE) { currentcolor = RED; tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE); } else if (xpos < BOXSIZE * 2) { currentcolor = YELLOW; tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE); } else if (xpos < BOXSIZE * 3) { currentcolor = GREEN; tft.drawRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, WHITE); } else if (xpos < BOXSIZE * 4) { currentcolor = CYAN; tft.drawRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, WHITE); } else if (xpos < BOXSIZE * 5) { currentcolor = BLUE; tft.drawRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, WHITE); } else if (xpos < BOXSIZE * 6) { currentcolor = MAGENTA; tft.drawRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, WHITE); } if (oldcolor != currentcolor) { //rub out the previous white border if (oldcolor == RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED); if (oldcolor == YELLOW) tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW); if (oldcolor == GREEN) tft.fillRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, GREEN); if (oldcolor == CYAN) tft.fillRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, CYAN); if (oldcolor == BLUE) tft.fillRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, BLUE); if (oldcolor == MAGENTA) tft.fillRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, MAGENTA); } } // are we in drawing area ? if (((ypos - PENRADIUS) > BOXSIZE) && ((ypos + PENRADIUS) < tft.height())) { tft.fillCircle(xpos, ypos, PENRADIUS, currentcolor); } // are we in erase area ? // Plain Touch panels use bottom 10 pixels e.g. > h - 10 // Touch panels with icon area e.g. > h - 0 if (ypos > tft.height() - 10) { // press the bottom of the screen to erase tft.fillRect(0, BOXSIZE, tft.width(), tft.height() - BOXSIZE, BLACK); } } }
  4. Witam! To mój pierwszy wpis w dziale DIY. Projektem jest (a właściwie dopiero będzie) mini konsolka do gier na STM32F1. Robię ten projekt dla mojego 3-letniego synka. Docelowo będę mu wgrywać na nią różne napisane przeze mnie gry, ale na początek zacznę od klasyki, czyli gra w węża Robiłem już podobny projekt przy okazji kursu SMT32 na Forbocie, więc szybko powinienem napisać niezbędny kod. Tym razem ma to być gotowe urządzenie które bez problemu będzie mógł obsłużyć 3-latek. Założenia projektu: 1. Mikrokontroler STM32F1 2. Ekran TFT kolorowy 240x320 3. Zasilanie bateryjne LiPo z ładowaniem przez gniazdo USB (więcej szczegółów w moim wątku w dziale Zasilanie - szczególnie ostatni mój post) 4. Obudowa w całości drukowana w 3D 5. Żadnych gotowych modułów. Własny projekt PCB i własny montaż. 6. Klawiatura: Krzyżyk, przycisk A, przycisk B oraz przycisk POWER, jak w starych Game - Boy'ach 7. Dzwięk: Nad tym jeszcze nie myślałem, brak I2S oraz DACa na mojej płytce Nucleo trochę utrudnia sprawę. Może będzie coś na Timerach i PWM. Zobaczymy. Teraz po kolei. Pierwsze co musiałem zrobić to ogarnąć wyświetlanie na TFT. Zakupiłem trochę w ciemno kilka wyświetlaczy 2,8" na ILI9341. Mój brak doświadczenia z TFT natychmiast się zemścił. Po odbiorze przesyłki okazało się że obsługa SPI wcale nie jest oczywista i jestem skazany na 16-bitową magistralę. Nie znalazłem nigdzie driverów na STM32 do sterowania tym kontrolerem przy takim połączeniu, ale znalazłem kilka projektów na GitHub'ie gdzie było sterowanie przez magistralę 8-bitową. Postanowiłem więc na podstawie tych projektów napisać własne drivery i procedury wyświetlania podstawowych kształtów. W trakcie prac nad optymalizacją wyświetlania okazało się że jednak 16-bitowa magistrala to doskonały pomysł i jest 4-krotnie szybsza od 8-bitowej. Dlaczego? Już tłumaczę: Gdy używa się 8-bitowej szyny danych to wysłanie piksela wygląda następująco (już po ustawieniu adresu): - Ustawiamy pierwsze 8 bitów koloru - WR strobe - czyli szybka zmiana linii WR na 0 i powrót 1 - Ustawiamy kolejne 8 bitów koloru - WR strobe - czyli szybka zmiana linii WR na 0 i powrót 1 I powtarzamy do czasu wypełnienia zaadresowanego okienka. Czyli na każdy piksel przypadają 4 kroki. Gdy używamy 16-bitowej magistrali - wygląda to następująco: - Ustawiamy 16 bitów koloru - WR strobe - czyli szybka zmiana linii WR na 0 i powrót 1 I powtarzamy do czasu wypełnienia zaadresowanego okienka. Czyli na każdy piksel przypadają 2 kroki. Ale przecież pisałem że jest 4 razy szybciej, a tu wychodzi że 2 razy No więc łatwo można zauważyć, że przy 16 bitach raz ustawiony kolor na linii danych możemy zostawić do czasu aż będziemy musieli użyć innego koloru. Więc jeżeli mamy kilkaset pikseli do wypełnienia jednym kolorem to raz go ustawiamy, a później już tylko WR strobe tak długo jak potrzebujemy Czyli realnie wykonujemy tylko jeden krok. Zaimplementowałem to w moich driverach i rezultaty były doskonałe. Na tyle dobre że odpadła mi konieczność posiadania pamięci pod bufor klatki. Wszystko wyświetla się błyskawicznie: Aktualnie mogę wyświetlać do 8Mpix/s, co teoretycznie pozwala odświeżyć ekran 240x320 ponad 100 razy na sekundę na STM32F1 taktowanym 64MHz. Czyli mogę jeszcze podnieść tą częstotliwość do 72 MHz i jeszcze zwiększyć transfery. Niestety chwilowo mam odcięty programator od płytki Nucleo i muszę kożystać z wewnetrznego oscylatora który pozwala rozkręcić mikroprocesor do 64MHz. Kolejnym problemem z którym musiałem się zmierzyć to mała ilość flash na grafiki do gier. Jak łatwo policzyć jedna pełnoekranowa grafika to 153600 bajty, a mam tylko 128k do dyspozycji. A jeszcze musi się zmieścić program. Rozwiązaniem problemu jest kompresja. Tu znów musiałem od zera napisać program do kompresji grafiki który spełniałby moje wymagania. Kompresor został napisany w Pythonie. A szybki dekoder zaimplementowany w C w driverach na STM32. Pisałem program praktycznie od zera wg mojego pomysłu. Otóż dzieli on grafikę na bloki o jednolitych kolorach, a ich metadane zapisuje w binarnym pliku wyjściowym, albo w pliku C. Bloki są następujące: pozioma linia, pionowa linia, prostokąt. Pojedynczy piksel to pozioma linia o długości 1. Kompresja odbywa się przez rozkład grafiki na takie bloki, a następnie zapisaniu ich parametrów do pliku wyjściowego. Procedurę dekompresji zaimplementowałem w driverach do wyświetlacza, a każdy blok łatwo można wysłać bezpośrednio do pamięci ekranu, gdzie obraz zostaje odtworzony. Kolejną funkcją którą zaimplementowałem w kompresorze jest możliwość kodowania różnicy pomiędzy dwoma grafikami. Tzn jeżeli robię animację to program kompresuje tylko piksele które różnią dwie klatki. Poniżej proces odtwarzania obrazka na wyświetlaczu w zwolnionym tempie: Skoro miałem już ograne wyświetlanie grafiki, przyszedł czas na prototypowanie konsoli i pisanie samego kodu gry Aktualnie moje stanowisko pracy wygląda następująco: Sama gra jest na etapie tworzenia grafiki. Na razie mam animacje na intro: To tyle na dzisiaj. Wraz z postępami będę aktualizował ten wątek. Pozdrawiam, Marek
  5. Witam, Uruchomiłem przykładowy program z STM32Cube_FW_F7_V1.15.0, który steruje wyświetlaczem przez interfejs DSI w trybie Video. Mikrokontroler przechowuje obraz w zewnętrznej pamięci sterowanej przez kontroler FMC. Dsi współpracuje z LTDC, który po prostu generuje sygnał RGB oraz sygnały synchronizujące H-sync i V-sync i tą część w większości rozumiem i ogólnie mi to działa. Nie rozumiem tylko, o co chodzi z tym kontrolerem FMC, ponieważ zapis do tej pamięci powoduje wyświetlenie obrazu. Rozumiem, że wyświetlacz jest w trybie odświeżania i jak zmieni się obraz no to od razu się pokazuję. Tylko, że jaki interfejs odpowiada za przesłanie obrazu z pamięci zewnętrznej do wyświetlacza ?? Sama pamięć nie ma fizycznego połączenia z LCD tak jak na schemacie w załączniku: Myślałem, że w tle działa DMA, które przesyła dane z pamięci do DSI ale takiej konfiguracji również nie ma. Ogólnie chciałbym po prostu użyć DSI i LTDC do kontroli wyświetlacza bez kontrolera FMC, potrafię skonfigurować LCD i widzę, że LCD reaguje, podświetlenie itp. ale nie wiem jak przesłać obraz. Mogę dodać zdjęcie konfiguracji lub przesłać cały program, jeżeli ma ktoś dostęp do tego modułu "stm32f769-discovery". Pozdrawiam Adrian
  6. Co może zrobić uczeń podstawówki, kiedy nie można w szkole używać telefonów? Specjalny kalkulator! Tak, wiem że urządzenie jest trochę przekombinowane - za pare zł mam nowy kalkulator z kiosku, ale to nie jest zwykły kalkulator.Ten kalkulator, albowiem, robiłem ja Budowa Urządzenie posiada wyświetlacz TFT 1.8" ze slotem na kartę pamięci, z której możemy odtwarzać zdjęcia. Do wprowadzania informacji posłużyła mi klawiatura 4x4 w formie naklejki. Całość napędza Arduino Pro Mini, które przeprogramowałem na korzystanie z wewnętrznego kwarcu 8Mhz i wyłączenie BOD. Energię dostarcza akumulator Lipo wyjęty z tableta, ładowany przez dolutowanie się do akusa. Napięcie obniża stabilizator AMS1117 na 3,3v, co rozwiązało kwestię napięcia logiki (TFT ma 3.3v, arduino normalnie 5v) oraz zużycia energii. Wyświetlacz, do programowania, można zdejmować. Po prawej stronie dostrzegamy przełącznik włączający urządzenie, zaś pod TFT znajduje się przycisk funkcyjny. Obudowy nie chciałem robić, gdyż chciałem wzbudzić zainteresowanie wśród kolegów Funkcje Kalkulator ma funkcję liczenia. Wow. Potrafi dzielić, mnożyć, dodawać i odejmować liczby dziesiętne, dodatnie i ujemne - ale nie umie wykonywać kolejności działań (dlatego według kalkulatora 2+2x2=8). ALE. Oprócz kalkulatora, utworzyłem aplikację paint - służy do malowania piksel po pikselu. Dobre na nudne lekcje polskiego. Po włączeniu urządzenia, wyświetla nam się lista dostępnych aplikacji. Oprócz niedokończonego snejka, jest jeszcze "czwarta aplikacja" - ściąga Wyświetla ona wzory z fizyki, chemii i matematyki oraz prawa dynamiki Newtona. Kalkulator może również w progmemie przechować jedno kolorowe zdjęcie, i wyświetlić je po 8x naciśnięciu przycisku Równa się. Taki kalkulator to fajna rzecz, z racji tego że można go używać w szkole bez ograniczeń i da się na nim pobawić. W ostateczności przeglądać memy, po włożeniu karty SD. Pozdrawiam, Leoneq :3
×
×
  • 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.