Po godzinach, czyli … projekt radia internetowego w obudowie od starej Diory Menuet – Raspberry PI.

Podstawa, czyli nasza obudowa

Całkiem przypadkowo odwiedzając pewną piwnicę zauważyłem kurzącą się piękną Diore. Pytając właścicielkę o radio, czy działa, jakie są pomysły na jego wykorzystanie, otrzymałem propozycję ze mogę zostać jego nowym właścicielem. Bez wahania przyjąłem prezent. Do domu wróciłem bogatszy o piękne drewniane pudło.

Niestety radio oprócz obudowy było w kiepskim stanie, jako że ze starą elektroniką nie jestem za pan brat trzeba było szukać innych inspiracji i pomysłów. Całkiem przypadkowo na horyzoncie pojawiła się Raspberry Pi tzw. „malinka” i pomysł wyklarował się sam.

Założenia

  • radio automatycznie łączy się z WIFI i pobiera wcześniej zdefiniowane stacje radiowe, każde w osobnym pliku .pls, w każdym momencie można stacje dodawać, usuwać,
  • wykorzystanie do nawigacji oryginalnych przycisków 1-5 które wczytują ulubione stacje,
  • wykorzystanie pokręteł, lewe do głośności, prawe do zmiany stacji -/+ stacja, w kolejności według jakiej zostały pobrane,
  • sterowanie pilotem, głośność, do przodu i do tyłu, przyciski 1-4 dla ulubionych stacji, zmiana trybu Głośnik-Radio, wyciszanie, wyłączanie
  • głośnik bluetooth dla wcześniej sparowanych z radiem urządzeń,
  • podświetlanie skali diodami led,
  • sygnalizowanie diodą akcji z pilota i przycisków,
  • wykorzystanie mikrokomputera Raspberry PI,
  • głośniki 2+1.

Zdaję sobie sprawę, że wiele rzeczy można było zrobić lepiej. Był to mój pierwszy tego typu projekt i miałem pewne ograniczenia czasowe więc proszę o wyrozumiałość 🙂

Najważniejsze dla mnie radio działa już rok, a jego słuchanie sprawia olbrzymią frajdę nie tylko mi 🙂

 

STAN ZEROWY

 

DIORA POLIFTINGOWA

 

Wykorzystane materiały, czyli czego potrzebujemy.

Maskownica – tkaninę na maskownicę udało znaleźć się na allegro. Oryginał to nie jest, ale wizualnie w komplecie prezentuje się satysfakcjonująco.
Koszt 30zł.

Stare głośniki niestety były w fatalnym stanie, membrany zniszczone. Jako że w radiu chciałem miękki przyjemny bass padł pomysł, żeby wykorzystać głośniki 2+1 ze średniej półki, z subwooferem który zmieści się w obudowie. Z pomocą przyszedł tym razem olx. Udało się kupić Logitech X-230 z popękanymi obudowami satelitek, ale obudowa w tym przypadku była zbędna.
Koszt 50zł

Farby. Tu wykorzystałem pigmenty do farb znalezionych w garażu. Dwa kolory czarny do podstawy i kolor jasny brąz, dokładnie jak w oryginale do ramek wokół maskownicy i przycisków.
Koszt 0zł

Wosk. Jako że nie jestem fanem szlifowania, a i obudowa była w dobrym stanie postanowiłem, że 2 warstwy wosku wystarczą żeby nasza skrzynka lśniła jak trzeba. Z efektu jestem zadowolony.
Koszt 30zł

Elementy miedziane. Były mocno zaśniedziałe do czyszczenia użyłem jakiegoś magicznego ekstraktu, który znalazł się w kuchni.
Koszt 0zł

 

Elektronika pod obudową.

Raspberry Pi 3 model B - 189zł
Zasilacz microUSB 5,1V 2,5A - 45zł
Karta pamięci micro SD / SDHC - 35zł
Odbiornik podczerwieni 38kHz TSOP4838 2,5zł
Dioda LED 5mm czerwona 80st. - 0,25zł
Dioda LED 5mm biała 60st. - 5 szt. - 3,60zł
Wyłącznik krańcowy - WK817 - 5 szt. - 10zł
Enkoder mechaniczny 24 imp/obr 20mm stojący- 6zł
Zestaw rurek termokurczliwych 27 szt. - 3zł
Zestaw rezystorów 1/4W E3 160szt. - 3,90zł
MODUŁ BLUETOOTH V4.0 USB GEMBIRD - 27zł
Pilot od zewnętrznej karty graficznej Creative znaleziony w szufladzie - 0zł

Razem cała elektronika: 325zł

Czyli sumarycznie koszt całego radia to 435zł, udało się nie przekroczyć założonego budżetu 500zł.

 

Montowanie całości

Prace rozpoczęte były od demontażu wszystkiego co się nie przyda i zabiera miejsce w obudowie. Trochę, żal było lamp, ale czekają w garażu na swój dzień, kiedyś zapewne uda się je do czegoś ciekawego wykorzystać. Kolejny etap to prace przy obudowie, kolejno czyszczenie obudowy, czyszczenie elementów miedzianych, woskowanie skrzynki radia, malowanie detali (ramka i podstawa). Na koniec montaż nowej maskownicy radia i w końcu obudowa wygląda jak najpiękniejszych snach 🙂

Mając odnowioną obudowę można było rozpocząć prace przy montażu poszczególnych elementów

 

Mechanizm mocowanie przycisków i pokręteł w obudowie. Stary mechanizm działał dość topornie i zajmował zbyt dużo miejsca. W żaden sposób subwoofer nie mieścił się w obudowie. Jako ze był on dla mnie niezbędny kolejne dni upłynęły na myślach jak to wszystko zmontować żeby przetrwało próbę czasu i do tego nie zostało córeczce w ręku. Niestety brak drukarki 3d wymógł powrót do profesji stolarza. Rzeźbienie brzeszczotem to mój drugi fach. Do tego doszło pare podkładek działających jako dystanse między kolejnymi przyciskami. Wygląda to dziwnie, ale najważniejsze działa całkiem dobrze.

Montaż pokręteł wykonałem na drewnianych stelażach enkodery zamocowane zostały w wywierconych odpowiednio dziurach, a z frontu na zakończenia nałożone oryginalne pokrętła. Połączenia wszystkiego wykonane zostały za pomocą kabli zakończonych konektorami lub pinami żeńskimi. Dodatkowo, żeby kable się nie plątały z pomocą przyszedł magiczny klej na gorąco. Odbiornik podczerwieni i dioda sygnalizująca działanie pilota lub przycisków zmontowana również na klej na gorąco.

Oryginalną skalę od środka zasłoniłem półprzezroczystą pleksi, aby białe światło z 2 żarówek LED nie było punktowe, ale rozpraszało się na folii. Spodziewałem się lepszego efektu, ale nie było już czasu na kolejne nowe koncepcje. Skala jest podświetlana jednak nie ma na niej suwaka.

Głośniki zamocowane od środka kołkami bezpośrednio do obudowy. Subwoofer montowany na metalowe płaskowniki, aby sztywno siedział w obudowie. Na bocznej ściance obudowy wewnątrz zostawiłem sterowanie bassem od głośników, aby prosto można było zmieniać to ustawienie. Malinka i głośnik mają oddzielne zasilanie więc w środku upchnąłem kompaktowy przedłużacz aby radio miało tylko jeden kabel wyjściowy z obudowy.

Na koniec zostawiłem montaż mózgu radia. Malinka przymocowana do podłogi radia na dystansach, żeby było jej odpowiednio chłodno i nie za gorąco. Tu też pomocny był klej na gorąco. Oczywiście jest na tyle dużo miejsca aby dało radę w przyszłości podłączyć monitor czy klawiaturę bez potrzeby demontażu.

 

I staje się głośno…

Równolegle z pracami przy obudowie postępowały prace programistyczne i składanie wszystkich elementów na płytce prototypowej Raspberry PI. Kolejno opisze ważniejsze zagadnienia.

Całość pisana w Pythonie. Program wykonuje się w pętli While, sprawdzamy stany na wybranych pinach GPIO Raspberry PI lub kody przechwycone z pilota i odpowiednio reagujemy.

 

Inicjalizacja radia, czyli

# -*- coding: utf-8 -*-
 import time
 import pylirc
 import moc
 import os
 from subprocess import call
 import RPi.GPIO as GPIO

 GPIO.setmode(GPIO.BCM)
 GPIO.setwarnings(False)

#Dioda LED sygnalizująca akcje, Pin numer 12
 GPIO.setup(12, GPIO.OUT)

#Piny wykorzystane do przycisków 1-5
 GPIO.setup(5, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)
 GPIO.setup(6, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)
 GPIO.setup(13, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)
 GPIO.setup(19, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)
 GPIO.setup(26, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)

#Piny wykorzystane do Enkoderów
 GPIO.setup(16, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)
 GPIO.setup(20, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)
 GPIO.setup(23, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)
 GPIO.setup(24, GPIO.IN,  pull_up_down=GPIO.PUD_DOWN)

#parametry startowe
 playlists= []
 radio_now=1
 path="/home/pi/Music/"
 volume=75
 mode=1

#Inicjalizacja pilota
 pylirc.init("irexec", "/home/pi/.lircrc", 0)

#LED sygnalizuje włączenie, zapalona do załadowania stacji
 GPIO.output(12,GPIO.HIGH)

#Szukanie playlist
 for file in os.listdir(path):
 if file.endswith(".pls"):
     playlists.append(file)
 playlists.sort()

#Enkoder lewy - zmiana głośności
 error = 0
 counts = 0
 Encoder_A,Encoder_B = GPIO.input(20),GPIO.input(16)
 Encoder_A_old = GPIO.input(20)
 Encoder_B_old = GPIO.input(16)

#Enkoder prawy - zmiana stacji
 s_error = 0
 s_counts = 0
 s_Encoder_A,s_Encoder_B = GPIO.input(24),GPIO.input(23)
 s_Encoder_A_old = GPIO.input(24)
 s_Encoder_B_old = GPIO.input(23)

#Głośność startowa
 vol = "amixer sset PCM " + str(volume) + "%"
 call(vol, shell=True)

#START
 call('sudo service gmediarenderer stop', shell=True)
 print("Radio zostało włączone")
 print("Ładowanie pierwszej stacji radiowej")
 radio_station_load(1)

Obsługa pilota

Wykorzystana biblioteka: pyLIRC.
Najpierw wymagane było zczytanie kodów z przycisków pilota i odpowiednie ich zmapowanie do konkretnych komend. Niestety szczegółowa obsługa przycisków pilota to temat na oddzielny wpis. Poniżej przykładowa akcja, czyli przycisk w prawo tj. „Następna stacja”.

#obsługa pilota
 button = pylirc.nextcode(1)
 if button:
   print("Akcja z pilota")
   for code in button:
     …
     if code["config"] == 'KEY_NEXT':
       radio_now = radio_station_load_next(radio_now)
     …
 button = []

Obsługa przycisków radia

Wykorzystane zostały wyłączniki krańcowe oraz piny GPIO. Sprawdzamy stan pinu, wczytujemy stream z wybranym radiem przypisanym do pozycji przycisku.

#Przycisk 1
 if GPIO.input(5):
   radio_station_load(1)

 

Obsługa pokręteł, dwa enkodery.

Przy enkoderach, aby sprawdzać w którą stronę kręcimy trzeba sprawdzać stan obecny jak i stan poprzedni na pinach. Każdy enkoder podpięty pod dwa piny GPIO. Razem mamy 4 wartości i w zależności od ich wartości ustalamy jaka akcja ma być wykonana. Poniżej kod enkodera prawego (do przełączania stacji).

 s_Encoder_A = GPIO.input(24)
 s_Encoder_B = GPIO.input(23)
 if ((s_Encoder_A,s_Encoder_B,s_Encoder_A_old,s_Encoder_B_old) == (1,1,1,0)) or ((s_Encoder_A,s_Encoder_B,s_Encoder_A_old,s_Encoder_B_old) == (0,1,1,1)) or ((s_Encoder_A,s_Encoder_B,s_Encoder_A_old,s_Encoder_B_old) == (0,0,0,1)) or ((s_Encoder_A,s_Encoder_B,s_Encoder_A_old,s_Encoder_B_old) == (1,0,0,0)):
   print "next station"
   radio_now = radio_station_load_next(radio_now)
 elif ((s_Encoder_A,s_Encoder_B,s_Encoder_A_old,s_Encoder_B_old) == (1,0,1,1)) or ((s_Encoder_A,s_Encoder_B,s_Encoder_A_old,s_Encoder_B_old) == (0,0,1,0)) or ((s_Encoder_A,s_Encoder_B,s_Encoder_A_old,s_Encoder_B_old) == (1,1,0,1)):
   print "prev station"
   radio_now = radio_station_load_prev(radio_now)
 s_Encoder_B_old = s_Encoder_B
 s_Encoder_A_old = s_Encoder_A

Przechowywanie stacji radiowych.

Pliki .PLS do odpowiednich stacji radiowych znajdują się w tym samym folderze co skrypt. Dorzucenie kolejnego pliku w to miejsce spowoduje wczytanie go do tablicy z adresami playlist, sprawdzane i budowane jest to za każdym razem po włączeniu radia.

#Szukanie playlist
 for file in os.listdir(path):
  if file.endswith(".pls"):
     playlists.append(file)
 playlists.sort()

 

Odtwarzanie stacji radiowych w Raspberry PI

Używam biblioteki MOC. Poniżej przykładowe skrypty, ładowanie konkretnej stacji, jako parametr podajemy jej numer porządkowy oraz ładowanie następnej (poprzedniej) stacji po akcji z pilota ‚KEY_NEXT’ lub z prawego pokrętła (przełączanie stacji jest zapętlone, po ostatniej stacji wczytuje się pierwsza itd.)

#Ładowanie konkretnej stacji
 def radio_station_load(number=1):
   GPIO.output(12,GPIO.HIGH)
   global radio_now
   if number > 0 and number <= radio_count:
     radio_now = number
   else:
     radio_now = 1
   print("Ładowanie stacji nr  " + str(radio_now))
   playlist = path + playlists[radio_now-1]
   moc.playlist_play(playlist)
   GPIO.output(12,GPIO.LOW)

#Ładowanie następnej
 def radio_station_load_next(radio_now2):
   GPIO.output(12,GPIO.HIGH)
   if radio_now2 < 1:         
     radio_now2 = radio_count     
   elif radio_now2 >= radio_count:
     radio_now2 = 1
   else:
     radio_now2 +=  1

   print("Ładowanie stacji nr  " + str(radio_now2))
   playlist = path + playlists[radio_now2-1]
   moc.playlist_play(playlist)
   GPIO.output(12,GPIO.LOW)
 return radio_now2

 

Bluetooth

Przycisk MODE na pilocie zmienia nam tryb Głośnik-Radio. W przypadku Głośnika do obsługi dźwięku korzystam z biblioteki Pulseaudio, biblioteka Moc jest stopowana. Odwrotnie w trybie Radio.

if code["config"] == 'KEY_MODE':
   GPIO.output(12,GPIO.HIGH)
   if mode==1:
       mode=2
       print "Zmiana trybu - glosnik"
       moc.playlist_stop()
       call('pulseaudio -D', shell=True)
       call('nohup bluetoothct >/dev/null 2>&1', shell=True)
   else:
       mode=1
       print "Zmiana trybu - radio"
       call('pulseaudio -k', shell=True)
       call(vol, shell=True)
       radio_station_load(radio_now)
   GPIO.output(12,GPIO.LOW)

 

 

Pomysły na rozwinięcie projektu.

  1. Przycisk standby. Niestety Raspberry PI nie posiada w standardzie. Taka funkcja byłaby niesamowicie przydatna. Aktualnie funkcje tą pełni przycisk na listwie przedłużacza. Oczywiście to słaby zamiennik ale troszkę pomaga w użytkowaniu.
  2. Odtwarzacz na winyle w górnej części podłączony do Raspberry PI. Z braku czasu i pomysłów od czego zacząć na razie czeka na lepsze czasy. Myśle ze na emeryturze wrócimy do tematu.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *