Elektroda.pl
Elektroda.pl
X
PCBway
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Wyświetlacze graficzne, linie, figury, praca na RAMie procesora

23 Maj 2011 08:45 2713 26
  • Specjalista - oświetlenie sceniczne
    Szukam materiałów traktujących o rysowaniu prostych figur, łączeniu punktów itp.
    Odpaliłem akurat KS0108, (rysuje od lewej do prawej z góry do dołu).
    Jak zacząć napis od dowolnego puntu pozbywając się ograniczenia do konkretnych wierszy?
    Czy nie lepszym rozwiązaniem jest najpierw zrobienie obrazu w RAMie, a dopiero na koniec go wysłać do LCD?.

    Ponadto, potrzebował bym ten sam obraz wyświetlić na oddalonych urządzeniach więc w gre chyba tylko wchodzi stworzenie ramki w RAMie
  • PCBway
  • Moderator Mikrokontrolery Projektowanie
    Po co? Przecież w tym modelu wyświetlacza masz już framebuffer, który możesz adresować w dowolny sposób, więc jego dublowanie nie ma wielkiego sensu - chyba, że przeprowadzasz jakieś kosztowne operacje na VRAM, wymagające np. odczytu. Wtedy stworzenie bufora ma jakiś sens. Co do reszty - zacznij od tego, że wszystko da się narysować posiadając funkcję rysującą pixel, z tego możesz poskładać linie, teksty i co tam chcesz.
  • Poziom 24  
    Przecież zwykłe zapalenie/zgaszenie piksela na już istniejącym tle będzie wymagało odczytu z wyświetlacza. Jak procesor ma wystarczającą ilość RAMu, to oczywiście lepiej rysować całość w RAMie i na koniec wysłać całość na wyświetlacz. To rozwiązanie ma jeszcze tę zaletę, że można periodycznie (raz na kilka minut) inicjalizować wyświetlacz np. gdy jest na długim kablu i jest podatny na zakłócenia.

    Co do meritum, to jak chcesz rysować czcionki od dowolnego piksela na KS0108, to musisz wyliczyć o ile pikseli trzeba przesunąć bitmapę ze znakiem (literą/cyfrą) w pionie, i dopiero tak przesuniętą bitmapę nakładać na tło. W poziomie nie ma problemu.
  • Moderator Mikrokontrolery Projektowanie
    Niekoniecznie stworzenie bufora coś dla tak prostej operacji przyśpieszy. Zakładając, że nie mamy bufora, trzeba:
    1. Wyliczyć adres bajtu
    2. Odczytać bajt z VRAM
    3. Wyliczyć maskę (tu zapewne kosztowne operacje przesunięć bitowych)
    4. Zapisać nową wartość do VRAM.
    Mając bufor:
    1. to samo
    2. Odczyt jest z bufora a więc trochę szybszy
    3. to samo
    4. Zapisać nową wartość do VRAM i bufora (więc ciut wolniej)
    Efekt końcowy może być taki, że stracimy sporo pamięci, a nic nie zyskujemy.
    Jeśli na LCD pojawiają się zakłócenia to należy zlikwidować problem, a nie stosować półśrodki, polegające na cyklicznej reinicjalizacji.
  • Poziom 24  
    Z dziką rozkoszą obejrzę zrobione przez ciebie urządzenia, które przy strzałach z testera ESD w pobliżu wyświetlacza nie przekłamują nawet jednego piksela.

    Co do prędkości to nie będę komentował.
  • PCBway
  • Specjalista - oświetlenie sceniczne
    Wydaje mi się że lepszym rozwiązaniem są operacje na RAMie, tym bardziej że ten sam obraz muszę wysłać do innego urządzenia. Bufora starczy na cały ekran, więc po co kombinować z odczytem LCD i przesłania pixeli dalej.

    Z tym że tutaj w ogóle nie mam pojęcia jak zapalać poszczególne pixele w ramie (język C).


    ------
    Nawet tekstowe LCD ma prawo się wywalić i w praktyce tak bywa, może nie koniecznie zły jest układ, ale sam LCD może nie wytrzymać zakłócenia. Osobiście robię ponowną inicjalizacje po 1min nie dotykania urządzenia.
  • Poziom 23  
    Witam,

    Tutaj mój prymitywny fb w ramie na wyświetlacz monochromatyczny 240x160.
    Obsługuje okna więc można łatwo przepisywać grafiki z flasha bezpośrednio do pamięci. Później już tylko przesłać całą pamięć do wyświetlacza

    Code:

    /*
     * fb.c
     *
     *  Created on: 17-02-2011
     *      Author: Piotr Machura
     *
     *      frame buffer dla UC1611 240x160
     *
     */


    #include "fb.h"
    #include "sys.h"
    #include "UC1611S.h"
    #include "LPC17xx.h"

    __attribute__ ((section(".dodatkowy")))
    volatile u8 screen_buf[21][240];

    static u16 fb_xs;      // start
    static u16 fb_xe; // end

    static u16 fb_ys;       // start
    static u16 fb_ye; // end

    static u16 fb_x;   // position
    static u16 fb_y; // position



    void fb_set_window(u8 x, u8 y, u8 x_size, u8 y_size)
    {
       fb_xs = x;
       fb_ys = y;
       fb_xe = x+x_size;
       fb_ye = y+y_size;
       fb_x = x;
       fb_y = y;
    }

    void fb_putpxl(u16 x,u16 y, u8 data)
    {
       u8 shift = y%8;
       if(data)
          screen_buf[y/8][x] |= (1<<shift);
       else
          screen_buf[y/8][x] &= ~(1<<shift);
    }

    void fb_line(u16 x0, u16 y0, u16 x1, u16 y1,u8 pattern)
    {
       u8  pattern_cnt;
       s16 dy;
       s16 dx;
       s16 stepx, stepy;

       pattern_cnt = 0;

       // pattern 0 - normalna linia, 1 - - - - 2 -- -- -- -- --

       dy = y1 - y0;
       dx = x1 - x0;

       if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
       if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
       dy <<= 1;                                                  // dy is now 2*dy
       dx <<= 1;                                                  // dx is now 2*dx

       if(pattern != 3)
          fb_putpxl(x0,y0,1);

       if (dx > dy)
       {
          int fraction;
          fraction = dy - (dx >> 1);                         // same as 2*dy - dx

          while (x0 != x1)
          {
             if (fraction >= 0)
             {
                y0 += stepy;
                fraction -= dx;                                // same as fraction -= 2*dx
             }

             x0 += stepx;
             fraction += dy;                                    // same as fraction -= 2*dy

             switch(pattern)
             {
                 default:
                   fb_putpxl(x0,y0,1);
                 break;

                 case 1:
                    if(pattern_cnt)
                      fb_putpxl(x0,y0,1);
                    pattern_cnt^=1;
                 break;

                 case 2:
                    if(pattern_cnt<2)
                       fb_putpxl(x0,y0,1);

                    pattern_cnt++;
                    if(pattern_cnt >= 4)
                       pattern_cnt = 0;
                 break;

                 case 3:
                    fb_putpxl(x0,y0,0);
                 break;

                 case 4:
                   fb_putpxl(x0,y0,1);
                   fb_putpxl(x0,y0-1,1);
                 break;
             }
          }
       }
       else
       {
          int fraction;
          fraction = dx - (dy >> 1);
          while (y0 != y1)
          {
             if (fraction >= 0)
             {
                x0 += stepx;
                fraction -= dy;
             }
             y0 += stepy;
             fraction += dx;

             switch(pattern)
             {
                 default:
                   fb_putpxl(x0,y0,1);
                 break;

                 case 1:
                    if(pattern_cnt)
                      fb_putpxl(x0,y0,1);
                    pattern_cnt^=1;
                 break;

                 case 2:
                    if(pattern_cnt<2)
                       fb_putpxl(x0,y0,1);

                    pattern_cnt++;
                    if(pattern_cnt >= 4)
                       pattern_cnt = 0;
                 break;

                case 3:
                   fb_putpxl(x0,y0,0);
                break;
                case 4:
                  fb_putpxl(x0,y0,1);
                  fb_putpxl(x0,y0-1,1);
                break;
             }
          }
       }
    }

    void fb_putdata(u8 data, u8 op)
    {
       u8 shift = fb_y%8;

       if(shift)   // jesli z reszta to przesuniecie....
       {
          if(op==OR)
          {
             //if(fb_y==fb_ys)
                screen_buf[fb_y/8][fb_x] = (data << shift) | (screen_buf[fb_y/8][fb_x] & (0xFF >> (8-shift)));
             //else
             //   screen_buf[fb_y/8][fb_x] = (data << shift);
          }
          else
             screen_buf[fb_y/8][fb_x] |= (data << shift);

          if(op==OR)
          {
             if(fb_y/8==(fb_ye/8-1))
             {
                u8 t = screen_buf[fb_y/8+1][fb_x] & (0xff<<shift);
                screen_buf[fb_y/8+1][fb_x] = t | (data >> (8-shift));
             }
             else
                screen_buf[fb_y/8+1][fb_x] = (data >> (8-shift));
          }
          else
             screen_buf[fb_y/8+1][fb_x] |= (data >> (8-shift));
       }
       else
       {
          if(op==OR)
             screen_buf[fb_y/8][fb_x] = data;
          else
             screen_buf[fb_y/8][fb_x] |= data;
       }

       fb_x++;

       if(fb_x >= fb_xe)
       {
          fb_x=fb_xs;
          fb_y+=8;
       }

       if((fb_y >= fb_ye) || ((fb_y/8) >= 20))
       {
          fb_xs = 0;
          fb_xe = 0;
          fb_ys = 0;
          fb_ye = 0;
          fb_x = 0;
          fb_y = 0;
       }
    }

    void fb_clear(void)
    {
       u16 _k,_l;
       for(_k=0 ; _k < 20; _k++)
            for(_l=0 ; _l < 240; _l++)
                screen_buf[_k][_l] = 0;
    }


    void fb_refresh_screen(void)
    {
       u16 _k,_l;
      GPIO2->FIOSET = CS;
      uc1611S_set_window(0,0,240,160);
      for(_k=0 ; _k < 20; _k++)
         for(_l=0 ; _l < 240; _l++)
             uc1611S_send_data(screen_buf[_k][_l]);

      GPIO2->FIOCLR = CS;
    }



    Przykład:
    Code:

    void put_custom_icon(u16 x,u16 y, u16 x_size, u16 y_size, const u8* name,u8 blank)
    {
      u16 k,l,color;

      fb_set_window(x,y,x_size,y_size);

      for(k=0 ; k < (y_size/8); k++)
         for(l=0 ; l < x_size; l++)
        {
            color = name[k*x_size + l];

            if(blank)
                fb_putdata(0x00,OR);
            else
               fb_putdata(color,OR);
         }

    }
  • Moderator Mikrokontrolery Projektowanie
    Zbych_ napisał:
    Z dziką rozkoszą obejrzę zrobione przez ciebie urządzenia, które przy strzałach z testera ESD w pobliżu wyświetlacza nie przekłamują nawet jednego piksela.

    Co do prędkości to nie będę komentował.


    Znaczy co, komórki i cały sprzęt posiadający LCD działa tylko dlatego, że cyklicznie resetuje LCD? To jest dopiero ciekawa teoria.
    Jeśli LCD ci tak kiepsko działa, to skąd pewność, że to samo nie dzieje się z procesorem? Aha, pewnie bazujesz na tym, że WD ci cyklicznie go resetuje :)
  • Poziom 24  
    tmf napisał:
    Znaczy co, komórki i cały sprzęt posiadający LCD działa tylko dlatego, że cyklicznie resetuje LCD? To jest dopiero ciekawa teoria.


    Robiłeś kiedyś testy ESD wyświetlaczy? Bo po twoje bucie widzę, że nie.
  • Specjalista - oświetlenie sceniczne
    Robi się OT.

    TMF, Oczywiście powinno się zwalczać sytuacje w których byle bzdura powoduje zwiechę, ale Zbych ma trochę racji którą mogę potwierdzić praktycznie. Weź starą indukcyjną zapalarkę do gazu i pomęcz układy. Ciekawe czy wywali ci sie wszystko na raz, czy wspomniany LCD, BT czy co tam masz
    Są to urządzenia raczej nie zależne od siebie, proca, pcb, czy filtrów- weźmiesz inny moduł i będzie OK to co w tedy?. Padną same z siebie bo są po prostu mniej odporne. Jeśli twierdzisz inaczej, to jestem zdania że nie męczyłeś swoich dzieł w laboratorium certyfikującym :)
    Owszem, masz wpływ na ich działanie poprzez filtry, obudowę, ale co jeśli już do tego dojdzie? pozwolisz aby LCD wyświetlał krzaki gdy reszta pracuje. Z resztą nawet niektóre normy mówią że na czas działania zakłócenia dopuszczone sa anomalie, ale po ich zaniku ma powrócić do stanu przed zakłóceniem.

    Po co producent daje psa?, żeby kiepski program mógł sie co jakiś czas sam uruchomić, czy po to aby np zegarek ścienny który poprawnie pracuje w swoim środowisku mógł wstać jak pan czesiek przyczepi go do spawarki?
  • Moderator Mikrokontrolery Projektowanie
    Nie myl sytuacji ekstremalnych do których został stworzony WD, z niedbałym projektowaniem układów, a potem łataniem błędów przy pomocy WD i innych sztuczek.
    Zbych_: czyli twierdzisz, że od zapalarki piezo wykrzaczy mi się np. LCD w komórce, tak? Bo jeśli nie to znaczy, że jednak da się zaprojektować układ odporny na takie cyrki. Sprzęt medyczyny, też jak się zapoda impuls z defibrylatora wg ciebie szaleje i tak ma być?
    Skąd pogląd, że LCD jest mniej odporny na zakłócenia niż procesor? Tylko proszę konkrety, a nie populistyczne teksty typu "Robiłeś kiedyś testy ESD wyświetlaczy?".
  • Specjalista - oświetlenie sceniczne
    O zapalarce pisałem ja, więc odpowiem: jest to pomysł, a raczej wniosek z praktycznych prób. Zbliżenie zapalarki powodowało reset LCDka (czarny górny wiersz)

    A zapalara stara PRLowska- indukcyjna.
  • Poziom 24  
    tmf napisał:
    Zbych_: czyli twierdzisz, że od zapalarki piezo wykrzaczy mi się np. LCD w komórce, tak


    Czy ja pisałem coś o zapalarce? Żeby wykrzaczyć wyświetlacz zakłócenie musiałoby przejść konkretną drogą. Czasami układ jest odporny na jedną polaryzację impulsów, a wykrzacza się przy przeciwnej. Z zapalarką może wyjść, ale nie musi.
    W nowszych komórkach kontroler wyświetlacza i tak jest w procesorze, więc prawdopodobieństwo, że coś zobaczysz jest małe.

    Jak masz ochotę to weź jakieś ustrojstwo własnej konstrukcji z wyświetlaczem i zrób wyładowanie kontaktowe w ramkę wyświetlacza.

    tmf napisał:
    Sprzęt medyczyny, też jak się zapoda impuls z defibrylatora wg ciebie szaleje i tak ma być?


    Nie wiem skąd ten wniosek. Ja mówię o wykrzaczającym się wyświetlaczu, a ty zaraz obwieścisz kolejną datę końca świata.

    tmf napisał:
    Skąd pogląd, że LCD jest mniej odporny na zakłócenia niż procesor?


    Z praktyki kolego. Przed użyciem wyświetlacza danego producenta, robiliśmy w firmie testy. _Każdy_ wyświetlacz z kontrolerem wcześniej, czy później się wykrzaczy. Wystarczy spojrzeć na szkło, masz tam kupę elektrod, które pracują jak anteny.

    Właśnie się męczę z urządzeniem, w którym ktoś radośnie (tak jak ty) założył że wyświetlacz jest niezakłócalny i efekt jest taki, że raz na kilka/kilkanaście dni urządzenie trzeba wyłączyć z prądu, bo wyświetlacz jest pusty (reszta urządzenia dalej działa poprawnie).
  • Moderator Mikrokontrolery Projektowanie
    Nie, pokazuję ci przykłady z życia, w których zakłócenia jakoś nie powodują problemów - czyli da się układ tak skonstruować, aby był odporny na zakłócenia. A skoro się da, to tak właśnie należy je projektować, a nie tworzyć rozwiązania maskujące błędy projektu.
    Wracając do początkowego postu, akurat mam KS0108 pod ręką i kilka moich funkcji do jego obsługi, więc zrobiłem porównanie jak wygląda prędkość jego obsługi z buforem oraz wykorzystując tylko VRAM, funkcje, które testowałem opierają są na funkcji rysującej piksele o takiej oto definicji:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Powyższa funkcja operuje na buforze, po odkomentowaniu zakomentowanych linii i zakomentowaniu linii odwołujących się do bufora, odwołuje się wyłącznie do VRAM, oto wyniki (ilość cykli procesora):
    Funkcja Bufor VRAM Zysk
    SetPixel 428 742 42%
    Rysowanie linii
    32 px 14460 24822 41,8%
    Tekst
    (10 znaków) 221014 371734 40,%
    Pozornie wydaje się to dużo, ale:
    - tracimy 1 kB SRAM, a pamięć jest raczej cennym zasobem w mikrokontrolerze
    - zysk na poziomie 40% nie przekłada się na większą płynność wyświetlania grafiki, gdyż czas generacji ramki jest i tak za długi
    - gdybym wykorzystał mechanizmy sprzętowe generowania strobów zapisu i odczytu dostępne w procesorach z interfejsem XRAM, zysk spada do ok. 10-15%.
    - należy pamiętać, że duża część operacji nie wymaga wcale odczytu VRAM (rysowanie poziomych linii, kasowanie tła, pisanie tekstu z kasowaniem tła), więc realny zysk w aplikacji jest na poziomie mniejszym niż 5% - tyle mi wyszło po odpaleniu aplikacji symulującej okienka.
    Co oczywiście nie znaczy, że stosowanie bufora nie ma sensu - ma, ale trzeba wiedzieć po co się to robi i gdzie można zyskać.
  • Poziom 24  
    Masz KS0108 pod ręką, to udowodnij, że jest odporny.

    Stosowanie bufora ma sens. A we współczesnych uC 1kB RAM to nie tragedia.
    Część argumentów już podałem. Można jeszcze dorzucić mniejszy ruch na magistrali - czyli mniejsze zakłócenia, możliwość użycia DMA do wyrzucania danych na wyświetlacz. Transmisja do wyświetlacza może być jednokierunkowa, co upraszcza buforowanie.
  • Moderator Mikrokontrolery Projektowanie
    Jest odporny, błędy pojawiają się wyłącznie w trakcie transmisji, nigdy w przypadku wyświetlania stałej zawartości - testowane na płytce stykowej, gdzie KS jest połączony ok. 10cm drutami z procesorem. Przypuszczam, że dodanie szeregowych rezystorów, małych kondensatorów i koralików rozwiązałoby problem.
    Co do argumentów:
    - w jaki sposób dodanie bufora ma zmniejszyć ruch na magistrali, w sytuacji w której regularnie retransmitujesz całą zawartość bufora?
    - brak bufora nie uniemożliwia użycia DMA - dane ciągle mogą być w ten sposób transmitowane.
    - ostatni powód potencjalnie jest istotny, jeśli LCD buforowania wymaga. W 90% nie wymaga. Albo prościej jest dodać procesor po stronie LCD i całą transmisję oprzeć na czymś odpornym, np. RS485.
  • Poziom 23  
    Oczywiście że problem powstaje przy zapisie/odczycie wyświetlacza. W urządzeniach które robimy ekran jest odświeżany przynajmniej raz na sekundę. Korzystamy z urządzenia do generowania zakłóceń na liniach zasilających i nie udało nam się jeszcze znaleźć rozwiązania z zawieszaniem zewnętrznego kontrolera (SSD1963) LCD. Test 1kV przechodzą z trudem. Test 2kV już jest problemem. A 2kV to jest jakaś granica z normy.

    Transmisja jednokierunkowa owszem upraszcza. Jednak przydaje się również odczyt rejestrów konfiguracyjnych ponieważ tylko tak procesor może stwierdzić że jest problem z TFT LCD i przeprowadzić ponowną inicjalizację i odświeżenie ekranu.

    Co do bufora w RAMie, ja z takiego korzystam w jednym projekcie ponieważ konstruktor zapomniał wyprowadzić sygnał odczytu z wyświetlacza. Na procesorze LPC17xx @24MHz w ciągu sekundy mogę odświeżyć LCD 240x160 ponad 100razy wykorzystując GPIO. Bufor na taki ekran to tylko 4800B :)


    EDIT:

    Co do korzystania z zapalarki... My również korzystaliśmy z iskrownika opartego o świece zapłonową. Wszystkie sterowniki były odporne... Jednak dopiero na poważnym urządzeniu które generuje zakłócenia na zasilaniu wyszły prawdziwe problemy.
  • Specjalista - oświetlenie sceniczne
    No i mam lekki problem z włączaniem pojedynczych pikseli. Prawie to działa, punkt się oświeca w spodziewanym miejscu, jedna coś jest nie tak z pobranym z LCD bajtem do zmiany- obraz jest niszczony, zwłaszcza na prawej połowie. Różne znalazłem opisy, jedni wspomniany bajt odczytują raz, inni dwa i przyznam że ten ostatni sposób jest bliższy ideału. Mimo że nie znalazłem o tym informacji w manualu.

    (Wgrywanie bitmapy z flasha działa mi idealnie)

    kawałek z pętli głównej, nie widać ale przed tym ustawiam lcd_x i y, ich dalsza inkrementacja tylko dla bajeru

    Kod: c
    Zaloguj się, aby zobaczyć kod


    procedury:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    [/code]
  • Poziom 24  
    Czytaj dane z wyświetlacza wtedy gdy masz aktywną linię CS:

    Code:
    char LCD_READ_DATA(void)
    
       {
          char data;
          SET_RW;
          SET_RS;
          DDR(LCD_PORT)=0;
          asm("nop");
          SET_EN;
          asm("nop");
          data=PIN(LCD_PORT); //<--------------------
          CLR_EN;
          asm("nop");
          
          return data;
       }
  • Moderator Mikrokontrolery Projektowanie
    Ze względu na specyfikę sterownika należy dwukrotnie dokonać odczytu. Ty ten drugi odczyt masz zakomentowany, w efekcie odczytujesz nieprawidłową wartość.
  • Specjalista - oświetlenie sceniczne
    Zbych, przed READ_DATA jest LCD_POZ a tam odpowiednio ustawione linie CS.

    Dwukrotny odczyt pozycji daje inny efekt błędu, choć tak jak wspomniałem obraz jest bliższy ideału.
  • Poziom 24  
    Masz rację, chodziło mi o linię E, tak jak to pokazałem na zacytowanym kawałku kodu.
  • Specjalista - oświetlenie sceniczne
    To E oczywiście poprawione, ale mniejsza z tym bo teraz wszystko robię w RAMie i tutaj kolejne pytanie bo nie mogę za bardzo pojąć jak połączyć dwa punkty.
    Na swój chłopski rozum wydumałem (krótko mówiąc) że długość linii w X podzielę przez szerokość w Y, uzyskana wartość to długość x po której następuje zwiększenie y.
    Działa to ale oczywiście nie do końca,i tylko gdy końiec jest ma większą wartość niż początek :) Nie znam dobrze C więc analiza gotowych kodów które znalazłem nie idzie mi najlepiej. Jaki jest dobry sposób na linie?

    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Specjalista - oświetlenie sceniczne
    Nie rozumiem tu czegoś.

    Code:
    function line(x0, x1, y0, y1)
    
         int deltax := x1 - x0
         int deltay := y1 - y0
         real error := 0
         real deltaerr := abs (deltay / deltax)    // Assume deltax != 0 (line is not vertical),
               // note that this division needs to be done in a way that preserves the fractional part
         int y := y0
         for x from x0 to x1
             plot(x,y)
             error := error + deltaerr
             if error ≥ 0.5 then
                 y := y + 1
                 error := error - 1.0


    Wg opisu błąd cały czas jest zwiększany i gdy >= 0,5 to y++. Wydaje mi się że ten kod będzie rysować albo linie prostą, albo 45°
  • Użytkownik usunął konto  
  • Specjalista - oświetlenie sceniczne
    No, coś w końcu działa. Akurat TMF z dedykacją dla ciebie- pierwsza szpila to strzał złapany od piezo. Żeby zmieścić wykres musiał zostać pomniejszony 46x. Swoją drogą, byka pewnie wypluł DS18b20 więc jak go zabezpieczysz żeby nie leczyć sprawy programowo?.


    Link




    WYpadało by jeszcze zrobić wartości ujemne, i nie wiem czy pisząc to tak jak do tej pory po prostu się nie "zakopałem" z ujemnymi. Na ich myśl dostaje zwarcia w mózgu
    Kod: c
    Zaloguj się, aby zobaczyć kod



    Odczyt, buforowanie i kreślenie wykresu


    Kod: c
    Zaloguj się, aby zobaczyć kod



    Kod: c
    Zaloguj się, aby zobaczyć kod