Freitag, 14. Oktober 2022

iRadio-Weihnachtsuhr mit Lorenz C2 Simulation

 


Einleitung

trotz der aktuell schwierigen Situation bei der Beschaffung von Raspberry 3 Systemen möchte ich wieder ein iRadio vorstellen. Ich will auf alle erforderlichen Schritte eingehen, damit es wieder eine aktuelle und komplette Anleitung für Nachbauer gibt.

Es ist so, dass man notwendige Informationen, die man zum Nachbau benötigt, oft kreuz und quer im Forum zusammensuchen muss. Mit z.T. veralteten Anweisungen in manchmal ewig langen threads. "Ein minimales Internetradio für alte und neue Raspberrys" hat bis dato 190 postings, bei "FAQ zum iRadio" sind es gar 590 postings! Klar, die threads dokumentieren den kompletten Werdegang von iRadio, von der Pimoroni-Basis angefangen, über alle möglichen Arten von Display-Ausgaben, bis zu Erweiterungen wie z.B. Abstimmgeräuschgenerator, SDR, DAB, Mediaplayer, Sprachausgabe usw. Aber selbst die Anleitungen in meinem blog habe ich auf Archiv gelegt, weil ich einfach keine komplette Aktualität mehr gewährleisten kann. Wenigstens habe ich meinen iRadio-Projekten fast immer eine Kurzanweisung mitgegeben, so dass vor allem spezielle Problemlösungen beim Projekt dokumentiert sind. Dies will ich auch hier beibehalten.

die Hardware

als ich dieses leere Uhrengehäuse vom Flohmarkt anschleppte wusste ich noch nicht was ich daraus bauen würde.

Ein Internetradio, oder eine Jukebox? Ich hatte ja schon öfters Radios in Uhrengehäuse gebaut. Warum aber nicht mal eine Uhr in einem Uhrengehäuse? Die Voraussetzungen haben wir doch: iRadio mit LorenzC2_V2 Simulation!

zwei Uhren-Radios habe ich mit dieser Software bereits aufgebaut:

ITT Radiowecker CR220 mit iRadio und Lorenz C2 Simulation

vom eigentlichen Lorenz-Radio zeige ich hier die Gehäuseaufbereitung:

iRadio Lorenz C2 Gehäuse (Studie).

Die Technik dazu hatten wir in der "FAQ zum iRadio" ab ca. post#129 durchgesprochen.

Eine echte Bedienungsanleitung oder eine Zusammenfassung aller Funktionen sucht man vergeblich. Vielleicht gelingt es mir im weiteren Verlauf dieser Vorstellung die Lücken zu schliessen.

Gehäusebau

Am Anfang steht die Planung. Die Glasplatte wurde ausgebaut und ein Laustsprecher eingepasst. Er passt so haarscharf ins Gehäuse dass ich die rückwärtige Klemmleiste ausbauen musste weil mir die paar Milimeter in der Tiefe gefehlt hatten. Und 2 kleine Aussparungen musste ich in den Türrahmen anbringen damit die Türe sich schließen läßt.


 

Das Gehäuse wurde von jeglichem Lack befreit und mit einer klaren Lasur behandelt:

ein gebrauchtes 7 Zoll Display habe ich bei ebay eingekauft und ein schönes Ziffernblatt gesucht. Später tauschte ich das Ziffernblatt wegen der nahenden Feiertage wieder aus gegen ein Weihnachtsmotiv. Deshalb der Titel "Weihnachtsuhr".

die restliche Elektronik besteht aus einem Tastenfeld mit Verteilung, dem Raspberry 3B+ mit USB-Soundkarte, einem Class-D Monoverstärker, der bei 24V 35W Ausgangsleistung liefert (wird hier aber nur mit 12V betrieben), einem Relais für standby-Betrieb (es nimmt dem Verstärker die Betriebsspannung), und 3 Netzteilen. Einmal 5V/2A für den Raspberry, nochmal 5V/2A für das Display und 12V/1A für den NF-Verstärker. Das Relais schalte ich über eine Transistorstufe.

der Platz wurde eng. Die rote Box beinhaltet alle 3 Netzteile und fügt sich elegant in den schmalen Platz hinter dem Tastenfeld ein.

Die Optik war noch nicht sehr ansprechend.

mit etwas Dekorfolie erreichte ich wenigstens Akzeptanz in der Familie. Wer noch Ideen bezügl. des Designs hat darf mich gerne anschreiben 

zur Bedienung:

die rote Taste schaltet vom Standby in den Radiobetrieb. Dazu ist zu sagen dass im Standby nur die Uhrzeit angezeigt wird und im Radiobetrieb das Ziffernblatt als Skala fungiert. Über das Relais schaltet sich dann der NF-Verstärker dazu, und der Sendername wird eingeblendet. Die schwarze Taste rechts oben schaltet wieder zurück ins Standby.

die grüne und gelbe Taste in der mittleren Reihe schalten den Sender vor bzw. zurück.

Die beiden unteren schwarzen Tasten sind für Lautstärke plus und minus.

Die Farben ergaben sich weil ich einen bunten Satz Arcade-Tasten eingekauft hatte.

Prinzipiell kann die Software auch die Betriebsart Bluetooth und einen Weckerbetrieb. Beide Funktionen habe ich (noch) nicht eingebaut.

Das wäre genug zur Hardware. Im nächsten Teil kommen wir zur Konfiguration der Software. 

Die LorenzC2_V2 Simulation ist die aufwändigste aller Skalensimulationen. Sie entstand aus dem unerschöpflichen Ideenpool von Uli und seiner Leidenschaft für das Lorenz C2. Und Bernhard wollte ihm zeigen was alles davon umsetzbar ist. Ich war dann derjenige der parallel zur Entwicklung alles in der Praxis getestet hat. Soweit muss aber niemand folgen. Ich zeige jetzt erst mal dass die grundsätzliche Installation von iRadio eine Minutensache ist und schnell und einfach erledigt ist. Eine Beschreibung wie man ein Raspbian oder ein Raspberry Pi OS auf eine SD-Karte bekommt erspare ich mir. Ich setze ein funktionierendes Betriebssystem voraus mit einem Benutzer pi, welches in die Eingabeaufforderung bootet (Console Autologin), eine Internetverbindung hat, eine SSH-Verbindung und eine funktionierende Tonausgabe egal welcher Art. Wie man sich danach sein iRadio individuell ausbaut ist jedem selbst überlassen. Ideen und Anleitungen finden sich in diesem Forum genügend. Ganz ohne Sucherei wird es also nicht unbedingt gehen.


Grundsätzliche Installation von iRadio

wenn obige Voraussetzungen auf Betriebsystemebene erfüllt sind besteht die grundsätzliche Installation wirklich nur aus 2 Befehlen:

git clone https://github.com/BM45/iRadio.git

und Ausführen der build im Ordner iRadio:

sudo ./build.sh

nach dem Neustart hört man einen Radiosender aus der Demo-Senderliste und hat ein funktionierendes webinterface (http://IP_oder_Hostname:8080). Einloggdaten: Benutzername leer lassen und Kennwort raspberry. Jetzt kann man nachlesen wie man sich seine eigene playlist erstellt, kann sich Gedanken machen wie man das Radio steuern will, und ob und wie man die Ausgabe baut.


Installation der Skalensimulation LorenzC2_V2

jetzt geht es ans Eingemachte!

was bei x11 Simulationen immer zu tun ist:

sudo apt-get install libsdl2-*

und eine eigene playlist muss einmal das System durchlaufen. Testweise hatte ich in der playlist.m3u nur einen Eintrag. Das genügt nicht! Es müssen mindestens 2 sein, sonst startet der x11-Grafikdaemon nicht.

was auch immer zu tun ist sind die absoluten Pfade zu den Grafiken in der sdlscale.cxx. Bernhard hielt es nie für notwendig die Pfade direkt im repository zu berücksichtigen. Das geschieht in der Datei sdlscale.cxx im Ordner /home/pi/iRadio/display/x11/LorenzC2_V2 an 5 Stellen:


    textur_skale = IMG_LoadTexture(renderer, "/home/pi/iRadio/display/x11/LorenzC2_V2/skale.png");
    textur_zeiger = IMG_LoadTexture(renderer, "/home/pi/iRadio/display/x11/LorenzC2_V2/zeiger.png");
    textur_zeiger_stunde = IMG_LoadTexture(renderer, "/home/pi/iRadio/display/x11/LorenzC2_V2/zeiger_stunde.png");
    textur_zeiger_minute = IMG_LoadTexture(renderer, "/home/pi/iRadio/display/x11/LorenzC2_V2/zeiger_minute.png");
   
    textur_zeiger_wecker = IMG_LoadTexture(renderer, "/home/pi/iRadio/display/x11/LorenzC2_V2/zeiger_wecker.png");


jetzt kann die build.sh im LorenzC2_V2 Ordner ausgeführt werden.

sudo ./build.sh

in der rc.local wird der Start der Simulation eingetragen:

startx /home/pi/iRadio/display/x11/LorenzC2_V2/sdlskale &

ebenso der Dienst weckerd, nachdem er nach /usr/bin kopiert wurde. Sofern man denn einen Wecker mit einbauen will.

/usr/bin/weckerd &

Dann widmen wir uns dem Bildschirm. Da die Simulation für 800x480 px Auflösung gebaut ist wird diese Auflösung auch in der /boot/config.txt definiert:

max_usb_current=1
hdmi_group=2
hdmi_mode=87
hdmi_cvt=800 480 60 6 0 0 0


die skale.png habe ich gegen ein eigenes Bild ausgetauscht:

welches später wieder durch ein Weihnachtsmotiv ersetzt wurde (muss ich wegen der Größe zippen):


.zip   skale_santa.zip (Größe: 509,96 KB / Downloads: 2)

die Zeiger färbte ich schwarz ein und ersetzte sie ebenfalls:


.zip   zeiger.zip (Größe: 59,26 KB / Downloads: 1)

In der sdlskale.cxx musste der Zeigermittelpunkt korrigiert werden:

  // Position und Dimension des Skalenzeigers
  SDL_Rect ZeigerRect;
  ZeigerRect.x = 240; ZeigerRect.y = 85;
  ZeigerRect.w = 320;  ZeigerRect.h = 320;




Bau des gpiod

in der README.txt ist zu lesen:

Zitat:stby_gpiod als gpiod nach /usr/bin kopieren, oder
Drehencoderdaemon stby_rotary_gpiod als gpiod nach /usr/bin kopieren

Es gibt also die Wahl zwischen einer Tastensteuerung und einer Encoder-Steuerung. Bis jetzt hatten wir bei der Lorenz C2 Simulation nur die Encoder-Version. Ich wollte aber eine Tastensteuerung mit dicken Arcade-Tasten. Dazu waren im Quellcode noch ein paar Änderungen notwendig. Auch benannte ich den Daemon nicht entsprechend der README um, sondern behielt den Namen des Quellcodes bei. So hielt ich mir die Möglichkeit offen beide Steuerungen parallel zu betreiben, falls ich mal für die Weckereinstellung noch einen Drehencoder dazusetzen möchte. Aus dem Grund musste ich auch gpios umlegen.

Vorgesehen für die Encoder-Steurerung habe ich:

Zitat:#define RoAPin 23 // GPIO-Pin , Pinnummer 33
#define RoBPin 24 // GPIO-Pin, Pinnummer 35
#define RoSWPin 25 // Pinnummer 37

#define PowerPin 26 // GPIO-Pin 12, Pinnummer 32

Für Tastensteuerung habe ich also jetzt einen Daemon mit dem Namen stby_gpiod und ein evtl. Encoder-Daemon bekommt den Namen stby_rotary_gpiod.

es ergibt sich für die /etc/rc.local:

Zitat:/usr/bin/vlcd
#/usr/bin/displayd &
#/usr/bin/stby_rotary_gpiod &
/usr/bin/stby_gpiod &
/usr/bin/gpiod_volume &
#/usr/bin/weckerd &
#startx /home/pi/iRadio/display/x11/skale1/sdlskale &
sleep 10
echo "play" | nc 127.0.0.1 9294 -N
echo "goto 0" | nc 127.0.0.1 9294 -N
#/usr/bin/gestured & # Gestenerkennung starten

startx /home/pi/iRadio/display/x11/LorenzC2_V2/sdlskale


ja, hier ist noch ein weiterer gpiod dazugekommen, nämlich für die Lautstärkeeinstellung.

Schauen wir uns mal die Steuerungsbefehle an:

stby    - Der Displaydaemon wird in den Standbybetrieb geschickt.
netr    - Displaydaemon geht in den Internetradiomodus
blth    - Displaydaemon schaltet in den Bluetoothmodus.
weck    - Es wurde eine neue Weckzeit eingestellt

Konsolenbeispiel:

echo "stby" | nc -u 127.0.0.1 6030 -w 0
echo "netr" | nc -u 127.0.0.1 6030 -w 0
echo "blth" | nc -u 127.0.0.1 6030 -w 0
echo "weck" | nc -u 127.0.0.1 6030 -w 0

Bluetooth und Weckzeit benötige ich bei diesem Projekt (zumindest zur Zeit) nicht.

was wir für die Verdrahtung und den Bau des stby_rotary_gpiod auch noch benötigen ist eine solche Tabelle:

der PowerPin ist ja bereits festgelegt:

#define PowerPin 26 // GPIO-Pin 12, Pinnummer 32

der gpio ist mit Bedacht gewählt. Er sollte beim booten des Raspberry ausgeschaltet sein. Er wird in der weckerd.cxx eingetragen sowie in der connect für den optionalen Bluetoothbetrieb.


stby_gpiod

anders sieht es bei der stby_gpiod aus. Hier hat Bernhard die BCM2835-library eingesetzt bei der die gpio's anders angesprochen werden:

Install BCM2835 Library in Raspberry Pi

hier die neue stby_gpiod.c:

Code:
// gpiod.c
//
// Beispielprogramm fuer bcm2835 lib
// Schaltet per GPIO-Taster nach Masse einen laufenden VLC-Prozess (next, prev, ...)
//
// After installing bcm2835, you can build this
// with something like:
// gcc  gpiod.c -o gpiod -lbcm2835
// sudo ./gpiod
//
// Author: Bernhard45 (mbernhard1945@gmail.com)

#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

//#define DEBUG

// Tasteranschluesse
#define PIN_PRG_HOCH RPI_GPIO_P1_11
#define PIN_PRG_RUNTER RPI_GPIO_P1_12
#define PIN_PRG_AUS RPI_GPIO_P1_08
#define PIN_PRG_AN RPI_GPIO_P1_10

#define POWERPIN RPI_V2_GPIO_P1_32  // GPIO-Pin 12, Pinnummer 32


int main(int argc, char **argv)
{
  int bRadioAn = 1;   // 0 - Radio aus ; 1 - Radio an

    if (!bcm2835_init())
        return 1;

    // Pin als Eingang setzen , mit Pull-Up
    bcm2835_gpio_fsel(PIN_PRG_HOCH, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(PIN_PRG_HOCH,BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel(PIN_PRG_RUNTER, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(PIN_PRG_RUNTER,BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel(PIN_PRG_AUS, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(PIN_PRG_AUS,BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel(PIN_PRG_AN, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(PIN_PRG_AN,BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel(POWERPIN,BCM2835_GPIO_FSEL_OUTP);

    // Endlosschleife, da Daemonbetrieb
    while (1)
    {
        // Zustand am Pin einlesen
        uint8_t val_prg_hoch   = bcm2835_gpio_lev(PIN_PRG_HOCH);
        uint8_t val_prg_runter = bcm2835_gpio_lev(PIN_PRG_RUNTER);
    uint8_t val_prg_aus    = bcm2835_gpio_lev(PIN_PRG_AUS);
    uint8_t val_prg_an     = bcm2835_gpio_lev(PIN_PRG_AN);

        #ifdef DEBUG
                printf("Tastenwert PIN_HOCH: %d\n", val_prg_hoch);
                printf("Tastenwert PIN_RUNTER: %d\n", val_prg_runter);
                printf("Tastenwert PIN_AUS: %d\n", val_prg_aus);
                printf("Tastenwert PIN_AN: %d\n", val_prg_an);
        #endif

        if (val_prg_hoch == 0) {
        if (bRadioAn)
                        system("echo \"next\" | nc 127.0.0.1 9294 -w 0");
        }

    if (val_prg_runter == 0) {
                if (bRadioAn)
                system("echo \"prev\" | nc 127.0.0.1 9294 -w 0");
        }

    if (val_prg_aus == 0) {
                bRadioAn = 0;
        system("echo \"stop\" | nc 127.0.0.1 9294 -w 0");
                system("echo \"stby\" | nc -u 127.0.0.1 6030 -w 0");
                bcm2835_gpio_write(POWERPIN,LOW);
        }

    if (val_prg_an == 0) {
                bRadioAn = 1;

    uint8_t val_prg_an     = bcm2835_gpio_lev(PIN_PRG_AN);

        #ifdef DEBUG
                printf("Tastenwert PIN_HOCH: %d\n", val_prg_hoch);
                printf("Tastenwert PIN_RUNTER: %d\n", val_prg_runter);
                printf("Tastenwert PIN_AUS: %d\n", val_prg_aus);
                printf("Tastenwert PIN_AN: %d\n", val_prg_an);
        #endif

        if (val_prg_hoch == 0) {
        if (bRadioAn)
                        system("echo \"next\" | nc 127.0.0.1 9294 -w 0");
        }

    if (val_prg_runter == 0) {
                if (bRadioAn)
                system("echo \"prev\" | nc 127.0.0.1 9294 -w 0");
        }

    if (val_prg_aus == 0) {
                bRadioAn = 0;
        system("echo \"stop\" | nc 127.0.0.1 9294 -w 0");
                system("echo \"stby\" | nc -u 127.0.0.1 6030 -w 0");
                bcm2835_gpio_write(POWERPIN,LOW);
        }

    if (val_prg_an == 0) {
                bRadioAn = 1;
        system("echo \"play\" | nc 127.0.0.1 9294 -N");
                system("echo \"netr\" | nc -u 127.0.0.1 6030 -w 0");
                bcm2835_gpio_write(POWERPIN,HIGH);

        }

    // for Bluetoothmode send system("echo \"blth\" | nc -u 127.0.0.1 6030 -w 0");

        delay(500);
    }

    return 0;
}

 

gpiod_volume

die Lautstärkeeinstellung bauen wir im Ordner ~/iRadio.

es werden diese Kopieraktionen ausgeführt:

sudo cp gpiod.c gpiod_volume.c
sudo cp install_Tastensteuerung.sh install_Tastensteuerung_volume.sh


in der gpiod_volume.c werden die gpio für Hoch/Runter geändert und die für Halt/Weiter auskommentiert. Wir brauchen hier ja nur die 2 Taster für Lautstärke plus und minus. Die dafür nötigen Kommandos werden den Hoch/Runter-Funktionen zugewiesen:

 

Code:
// gpiod.c
//
// Beispielprogramm fuer bcm2835 lib
// Schaltet per GPIO-Taster nach Masse einen laufenden VLC-Prozess (next, prev, ...)
//
// After installing bcm2835, you can build this
// with something like:
// gcc  gpiod.c -o gpiod -lbcm2835
// sudo ./gpiod
//
// Author: Bernhard45 (mbernhard1945@gmail.com)

#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

//#define DEBUG

// Tasteranschluesse
#define PIN_PRG_HOCH RPI_V2_GPIO_P1_38
#define PIN_PRG_RUNTER RPI_V2_GPIO_P1_40
//#define PIN_PRG_HALT RPI_GPIO_P1_08
//#define PIN_PRG_WEITER RPI_GPIO_P1_10

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    // Pin als Eingang setzen , mit Pull-Up
    bcm2835_gpio_fsel(PIN_PRG_HOCH, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(PIN_PRG_HOCH,BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel(PIN_PRG_RUNTER, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(PIN_PRG_RUNTER,BCM2835_GPIO_PUD_UP);

//    bcm2835_gpio_fsel(PIN_PRG_HALT, BCM2835_GPIO_FSEL_INPT);
//    bcm2835_gpio_set_pud(PIN_PRG_HALT,BCM2835_GPIO_PUD_UP);

//    bcm2835_gpio_fsel(PIN_PRG_WEITER, BCM2835_GPIO_FSEL_INPT);
//    bcm2835_gpio_set_pud(PIN_PRG_WEITER,BCM2835_GPIO_PUD_UP);

    // Endlosschleife, da Daemonbetrieb
    while (1)
    {
        // Zustand am Pin einlesen
        uint8_t val_prg_hoch   = bcm2835_gpio_lev(PIN_PRG_HOCH);
        uint8_t val_prg_runter = bcm2835_gpio_lev(PIN_PRG_RUNTER);
//      uint8_t val_prg_halt   = bcm2835_gpio_lev(PIN_PRG_HALT);
//      uint8_t val_prg_weiter = bcm2835_gpio_lev(PIN_PRG_WEITER);

        #ifdef DEBUG
                printf("Tastenwert PIN_HOCH: %d\n", val_prg_hoch);
                printf("Tastenwert PIN_RUNTER: %d\n", val_prg_runter);
//              printf("Tastenwert PIN_HALT: %d\n", val_prg_halt);
//              printf("Tastenwert PIN_WEITER: %d\n", val_prg_weiter);
        #endif

        if (val_prg_hoch == 0)
                system("echo \"volup 2\" | nc 127.0.0.1 9294 -N");

        if (val_prg_runter == 0)
                system("echo \"voldown 2\" | nc 127.0.0.1 9294 -N");

//        if (val_prg_halt == 0)
//                system("echo \"stop\" | nc 127.0.0.1 9294 -N");

//        if (val_prg_weiter == 0)
//                system("echo \"play\" | nc 127.0.0.1 9294 -N");

        delay(500);
    }

    return 0;
}

 


in der install_Tastensteuerung_volume.sh gibt es ein paar Umbenennungen:

 

Code:
#!/usr/bin/env bash

# ueberpruefe auf sudo-Rechte
if [ "$(id -u)" != 0 ]; then
  echo "Zur Ausfuehrung dieses Scripts sind Administratorrechte noetig"
  exit 1
fi

gcc /home/pi/iRadio/gpiod_volume.c -o /home/pi/iRadio/gpiod_volume -lbcm2835

killall gpiod_volume
sleep 10

echo "Kopiere neuen Daemonen..."

cp /home/pi/iRadio/gpiod_volume /usr/bin/

echo "Aenderungen sind nach dem Neustart aktiv!"

 

das Script kann nun ausgeführt werden:

sudo ./install_Tastensteuerung_volume.sh

und der gpiod_volume in der rc.local hinterlegt werden:

/usr/bin/gpiod_volume &


ergänzend:

zum Schluss noch ein paar Hinweise:

Der switch des Encoders (falls verwendet) ist zeitsensitiv. Die Funktionen ersehen wir dem Quellcode:

Zitat:// zwischen 500 und 1200 ms, an/aus

// laenger als 2500 ms, Wecker an/aus


Die Weckzeit wird im Stby-Modus eingestellt. Und zwar mit dem Rotaryencoder in Fünfminutenschritten.

Eine Änderung des PowerPin muss auch im connect-Skript übernommen werden und das Skript dann wieder nach /etc/bt_speaker/hooks/ kopiert werden. 

 

 

  
 


 







 



 




 


 




 


Keine Kommentare:

Kommentar veröffentlichen