Writing to a Serial Port

I am trying to write to a serial port and capture the reponse in a file -

adduser ethan dialout 
The user `ethan' is already a member of `dialout'
root@meow:/home/ethan# ls -l /dev/ttyS0
crw-rw-r-- 1 ethan dialout 4, 64 Oct  7 20:55 /dev/ttyS0

$fh1 = fopen("/dev/ttyS0", "w+");
fwrite($fh1, "W\n"); //This sends a signal to a scale to return the weight of an object
fread($fh1, 100);
echo $fh1;

If I run this code -

Warning: fopen(/dev/ttyS0): failed to open stream: Permission denied in /var/www/TestScale.php on line 20

Warning: fwrite() expects parameter 1 to be resource, boolean given in /var/www/TestScale.php on line 21

Warning: fread() expects parameter 1 to be resource, boolean given in /var/www/TestScale.php on line 22

TIA

Are you running that php script as root user...and post the output of setserial -a /dev/ttyS0 here...

Thanks shamrock.
Running as user.

How would I run a PHP script as root?
TIA

root@meow:/home/ethan# setserial -a /dev/ttyS0 
/dev/ttyS0, Line 0, UART: 16550A, Port: 0x03f8, IRQ: 4
    Baud_base: 115200, close_delay: 50, divisor: 0
    closing_wait: 3000
    Flags: spd_normal skip_test

Perhaps if you walk before running we might be able to solve your problem(s) as you have asked a near identical question here:-

Thanks wisecracker -

Correct.

That thread was in the Debian forum.

This question here is in PHP programming and I thought, mistakenly, that this question belonged here. I do not think threads are identical. If an apology is needed, I apologize.

I do not think the question is identical. Related, but PHP & CGI have their own issues. Still not quite the right forum, but I can fix that. No harm done.

If you are running it from PHP, you are probably running it from CGI, yes? User accesses a webpage via HTTP and your script runs -- but as "apache", not as you.

Thanks Corona688.

I'm not sure that I understand you.

Here is the code -

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<html>

    <head>
        <title>Test Scale</title>
    </head>
        <body>
        <strong>
            <div align='center'>
                  <h3>Test Scale</h3>
            </strong>
                    </div>

<?php
            error_reporting(E_ALL | E_NOTICE);
            ini_set('display_errors','1');
            
            $fh1 = fopen("/dev/ttyS0", "w+");
            fwrite($fh1, "W\n");
            fread($fh1, 100);
            echo $fh1;

?>

        </body>
</html>

When I can get this to run, I'll add a form which will call the code.

TIA

And you run this code by browsing to http://localhost/whatever/myserialscript.php yes?

By doing so, you are instructing your web server to run the script. Your web server probably runs as the apache user and group.

Where is fclose($fh1); ?

@OP:
Based on the error it seems whoever is trying to run the php script does not have the privileges to do so...can you copy the php snippet and run it on the command line as the user or group member that owns /dev/ttyS0...

Or simply change the permissions on the port to 0666. If you get it to work with that, you can consider what security implications there may be later.

[LEFT]Thanks Shamrock.

".can you copy the php snippet and run it on the command line as the user or group member that owns /dev/ttyS0..."

I'm sorry, I am a newbie. How??
[/LEFT]

---------- Post updated 10-19-14 at 04:47 PM ---------- Previous update was 10-18-14 at 09:27 PM ----------

Here is some more info -

root@meow:/dev# ls /dev/ttyS0
/dev/ttyS0
root@meow:/dev# echo test > /dev/ttyS0
root@meow:/dev# ls bla
ls: cannot access bla: No such file or directory
root@meow:/dev# touch bla
root@meow:/dev# ls -l bla
-rw-r--r-- 1 root root 0 Oct 18 22:55 bla
root@meow:/dev# echo test > /dev/ttyS0 >bla
root@meow:/dev# cat bla
test
root@meow:/dev# echo "W\n" > /dev/ttyS0 >bla
root@meow:/dev# cat bla
W\n

Therefore I can write to the port and read from it.
How do I get the output from the scale, which is called by W\n?

TIA

This is not reading from the port. You cannot do 2 redirections. You're attaching stdout to /dev/ttyS0 but immediately changing that to a file called bla.

mute@thedoctor:~$ echo hi >file1 >file2
mute@thedoctor:~$ ls -l file?
-rw-r--r-- 1 mute mute 0 Oct 19 21:29 file1
-rw-r--r-- 1 mute mute 3 Oct 19 21:29 file2

This shows how redirection to two places fails. You only need to:

$ echo W >/dev/ttyS0
$ cat /dev/ttyS0

Try to set permissions, as root, to allow everyone access to the serial port with chmod 0666 /dev/ttyS0 . If your code then works, the issue is that the webserver doesn't run as ethan, but another user who doesn't have access to ttyS0.

Thanks neutronscott -

This is what I get -

root@meow:/var/www# ls -l /dev/ttyS0
crw-rw-rw- 1 ethan ethan 4, 64 Oct 18 22:54 /dev/ttyS0
root@meow:/var/www#  echo hi >/dev/ttS0y >bla
root@meow:/var/www# cat bla
hi
root@meow:/var/www# echo W >/dev/ttyS0
root@meow:/var/www# cat /dev/ttyS0  hangs here
^C

The reason why the serial port is hanging is beacuse of two things, either:-

1) The serial speed is greater than 9600bps and requires HW control.
2) IF the port is reading a decimal value of 0, (zero), then nothing __seems__ to happen.

Another reason could be that the remote nachine is not on the same speed as the local one, but highly unlikely.

Have you tried testing your local machine first with a loopback plug at the speed you require?

Get that side working first then hook up to the remote machine and work on getting them both talking.

Thanks wisecracker -

I think I set the port speed to 9600.

From minicom

-----------------------------------------------------------------------+                                  
Comp| A -    Serial Device      : /dev/ttyS0                                |                                  
Port| B - Lockfile Location     : /var/lock                                 |                                  
    | C -   Callin Program      :                                           |                                  
Pres| D -  Callout Program      :                                           |                                  
    | E -    Bps/Par/Bits       : 9600 7E1                                  |                                  
    | F - Hardware Flow Control : Yes                                       |                                  
    | G - Software Flow Control : No                                        |                                  
    |                                                                       |                                  
    |    Change which setting?                                              |                                  
    +-----------------------------------------------------------------------+ 

I'm a newbie. I've ordered a loopback plug from Newegg.
How do I use it?

So have you been successful with communicating with this device within minicom? That'd be the first step before trying to with PHP.

Thanks neutronscott -

Next step, please.

Is that a yes?

I looked at some weight protocols and you may need to send \r:

$ printf '\rW\n' >/dev/ttyS0
$ cat /dev/ttyS0

You should see a weight then. If so, and your permissions are correct, your PHP may work using \rW\n

Thanks neutronscott -

cat /dev/ttyS0

No output