Wyświetlacz hd44780 na linii I2C

Po co gromadzić dane, jeśli nie można ich przejrzeć? Dzięki wyświetlaczowi zintegrowanemu z domową stacją meteo, można sprawdzić temperaturę, wilgotność i inne parametry bez konieczności odpalania komputera/telefonu.

Hardware

Aby podłączyć HD44780 do urządzenia z UNIXem najprościej użyć konwertera LCS2USB, ale w tym przypadku nie wchodziło to w grę. Prawie 10 metrów przewodu, z tego około 3 metry na zewnątrz budynku, to zdecydowanie zbyt wiele, by użyć standardu USB. Z pomocą przyszedł oczywiście interfejs I2C, „rozciągnięty” po prawie całym domu.

Schemat podstawowyZastosowałem podstawową aplikację sterownika, z wykorzystaniem układu PCF8574 (czyli 8-portowego ekspandera szyny I2C). Oczywiście niezbędne było wykorzystanie buforów P82B715, które pozwalają znacznie wydłużyć zasięg magistrali. Płytka, dla celów redukcji strat energii, zasilana jest napięciem 12V. Niezbędna jest więc redukcja napięcia do poziomu +5V. Zastosowałem regulator LDO firmy maxim (MAX604). Dla celów ewentualnej przyszłej rozbudowy wypuściłem na szpilkach 4 złącza – zasilanie, SCL i SDA. Obecnie podłączyłem do tego złącza minipłytkę z termometrem, który mierzy temperaturę w przedpokoju. Jasność wyświetlacza regulowana jest za pomocą tranzystora unipolarnego, na którego bazę podaje napięcie z przetwornika DAC. I choć w planach była dynamiczna zmiana jasności podświetlenia w zależności od nasłonecznienia na zewnątrz, obecnie wyświetlacz podświetlony jest wyłącznie na dwa sposoby – „na maksa” w ciągu dnia, i „przygaszony” po godzinie 23 wieczorem.

Czy jest alternatywa dla wytrawiania, wiercenia, lutowania?

I2c-LCD adapter
I2c-LCD adapter
Oczywiście – moja płytka jest tylko rozbudowaną wersją najprostszego adaptera, dostępnego na popularnych portalach aukcyjnych. Można go kupić w Chinach za około 1 dolara Słowa klucze to I2C LCD adapter. Oba układy są kompatybilne ze sobą, poprawnie wykrywane przez LCDproc.

Software

Do sterowania zasilaczem wykorzystałem rewelacyjny pakiet LCDproc z samodzielnie napisanym w php klientem, wyświetlającym dane. Pakiet składa się z serwera, do którego łączą się aplikacje klienckie i wyświetlają dane. Instalacja pod OpenWRT jest bardzo prosta:

opkg update && opkg install lcdproc

Konfiguracja serwera sprowadza się do edycja pliku /etc/LCD.conf i zmiany kilku linii:

[server]
DriverPath=/usr/lib/lcdproc/
Driver=hd44780
Bind=127.0.0.1
Port=13666
User=nobody
GoodBye="Thanks for using"
GoodBye="   LCDproc!"
WaitTime=3
ServerScreen=no
Heartbeat=off
## Hitachi HD44780 driver ##
[hd44780]
ConnectionType=i2c
Port=0x20
Device=/dev/i2c-0
Speed=0
Keypad=no
Contrast=0
Backlight=no
Size=20x2
DelayMult=4
RefreshDisplay=5
DelayBus=true

Większość opcji nie wymaga komentarza. Należy zwrócić uwagę na konfigurację sterownika wyświetlacza, podając prawidłowy sposób podłączenia (ConnectionType), Port (czyli identyfikator urządzenia PCF – u mnie 0x20), Size (czyli wielkość wyświetlacza). Trzy ostatnie parametry pozwalają zmniejszyć szybkość pracy, a więc częstotliwość wyświetlania zakłóceń na wyświetlaczu.

Uruchamiamy serwer:

/etc/init.d/LCDd start

Na wyświetlaczu powinna się wyświetlić informacja o jego typie i wielkości, a następnie ekran informujący nas, że nie ma podłączonych klientów. Aplikacje klienckie łączą się z serwerem, a następnie przesyłają mu informacje ile ekranów (screen_add, screen_set) ma być wyświetlane, przez jak długi czas i jakie dane mają być rozmieszone na poszczególnych z nich (widget_add, widget_set). Mój skrypt został napisany w php, i składa się z nieskończonej pętli pobierającej dane z pliku i aktualizujące dane na widgetach co 5 sekund. Ekrany rotują się niezależnie od aktualizowanych danych – zarządza tym już serwer LCDd.

#!/usr/bin/php-cgi -q
<?php
date_default_timezone_set("Europe/Warsaw");
set_time_limit(0);
$disp = "lcd1";
$disp2 = "lcd2";

function dane() {
 //pobieram dane z pliku, zwracam w postaci tablicy
 //napisz ją tak, by pasowała do Twoich danych
}

function lcd_cmd($c) {
    global $f;
    //echo "LCD_cmd=> $c \n";
    fputs($f, $c."\n");
    usleep(100);
    $rep = str_replace("\n", "", fgets($f));
    //echo "LCD_out=> ".$rep."\n";
    return $rep;
}

function lcd_open() {
    global $f;
    $f = fsockopen("localhost", 13666, $errno, $errstr, 0);
    if (!$f){
        echo "$errstr ($errno)<br />\n";
        return false;
    } 
    $hello = lcd_cmd("hello"); 
    $hgt = (int) substr($hello, strpos($hello, "hgt")+3 , 3);
    lcd_cmd('client_set name usb');   
    return $hgt;
}

function lcd_init(){
    global $f;
    global $disp, $disp2;
    $wys = lcd_open();
    
    lcd_cmd('screen_add ' . $disp);    
    lcd_cmd('screen_set ' . $disp . ' heartbeat off');
    lcd_cmd('screen_set ' . $disp . ' backlight on');

    lcd_cmd('screen_set ' . $disp . ' duration 45');
    lcd_cmd('screen_set ' . $disp . ' priority 101');

    lcd_cmd('widget_add ' . $disp . ' t_in' . ' string');
    lcd_cmd('widget_add ' . $disp . ' t_out' . ' string');
       
    lcd_cmd('screen_add ' . $disp2);    
    lcd_cmd('screen_set ' . $disp2 . ' heartbeat off');
    lcd_cmd('screen_set ' . $disp2 . ' backlight on');    

    lcd_cmd('screen_set ' . $disp2 . ' duration 45');
    lcd_cmd('screen_set ' . $disp2 . ' priority 101');
        
    lcd_cmd('widget_add ' . $disp2 . ' h_out' . ' string');
    lcd_cmd('widget_add ' . $disp2 . ' p_out' . ' string');

}

function loop() {
    global $f;
    global $disp, $disp2;
    while (1) {
	$dane = dane();        
        lcd_cmd('widget_set ' . $disp . ' t_in' . ' 1 ' . "1" . ' "Temp IN   ' . $dane["temp_in"] . ' C"');
        lcd_cmd('widget_set ' . $disp . ' t_out' . ' 1 ' . "2" . ' "Temp OUT  ' . $dane["temp_out"] . ' C"');
        
        lcd_cmd('widget_set ' . $disp2 . ' h_out' . ' 1 ' . "1" . ' "Wilgotnosc  ' . $dane["hum_out"] . '%"');
        lcd_cmd('widget_set ' . $disp2 . ' p_out' . ' 1 ' . "2" . ' "Cisnienie ' . $dane["pres_out"] . 'hPa"');

        sleep(5);    
    };
    
}

lcd_init();
loop();
?>

Po zapisaniu kodu na dysku, przechodzimy do foldera, w którym został on zapisany, nadajemy mu atrybut x (czyli executable) i uruchamiamy:

chmod +x wyswietlacz.php
./wyswietlacz.php

i uruchamiamy – w tym momencie serwer wyświetli na moment informację Clients:1, a potem zaczną się naprzemiennie wyświetlać ekrany klienta. Najpierw, by ułatwić debugowanie można usunąć komentarze w funkcji lcd_cmd(), by widzieć co kolejno jest przesyłane do serwera LCDd i jak on na to odpowiada (CTRL+C zatrzymuje skrypt). Gdy jest już gotowy, uruchamiamy go za pomocą poniższego polecenia, by pracował w tle.

./wyswietlacz.php >/dev/null 2>&1 &

W poniższej paczce danych .rar znajdują się dwa pliki – schemat i płytka (w formacie Eagle) wyświetlacza.

DIsplay board
DIsplay board
sanok_system.rar
Version: 1
82.1 KiB
31 Downloads
Szczegóły
Udostępnij:Share on FacebookEmail this to someoneWykop!Share on Google+Print this pageShare on TumblrTweet about this on Twitter

Dodaj komentarz

Twój adres email nie zostanie opublikowany.