Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

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

bombardier89 26 Oct 2014 11:09 5790 17
SterControl
  • #1
    bombardier89
    Level 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.
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • SterControl
  • Helpful post
    #2
    michalko12
    MCUs specialist
    W pierwszej kolejności należy przejść na sprzętowe SPI bo to co jest teraz to jest masakra.

    Code: c
    Log in, to see the code
  • #3
    bombardier89
    Level 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.
  • #4
    piotrva
    VIP Meritorious for electroda.pl
    Poszukaj w nocie katalogowej procesora - tu wypada napisać od razu funkcje operujące na rejestrach interfejsu SPI - tak będzie najszybciej.

    https://www.google.pl/search?q=avr+spi
  • #5
    michalko12
    MCUs specialist
    bombardier89 wrote:

    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/programowanie-spi-szeregowy-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.
  • SterControl
  • #6
    bombardier89
    Level 14  
    Ok, napisałem coś takiego:

    
     
    #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?
  • #7
    michalko12
    MCUs specialist
    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 wrote:
    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!
  • #8
    bombardier89
    Level 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.
  • #9
    michalko12
    MCUs specialist
    A jeszcze się tak zapytam czy podłączyłeś wyświetlacz pod piny od sprzętowego SPI?
  • #10
    bombardier89
    Level 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
  • #11
    michalko12
    MCUs specialist
    A co to za zmyłka?
    Code: c
    Log in, to see the code



    Code: c
    Log in, to see the code


    Tak w ogóle to wychodzi masło maślane, zrób porządek z tymi funkcjami.
  • #12
    bombardier89
    Level 14  
    Po zmianie jest nadal to samo.
  • #13
    michalko12
    MCUs specialist
    Bez testLCD(); co się wyświetli?
  • #14
    bombardier89
    Level 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.
  • Helpful post
    #15
    michalko12
    MCUs specialist
    Sprawdź połączenie pinu RS czy dobrze łączy i czy pod właściwe piny podłączony.
  • #16
    bombardier89
    Level 14  
    Pin jest OK.
  • #18
    bombardier89
    Level 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!