[PHP] socket server en loop seriele poort

Pagina: 1
Acties:

Onderwerpen


  • Promy
  • Registratie: Oktober 2002
  • Laatst online: 21:12
via een eenvoudig script lees ik continu de seriele poort uit (verbonden met alarm) en verwerk de data in een algemene variabele die de status van alle alarmcontacten weergeeft.
Nu wil ik deze info beschikbaar hebben op een webpagina.
Voorlopig werk ik via een txt file met hierin de variable: het script dat de seriele poort monitort schrijft telkens de variabele weg als ze aangepast is en het script van de webpagina lees dit bestand uit (bij refresh van de webpagina).

Nu is dit systeem natuurlijk heel omslachtig en geeft het fouten als je tegelijk het bestand schrijft en leest...

Dus dacht ik het geheel via een socket te doen, maar hier loop ik tegen wat problemen aan, meer bepaald dat de code voor het uitlezen van de seriele poort niet altijd wordt uitgevoerd, maar enkel als er een vraag komt van de socket client.

Kan er me iemand zeggen wat ik misdoe? Bedoeling is om continu de seriele poort uit te lezen, variabele actueel te houden en deze door te geven op vraag van de client.

m'n code is (socket server van het voorbeeld van php.net)
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php
//deel seriële poort uitlezen
include "php_serial.class.php";

    // Let's start the class
    $serial = new phpSerial();

    // First we must specify the device. This works on both Linux and Windows (if
    // your Linux serial device is /dev/ttyS0 for COM1, etc.)
    $serial->deviceSet("/dev/ttyAMA0");

    // Set for 9600-8-N-1 (no flow control)
    $serial->confBaudRate(19200); //Baud rate: 9600
    $serial->confParity("none");  //Parity (this is the "N" in "8-N-1")
    $serial->confCharacterLength(8); //Character length     (this is the "8" in "8-N-1")
    $serial->confStopBits(1);  //Stop bits (this is the "1" in "8-N-1")
    $serial->confFlowControl("none");

    // Then we need to open it
    $serial->deviceOpen();

// read from serial port
$read = $serial->readPort();
$totaalzone = "Z0000000000000000000000000000000000000000" ;// we voorzien 40 mogelijke contacten, nu 38 aangesloten

// PHP SOCKET SERVER
error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting
 * as it comes in. */
ob_implicit_flush();

$address = '10.0.2.183';
$port = 9859;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}

if (socket_bind($sock, $address, $port) === false) {
    echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}

if (socket_listen($sock, 5) === false) {
    echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}

do {
   
    
    
    
    if (($msgsock = socket_accept($sock)) === false) {
        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    /* Send instructions. */
    $msg = "\nWelcome to the PHP Test Server. \n" .
        "To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
    socket_write($msgsock, $msg, strlen($msg));

    do {

            // eerst de delen van de seriele poort
              $read = $serial->readPort();
              echo $read;
           if (substr($read,1,1) == "Z") {  //het is een zone commando die opgevangen is
                $zone_nr = intval(substr($read,2,3));
                $zone_status = $read[5];
                if ($zone_nr < 41) { // om geen foutmelding te krijgen als we iets fout uitlezen
                    $totaalzone[$zone_nr] = $zone_status;           
                 }// end if
           }//end if van zone commando
            
           if (substr($read,2,1) == "*") {  //het is een LCD status commando die opgevangen is
                $lcd_status = substr($read,1,strlen($read)-1);
           }//end if lcd commando
           
           

        
        if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
            echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n";
            break 2;
        }
        if (!$buf = trim($buf)) {
            continue;
        }
        if ($buf == 'quit') {
            break;
        }
        if ($buf == 'shutdown') {
            socket_close($msgsock);
            break 2;
        }
        $talkback = "PHP: You said '$buf'.\n";
        //socket_write($msgsock, $talkback, strlen($talkback));
        socket_write($msgsock, $totaalzone, strlen($totaalzone));
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);

socket_close($sock);
$serial->deviceClose();
?>

  • Broken
  • Registratie: Maart 2004
  • Laatst online: 05-01 11:21
Wat gaat er dan mis nu? Krijg je een fout ofzo?

Je zult echt even wat debug informatie moeten posten.

01101000 01100101 01101100 01110000


  • Promy
  • Registratie: Oktober 2002
  • Laatst online: 21:12
wat er misgaat is dat ik bij het triggeren van een alarmcontact (waardoor er iets op de bus komt) geen echo krijg van $read (regel 69) op de console.
Wanneer ik dan een telnet connectie maak met de socket server en een willekeurig commando geef (bv test), dan krijg ik de echo op de console van de laatste commando's, maar de variabele $totaalzone (die ik via de telnet doorkrijg (regel 101) bevat slechts de eerste wijziging
Zelfs al ben ik ingelogd op de socketserver, dan nog werkt het geheel niet (geen echo op de console en de variabele $totaalzone wijzigt niet meer)

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 07-01 17:41
Ik weet niet exact hoe het protocol werkt, maar je doet een readPort() op regel 24. Vervolgens enter je de while loop en doe je weer een readPort() die vervolgens blocked? (dus, de 1e readPort returned wat en de 2e niet?)

Klopt het wel dat je dit twee keer achter elkaar moet doen? En wat geeft de 1e readPort() voor resultaat?

...


  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Promy, het is natuurlijk niet de bedoeling dat je hier code dumpt, maar ook actief meedenkt over een mogelijke oplossing. Kijk even op Programming FAQ - Algemeen en probeer je topicstart beter uit te breiden en toe te lichten waar je denkt dat het fout gaat, hoe je dat hebt gedebugged en wat de resultaten zijn.

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


  • Promy
  • Registratie: Oktober 2002
  • Laatst online: 21:12
Ik heb ondertussen het geheel nog wat verder uitgezocht en volgenw mij zit het probleem in het feit dat de do { ....} while (true); maar 1 keer loopt en wacht op input... terwijl ik zou verwachten dat je hiermee net een continue loop maakt?

ik vermoed dat de if (($msgsock = ... op lijn 56 de boel stopzet tot er iets komt en idem met socket_read op lijn 85


cfr de FAQ staat alle errors voor php aan, maar er komen er geen...
via een echo ben ik tot vorige conclusie gekomen.

[ Voor 14% gewijzigd door Promy op 29-07-2013 22:56 ]


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 29-12-2025

BikkelZ

CMD+Z

Je hebt twee do whiles die genest zijn, dus zolang de binnenste aan het loopen is wordt de buitenste niet nog een keer aangeroepen. Waarschijnlijk bedoel je dat de binnenste loop ook maar één keer loopt, just checking.

Verder is het lastig als je geen errors krijgt. Donder overal meer echos neer om te beginnen, dus ook al je if-branches en laat ons ook weten tot welke echo je wel en geen output krijgt.

iOS developer


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 22-12-2025
Je hebt te maken met een blocking socket, dit:
code:
1
socket_read($msgsock, 2048, PHP_NORMAL_READ)
wacht tot er daadwerkelijk iets onvangen wordt op de socket, en blijft hier anders op wachten.

met socket_set_nonblock kan je een non-blocking socket maken, maar hierbij moet je je foutafhandeling wel aanpassen.
Pagina: 1