Raspberry Pi to bardzo ciekawe i ostatnio popularne urządzenie. Ten minikomputer potrafi naprawdę dużo. Dzięki złączu GPIO (General Purpose Input/Output) możemy komunikować się z innymi urządzeniami systemu komputerowego np. z mikroprocesorami czy urządzeniami peryferyjnymi. Umożliwia nam to komunikację dwustronną tzn. zapis i odczyt. Jednym z prostszych zastosowań takiego złącza jest możliwość uruchomienia ekranu LCD i kontrolowaniu go przez Raspberry Pi.
Naszym celem było wyświetlenie prostego tekstu na ekranie oraz napisanie aplikacji, która pozwoli na pokazywanie aktualnej pogody w danym mieście.
Wyświetlacz LCD
Większość z dostępnych na rynku wyświetlaczy LCD 2×16 znaków jest zgodna ze standardem Hitachi HD44780. Model jaki podłączyliśmy to: WC1602A-STBLWHTC-06. Model z niebieskim podświetleniem pasuje do kolorystki naszego serwisu ;-)
Oznaczenie pinów na wyświetlaczu LCD
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
Vss | Vdd | V0 | RS | R/W | E | DB0 | DB1 | DB2 | DB3 | DB4 | DB5 | DB6 | DB7 | LED+ | LED- |
- Vss (source supply) – służy do podłączenia GND (uziemienie)
- Vdd (drain supply) – zasilanie układu +5V
- RS – w zależności od stanu (wysoki, niski) wyświetlacz oczekuje na dane lub instrukcje
- R/W – stan niski przełącza LCD w tryb odbioru informacji poprzez linie DB0..DB7. Jest to tryb zapisu. Stan wysoki przełącza moduł do wysyłania informacji do zewnętrznego urządzenia. Dzięki R/W ustalamy kierunek komunikacji.
- E (enable) – podanie impulsu na to wejście powoduje odebranie przez mikrosterownik HD44780 informacji z linii DB0..DB7 oraz RS i R/W.
- DB0..DB7 – szyna danych.
- LED+/LED- – są to piny zasilające +5V oraz GND wykorzystywane w LCDkach z podświetleniem.
Do sterowania wyświetlaczem poprzez GPIO wykorzystałem bibliotekę RPi.GPIO, której proces instalacji opisaliśmy w artykule.
Schemat podłączenia LCD pod Raspberry Pi
Ekran LCD podłączamy do GPIO zgodnie ze schematem zamieszczonym poniżej. Dla wygody możemy skorzystać z płytki uniwersalnej, do której przylutujemy kable. Można również skorzystać z taśmy np. 26pin.
Pin: LCD | Funkcja LCD | PIN: Raspberry Pi | Funkcja Raspberry Pi |
01 | GND (uziemienie) | 06 | GND (uziemienie) |
02 | +5V | 02 | +5V |
03 | Kontrast | 06 | GND (uziemienie) |
04 | RS | 26 | GPIO7 |
05 | RW | 06 | GND (uziemienie) |
06 | E | GPIO8 | 24 |
07 | DB0 | ||
08 | DB1 | ||
09 | DB2 | ||
10 | DB3 | ||
11 | DB4 | 22 | GPIO25 |
12 | DB5 | 18 | GPIO24 |
13 | DB6 | 16 | GPIO23 |
14 | DB7 | 12 | GPIO18 |
15 | +5V przez 560 ohm | ||
16 | GND (uziemienie) | 06 | GND (uziemienie) |
Pogodynka w Pythonie
Prosty program napisany w Pythonie służy do wyświetlania znaków na ekranie LCD. Źródła dostępne są również w serwisie GitHub.
[python]#!/usr/bin/python
# -*- coding: utf-8 -*-
# HD44780 LCD Script for Raspberry Pi
#
# Author : Kamil Porembinski
# Site : https://osworld.pl
#
# Based on Matt’s Hawkins script
# Site : http://www.raspberrypi-spy.co.uk
#
# Date : 23/08/2012
#import
import RPi.GPIO as GPIO
import time
import urllib2
import re
# Script options
settings = {
# City to monitor (ex. "Lodz", "Warsaw, Cracow", …)
'city’ : 'Lodz’,
# Language of the conditions (ex. en, pl, fr, …)
'language’ : 'pl’,
}
GOOGLE_WEATHER_URL = 'http://www.google.com/ig/api?weather=%s&hl=%s&oe=utf-8′
# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18
# Define some device constants
LCD_WIDTH = 16 # Maximum characters per line
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
# Timing constants
E_PULSE = 0.00005
E_DELAY = 0.00005
E_TIME = 5
def lcd_init():
# Initialise display
lcd_byte(0x33,LCD_CMD)
lcd_byte(0x32,LCD_CMD)
lcd_byte(0x28,LCD_CMD)
lcd_byte(0x0C,LCD_CMD)
lcd_byte(0x06,LCD_CMD)
lcd_byte(0x01,LCD_CMD)
def lcd_string(message):
# Send string to display
message = message.ljust(LCD_WIDTH,)
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
def lcd_byte(bits, mode):
# Send byte to data pins
# bits = data
# mode = True for character
# False for command
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
# Toggle 'Enable’ pin
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
# Toggle 'Enable’ pin
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
def rmpl(text):
pl_tab = {u’ą’:’a’, u’ć’:’c’, u’ę’:’e’, u’ł’:’l’, u’ń’:’n’, u’ó’:’o’, u’ś’:’s’, u’ż’:’z’, u’ź’:’z’,u’Ą’:’A’, u’Ć’:’C’, u’Ę’:’E’, u’Ł’:’L’, u’Ń’:’N’, u’Ó’:’O’, u’Ś’:’S’, u’Ż’:’Z’, u’Ź’:’Z’}
return ”.join( pl_tab.get(char, char) for char in text )
def convert_mph(match):
try:
mph = int(match.group(0).split(’ ’)[0])
kph = mph*1.6
return "%s kph" % (int(round(kph)),)
except:
return match.group(0)
def get_weather_for_city():
from xml.dom.minidom import parseString
from xml.etree import ElementTree as ET
url = GOOGLE_WEATHER_URL % (settings["city"].replace(’ ’, '+’), settings["language"])
try:
source = urllib2.urlopen(url).read()
source = source.decode(’utf-8′, 'ignore’)
source = source.encode(’utf-8′)
etree = ET.fromstring(source)
weather = etree.find(’weather’)
except:
return("There was an error while retrieving data from the server.")
parts = []
out = {}
information = weather.find(’forecast_information’)
city = rmpl(information.find(’city’).get(’data’))
out["city"] = city
conditions = weather.find(’current_conditions’)
temperature = rmpl(conditions.find(’temp_c’).get(’data’) + 'C’)
out["temperature"] = "Temperatura: " + temperature
humidity = rmpl(conditions.find(’humidity’).get(’data’))
out["humidity"] = humidity
wind = rmpl(conditions.find(’wind_condition’).get(’data’))
wind = re.sub(’\d+ mph’, convert_mph, wind)
out["wind"] = wind
condition = rmpl(conditions.find(’condition’).get(’data’))
out["condition"] = condition
return out
def main():
# Main program block
GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers
GPIO.setup(LCD_E, GPIO.OUT) # E
GPIO.setup(LCD_RS, GPIO.OUT) # RS
GPIO.setup(LCD_D4, GPIO.OUT) # DB4
GPIO.setup(LCD_D5, GPIO.OUT) # DB5
GPIO.setup(LCD_D6, GPIO.OUT) # DB6
GPIO.setup(LCD_D7, GPIO.OUT) # DB7
# Initialise display
lcd_init()
while 1 == 1:
out = get_weather_for_city()
# Send some text
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string(time.strftime(’ %H:%M:%S ’))
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string(time.strftime(’ %d-%m-%Y ’))
time.sleep(E_TIME)
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string(out["city"])
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string(out["temperature"])
time.sleep(E_TIME)
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string(out["humidity"])
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string(out["condition"])
time.sleep(E_TIME)
if __name__ == '__main__’:
main()[/python]
Z racji tego, że jest to pierwszy mój program w Pythonie, liczę na poprawki do kodu ;-)
Jaki jest orientacyjny koszt takiej zabawki nie licząc ceny Raspberry Pi?
Jakies 15zl za wyswietlacz na allegro ;) opornika i kabelkow nie licze bo to ponizej 10gr;)
Wyświetlacz 17 zł w sklepie elektronicznym.
Kabelki i rezystor i troszkę cyny – 10 zł
Kurcze kupie sobie :) a co tam zaszaleje i wydam te 27 zł :D
Ciekawe czy można pobierać info z xbmc o obecnie odtwarzanym strumieniu :)
Z tym trzeba było spróbować :) http://allegro.pl/wyswietlacz-lcd-128×240-bascom-…
Wygląda super! Czemu nie ;-) Kupisz? :D
Znalazłem w Sieci fajny opis do ministacji meteorologicznej: http://rab.ict.pwr.wroc.pl/~kreczmer/wds/projekty…
Czy wpisy są cenzurowane? Wklejam to trzeci raz…
Dzięki! Czasem wpis jest klasyfikowany jako SPAM, ale sprawdzamy ręcznie i komentarz wraca ;-)
To jest ten: http://mselektronik.pl/16×2-stn-5v-led-nieb-biale…
?
Tak to ten. Można do niego dorobić jeszcze regulację kontrastu, ale to na dalszy etap przerzuciłem. Mam jeszcze inne wyświetlacze np. 4×16, ale nie są chyba zgodne z Hitachi HD44780.
To by było ciekawe. Pewnie można. W końcu to Open Source.
API jest więc można :)
Podsyłam znaleziony w Sieci plik, może będzie inspiracją: http://sequoia.ict.pwr.wroc.pl/~kreczmer/wds/proj…
Ładnie napisane gratuluję :)
Bardzo fajny pomysł. Super. Chyba wygram sobie Raspberry Pi i też takie zrobię.
Bardzo fajnie i przejrzyście opisane oraz zilustrowane! Szkoda, że jestem antytalentem w lutowaniu i tego typu pracach – bo chętnie bym coś takiego chciał mieć. Może sprzedacie albo zrobicie mi takie coś? :P
Nie masz nikogo ze znajomych co potrafią takie rzeczy? Na pewno pomogą ;)
Ewentualnie zapytaj na http://picoboard.pl/ ;-)
Zrobiłem tak jak w artykule, ale wyświetla mi się jedna linia pełna kwadratów.
czy zamiast rezystora 580 ohm mogę dać 560 om ?
Właśnie taki: http://sklep.avt.pl/p/pl/70496/rezystor+560om+1w+…
będę tam robić zamówienie
Powinno być OK. Dla pewności możesz spytać na http://picoboard.pl/
Ja nie dałem rezystora na podświetlenie i działa o.O
Nie używaj tej emotki, źle się tutaj kojarzy.
Pytanie z innej beczki, warto montować radiatory w Rasberry PI? Po zamontowaniu radiatorów podkręcaliście procek?
Zerknij tutaj: http://picoboard.pl/viewtopic.php?f=5&t=13&am…
Google api nie działa już, znaleźliście jakiś zamiennik?
Nie, bo nie wiedziałem, że nie działa. Na szybko znalazłem: http://www.weather.com/services/xmloap.html
Jesteś pewny, że nie powinno tam być buforów konwertujących napięcia? RPi nie toleruje na GPIO więcej niż 3,3V. Co prawda w tej aplikacji zapisujesz dane do wyświetlacza, jednak z różnych przyczyn, na przykład zakłóceń w zasilaniu czy przypadkowym ustawieniu linii r/w na odczyt danych z LCD, może się zdarzyć, że ten wysteruje którąś z linii danych w stan wysoki (a jest zasilany z 5V) i z RPi – nie daj! – poleci "magiczny dymek".
Wątek dość stary ale doszedłem do momentu kiedy przy próbie uruchomienia wyświetla się data i godzina i po dwóch sekundach pojawia się komunikat z pythona
„Traceback (most recent call last):
File „weather_lcd2.py”, line 200, in
main()
File „weather_lcd2.py”, line 189, in main
lcd_string(out[„city”])
TypeError: string indices must be integers, not str”
I kompletnie nie mam pojęcia co to za babol..
Mam to samo o nie idzie się tego pozbyć…
mam to samo pomoze ktos?
gnd to nie uziemienie to masa :/
Czy istnieje możliwość wyświetlania informacji na dzień kolejny? Jeśli tak, to co trzeba zmienic w kodzie ?
I love how you incorporate personal stories and experiences into your posts It makes your content relatable and authentic
농심, 동반성장지수 6년 연속 ‘최우수’ 등급 획득 개인회생자대출상품 [2보] '선거법 위반’ 박경귀 아산시장 당선무효…벌금 1천500만원 확정 개인회생자대출상품