- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 52

Thema: Lighttpd + UART - Wird nichts gesendet

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    35
    Beiträge
    3.501
    Blog-Einträge
    9
    Ok
    Dank dir schon mal für die Mühe!
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    So, ich habe mal in der php.ini die Fehleranzeige eingeschaltet. Da kommt dann bei meinem Senden-Programm, die Meldung, dass er /dev/ttyAMA0 nicht öffnen kann. Über echo kommt keine Fehlermeldung. Leider komm ich grad nicht weiter, da meine 2GB Karte voll ist. Ich muss erstmal das Backup von gestern zurückspielen und dann gibt es Essen. Die Probleme hatte ich alle mit dem Apache nicht...
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  3. #3
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    35
    Beiträge
    3.501
    Blog-Einträge
    9
    Hey,

    danke fuer die Muehe.......wie hast du dir den Fehler anzeigen lassen?
    Per PHP ueber den Shell_exec Befehl oder hast du das via C Programm getestet?
    Aber die Erkenntnis bestaetigt meine Theorie, dass es sich um ein Rechteproblem handelt.
    Nur die Frage ist....wie stelle ich es um.
    Was sagt den dein Bauchgefuehl? Hat man mit Apache weniger Probleme als mit Lighttpd?
    Weil Performancetechnisch ist das Raspberry Pi durch die Raspian Distribution ja recht gut dabei, sodass ich denke das da Apache nicht so ins Gewicht schlagen sollte.......
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Der Fehler wird mir auf dem WebIf angezeigt, da ich $output einfach noch mit einblende.
    Was mich stört ist, dass ich als user root arbeite. Es wird mir auch root als php-Benutzer angezeigt. Ich deinstalliere gerade php und danach lighthttp um dann (ab morgen) den apache zu testen.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    So, Apache hat auch nicht geholfen.

    Ich nutze jetzt das senden Programm, welches per sudo aufgerufen wird. Dazu muss noch die Passwortabfrage deaktiviert werden.

    Also Befehl
    Code:
    visudo
    in die Konsole eingeben

    Dort dann die Zeile
    Code:
    www-data       ALL=(ALL) NOPASSWD: /var/scripte/senden
    am Ende einfügen.

    Jetzt wird für das eine Senden Programm kein Kennwort bei sudo verlangt.

    Meine Webseite zum Testen:
    Code:
    <html>
    <head>
    <title>Raspberry Pi PHP- Server - UART Test</title>
    </head>
    <body>
    <h1>Raspberry Pi PHP- Server - UART Test</h1>
    <div id="nav"><a href="index.php?safemode=1">Safemode?</a> <a href="index.php">Neu laden</a></div>
    <div id="main"><h2>RasPi-Sendetest<h2><br>
    <?php
    header("Cache-Control: no-cache, must-revalidate"); 
    echo "<br>";
    echo "Befehl eingeben";
    echo "<br>";
    
    if (isset($_GET["safemode"])) {
        if( ini_get('safe_mode') ){
            echo "<br>Safemode an<br>";
        }else{
            echo "<br>Safemode aus<br>";
        }
    };
    if (isset($_POST["befehl"])) {
            if ($_POST["befehl"]!=""){
                $befehl="sudo /var/scripte/senden ".$_POST["befehl"];
                $output = shell_exec($befehl); 
            }    
    };
     
    echo "<form method='post' action='index.php'>";
    echo "<input type='text' maxlength='40' size='40' id='1' name='befehl' value='HalloWelt' />";
    echo "<br>";
    echo ".$output"
    ?>
    
    <input type="submit" value="Senden"> </form>
    </div>
    </body>
    Mein Senden Programm:
    Code:
    // Compile with: GCC /var/scripte/senden.c -o /var/scripte/senden
     
    //#include <iostream>
    //using namespace std;
    #include <sys/types.h>                        //nicht benötigtes scheint keinen Platz zu verschwenden...
    #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>
    
    #define BAUDRATE B19200
    char MODEMDEVICE[]= "/dev/ttyAMA0";    // !!!
    
    int    fd;                // File descriptor
    struct    termios newtio={};
    
    unsigned char send(char c)
    {
        int res=write(fd, &c, 1);
        if (res<0) printf("Fehler beim Senden\n");
        return res;
    }
    
    int init()
    {
        /*** Init ***/
        
        //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_WRONLY | 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;    //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 */
    
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &newtio);
        return fd;
    }
    int einmal()
    {
        int i=0;
        int anzahl=0;
        int laenge=0;
        char *ptr;
        FILE *in;
        extern FILE *popen();
        char buff[30];
        char rueckgabe[30]="";
    
        if(!(in = popen("pidof senden", "r"))){
            exit(1);
        }
        
        fgets(buff, sizeof(buff), in);
        pclose(in);
        laenge=strlen(buff);
        for(i=0;i<laenge;i++)
        {
            if(buff[i]==' ') anzahl++;
        }
        return anzahl;    
    }
    
    
    int main(int argc, char** argv)
    {
        char c;
        char vBuf[100]="",*pBuf;
        char buffer [100]="";
        char buffer1 [100]="";
        int i=0;
        int anzahl;
        anzahl=einmal();
        if (anzahl>0){
            anzahl++;
            sleep(anzahl);
        }
         init();
        if (argc == 1) {                                                    //Wenn nichts angegeben, dann Uhrzeit und Datum senden
            time_t rawtime;
            
            struct tm * timeinfo;
            time ( &rawtime );
            timeinfo = localtime ( &rawtime );
    
            strftime (buffer,80,"U%H:%M:%S",timeinfo);                        //Uhh:mm:ss
            pBuf=buffer;
            strcat(pBuf,"\r");
            while(pBuf && *pBuf)                                            //Zeichen einzeln senden
                send(*pBuf++);
    
            strftime (buffer,80,"D%d.%m.%y",timeinfo);                        //Dtt.mm.yy
            pBuf=buffer;
            strcat(pBuf,"\r");
            sleep(1);
            while(pBuf && *pBuf)                                            //Zeichen einzeln senden
                send(*pBuf++);
        }else{                                                                //Sonst Parameter einlesen und senden    
            if(strlen(argv[1])>75){                                            //Puffer im AVR ist auf 80 gestellt
                strncpy(buffer,argv[1],76);                
                buffer[76]='\0';
            }else{
                strcpy(buffer,argv[1]);
                if (argc >2){
                    for (i=2;i<argc;i++){
                        if(strlen(buffer)+strlen(argv[i])>75){
                            strcat(buffer," ");                                
                            strncat(buffer,argv[i],(76-strlen(buffer)));
                            buffer[76]='\0';
                            break;                                            //exit for in c...
                        }else{
                            strcat(buffer," ");
                            strcat(buffer,argv[i]);
                        }
                    }
                }
            }
            int o=0;
            for(i=0;i<strlen(buffer);i++){
                buffer1[o]=buffer[i];
                if (buffer1[o]==164){                                    //ä
                    buffer1[o]= 228;
                }
                if (buffer1[o]==188){                                    //ü
                    buffer1[o]= 252;
                }
                if (buffer1[o]==182){                                    //ö
                    buffer1[o]= 246;
                }
                if (buffer1[o]==132){                                    //Ä
                    buffer1[o]= 196;
                }
                if (buffer1[o]==156){                                    //Ü
                    buffer1[o]= 220;
                }
                if (buffer1[o]==150){                                    //Ö
                    buffer1[o]= 214;
                }
                if (buffer1[o]==159){                                    //ß
                    buffer1[o]= 223;
                }
                if (buffer1[o]==138){                                    //&
                    buffer1[o]= 38;
                }
                if (buffer1[o] != 195){                                    //Initialisierung Umlaut
                    o++;
                }
            }
            pBuf=buffer1;
            strcat(pBuf,"\r");                                                //CHR(13) anfügen, damit der AVR auswertet        
            while(pBuf && *pBuf){                                            //Zeichen einzeln senden
                send(*pBuf++);
            }
        } 
        close (fd);
        return 0;
    }
    Geändert von peterfido (13.09.2012 um 16:44 Uhr)
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  6. #6
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    35
    Beiträge
    3.501
    Blog-Einträge
    9
    Danke für die Tipps.
    Ich schaue es mir mal an.
    Wie funktioniert das mit dem C Programm?
    Ist das ein Programm was nur 1x ausgeführt wird wenn man auf nen Button drückt oder wie muss ich das verstehen?
    Bzw. kannst du mir ein bischen näher erklären wie ich die Interaktionen in einem Webinterface mit einem C-Programm koppeln kann, so das über das Webinterface Daten an ein C-Programm gegeben werden?
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Das hier vorgestellte sendet das, was als Parameter übergeben wurde, an die UART und wird dann gleich wieder beendet. Wird es nur so, also ohne Parameter aufgerufen, sendet es die Uhrzeit mit einem U voran, sowie eine Sekunde später das Datum mit einem D voran. Ansonsten werden Umlaute noch angepasst und als letztes ein CR gesendet.

    Das funktioniert bei mir sehr zuverlässig. Einige Strings müssen in Häkchen gesetzt werden, da sonst bestimmt Zeichen einen Strich durch die Rechnung machen. Aufgefallen sind mir da die Klammern und das Kaufmannsund.

    Darüber hinaus prüft es noch, ob es bereits läuft und macht pro bereits laufende Instanz eine Sekunde Pause. So wird verhindert, dass mehrere Strings durcheinander gemischt werden und nur Murks ankommt.

    Ich habe mein Protokoll darauf hin aufgebaut, dass das erste Zeichen angibt, was da jetzt kommt. U für Uhrzeit, D für Datum R für Radiosender I für Interpret, T für Titel, S für Anzahl der Titel in der Senderliste, C für aktuelle Position in der Liste und V für aktuelle Lautstärke. Alles bis auf U und D übernimmt aber ein anderes Programm, welches über das "senden" Programm Informationen zum AVR schickt.

    Der Rückkanal AVR>>Raspi erfolgt über ein anderes Programm, welches ständig im Hintergrund läuft. Immer, wenn Daten über UART eintreffen, werden diese dann von diesem Programm ausgewertet und entsprechend gehandelt. Da musste ich allerdings das Protokoll ertwas erweitern: Seit ich eine definiertes Zeichen als Indiz für einen neuen Datensatz nutze, läuft es fehlerfrei durch. Ohne dieses Zeichen musste ich hin und wieder einen Befehl doppelt senden.

    Meine Experimente, wo nur ein Programm in beide Richtungen agiert, waren zwar auch erfolgreich, jedoch stieg durch die ständige Loop die Prozessorlast teilweise auf über 30% nur für das Programm an, was ich nicht wollte. Mit den 3 Programmen bin ich so gut wie immer im einstelligen Prozentbereich für diese. Das 3. Programm überwacht alle 2 Sekunden den Status des MPD und schläft dazwischen immer. Nur bei Änderungen werden Informationen über "senden" an den AVR gemeldet. Ansonsten prüft es auch noch per pidof, ob das Empfänger Programm noch läuft und startet es, wenn es dieses nicht findet. Umgekehrt prüft das Empfänger Programm auch den Status des Überwachers, wenn eine Zeichenkette eingetroffen ist (Also nach dem chr(13)). Das gegenseitige Überwachen kommt aber im nächsten Step raus und wird per Cronjob minütlich durch ein Programm namens Wachhund übernommen. Das ist auch schon fertig und überwacht dann zusätzlich noch den MPD.

    Ich kann auch über den AVR alle aktuellen Werte anfordern, was in der Testphase von Vorteil ist, wenn der AVR neu startet, der Raspi aber durchläuft. Dazu sendet er ein bestimmtes Zeichen (CHR(). Das erkennt der Empfänger und beendet den MPD Überwacher und startet ihn darauf neu, was zur Folge hat, dass alle aktuellen Werte zum AVR geschickt werden.

    Um eine Kommunikation mit einem Programm per php zu realisieren, gibt es mehrere Möglichkeiten. Ich würde ein Programm mit Parametern aufrufen und für den Rückkanahl die Ausgabe auswerten. Dieses müsste dann im Beispiel im $output ankommen. Wie es bei Leerzeichen und anderen Zeichen, wie die oben erwähnten Klammern, sowie & reagiert, habe ich noch nicht getestet. Kann ich aber mal eben schnell probieren. Dazu melde ich mich später nochmal.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

Ähnliche Themen

  1. [ERLEDIGT] MCP2515 Remoteframe wird nicht gesendet.........
    Von Kampi im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 30.08.2012, 22:49
  2. [ERLEDIGT] Frage zu LightTPD
    Von Kampi im Forum Raspberry Pi
    Antworten: 69
    Letzter Beitrag: 17.07.2012, 14:57
  3. Auf LC-Display wird nichts angezeigt
    Von cesupa im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 28.02.2008, 18:44
  4. I2C Adapter Software es wird immer WRITE gesendet
    Von yunscher im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 29.03.2007, 18:12
  5. wegen UART wird 7805 kochend heiß
    Von batti112 im Forum Elektronik
    Antworten: 26
    Letzter Beitrag: 15.06.2004, 09:48

Berechtigungen

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

LiFePO4 Speicher Test