Skocz do zawartości
Programista3

Zegar, radio internetowe oraz pogoda na Raspberry Pi

Pomocna odpowiedź

Tym razem projekt nie zachwyca wyglądem ale jest ciekawszy pod względem oprogramowania. Projekt składa się z wyświetlacza segmentowego do wyświetlania godziny, klawiatury numerycznej 12-klawiszy do wprowadzania danych i wyświetlacza LCD 2x16 do wyświetlania wszelkich informacji. Całość podłączona jest do Raspberry Pi.

WP_20190122_21_27_39_Pro.thumb.jpg.f5f0f285956511c50e41b4733d474a84.jpg

Wykorzystane części

Dostępne funkcje

Wyświetlacz segmentowy wskazuje aktualną godzinę. Kolejnymi funkcjami są odtwarzanie radia internetowego (np. ESKA, RMF FM) oraz prognoza pogody na 9 dni realizowana za pomocą API OpenWeatherMap. Z poziomu klawiatury można również wyświetlić aktualną temperaturę i użycie CPU, czas działania maliny, zrestartować/zamknąć system, zrestartować wifi oraz ustawić jasność wyświetlacza segmentowego.

Podłączenie

  • Wyświetlacz LCD podłączamy następująco:
    Pin 1 wyświetlacza do GND, pin 2 do 5V, pin 3 do środkowej nóżki potencjometru, pin 4 go GPIO25, pin 5 do GND, pin 6 do GPIO24, pin 11 do GPIO23, pin 12 do GPIO17, pin 13 do GPIO18, pin 14 do GPIO22, pin 15 do GPIO4, pin 16 do GND, lewą nóżkę potencjometru do 5V, prawą do GND.
  • W wyświetlaczu alfanumerycznym podłączenie wygląda następująco:
    GND do GND, VCC do 5V, CLK do GPIO21, DIO do GPIO20
  • Klawiaturę podłączamy zaczynając od lewej strony kolejno do pinów: 27, 5, 6, 13, 26, 12, 19 (pierwsze 4 odpowiadają wierszom, kolejne 3 kolumnom na klawiaturze)

Oprogramowanie

Kompletny kod znajduje się w załączniku, tutaj opiszę tylko niektóre ciekawsze, bardziej przydatne funkcje. Do obsługi wyświetlacza segmentowego używam tej biblioteki. Inicjujemy zegar wskazując użyte piny oraz jasność:

self.display = tm1637.TM1637(CLK=21, DIO=20, brightness=1.0)

Do obsługi wyświetlacza LCD 2x16 używam biblioteki Adafruit CharLCD. Także tutaj podajemy piny użyte w połączeniu. Tworzę również 8 dodatkowych znaków których będzie można użyć w wyświetlaczu (ą, ć, ę, ł, ń, ó, ż, ź). Znaki te można wykorzystać zamieniając polskie znaki w tekście do wyświetlenia na odpowiednie dodatkowe znaki np ą = \x00, ć = \x01 itd.

self.lcd = LCD.Adafruit_CharLCD(25, 24, 23, 17, 18, 22, 16, 2, 4)
self.lcd.create_char(0, [0,0,14,1,15,17,15,2])
self.lcd.create_char(1, [2,4,14,16,16,17,14,0])
self.lcd.create_char(2, [0,0,14,17,31,16,14,2])
self.lcd.create_char(3, [12,4,6,12,4,4,14,0])
self.lcd.create_char(4, [2,4,22,25,17,17,17,0])
self.lcd.create_char(5, [2,4,14,17,17,17,14,0])
self.lcd.create_char(6, [2,4,14,16,14,1,30,0])
self.lcd.create_char(7, [4,0,31,2,4,8,31,0])

Aby używać klawiatury korzystam z modułu pad4pi

KEYPAD = [
  ["1","2","3"],
  ["4","5","6"],
  ["7","8","9"],
  ["*","0","#"]
]
ROW_PINS = [27, 5, 6, 13]
COL_PINS = [26, 12, 19]
factory = rpi_gpio.KeypadFactory()
self.keypad = factory.create_keypad(keypad=KEYPAD, row_pins=ROW_PINS, col_pins=COL_PINS)

To wystarczy aby móc korzystać z podłączonych elementów. Funkcja gówna wygląda następująco:

self.display.StartClock() # Uruchomienie zegara w tle
self.readSettings() # Odczyt ustawień jasności z pliku
self.keypad.registerKeyPressHandler(self.keyPress) # Obsługa zdarzenia naciśnięcia klawisza na klawiaturze
while True: # Miganie dwukropkiem na zegarze co 1s
  self.display.ShowDoublepoint(True)
  sleep(1)
  self.display.ShowDoublepoint(False)
  sleep(1)

Wszelkie funkcje urządzenia realizowane są w metodzie keyPress wykonującej się po wciśnięciu klawisza na klawiaturze. Po wciśnięciu dowolnego klawisza, jeśli podświetlenie wyświetlacza jest wyłączone to zostaje włączone i wyświetlony zostaje ekran główny - pierwsza linia to data, w drugiej wyświetlane są informacje o braku internetu lub aktualnie odtwarzanej stacji radia.

WP_20190122_21_27_49_Pro.thumb.jpg.701eb6444836865240e6990ae96a1c64.jpg

Podświetlenie wyświetlacza jest automatycznie wyłączane po 20s bezczynności co realizowane jest kodem na początku metody keyPress:

if(self.timerActive == True): # Zatrzymanie odliczania jeślie trwa
  self.timer.cancel()
else:
  self.timerActive = True
self.timer = threading.Timer(20.0, self.clear) # Po zakończeniu odliczania zostanie wykonana metoda która wyczyści i wyłączy wyświetlacz
self.timer.start() # Rozpoczęcie odliczania od nowa

Z poziomu ekranu głównego można przejść do menu(#) lub opcji(*). W menu dostępne opcje to radio(1) oraz pogoda(2). Stream radia odtwarzany jest za pomocą modułu python-vlc. Odtwarzanie radia z adresu url za pomocą vlc może wyglądać tak:

self.Instance = vlc.Instance()
self.player = self.Instance.media_player_new() # Utworzenie nowego odtwarzacza
self.rmffm = self.Instance.media_new("http://195.150.20.9:8000/rmf_fm") # Dodanie źródła
# Następnie w w miejscu w kodzie gdzie chcemy uruchomić radio wystarczy wybrać źródło i rozpocząć odtwarzanie
self.player.set_media(self.rmffm)
self.player.play()

Niestety w niektórych stacjach adres streamu nie jest stały i konkretny adres url działa tylko przez kilka godzin np. radio ESKA. W takich sytuacjach pomóc może napisanie skryptu który automatycznie pobierze aktualny adres url. Ponieważ często słucham radia ESKA napisałem taki skrypt dla tego radia (plik znajduje się w załączniku). W tym przypadku skrypt jest napisany w PHP i umieszczony na darmowym hostingu ale równie dobrze mógłby być napisany w Pythonie jako część tego programu. Aby pobrać aktualny adres streamu za pomocą swojego skryptu używam kodu:

self.eska_rzeszow = self.Instance.media_new(urllib2.urlopen("http://programista3.000webhostapp.com/inne/pi/radioapi.php?id=0").read())

WP_20190122_21_29_06_Pro.thumb.jpg.4c38350c98cc41055d2d512bf923b480.jpg

Kolejną funkcją dostępna z poziomu menu jest pogoda. Po wejściu w ten tryb wyświetlana jest aktualna pogoda a za pomocą klawiszy 1-9 można wyświetlać prognozę na kolejne dni. Wyświetlana jest temperatura, ciśnienie, wilgotność oraz słowny opis pogody.

WP_20190122_21_28_54_Pro.thumb.jpg.a94c04c7d3107d6e3d4aa3d7be021be4.jpg

Naciskając * można wyświetlić szczegóły dla danego dnia. W widoku szczegółowym wyświetlane są temperatura minimalna i maksymalna, ciśnienie, wilgotność, zachmurzenie oraz prędkość wiatru.

WP_20190122_21_28_47_Pro.thumb.jpg.edf4c1e9a86944f760768b9045883216.jpg

Prognoza pogody pobierana jest za pomocą darmowego API OpenWeatherMap. Do pobrania prognozy wykorzystuję kod:

self.forecast = self.getUrl("http://api.openweathermap.org/data/2.5/forecast/daily?q=rzeszow&mode=json&units=metric&lang=pl&cnt=10&appid=xxx")
self.forecast = json.loads(self.forecast) if self.forecast else False

Wyświetlanie podstawowych informacji o pogodzie wygląda następująco:

description = (self.forecast['list'][int(key)]['weather'][0]['description'].encode('utf-8').capitalize())
self.writelcd(str(int(self.forecast['list'][int(key)]['temp']['day']))+chr(223)+"C "+str(int(self.forecast['list'][int(key)]['pressure']))+"hPa "+str(self.forecast['list'][int(key)]['humidity'])+"%\n"+description)

W opcjach urządzenia znajdują się natomiast funkcje takie jak restart wifi, restart systemu i wyłączenie systemu które są realizowane za pomocą funkcji call z biblioteki subprocess, ustawienia jasności wyświetlacza segmentowego, czas działania, temperatura CPU oraz użycie CPU.

Czas działania pobierany jest za pomocą biblioteki psutil:

def uptime(self):
  time_sec = time.time()-psutil.boot_time()
    if(time_sec > 172800):
  return str(round(time_sec/86400))+" dni"
    elif(time_sec > 3600):
  return str(round(time_sec/3600))+" h"
    elif(time_sec > 60):
  return str(round(time_sec/60))+" min"
    else:
  return str(time_sec)+" s"

Użycie CPU to również biblioteka psutil:

self.writelcd("  Użycie CPU\n     "+str(psutil.cpu_percent())+"%")

Natomiast temperaturę CPU można odczytać z pliku:

file = open("/sys/class/thermal/thermal_zone0/temp")
temp = file.read()
file.close()
self.writelcd("Temperatura CPU\n      "+temp[:2]+chr(223)+"C")

Jestem otwarty na pomysły jak mógłby wyglądać projekt i jakie funkcje można do niego dodać. Kompletny kod znajduje się w załączniku.

WP_20190122_21_30_37_Pro.jpg WP_20190122_21_29_56_Pro.jpg WP_20190122_21_15_31_Pro.jpg

rpiha.rar

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Podoba Ci się ten projekt? Zostaw pozytywny komentarz i daj znać autorowi, że zbudował coś fajnego!

Masz uwagi? Napisz kulturalnie co warto zmienić. Doceń pracę autora nad konstrukcją oraz opisem.

Właśnie zaakceptowałem Twój opis, możesz go teraz zgłosić do akcji rabatowej umieszczając link w temacie zbiorczym. Dziękuję za przedstawienie ciekawego projektu, zachęcam do prezentowania kolejnych DIY oraz aktywności na naszym forum.

Proszę tylko, aby kolejne osoby planujące opisywać projekty "w tego typu obudowach" występowały o wcześniejsze akceptacje 😉

Udostępnij ten post


Link to post
Share on other sites

A właśnie chciałem zrobić i zgłosić swój fajny unikatowy projekt w pudełku po butach. 

Sorry, nie po butach, w ładnym, pozłacanym pudełku po jakimś kremie czy perfumach, ale okazuje się, że nie będzie taki unikatowy, jak zakładałem.

Dnia 23.01.2019 o 22:20, Programista3 napisał:

Jestem otwarty na pomysły jak mógłby wyglądać projekt i jakie funkcje można do niego dodać.

Może w pudełku po butach mógłby wyglądać? 

A jakie funkcje?

Wydawało mi się, że to Ty jesteś twórcą projektu i to Ty powinieneś być dla mnie i dla innych początkujących źródłem natchnienia, a przynajmniej [bo może też jesteś początkujący] gdy prezentujesz się na forum. [?]

A takie pytanie? Czemu nie zrobiłeś w tym czymś, jeszcze jednej dziury? Na tzw ośkę potencjometru?

Udostępnij ten post


Link to post
Share on other sites
7 godzin temu, narbej napisał:

Wydawało mi się, że to Ty jesteś twórcą projektu i to Ty powinieneś być dla mnie i dla innych początkujących źródłem natchnienia, a przynajmniej [bo może też jesteś początkujący] gdy prezentujesz się na forum. [?]

Może mam złe wyobrażenie o prezentacji projektów, ale wydaje mi się, że publikuje się je również po to, żeby dowiedzieć się co myślą o nich inni, jak oni by to zrobili, czy mają jakieś pomysły na ulepszenia lub podobne projekty itp. a nie tylko po to, żeby stworzyć bibliotekę projektów, w której ludzie będą szukać inspiracji. Mam nadzieję, że potrafisz sam wymyślić wspaniały projekt w ładnym pozłacanym pudełku, bez wzorowania się na czyimś projekcie 😉.

7 godzin temu, narbej napisał:

A takie pytanie? Czemu nie zrobiłeś w tym czymś, jeszcze jednej dziury? Na tzw ośkę potencjometru?

Uznałem, że nie ma potrzeby częstej zmiany kontrastu i wystarczy, aby potencjometr był ukryty z tyłu. Ogólnie projekt miał być "zamontowany" na półce w meblach gdzie elektronika miała być ukryta za kartonowym panelem zawierającym wszystko potrzebne do używania urządzenia. Liczyło się dla mnie działanie (głównie zegar i szybki dostęp do wybranego radia internetowego), a nie wygląd. Zresztą tworząc projekt nie zakładałem, że będę go gdzieś publikował 😕.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...