- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 10 von 46

Thema: Internetradio

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Experte Avatar von ePyx
    Registriert seit
    14.05.2008
    Ort
    Falkensee
    Beiträge
    700
    Kannst du mal bitte den Quellcode für die Parametrisierung des tty-Devices und für das Empfangen posten?

    Mich interessiert dabei eigentlich mehr wie du den filedescriptor erstellst und wie du die Daten einliest. Ob du SIGIO etc benutzt oder ob du nur pollst etc.
    Grüße,
    Daniel

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    44
    Beiträge
    61
    Hab im Moment eigentlich noch einen fast unverändertes empfangen.c. Habe nur ein paar Änderungen an der Konfiguration der UART Schnittstelle gemacht. Und das beste ist, ich weiß nicht mal ob ich polle, da ich die Config des UART noch nicht gerafft hab und leider auch kein super C-Programmierer bin. Also verzeiht bitte meine Unwissenheit.

    Den Rest des Codes und den Aufbau von peterfido habe ich mittlerweile verstanden. Von Zeile 45 bis 210 passiert erstmal nichts für mich interessantes, da dort ja nur die empfangenen Zeichen vom Atmel interpretiert werden. Das muss ich sowieso komplett umschreiben, da ich andere Codes verwende.

    Ich hab folgendes geändert:
    Die UART configuration also 9600,8e,1 und ein paar Dinge damit ich was auf dem Bildschirm zu sehen bekomme. Derzeit wird immer nur ein Zeichen abgeholt, was auf jeden fall noch geändert werden muss.

    Wenn ich den Code richtig interpretiere lässt das Ding den UART komplett offen, da er in der while Schleife bleibt und der fd(close) danach kommt. Mhm...

    Ziel ist wie im vorigen Beitrag beschrieben irgendwie hinzubekommen, dass die Blöcke erkannt werden und das in einem Puffer (255 Zeichen) abgeholt werden können. Den String für den Puffer könnte ich ja dann in der receive Funktion mittels schleife zusammenbauen und zurückgeben oder in eine globale Variable schreiben.

    Nur leider stehe ich da im Moment einfach etwas auf dem Schlauch, weil ich nicht ganz verstehe was in der int init() Funktion passiert.

    Code:
     GCC -o empfangen_gpio_wiring -l rt empfangen_gpio_wiring.c -lwiringPi
    
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <time.h>
    
    
    //WiringPi include für SEN/STA Erkennung
    #include <wiringPi.h>
    
    
    #include <stdio.h>
    //Konfig RASPI USART
    #define BAUDRATE B9600  // 9600 Baud definieren für 8E1 I-Bus
    char MODEMDEVICE[]= "/dev/ttyAMA0";    // Schnittstelle
    int getit; //Nachrichtenblock angekommen
    /*
    Sx          x=0 aktuellen Sender neu abspielen Nach Stop oder zum neu puffern, x>49 Sender x-48 abspielen
    Bx          x=0 abspielen stoppen, x=1 mpd neu starten
    Px            x=0 einen Senderplatz zurück x=1 einen Senderplatz hoch
    Tx            Taste x am Gerät gedrückt
    resetreset     Reboot des Raspi
    */
    char eingang[255]="";
    char d[1]="";
    int anzahl=0;
        
    int laenge=0;
    int logg=0;
    int    fd;                // File descriptor
    int sender;
    int lautst=95;
    long int time_back;
    long int time_ok;
    
    struct    termios newtio={};
    
    unsigned char eingangleer()            //Eingangstring leeren
    {
        int i;
        for(i=0; i < laenge; i++){
            eingang[i] = 0;
        }
      laenge=0;    
    }
    
    unsigned char platzlautsenden()        //Lautstärke und Senderplatz auf den kleinen Zahlen ausgeben
    {                                    //Lautstärke 100% und Senderplatz 3 wird zu 100:03
        char nummer[3];
        int i=0;
        char befehl[255]="";
    
        sprintf(nummer,"%d",lautst);
        strcpy(befehl,"/var/scripte/senden 2");
        if (strlen(nummer)<3){
            strcat(befehl,"0");
        }
        if (strlen(nummer)<2){
            strcat(befehl,"0");
        }
        strcat(befehl,nummer);
        strcat(befehl,":");
        i=sender;
        if(i>99){                //Die Anzeige ist 2-Stellig
            i=99;
        }
        sprintf(nummer,"%d",i);
        if (strlen(nummer)<2){
            strcat(befehl,"0");
        }
        strcat(befehl,nummer);
        system(befehl);
    }
    
    unsigned char radioein()            //gewählten Platz in der Playlist abspielen
    { 
        char nummer[3];
        char befehl[255]="";
    
        sprintf(nummer,"%d",sender);
        strcpy(befehl,"mpc -q play ");
        strcat(befehl,nummer);
        system(befehl);
        platzlautsenden();
    }
    
    unsigned char initmpd()                    //Schnittstelle parametrieren und öffnen
    {
        char befehl[30]="";
        char s[2]="";
        lautst=95;
        system("/var/scripte/radio2.sh");    //InitScript für mpd
        sleep(1);
        system("mpc playlist > /tmp/mpdlist");    //Playlist zwischenspeichern
        sleep(1);
        FILE *f;
        char Text[300]="";
        char Text1[70]="";
        char Text2[7]="volume";
        f = fopen("/tmp/mpdlist","r");
        anzahl=0;                //Anzahl Einträge der Senderliste zählen
        if(f!=NULL){
            fgets(Text, sizeof(Text), f);
            if(strlen(Text)<2){
                fclose(f);
                return;
            }else{
                anzahl=1;
                while( fgets(Text, sizeof(Text), f) !=0 ){
                    if(strlen(Text)>2){
                        anzahl++;
                    }
                    if(anzahl>199){        //Nicht mehr wie 200
                        break;
                    }
                }
            }
            fclose(f);
        }
        strcpy(befehl,"/var/scripte/senden 6");        //kleine Symbole im Display anzeigen lassen
        s[0]=208;                    //Antennensymbol + FM anzeigen, als Zeichen für Bereit
        strcat(befehl,s);
        system(befehl);
        strcpy(befehl,"/var/scripte/senden 7");                
        s[0]=130;                    //Stereo anzeigen
        strcat(befehl,s);
        system(befehl);    
    }
    
    unsigned char abspielen()                //Wiedergabe fortsetzen. Ist noch nichts abgespielt worden, Platz 1 abspielen
    {
        if (anzahl>0){
            if (sender==0){
                sender=1;
            }else{ if(sender>anzahl){
                sender=anzahl;
                }
                radioein();
            }
        }
    }
    
    unsigned char platzplus()                //Senderplatz um 1 erhöhen
    {                                        //Bei weniger Sendern in Liste auf Platz 1 zurück
        if (anzahl>0){
            sender++;                                    
            if (sender>anzahl){                            
                sender=1;
            }
            radioein();
        }    
    }
    
    unsigned char platzminus()                //Senderplatz um 1 verringern
    {                                        //Bei 0 auf letzten Platz springen
        if (anzahl>0){
            sender--;                                    
            if (sender<1){                                
                sender=anzahl;
            }
            radioein();
        }    
    }
    
    unsigned char lautsetzen()                //Lautstärke einstellen
    {
        char nummer[3];
        char befehl[255]="";
    
        sprintf(nummer,"%d",lautst);
        strcpy(befehl,"mpc -q volume ");
        strcat(befehl,nummer);
        system(befehl);
        platzlautsenden();
    }
    
    unsigned char lauter()                    //Senderplatz um 5 Prozentpunkte erhöhen
    {
        if (lautst<96){
            lautst+=5;                                    
            lautsetzen();
        }    
    }
    
    unsigned char leiser()                    //Senderplatz um 5 Prozentpunkte verringern
    {
        if (lautst>5){
            lautst-=5;                                    
        }else{
            lautst=0;
        }
        lautsetzen();
    }
    
    unsigned char radioaus()                //Wiedergabe anhalten
    {
        system("mpc -q stop");
        system("/var/scripte/senden 45");
        sleep(1);
    }
    
    unsigned char auswerten()                //Angekommene Daten auswerten
    { int i;    
      int fd1;
      int zeile;
      char ret;
      char farbe[6]="";
      
      /* Zum Schreiben öffnen */
        if ((strcmp(eingang,"resetreset") ==0 )){
            system("reboot");
        }
        if (eingang[0] == 83){                         // S
            zeile=eingang[1]-48;               //Werte von 48-255 = 207 mögliche Sender, wird auf 200 limitiert
            if (zeile == 0){               // bei 0 einfach weiter abspielen oder Platz 1 beginnen
                abspielen();
            }else if (zeile<=anzahl){
                sender=zeile;
                radioein();
            }
          }
        if (eingang[0] == 84){                          // T
            if (eingang[1]>49&&eingang[1]<57){    //Wert soweit OK, Taste 1 = Powertaste und wird vom AVR ausgewertet
                if (eingang[1]==50){        //2 - OK Taste
                    abspielen();
                }
                if (eingang[1]==51){        //3 - Wippe rechts
                    lauter();    
                }
                if (eingang[1]==52){        //4 - BACK Taste
                    radioaus();
                }
                if (eingang[1]==53){        //5 - Menü Taste
                    system("/var/scripte/senden");
                }
                if (eingang[1]==54){        //6 - Wippe hoch
                    platzplus();
                }
                if (eingang[1]==55){        //7 - Wippe links
                    leiser();
                }
                if (eingang[1]==56){        //8 - Wippe runter
                    platzminus();
                }
            }
        }
        if (eingang[0] == 80){                          // P
            if (eingang[1]==49){             //1
                platzplus();
            }else{
                platzminus();
            }
          }
        if (eingang[0] == 66){                          // B
            if (eingang[1]==48){             //0 Wiedergabe stoppen
                radioaus();
            }
            if (eingang[1]==49){             //1 mpd zurücksetzen
                initmpd();
            }
        }
        eingangleer();
     }
    
    unsigned char receive()                        //Zeichen empfangen
    {
        
        int res;
        unsigned char buffer;
    
        res = read(fd, &buffer, 1);
    
        getit = fd;
        return buffer;
    }
    
    int init()                        //Schnittstelle parametrieren und öffnen für I-Bus 9600 8E1
    {
        //O_RDONLY, O_WRONLY or O_RDWR -
        //O_NDELAY (geht weiter, wenn keine Daten da sind und gibt "-1" zurueck)
        // man 2 open fuer mehr Infos - see "man 2 open" for more info
        // O_NOCTTY No ControllTeleType 
    
        fd = open(MODEMDEVICE, O_RDONLY | O_NOCTTY );
        if (fd < 0){
            printf("Fehler beim oeffnen von %s\n", MODEMDEVICE);
            exit(-1);
        }
        memset(&newtio, 0, sizeof(newtio));
        newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | PARENB;    //setzt die neuen Porteinstellungen
        newtio.c_iflag = IGNPAR;
        newtio.c_oflag = 0;
        newtio.c_lflag = 0;         /* set input mode (non-canonical, no echo, ...) */
        newtio.c_cc[VTIME] = 0;     /* inter-character timer unused */
        newtio.c_cc[VMIN] = 1;    /* blocking read until 1 chars received old 1 */
    
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &newtio);
        //getit = O_NDELAY;
        return fd;
    }
    
    int main(int argc, char** argv)        //Programmstart
    {
      //new
      int pin = 7;  //GPIO 4
      int value = 0; // Deklaration Eingangswert GPIO4
      getit = 0;
      printf ("Raspberry Pi wiringPi test program\n") ;
    
      if (wiringPiSetup () == -1)
        exit (1) ;
      //new end Check wiring pi
      
      pinMode(pin,INPUT);
      
        
        
        char c;
         init();                    //Schnittstelle UART parametrieren und öffnen
        sleep(5);                 //warten bis mpd gestartet ist
         initmpd();                //mpd auf definierten Zustand bringen
        while (1)
            {
        
        value = digitalRead (pin);
         printf("Status Schnittstelle %d \n", getit );
        
        //printf("SEN/STA: %d\n", value); // BUSRUHE?
        
        c=receive();
        //if((value==1)){
            printf("MESSAGE %X\n", c); // c in Hex ausgeben    %d = Dezimal %H = Hex
            
        //}
        
        
    /*         
            c=receive();                //Zeichen holen
            if((c==13)){            //CR als Abschluß einer Zeile
                auswerten();        
            }else if(c>13&&c<128){        //Alles von ASCii 14 bis 127 wird akzetpiert
                eingang[laenge]=c;        
                laenge++;                
                if (laenge >254){    //Bei 254 Zeichen im Puffer wird automatisch ausgewertet
                    auswerten();
                }
            }
        printf("The answer is %X\n", c); // c in Hex ausgeben    %d = Dezimal %H = Hex
     */    
        
    
        
        
        } 
        
        close (fd);
        return 0;
    }
    Grüße Rainer
    Wenns brennt, dann brennts....

  3. #3
    Erfahrener Benutzer Roboter Experte Avatar von ePyx
    Registriert seit
    14.05.2008
    Ort
    Falkensee
    Beiträge
    700
    Der Code sieht sehr nach zusammen kopiert und entsprechend erweitert aus. Was schon recht doof ist, der bei termios der aktuelle Zustand des Terminals nicht gespeichert, sondern einfach überschrieben wird.

    Das TTY-Device kann man als O_NONBLOCK deklarieren. Um zu erkennen ob Bytes im Puffer der seriellen Schnittstelle sind, kann man Signale benutzen. Das einfachste wäre das SIGIO-Signal, welches aufgerufen wird, sobald Daten eintreffen. Eine andere Möglichkeit um zu Prüfen ob Daten verfügbar sind ist :

    Code:
    int bytes_avaiable;ioctl(serial_file_descriptor, FIONREAD, &bytes_available);
    Wobei das kein komplettes Beispiel ist, daher sollte man sich die manpages ansehen.

    PS : Das Ausführen der Befehle mit System kann im Übrigen hunds-gefährlich werden, da sollte man eher einen bestehenden Prozess forken.
    Grüße,
    Daniel

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    44
    Beiträge
    61
    Danke für deine Info. Dein PS verstehe ich leider nicht, da ich bin ich wohl zu wenig bewandert. Das mit der Deklaration von O_NONBLOCK habe ich zusätzlich vom MODEMDEVICE auch schon probiert. Da kommt aber dann erstmal immer eine 0 und keine Daten mehr an. Ich muss mir das wohl oder übel noch näher ansehen.
    Wenns brennt, dann brennts....

  5. #5
    Erfahrener Benutzer Roboter Experte Avatar von ePyx
    Registriert seit
    14.05.2008
    Ort
    Falkensee
    Beiträge
    700
    Mit meinem PS meinte ich, dass es sehr gefährlich sein kann Befehle per System auszuführen. Beispielsweise durch Pufferüberläufe etc. . Daher gibt es die Möglichkeit Prozesse mit fork zu starten und ihnen Parameter zu übergeben bzw. sie während der Laufzeit zu steuern.
    Grüße,
    Daniel

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    44
    Beiträge
    61
    Hallo Daniel,

    ich hab den Code jetzt mal aufgeräumt und alles rausgeworfen was ich im Moment nicht brauche.

    Code:
    // Compile GCC -o serial_wiring -l rt serial_wiring.c -lwiringPi
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <time.h>
    //WiringPi include für SEN/STA Erkennung
    #include <wiringPi.h>
    //Konfig RASPI USART
    #define BAUDRATE B9600  // 9600 Baud definieren für 8E1 I-Bus
    char MODEMDEVICE[]= "/dev/ttyAMA0";    // Schnittstelle wählen
    int getit; //Nachrichtenblock angekommen
    int    fd;                // File descriptor
    struct    termios newtio={};
    
    unsigned char receive()                        //Zeichen empfangen
    {
        
        int res;
        unsigned char buffer;
    
        res = read(fd, &buffer, 1);
    
        getit = fd;
        return buffer;
    }
    
    int init()                        //Schnittstelle parametrieren und öffnen für I-Bus 9600 8E1
    {
        //O_RDONLY, O_WRONLY or O_RDWR -
        //O_NDELAY (geht weiter, wenn keine Daten da sind und gibt "-1" zurueck)
        // man 2 open fuer mehr Infos - see "man 2 open" for more info
        // O_NOCTTY No ControllTeleType 
    
        fd = open(MODEMDEVICE, O_RDONLY | O_NOCTTY );
        if (fd < 0){
            printf("Fehler beim oeffnen von %s\n", MODEMDEVICE);
            exit(-1);
        }
        memset(&newtio, 0, sizeof(newtio));
        newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | PARENB;    //setzt Einstellungen vom UART 
        newtio.c_iflag = IGNPAR;
        newtio.c_oflag = 0;
        newtio.c_lflag = 0;         /* set input mode (non-canonical, no echo, ...) */
        newtio.c_cc[VTIME] = 0;     /* inter-character timer unused */
        newtio.c_cc[VMIN] = 1;    /* blocking read until 1 chars received old 1 */
        newtio.c_cc[VSTART]   = 0;     /* Ctrl-q startet Datenübertragung */
        newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s stoppt Datenübertragung*/
        
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &newtio);
        return fd;
    }
    
    int main(int argc, char** argv)        //Programmstart
    {
      //new
      int pin = 7;  //GPIO 4
      int value = 0; // Deklaration Eingangswert GPIO4
      getit = 0;
      printf ("Raspberry Test UART+wiringPi\n") ;
    
      if (wiringPiSetup () == -1)
        exit (1) ;
      //Fehlerrückgabe wiringPi
      
      pinMode(pin,INPUT); //wiringPi GPIO4 Pin7 deklarieren
      
    
        char c;
         init();                    //Schnittstelle UART parametrieren und öffnen
        //sleep(5);                 //nix tun
         
        while (1)
            {
        
        value = digitalRead (pin);
         printf("Status SEN/STA %d \n", value );
        
        //printf("SEN/STA: %d\n", value); // BUSRUHE?
        
        c=receive();
        //if((value==1)){
            printf("MESSAGE %X\n", c); // c in Hex ausgeben    %d = Dezimal %H = Hex
            
      
            } 
        
        close (fd);
        return 0;
    }
    Welche manpages meinst du? In der "open" hab ich nichts entdeckt. Wie vielleicht schon erwähnt ich bin leider kein Profi deshalb wohl auch die dummen Fragen.

    Wie geht das genau mit SIGIO bzw in welchem man finde ich das?

    Grüße

    Rainer
    Wenns brennt, dann brennts....

  7. #7
    Erfahrener Benutzer Roboter Experte Avatar von ePyx
    Registriert seit
    14.05.2008
    Ort
    Falkensee
    Beiträge
    700
    Gibt keine dummen Fragen. Nur zusammen kopieren, sich danach wundern das nichts geht und dann fragen ist der falsche Weg. Bin auch kein Profi und habe mir das auch selbst beibringen müssen, da ich es benutzen wollte.

    Bei SIGIO handelt es sich um ein Signal, welches an den Prozess (also dein Programm) gesendet wird, sobald auf einem Filedescriptor ein I/O-Event stattfindet. Ähnlich funktioniert es bspw. wenn man CTRL+C sendet, dass wird
    auch als Signal an den Prozess geschickt. Damit ist es dann möglich trotz des Abbruchs das Programm sauber zu beenden. Signale haben Nichts mit open oder anderen Syscalls zu tun, daher wirst du dort auch nichts finden.

    Beispiel : http://www.tldp.org/HOWTO/Serial-Pro...OWTO/x115.html , Beispiel 3.3 Asynchronous Input

    Ein Beispiel auf Deutsch findet sich beispielsweise hier : http://www.cs.hs-rm.de/~linn/vpdv01/...u/addendum.htm

    Als Tipp kann ich nur noch geben, dass man die manpages auch auf deutsch installieren kann.
    Grüße,
    Daniel

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress