logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD

piloszkotosz 05 Sty 2022 14:38 981 20
REKLAMA
  • #1 19801714
    piloszkotosz
    Poziom 5  
    Witajcie.
    Ostatnio męczę wyświetlacz LCD TFT 2,8" po magistrali SPI na Atmega32. Dopiero się go uczę i przestawienie się ze zwykłych 2x16, czy 4x20 jest trochę kłopotliwe,jak dla mnie.

    Przećwiczyłem rysowanie podstawowych figur, czy napisów. Daję radę. Nie mniej jednak postanowiłem coś innego, a mianowicie wysłać jakieś dane w postaci choćby napięcia mierzonego na jednym z pinów ADC Atmegi.

    Niestety stanąłem w miejscu. Szukam jakiejś funkcji do wyświetlenia zmiennej uint, która jest np. w formie digital_voltage = pomiar(PA7);
    Digital_voltage jest zmienną uint16_t

    Potrafię wyświetlić char, string, figury, linie, ale ze zmienną typu uint16_t nie mam pojęcia.

    Może znajdzie się ktoś, kto naprowadzi mnie na właściwy trop. Im dłużej siedzę, tym gorzej. W końcu postanowiłem zapytać forum.

    Korzystam z bibliotek adafruit i podobnych, arduino i przerabiam sobie do C.

    Z góry dziękuję za pomoc.
  • REKLAMA
  • #3 19801780
    piloszkotosz
    Poziom 5  
    Witam.
    Dziękuję bardzo za szybką odpowiedź. Takie proste :D Jak przećwiczę, to napiszę. Najpóźniej jutro. Pozdrawiam.


    ------------------------------------------------------------------------

    Myślę, że ten temat będzie dla mnie ?

    Link


    ------------------------------------------------------------------------

    Witam ponownie.

    A więc udało mi się dzięki podpowiedzi wyświetlić napięcie w postaci cyfrowej.
    Użyłem takiej funkcji:

    Kod: C#
    Zaloguj się, aby zobaczyć kod


    Oczywiście nie do końca jestem zadowolony z efektu, ale wiem, że funkcja działa raczej prawidłowo.

    Jako, że to nie wyświetlacz lcd popularny na sterowniku 44780, to muszę poznać kilka myków jego zasady działania.

    Na tą chwilę, jeśli wejście ADC podepnę na stałe do Vcc i włączę urządzenie, to wyświetla się 1023. Ale jeśli ruszę potencjometrem, to cyfry przestają być prawidłowymi cyframi.

    Gdzieś czytałem, że można odświeżać tylko fragmenty ekranu. Czy tu nie chodzi właśnie o odświeżanie, nadpisanie poprzedniego wyniku ? Czy to nie są wyświetlane zbędne piksele po poprzednik pomiarach ? Sam pomiar jest bez uśredniania i cyfry mogą migać i zamalowywać obszary, co czyni wynik idiotycznym.

    I jeszcze jedno. Funkcje używane (powiązane z tą funkcją tft_int(); nie posiadają zmiennej dla tła litery, cyfry. Co za tym idzie, czy są odpowiednie ?
    Czy nie trzeba przerobić, dodając tło ?, czy nie. No bo jak kasować tłem ekranu znak ? Czy się trochę pogubiłem w tej pisaninie ?

    Funkcja w while(1)

    Kod: C#
    Zaloguj się, aby zobaczyć kod


    gdzie 100 i 100, to x y, 5 to rozmiar czcionki i ostatnie, to kolor czcionki.

    Podpowiedzcie, co dalej poczynić, a żeby wynik był poprawny podczas kręcenia potencjometrem. Jaka dobra metoda. Z góry dziękuję za wszelkie sugestie. Pozdrawiam.
  • REKLAMA
  • #4 19812376
    piloszkotosz
    Poziom 5  
    Może ktoś spotkał się z podobnym problemem ?

    Wyświetlam napięcie już przekonwertowane do "normalnych" wartości. ADC 0-1023 wyświetla, jako 0-5,1 volta.

    Kłopot polega na tym, że wartość np. 3,09 wyświetla, jako 3,9 volta. Wszystkie wartości typu 3,59 itp...... są ok.
    W pewnych momentach pomiaru brakuje 0 zera, jeśli po przecinku jest <10.

    Dla zwykłych wyświetlaczy nie było problemu napisać ifa, który robił swoje, ale tutaj nie mogę sobie poradzić.

    Może znajdzie się ktoś kto pomorze i da zielone światło w tunelu :(


    main()


    Kod: C#
    Zaloguj się, aby zobaczyć kod



    wchile()


    Kod: C#
    Zaloguj się, aby zobaczyć kod



    Jak prawidłowo pisać, a żeby kod był prawidłowo wyrównany. Zawsze coś się przesówa.
  • REKLAMA
  • #5 19812696
    inot
    Poziom 35  
    Spróbuj tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    dokładność
    % 3.2d
    Oznacza , że na wyjście należy zarezerwować obszar 3 znaków. Ostatnie dwa miejsca są zarezerwowane dla miejsc dziesiętnych.
  • #6 19812863
    piloszkotosz
    Poziom 5  
    Dzięki wielkie za zainteresowanie.

    W międzyczasie przemyślałem trochę kod i napisałem coś, co bardzo dobrze działa w całym zakresie wyświetlania od
    0.00 do pełnych woltów. Nigdzie nie ma dziur w wyniku i jest ok, ale sprawdzę również jutro Twoją podpowiedź.

    Jak mniej od 10, to wyświetlam znak zera i potem cyfrę 0-9. Jak 10, to jedynka wyświetla się zamiast pierwszego zera (lub może przykrywa znak zera). Dla tego gdzieniegdzie jest "%1d" a gdzie niegdzie "%2d"
    Ale czy dobrze to myślę ???

    Przy okazji zapytam, może mi wyjaśnisz w przestępny sposób o tworzeniu bufora, np: tak, jak ja napisałem, a napisałem w oparciu o przykłady. Piszę, działa, ale do końca nie rozumiem. Sam się uczę hobbystycznie i sporo czasu zajmuje. Ale najpierw kod, który działa, ale czy 100% poprawny ???


    Kod: C#
    Zaloguj się, aby zobaczyć kod




    Co do bufora to np:


    Kod: C#
    Zaloguj się, aby zobaczyć kod



    Z kont mam wiedzieć, jaka liczbę wpisać w nawias w zależności od okoliczności. Rozumiem, że jeśli wpiszę za dużą, to chyba rezerwuję jakąś część pamięci nie potrzebnie z nadwyżką, a atmega ma swoje ograniczenia przy lcd tft.

    Z kolei wpiszę za mało, to jest zonk. Jak to się liczy, albo gdzie znajdę źródło z łopatologicznym wytłumaczeniem. Z góry dziękuję za wyjaśnienie.
  • REKLAMA
  • #7 19812992
    inot
    Poziom 35  
    Ja bym to uprościł:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    tym sposobem:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 19813136
    piloszkotosz
    Poziom 5  
    Dzięki inot

    Tak jest o wiele prościej, ale również zależy mi na objętości wsadu. Ten sposób widziałem nie jednokrotnie w projektach na arduino i nie tylko, ale jakoś przyzwyczaiłem się do tej mojej aktualnie metody. Pan Mirek z Atne...l sugerował tą metodę i tak mi zostało. float i double sprzyja rozrastaniu się bajtów w kodzie..... Jeśli nie muszę, to staram się oszczędzać pojemność procka. Nie mniej jednak dziękuję za chęć pomocy.

    Co do przydzielania wielkości tego bufora, to może ktoś zechciałby się wypowiedzieć, jak to jest. Pozdrawiam.
  • #9 19813562
    inot
    Poziom 35  
    Cytat:
    tą metodę i tak mi zostało. float i double sprzyja rozrastaniu się bajtów w kodzie

    Nie pojmuję twojego rozumowania.
    Przecież float to tylko 4 bytes w SRAM , a uproszczony kod programu zaoszczędza o wiele więcej pamięci FLASH.

    Cytat:
    Co do przydzielania wielkości tego bufora

    Bierzesz tyle ile potrzebujesz.
    Wartość określająca rozmiar tablicy array musi byc stałą, chyba że używasz jako zaawansowany funkcji "malloc", "free" i odpowiednich pointerów.
  • #10 19815304
    piloszkotosz
    Poziom 5  
    Witam.
    Może i masz rację. Może zbyt demonicznie podszedłem do tematu, ale jak się poczyta, posłucha osób, które maja duże doświadczenie w temacie, to potem człowiek staje się przewrażliwiony. Zawsze można użyć większego procka. :-) jakby brakowało... Żartuję oczywiście.
    Pozdrawiam.
  • #11 19815478
    JacekCz
    Poziom 42  
    @piloszkotosz

    usilnie cie zachęcam do porządnego oswojenia C na desktopie. Zadania z jakiegoś kursu od najłatwiejszych do coraz trudniejszych,
    Mówię o konsolowych, olbrzymia większość kursów C/C++ dla środowisk GUI robi krzywdę początkującemu programiście.

    Na uK to nie nauka, nie wiesz co kopie ze strony elektroniki, co ze strony kodu, kiepskie debugowanie, analogicznie cele jakie sobie stawia psychika są pomieszane.
  • #12 19815691
    piloszkotosz
    Poziom 5  
    Dzięki za radę.
    Problem polega na tym, że jak się człowiek sam czegoś uczy, to jest trudniej. No i kolejność nauki, samodyscyplina, skakanie z kwiatka na kwiatek, czyli od prostego do nagle trudnego zagadnienia pomijając po drodze podstawy.

    Znam swoje błędy w nauce i złe podejście....

    Trochę skróciłem kod. Ubyło bajtów w zajętości ewidentnie, a działa tak samo.

    Kod: C#
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #13 19815739
    JacekCz
    Poziom 42  
    piloszkotosz napisał:


    Trochę skróciłem kod. Ubyło bajtów w zajętości ewidentnie, a działa tak samo.

    Kod: C#
    Zaloguj się, aby zobaczyć kod


    Tak samo, czyli nada źle? Część za przecinkiem będzie miał źle. Ma być

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Modulo 100 nie jest konieczne, to tylko bezpiecznik. Nie wiem czy w reszcie kodu taki bezpiecznik masz, wtedy zbędny.
    Wiedza z 50 strony każdej książki do C - ale nie od mędrców uProcesorowych uczących C, tylko dekstopowe.
  • #14 19816250
    piloszkotosz
    Poziom 5  
    A więc na wstępie dzięki za cierpliwość.

    Kod do obliczania mocy został w pracy, a w domu mam z napięciem, a więc tu zastosowałem tą sugestię. Rzadko używałem printif i pochodne, a jeśli już użyłem, to jako "gotowca" i szczerze mówiąc nie zastanawiałem się, jak ta funkcja działa.
    Teraz odnalazłem w necie i poczytałem o niej. Większość zrozumiałem, ale ta terminologia nie zawsze jest jasna.

    Odnośnie moich kodów, to stosowałem np. "%3d.%-2d" ten - po to, a żeby wyrównać do lewej lub prawej, ponieważ
    jeśli wyświetlam adc cyfrowe, to ono zabiera 4 miejsca, a jak jest 0 to mam zajęte tłem puste 3 pola. Wtedy wartość po kropce była oddalona od pełnych woltów o trzy znaki, a przecież tak nie może być pokazane na lcd. Dla tego kombinowałem w ten sposób. Może źle, ale robię, jak rozumiem "po swojemu". Dla tego nieraz takie dziwaczne kody mi wychodzą. Efekt zamierzony niby jest spełniony, ale kod długi i nie zawsze poprawny.

    Chciałbym ten etap zakończyć ze zrozumieniem całości, a więc zamieszczam kod. Jest prawie cały(nie licząc funkcji kolorowania, write, itp...) Wyłączyłem tło, a żeby było jasne, co się dzieje.

    Okomentowałem to co po swojemu napisałem. Czy dobrze interpretuję i jest poprawnie ?

    Na dole wersja skrócona przy pomocy kolegów. Na ekranie działają tak samo. I proszę o wytłumaczenie , co dokładnie robi 0 w %02d w linijce:

    Kod: C#
    Zaloguj się, aby zobaczyć kod



    Kod: C#
    Zaloguj się, aby zobaczyć kod



    Resztę chyba rozumiem. I proszę, jeśli można podać jakieś źródła do nauki "desktopowej" języka C. Chętnie poczytam. Może da mi to więcej.

    Dzieki za pomoc.


    Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD
  • #15 19816358
    inot
    Poziom 35  
    Cytat:
    co dokładnie robi 0 w %02d w linijce:

    Nie wiem jak to przetłumaczyć:

    With numerical output, zeros are padded up to the specified width.
  • #16 19816634
    piloszkotosz
    Poziom 5  
    Ja znalazłem takie tłumaczenie, o ile to się tyczy tego zera:


    0 Jeśli szerokość jest poprzedzona prefiksem , zera wiodące są dodawane do momentu osiągnięciu minimalnej szerokości. Jeśli zostaną 0 wyświetlone oba i , zostanie on -0 zignorowany. Jeśli parametr jest określony dla formatu liczb całkowitych (, , , , , ), a specyfikacja precyzji jest również obecna na przykład, parametr 0iu jest xXod—%04.d—0 ignorowany. Jeśli jest określony dla formatu zmiennoprzecinkowego lub , zera wiodące są dołączane do 0aA mantysy po 0x prefiksie 0X lub .


    Tylko ta terminologia do mnie nie dociera. Nigdy nie uczyłem się informatyki itp...

    Co do kodu, to dodam, że ten dłuższy po kompilacji podaje zajętość:

    Program 5438 bajty 33,2%
    Data 71 bajty 6,9%

    Krótszy natomiast:

    Program 5364 bajty 32,7%
    Data 67 bajty 6,5%

    Muszę jeszcze przy okazji sprawdzić, jaka byłaby zajętość przy pominięciu funkcji sprintf printf i wykorzystaniu funkcji w rodzaju lcd_int(); czy bufor_int(); Zauważyłem, że przy sprintf printf kody są zdecydowanie prostsze i krótsze.
  • #17 19816969
    inot
    Poziom 35  
    Cytat:
    co dokładnie robi 0 w %02d w linijce:


    With numerical output, zeros are padded up to the specified width.



    Albo w tutaj
    Cytat:
    sprintf(adc_value,"%4d",adc);

    w twoim programie wyświetlałoby 0512.
  • #18 19817205
    piloszkotosz
    Poziom 5  
    Witam.

    Przetestowałem wszystko praktycznie i wychodzi następująco. Zera się nie wyświetlają w przypadku:

    Kod: C#
    Zaloguj się, aby zobaczyć kod


    Wcześniej o tym pisałem, że zajmuje tylko tło tam gdzie aktualnie nie ma cyfry.
    Dla tego kombinowałem ze znakiem -. Doczytałem w opisie o sprintf w necie.

    Tu przykład wyświetlania bez znaku - dla różnych poziomów napięć:

    Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD


    A tutaj z dopisanym znakiem -



    Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD Wyświetlenie wartości napięcia na wyświetlaczu TFT LCD

    Dzięki.
  • #19 19817255
    JacekCz
    Poziom 42  
    inot napisał:
    To znaczy max. 2 pozycje a jeśli tylko 1 pozycja (np. 2,4) to będzie zero na końcu dodane i wyjdzie 2,40.


    żadne formatowanie nie dodaje zer na końcu

    Udzielasz szkodliwej rady (oraz używasz dziwnego słownictwa).
    To ma bardzo prostą i utrwaloną nazwę "zera wiodące" - "trailing zeros"

    Ech tzw praktycy ... od wiedzy teoretycznej się nie umeira

    Dodano po 5 [minuty]:

    piloszkotosz napisał:
    Muszę jeszcze przy okazji sprawdzić, jaka byłaby zajętość przy pominięciu funkcji sprintf printf


    Na AVR nie miałem okazji używać w/w, ale mam przeczucie, że są dwie wersje biblioteki standardowej, ze zmiennym przecinkiem i bez. To bardzo rozdyma kod (s)printf.

    W latach 198x-młodych 199x modyfikowałem sprintf dla zmniejszenia objętości wynikowej. Nie chodziło o mikrokontrolery, ale o tzw "programy rezydentne", generalnie cel ten sam, małą wielkość kody wynikowego i RAM.

    Ale i tak w setki, albo ponad tysiac bajtów. Małe, zwinne (i mniej elastyczne - np nie ma mowy o zerze wiodącym) są pochodne itoa()
    https://cpp0x.pl/dokumentacja/standard-C/itoa/316
  • #20 19817762
    robiw
    Poziom 26  
    Przyznam szczerze, iż nie czytałem wątku od początku, ale narzuca się pytanie czy tutaj rzeczywiście potrzebne są operacje na float? Napisałem setki programów a float użyłem góra raz. Zwykle da się to samo wykonać na int-ach po odpowiednim podejściu (DFT tak robiłem). Zawsze własne funkcje wyświetlania na TFT, LCD czy innym rodzaju wyświetlacza można bardziej zoptymalizować pod konkretne potrzeby...ale fakt, nie znam szczegółowo tematu. Taka luźna dygresja... Pozdrawiam. R
  • #21 19819100
    piloszkotosz
    Poziom 5  
    Ja robiłem próby z użyciem funkcji z adafruid dla arduino.

    Chodzi o użycie funkcji w rodzaju tft_int(): gdzie w ciele funkcji jest itoa, char, i td... Wynik się wyświetlał, ale były z tym jakieś problemy. Wrócę do tematu i zamieszczę te funkcje. Może ktoś zobaczy, co było nie ok. Muszę tylko z dzień odpocząć od C, bo już trochę się w głowie mąci. Jeśli chodzi o użycie (s)printf, to
    działa super i wiele mi pomógł. Pozdrawiam.

Podsumowanie tematu

Użytkownik pracuje nad wyświetlaczem TFT LCD 2,8" podłączonym do Atmega32 przez magistralę SPI i stara się wyświetlić wartość napięcia z pinu ADC. Po początkowych trudnościach z konwersją zmiennej uint16_t na format wyświetlany, udało mu się to osiągnąć przy pomocy funkcji sprintf oraz itoa. W trakcie dyskusji poruszono problemy z formatowaniem wartości napięcia, w tym z wyświetlaniem zer wiodących oraz precyzją wyświetlanych wartości. Użytkownicy dzielili się sugestiami dotyczącymi uproszczenia kodu oraz optymalizacji pamięci, a także omawiali różnice między używaniem typów zmiennoprzecinkowych a całkowitych w kontekście mikrokontrolerów.
Podsumowanie wygenerowane przez model językowy.
REKLAMA