-         
Seite 3 von 5 ErsteErste 12345 LetzteLetzte
Ergebnis 21 bis 30 von 46

Thema: Internetradio

  1. #21
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    48
    Beiträge
    765
    Anzeige

    Danke für den Tip!
    Im Prinzip wohl schon. Allerdings möchte ich LCD4Linux nutzen und das LCD soll auch an andere Geräte wie z.B. das NAS angeschlossen werden können.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  2. #22
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    39
    Beiträge
    61

    empfangen.c UART Kommunikation

    Hallo,

    ein sehr gelungenes Projekt und mein erster tieferer Kontakt mit dem Raspberry Pi. Ich hab mir gleich den MPD installiert und mal losgelegt. Jetzt habe ich ein WWW Radio für meine Stereoanalage, welchen ich nicht ganz so elegant nur mit dem Smartphone steuere.

    Ich bin gerade dabei eine Anbindung an mein Autoradio zu basteln. Da ich auch den MPD dafür benutzen will und die originalen Radiotasten zum steuern haben will, habe ich eine Frage zum "empfangen" Code.

    Ich habe leider eine etwas komplexere Schnittstelle mit Umsetzer von 1-Draht Bus auf RS232. Ich bekomme die Daten schon mal ins Board rein mit einem etwas angepassten "empfangen.c", wo ich schon mal heilfroh bin.

    Senden geht auch schon zumindest über Shell.

    Leider kommen immer mehrere Zeichen auf einmal an und dann ist kurzzeitig wieder Ruhe auf der Schnittstelle.
    Ein Beispiel in Hex
    ungefähr so
    18 04 FF 02 00 E1
    0.1s Pause
    18 04 FF 02 00 E1
    2s Pause
    FF FF FF FF FF FF (irgendein Code)
    Pause
    etc.

    Als Kommunikation habe ich 9600,8e,1

    Gibt es eine Möglichkeit mit der im Code verwendeten UART Kommunikation über einen Status zu erkennen wann ein Datensatz übertragen wurde bzw. gerade kein neues Zeichen am UART ankommt? Wenn das geht konnte ich die Zeichen immer sauber auslesen, da sich ja nicht kontinuierlich gesendet werden sondern Paketweise.

    Ich habe auch schon versucht über einen aus meinem Chip ausgegeben Sendungsstatus (via wiringPi) ans Ziel zu kommen. Doch ist das leider zu ungenau und es werden immer weider Zeichen verschluckt. Heißt entweder werden die GPIOs zu langsam erkannt oder der Chip ist hier ungenau.

    Über einen kleinen Anstoß meiner Grüzkiste wäre ich sehr froh.

    Viele Grüße

    Rainer
    Wenns brennt, dann brennts....

  3. #23
    Erfahrener Benutzer Roboter Experte Avatar von ePyx
    Registriert seit
    14.05.2008
    Ort
    Falkensee
    Beiträge
    700
    Könntest ja blockweise a 6 Byte lesen in dem du beim read eine Struktur/einen Array und als maximale Größe 6 (bzw die Größe der Struktur/des Arrays) übergibst.
    Wenn alle Bytes 0xFF sind definierst du dann, dass die Übertragung vorbei ist.
    Grüße,
    Daniel

  4. #24
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    39
    Beiträge
    61
    Danke ePyx für deine Antwort. Blockweise auslesen kann ich leider nicht machen, da die Bytelänge und die Ruhezeiten variieren. Ich hätte gestern schon einen Datenmitschnitt posten sollen, damit es klarer wird. Abschlusszeichen ala CR hab ich auch nicht. Der letzte Wert ist zwar immer die XOR Checksumme von den empfangenen Bytes pro Block, welche man zur Plausibilitätsprüfung heranziehen kann, doch weiß ich nicht wie man das während des empfangens schon verwerten soll.

    Code:
    2013-01-14 06:41:53.390    18 04 FF 02 00 E1
    2013-01-14 06:41:53.390    76 0C 68 39 00 82 00 10 00 05 01 00 01 BC
    2013-01-14 06:41:53.405    68 04 FF 3B 00 A8
    2013-01-14 06:41:53.421    68 05 18 38 01 00 4C
    2013-01-14 06:41:53.421    68 10 C0 23 41 30 00 20 20 20 20 20 20 20 20 20 20 EA
    2013-01-14 06:41:53.436    C8 05 80 23 42 20 0C
    2013-01-14 06:41:53.436    18 0A 68 39 00 02 00 10 00 05 01 55
    2013-01-14 06:41:53.670    68 04 BF 02 01 D0
    2013-01-14 06:41:53.686    68 05 80 41 01 01 AC
    2013-01-14 06:41:53.780    68 03 D0 5D E6
    2013-01-14 06:41:57.290    18 04 FF 02 00 E1
    2013-01-14 06:42:01.174    18 04 FF 02 00 E1
    2013-01-14 06:42:02.843    68 05 18 38 03 00 4E
    2013-01-14 06:42:02.874    18 0A 68 39 02 09 00 10 00 05 01 5C
    2013-01-14 06:42:02.968    68 03 18 01 72
    2013-01-14 06:42:03.015    18 04 FF 02 00 E1
    2013-01-14 06:42:03.108    18 0A 68 39 02 09 00 10 00 05 15 48
    2013-01-14 06:42:03.826    18 0A 68 39 09 09 00 10 00 08 99 C2
    2013-01-14 06:42:05.417    18 04 FF 02 00 E1
    2013-01-14 06:42:06.977    68 05 18 38 01 00 4C
    2013-01-14 06:42:06.993    C8 05 80 23 42 20 0C
    2013-01-14 06:42:07.040    68 10 C0 23 41 30 00 20 20 20 20 20 20 20 20 20 20 EA
    2013-01-14 06:42:07.040    C8 05 80 23 42 20 0C
    2013-01-14 06:42:07.055    18 0A 68 39 00 02 00 10 00 08 99 C0
    2013-01-14 06:42:09.676    18 04 FF 02 00 E1
    Wenns brennt, dann brennts....

  5. #25
    Erfahrener Benutzer Roboter Experte Avatar von ePyx
    Registriert seit
    14.05.2008
    Ort
    Falkensee
    Beiträge
    700
    Hast du dort irgendwelche Events ausgelöst? Also Tasten gedrückt oder so? Ein wenig Redundanz ist ja schon enthalten : Die Sequenzen 18 04 FF 02 00 E1, 68 05 18 38 01 00 4C und 68 10 C0 23 41 30 00 20 20 20 20 20 20 20 20 20 20 EA tauchen ja schon öfter auf.

    Würde halt gucken was sich bei einem Tastendruck oder einer anderen Einstellung bei den gesendeten Daten ändert und das Protokoll weiter analysieren.
    Grüße,
    Daniel

  6. #26
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.06.2008
    Beiträge
    185
    Hallo,da Linux ein Time sharing System ist, kann es zu diesen Pausen kommen. Du kannst versuchen, die Priorität deines Programmes zu erhöhen.Mit "nice -n15 Deinprogramm" starten, oder bei laufendem Programm mit "renice -n15 Deinprogramm".Vielleicht hilft das etwas.
    MfG
    Hans

  7. #27
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    39
    Beiträge
    61
    Danke für eure Antworten.

    das Timing wann die Blöcke kommen ist nicht kritisch. Sie werden alle vom RasPi erkannt.
    Die Events kommen von den Steuergeräten auf dem Bus, heißt dem Radio und dem CD-Wechsler Emulator.
    Das passt. Das einzige was ich im Moment noch nicht hinbekomme ist, das "empfangen.c" so anzupassen, dass wenn ein Block übertragen ist, dass heiß Ruhe auf dem Bus einkehrt die Daten auszulesen und in einen String zu schreiben.

    Es müsste doch irgendwie möglich sein das der UART vom Raspberry merkt, wann ein Zeichen ankommt und wann kein Zeichen mehr ankommt und dementsprechend einen Status setzt. Wenn dieser Status auf 1 geht und dann wieder auf 0 ist der Block übertragen und damit kann man dann einen String bauen. Diesen Datensatz kann man dann auswerten.

    Viele Grüße

    Rainer
    Wenns brennt, dann brennts....

  8. #28
    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

  9. #29
    Benutzer Stammmitglied
    Registriert seit
    24.06.2007
    Alter
    39
    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....

  10. #30
    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

Seite 3 von 5 ErsteErste 12345 LetzteLetzte

Berechtigungen

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