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

Arduino - Optymalizacja sterownika LCD LM15SGFNZ07 (Siemens A60, S55, ...)

bombardier89 26 Paź 2014 11:09 4524 17
  • #1 26 Paź 2014 11:09
    bombardier89
    Poziom 14  

    Dzień dobry,
    jakiś czas temu wpadła mi instrukcja podłączenia LCD od Siemensów A60, C60, S55, (...). Wykorzystuje ona bibliotekę, którą można pobrać stąd: https://bitbucket.org/mindogas/lm15sgfnz07
    zaś sama instrukcja podłączenia znajduje się tutaj.
    Wszystko działa (wyświetla poprawnie), z tym że robi to koszmarnie wolno. Takie np. czyszczenie LCD (wypełnianie go jakimś zadanym kolorem) trwa dwie sekundy. Utrudnia to bardzo wykorzystanie wyświetlacza w jakichś projektach, gdzie odświeżamy LCD co np. pół sekundy/sekundę.

    Czy ktoś z elektrodowiczów mógłby podsunąć jakieś pomysły na to, jak poprawić szybkość komunikacji Arduino z wyświetlaczem? Może znalazłby ktoś chwilę czasu, żeby zerknąć okiem na pliki biblioteki (zaledwie dwa pliki + jeden .h) i jakoś mi pomóc?

    Z góry bardzo dziękuję za jakikolwiek odzew w wątku.
    Pozdrawiam serdecznie.

    0 17
  • SterControl
  • Pomocny post
    #2 26 Paź 2014 12:16
    michalko12
    Specjalista - Mikrokontrolery

    W pierwszej kolejności należy przejść na sprzętowe SPI bo to co jest teraz to jest masakra.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • SterControl
  • #3 26 Paź 2014 14:10
    bombardier89
    Poziom 14  

    Mógłbyś dać jakieś wskazówki/fragment kodu? Próbowałem szukać informacji nt. w jaki sposób mógłbym to zrobić, ale bezskutecznie.

    0
  • #5 26 Paź 2014 15:08
    michalko12
    Specjalista - Mikrokontrolery

    bombardier89 napisał:

    Mógłbyś dać jakieś wskazówki/fragment kodu? Próbowałem szukać informacji nt. w jaki sposób mógłbym to zrobić, ale bezskutecznie.

    Na przykład na podstawie tych poradników:
    http://mikrokontroler.info/obsluga-sprzetowego-mudulu-spi-w-mikrokontrolerach-avr/
    http://www.forbot.pl/forum/topics20/programow...y-interfejs-urzadzen-peryferyjnych-vt2275.htm

    Nie proś, żeby pisać kod za Ciebie, bo to jest akurat bardzo prosta sprawa w stosunku do obsługi samego LCD.

    Ja jestem akurat przeciwnikiem całego tego systemu arduino, nie samej płytki z procesorem lecza całej tej nagonki internetowej na ten system. Uważam, że nic z tego dobrego nie wyniknie.

    0
  • #6 26 Paź 2014 16:42
    bombardier89
    Poziom 14  

    Ok, napisałem coś takiego:

    Code:

     
    #include <SPI.h>
     
    const int csPin = 10;
    const int resetPin = 4;
    const int cdPin = 3;

    void (*fpInitLCD)(void) = 0;                                 // function pointer for LCD initialization
    void (*fpCursor)(unsigned char row, unsigned char col) = 0;  // function pointer for LCD cursor
    void (*fpClearLCD)(void) = 0;     


    unsigned char lcdXpos = 0;        // x cursor position for LCD
    unsigned char lcdYpos = 0;        // y cursor position for LCD
    unsigned int fgColor = 0x000F;    // foreground color for LCD (xRGB)
    unsigned int bgColor = 0x0FFF;    // background color for LCD (xRGB)// function pointer for LCD clearscreen

    void setContrast_LM15(unsigned char contrast)
    {
       digitalWrite(cdPin, HIGH);
       digitalWrite(csPin, LOW);

       SPI.transfer(0xF4);
       SPI.transfer(0xB0 | (contrast >> 4));
       SPI.transfer(0xA0 | (contrast & 0x0F));

       digitalWrite(csPin, HIGH);
    }

    void window_LM15(unsigned char xstart, unsigned char ystart, unsigned char xend, unsigned char yend)
    {
        xstart <<= 1;
        xstart += 6;
        xend <<= 1;
        xend += 7;
       
        digitalWrite(cdPin, HIGH);   
        digitalWrite(csPin, LOW);
        SPI.transfer(0xF0);
        SPI.transfer(0x00 | (xstart & 0x0F));
        SPI.transfer(0x10 | (xstart >> 4));
        SPI.transfer(0x20 | (ystart & 0x0F));
        SPI.transfer(0x30 | (ystart >> 4));
        SPI.transfer(0xF5);
        SPI.transfer(0x00 | (xend & 0x0F));
        SPI.transfer(0x10 | (xend >> 4));
        SPI.transfer(0x20 | (yend & 0x0F));
        SPI.transfer(0x30 | (yend >> 4));
        digitalWrite(csPin, HIGH);
        digitalWrite(cdPin, LOW);     
    }

    void cursor_LM15(unsigned char row, unsigned char col)
    {
       window_LM15(col, row, 100, 79);
    }         

    void draw(unsigned char value)




    {               
       SPI.transfer(value);
    }

    void clearLCD_LM15(void)
    {     
       unsigned int i;

       digitalWrite(cdPin, LOW);
       digitalWrite(csPin, LOW);
               
       for(i = 0; i < 8080; i++)
       {
          draw(0xFF);
          draw(0xFF);
       }       

       digitalWrite(csPin, HIGH);
    }


    void testLCD(void)
    {     
       unsigned int i;

       setCursor(0,0);
       digitalWrite(cdPin, LOW);
       digitalWrite(csPin, LOW);

       for(i = 0; i < 2020; i++)
       {                   //white
          draw(0x0F);
          draw(0xFF);
       }       
       for(i = 0; i < 2020; i++)
       {                   //red
          draw(0x0F);
          draw(0x00);
       } 
       
       for(i = 0; i < 2020; i++)
       {                   //green
          draw(0x00);
          draw(0xF0);
       }       
       for(i = 0; i < 2020; i++)
       {                   //blue
          draw(0x00);
          draw(0x0F);
       }       

       digitalWrite(csPin, HIGH);
       setCursor(0,0);
       
    }


    void setCursor(unsigned char y, unsigned char x)
    {
       lcdXpos = x;
       lcdYpos = y;                                 
       if(cursor_LM15)
       {
          (*cursor_LM15)(y, x);
       }
    }




    unsigned char initData_lm15[] = {
    0xF4 , 0x90 , 0xB3 , 0xA0 , 0xD0,  0xF0 , 0xE2 , 0xD4 , 0x70 , 0x66 ,
    0xB2 , 0xBA , 0xA1 , 0xA3 , 0xAB , 0x94 , 0x95 , 0x95 , 0x95 , 0xF5 ,
    0x90,  0xF1 , 0x00 , 0x10 , 0x22 , 0x30 , 0x45 , 0x50 , 0x68 , 0x70 ,
    0x8A , 0x90 , 0xAC , 0xB0 , 0xCE , 0xD0,  0xF2 , 0x0F , 0x10 , 0x20 ,
    0x30 , 0x43 , 0x50 , 0x66 , 0x70 , 0x89 , 0x90 , 0xAB , 0xB0 , 0xCD ,
    0xD0,  0xF3 , 0x0E , 0x10 , 0x2F , 0x30 , 0x40 , 0x50 , 0x64 , 0x70 ,
    0x87 , 0x90 , 0xAA , 0xB0 , 0xCB , 0xD0,  0xF4 , 0x0D , 0x10 , 0x2E ,
    0x30 , 0x4F , 0x50,  0xF5 , 0x91,  0xF1 , 0x01 , 0x11 , 0x22 , 0x31 ,
    0x43 , 0x51 , 0x64 , 0x71 , 0x86 , 0x91 , 0xA8 , 0xB1 , 0xCB , 0xD1,
    0xF2 , 0x0F , 0x11 , 0x21 , 0x31 , 0x42 , 0x51 , 0x63 , 0x71 , 0x85 ,
    0x91 , 0xA6 , 0xB1 , 0xC8 , 0xD1,  0xF3 , 0x0B , 0x11 , 0x2F , 0x31 ,
    0x41 , 0x51 , 0x62 , 0x71 , 0x83 , 0x91 , 0xA4 , 0xB1 , 0xC6 , 0xD1,
    0xF4 , 0x08 , 0x11 , 0x2B , 0x31 , 0x4F , 0x51 , 0x80 , 0x94, 0xF5 ,
    0xA2 , 0xF4 , 0x60 , 0xF0 , 0x40 , 0x50 , 0xC0 , 0xF4 , 0x70};
     
    void setup()
    {
     unsigned int i;
     
     SPI.begin();
     
       digitalWrite(resetPin, LOW);
       delay(10);
       digitalWrite(resetPin, HIGH);
       delay(10);
       
       digitalWrite(cdPin, HIGH);
       digitalWrite(csPin, LOW);
       
       
       for(i = 0; i < sizeof(initData_lm15); i++)
       {
          SPI.transfer(initData_lm15[i]);   // send initialization data
       }
       delay(1);       
       digitalWrite(csPin, HIGH);
       
       delay(1);
       digitalWrite(csPin, LOW);
                 
        SPI.transfer(0xF0);
        SPI.transfer(0x81);
        SPI.transfer(0xF4);
        SPI.transfer(0xB3);
        SPI.transfer(0xA0);
       
        SPI.transfer(0xF0);
        SPI.transfer(0x06);
        SPI.transfer(0x10);
        SPI.transfer(0x20);
        SPI.transfer(0x30);
        SPI.transfer(0xF5);
        SPI.transfer(0x0F);
        SPI.transfer(0x1C);
        SPI.transfer(0x2F);
        SPI.transfer(0x34);
        digitalWrite(csPin, HIGH);
        digitalWrite(cdPin, LOW);

        setContrast_LM15(30);
               
        cursor_LM15(0,0);

         clearLCD_LM15();
         cursor_LM15(1,1);
         testLCD();
    }
     
    void loop()
    {

    }


    no i efektem jest sieka na ekranie (szum kompletny).
    Z ciekawości zmieniłem const int cdPin = 3; na const int cdPin = 1; i przez chwilę coś zatrybiło (tzn kolory wyświetliło OK, tylko poprzesuwane).

    Czy ktoś może mi pomóc w znalezieniu błędu?

    0
  • #7 26 Paź 2014 16:58
    michalko12
    Specjalista - Mikrokontrolery

    Nie wiem, ale mogę domniemać, że problemem może być konfiguracja SPI - spróbuj zwolnić transfer poprzez odpowiednie ustawienie dzilnika

    http://arduino.cc/en/Reference/SPISetClockDivider

    Sprawdź czy reszta konfiguracji SPI jest prawidłowa
    http://arduino.cc/en/Reference/SPISetBitOrder
    http://arduino.cc/en/Reference/SPISetDataMode

    Dodano po 6 [minuty]:

    bombardier89 napisał:
    Z ciekawości zmieniłem const int cdPin = 3; na const int cdPin = 1;
    Nie możesz sobie od tak zmieniać tej wartości. Masz przecież sygnał CD wyświetlacza podłączony pod konkrety pin procesora! Tutaj wartość ma być zgodna ze schematem!

    0
  • #8 26 Paź 2014 17:20
    bombardier89
    Poziom 14  

    Hm, przetestowałem wszystkie możliwe opcje. I tak:

    SPISetBitOrder - tylko na MSBFIRST się coś wyświetla
    SPISetDataMode - na SPI_MODE0 i SPI_MODE3 jest sieka (czyli kontrast ustawia OK), na SPI_MODE1 i SPI_MODE2 brak odzewu ze strony LCD
    SPISetClockDivider - przetestowałem wszystkie opcje, nie widzę różnicy.

    Kurczę, wydaje mi się że już jest blisko, ot łamigłówka...

    Dodano po 10 [minuty]:

    Sam LCD podpiąłem do Arduino tak:
    Arduino - Optymalizacja sterownika LCD LM15SGFNZ07 (Siemens A60, S55, ...) [/img]

    Dodano po 3 [minuty]:

    Dodaję też pinout tego wyświetlacza:

    1 - CS
    2 - Reset
    3 - RS
    4 - SCLK
    5 - SDTA
    6 - VCC
    7 - GND
    8 - LED1 VCC
    9 - LED1LED2 GND
    10 - LED2 VCC

    Jeżeli jesteście w stanie, pomóżcie proszę - mam wrażenie, że naprawdę niedużo brakuje.

    0
  • #9 26 Paź 2014 17:23
    michalko12
    Specjalista - Mikrokontrolery

    A jeszcze się tak zapytam czy podłączyłeś wyświetlacz pod piny od sprzętowego SPI?

    0
  • #10 26 Paź 2014 17:35
    bombardier89
    Poziom 14  

    Wg tego: http://arduino.cc/en/Reference/SPI tak (miso 12, sck 13, ss 10), zaś pin Reset z wyświetlacza mam wpięty do pinu 4 w Arduino, a CD mam wpięte do pinu 3.

    Dodano po 5 [minuty]:

    Dodam jeszcze, że kontrast ustawiany jest OK, tzn zmiana wartości faktycznie zmienia kontrast wyświetlacza

    0
  • #11 26 Paź 2014 17:48
    michalko12
    Specjalista - Mikrokontrolery

    A co to za zmyłka?

    Kod: c
    Zaloguj się, aby zobaczyć kod



    Kod: c
    Zaloguj się, aby zobaczyć kod


    Tak w ogóle to wychodzi masło maślane, zrób porządek z tymi funkcjami.

    0
  • #12 26 Paź 2014 17:53
    bombardier89
    Poziom 14  

    Po zmianie jest nadal to samo.

    0
  • #13 26 Paź 2014 17:58
    michalko12
    Specjalista - Mikrokontrolery

    Bez testLCD(); co się wyświetli?

    0
  • #14 26 Paź 2014 18:08
    bombardier89
    Poziom 14  

    Zarówno bez clearLCD_LM15();, jak i i testLCD(); kompletna sieka.
    Bez ustawiania kontrastu widać siekę jak przechyli się ekran o jakiś duży kąt.

    0
  • Pomocny post
    #15 26 Paź 2014 18:15
    michalko12
    Specjalista - Mikrokontrolery

    Sprawdź połączenie pinu RS czy dobrze łączy i czy pod właściwe piny podłączony.

    0
  • #16 26 Paź 2014 18:27
    bombardier89
    Poziom 14  

    Pin jest OK.

    0
  • #18 26 Paź 2014 18:45
    bombardier89
    Poziom 14  

    Stary, jesteś bogiem. Działa! :) Dziękuję!
    Jak już zrobię funkcje odpowiadające za tekst itd, opublikuję całość na githubie. Mam nadzieję, że przyda się nie tylko mi, wszak te wyświetlacze chodzą za bezcen :)
    Dziękuję po stukroć jeszcze raz!

    0
  Szukaj w 5mln produktów