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

LCD 4x20 - HD44780 wysypuje się

29 Kwi 2013 10:44 2319 12
  • Poziom 9  
    Witam.
    Mam problem z wyświetlaczem HD44780.
    Po jakimś czasie działania wysypuje się - jak zdjęcie: LCD 4x20 - HD44780 wysypuje się

    W czasie działania pokazuje się czas - godzina i data
    i co kilka sekund jest wyświetlany status w postaci * lub -.

    Próbowałem już wiele rzeczy. Zmieniałem delay-e przed wywoływaniem funkcji ustawiającej pozycję x/y.
    Po wyświetlaniu tez zwiększałem/zmniejszałem czas delay-a.

    I nic. Czym te krzaki są spowodowane. LCD działa u mnie na 4 bit linii danych.
  • Moderator Mikrokontrolery Projektowanie
    Albo są błędy w programie, albo masz problem elektryczny. Jak długa jest taśma łącząca LCD z układem? Sądząc po fragmencie zdjęcia ze złączem to masz tam jakiś mały koszmar :) Dodaj kondensatory odsprzęgające, uporządkuj przewody, maksymalnie je skróć.
  • Poziom 9  
    taśma ma około 30 cm. A koszmar jest hehe.
    Ale jak wyłączę zegarek a zostawię pokazywanie statusu, lub na odwrót: działa sam zegarek a status nie - to działa całymi dniami.

    wiem, że chodzi o program ale o co :)

    Tak wyświetlam czas:

    if(flaga==0)
    {
    sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
    lcdPosition ((int)disp,12 ,2 ) ;
    lcdPuts ((int)disp, buf1) ;

    sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
    lcdPosition ((int)disp, 10, 3) ;
    lcdPuts ((int)disp, buf1) ;

    delay(250);
    }

    A tak status:
    flaga=1;
    char buf1[2]="*";
    char buf2[2]="-";
    lcdPosition ((int)disp, 0 ,3 );
    if(reconnect) lcdPuts((int)disp,buf2);
    else lcdPuts((int)disp,buf1);
    delay(250);
    flaga=0;

    Używałem wcześniej lcdPutchar ale zmieniłem na lcdPuts bo już zacząłem myśleć, że jest walnięta ta funkcja. Korzystam z gotowych bibliotek.
  • Moderator Mikrokontrolery Projektowanie
    Zacząłbym od uporządkowania przewodów. A programowo - może gdzieś nadpisujesz bufor, albo bufor jest zbyt mały aby pomieścić cały łańcuch. Co to za biblioteka? W niej też może być problem. Funkcje opóźniające sam napisałeś? Dlaczego nie korzystasz z delay.h?
  • Specjalista - Mikrokontrolery
    Czy którąś z tych akcji wykonujesz w przerwaniu?
    Pokaż kod.

    Te delay() wyglądają mało sensownie.
  • Poziom 9  
    Generalnie to jest raspberry pi

    w wątku (poniżej) jets zegarek

    PI_THREAD (myThread)
    {

    struct tm *t;
    time_t tim;

    char buf1 [20];

    if(flaga==0) {

    while(1){
    tim = time (NULL) ;
    t = localtime (&tim) ;

    godzina = t->tm_hour;
    minuta = t->tm_min;
    dzien = t->tm_wday;


    sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
    lcdPosition ((int)disp,12 ,2 ) ;
    lcdPuts ((int)disp, buf1) ;


    sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
    lcdPosition ((int)disp, 10, 3) ;
    lcdPuts ((int)disp, buf1) ;

    delay(250);
    }
    }
    }

    a w programie w mian() wyświetlam, używając tego samego handlera wyświetlacza inne rzeczy. Doszło do mnie i zrobiłem flagę blokująca w zegarku - działającym w osobnym wątku, aby gdy jest ustawiona nie pisać do wyświetlacza,
    bo w jakimś innym miejscu programu mógłbym pisać w tym samy momencie. Tak to mam teraz i dalej się wykrzacza.

    Raz krócej, raz dłużej działa...
  • Specjalista - Mikrokontrolery
    A skąd niby program miałby się dowiedzieć o tym że podczas pisania na LCD po wcześniejszym sprawdzeniu, że wolno to robić, "ten drugi" zaczął pisać?

    Jak widzisz - pisać musisz tylko w jednym wątku, a drugi może ustawić znacznik, że trzeba wypisać jego informację.
  • Poziom 9  
    witam!

    Faktycznie. Popełniałem duży błąd bo mimo, że np. wątek aktualnie wyświetlał coś na lcd to ja ustawiałem flagę (dla wątku nie miało to znaczenia bo i tak był np. w połowie pisania na lcd), a ja w main zaczynałem symultanicznie pisać :)

    Ale i tak po zmianie dalej się sypie... Wklejam kod, na którym robię testy.
    Załączam też plik żeby był lepiej sformatowany - do otwarcia w sowim edytorze.

    Teraz PI_THREAD ustawia blokadę. A ja w main czyszczę disp jak blokada jest wyłączona. Po kilku minutach krzaki...

    <code>
    PI_THREAD (myThread)
    {

    struct tm *t;
    time_t tim;

    char buf1 [20];

    while(1){
    tim = time (NULL) ;
    t = localtime (&tim) ;

    flaga=1;

    sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
    lcdPosition ((int)disp,12 ,2 ) ;
    lcdPuts ((int)disp, buf1) ;


    sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
    lcdPosition ((int)disp, 10, 3) ;
    lcdPuts ((int)disp, buf1) ;

    flaga=0;
    delay(250);

    }
    }

    int inicjalizujWyswietlacz() {

    int fd1;
    if (wiringPiSetup () == -1) exit (1) ;

    fd1 = lcdInit (4,20, 4, 11, 10, 0,1,2,3,0,0,0,0);

    sleep (1) ;

    lcdPosition (fd1, 0, 0) ; lcdPuts (fd1, "Display init...") ;
    sleep (1);
    return fd1;
    }

    int main(int argc, char *argv[])
    {
    int a;
    int disp; //disp handler



    disp = inicjalizujWyswietlacz();
    lcdClear(disp);
    delay(250);
    piThreadCreate (myThread);


    sleep(2);

    while(1) {

    sleep(2);

    if(flaga==0)
    {
    lcdClear(disp);
    printf("\n czyszcze bo moge");
    }
    delay(250);

    }

    return 0;
    }
    </code>

    Dziękuję za sugestie!
  • Poziom 22  
    A spróbuj testowo wyświetlać dane stałe - nie pobieraj ich z funkcji, tylko po prostu ustaw jakieś litery/liczby. Zobaczysz czy dalej się sypie.
    Bo może układ sypie się w obsłudze wyświetlacza LCD.
    Miałem kiedyś taki przypadek, że LCD sypał się losowo (wylądało jak zakłócenia) - były źle ustawione timingi danych docierających do LCD (za krótkie trzymanie stanów na liniach).
    Po poprawce - wszystkie bledy znikły jak ręką odjął i od tej pory obsługa LCD działa niezawodnie.
  • Specjalista - Mikrokontrolery
    I cały czas jest tak samo źle, bo oba wątki piszą na wyświetlacz - szkolny błąd.
    Zrób obsługę wyświetlania w JEDNYM wątku,a drugi niech ustawia dla tego pierwszego znacznik, że ten pierwszy ma wyświetlić coś dla niego.

    Przyjrzałbym się również procedurom obsługi LCD. Większość tych dostępnych w sieci nie trzyma timingów.
  • Poziom 9  
    Hmm ale jak to... Przecież mam flagę która jest zmienną globalną. Ją testuję przed czyszczeniem. Jak jest ustawiona to nie robię lcdClear

    Edit: co do sugestii apropos wyświetlania przez wątek,gdy drugi zgłasza mu coś do wyswietlenia to fajny pomysł. Spróbuję. Ale wciąż mam klina co do programu,w którym kolega mówi,że dalej razem piszę do lcd...
  • Specjalista - Mikrokontrolery
    A jak już robisz lcdClear, to skąd ten drugi ma wiedzieć, że właśnie to robisz?

    Po raz trzeci - CAŁA obsługa LCD musi być w jednym wątku!
  • Poziom 9  
    Spoko, nie krzycz, już robię :)
    Na razie działa. Dziękuję koledze za sugestię.
    Mam nadzieję, że za kilka godzin się nie sypnie.