I have attempted serial comm via PHP to Arduono using a WAMP install on a PC...

serial comms seemed to work only one way.. and I was told that this was a PC issue, but on MAC/Linux, PHP serial comm works two ways without issue.

I have previously set up a RPi with Apache, MySQL and PHP...... (for some added support/features in an MQTT set-up/project)

I have never attempted to use PHP serial communication when things were on a Pi.

I will have an Arduino connected to the RPi.....
The RPi will have a webpage served up that I write.

What I would like to happen is upon clicking a link/hotspot in the hosted webpage it to send some serial data upon $_POST[] to the connected Arduino via PHP... have the webpage sit in an 'idle' state... and when the Arduino is done doing its task(s).. send out a serial message back to the RPi/PHP script.. and then change the display state/view of the hosted webpage.. (waiting for another 'user interaction' so to speak)

Re-cap:
Is 2-way serial communication possible with PHP when running on an RPi3?

Currently.. I have moved away from testing on my Windows PC/WAMP.. and have moved over to the RPI. Everything as far as set-up and installing apps/packages is working as expected. I have a DB with populated table(s).. and my web app is loading and displaying all dynamically generated content correctly as well.

Since I can not do this in a Windows environment, I have my Arduino connected via USB to my RPI...

I load up the Chromium browser.. and my web page (drink menu) is displayed to me..

I click on the 'order' button.. (which saves the button data to a hidden field, upon $_POST.. that data is sent via PHP to the connected Arduino.)

And here is where I am currently..

* Since the Arduino is now connected via USB to the RPi.. I can not use the serial monitor to know when/what serial data is being sent BACK to the RPi...

* I believe that the Arduino is receiving the (some) serial data.. because when I click on the 'order' button and submit the webpage. I see the RX/TX lights on the Arduino start to blink.

Question:
I'm having trouble thinking of a way I can DEBUG this.. (without serial monitor or a way to see what is being sent BACK to the RPi)..

I was also not clear on how to go about reading (listening) to the serial port.. since the webpage will already be parsed after submission (to display a please wait type message)...

So I figured possibly an AJAX type of approach.. so the page can send initial serial data to connected Arduino.... display a 'please wait' message..... (All done server side via PHP after submit)

and then have a little AJAX snippet call an external PHP script that does the serial read? (also not sure where the best places to open/close the port is.. if using an external script to READ the serial port?) Can 1 php script open the port.. and another still access it?

Here is my current approach to attempt to read the SERIAL data back form the Arduino after it is finished (no telling when this data will come back from the Arduino)

Linux follows the "everything is a file" motto of Unix. As soon you plug an Arduino into the Raspberry, a file should magically appear in /dev. This file represents a serial port and can be read and written to. The handling has not changed in the last 40 years so software like screen and minicom should directly work with it. Those are bidirectional serial terminals.

For Windows users PuTTY or GTKTerm might be better choices since they are graphical programs. All those programs can be installed via apt-get.

ghans

• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

* So when trying to read/send data over serial via PHP.....I can treat things like a file..

So in the example posted above...

everything is correct?

And in my 'serial_listener.php' file.. I should.... (kinda lost on how to go about READING the serial port... because it wont be an 'instant' response...
The Arduino has to complete its task(s) before it will kick back the serial 'conformation' to the RPi/PHP script...

So what is the best way to 'wait' for this serial data to come?
Do I need to open the port again from a different script? (or is opening it in one file enough for other files to use it as well?)

Here is my PHP script/file.... (a portion of it at least).. that deals with the SUBMISSION... (ie: sending the serial data OUT to the connected Arduino)...

And then the AJAX snippet that calls another (external) .php script that does the SERIAL port listening and returns the data back to the AJAX on success callback..

1) All the programs i mentioned should aid you in debugging serial comms. Since you seem unfamiliar with Linux, GTKTerm or PuTTY might be the better choice instead of the other two options.
2) The "MODE" command does not exist on Linux.
3) You should put the endless loops into your JavaScript instead of the PHP files.

ghans

• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

but perhaps this is WHY I am not receiving response data? the comm port isnt configured correctly?

2.) Why put the loop in the AJAX call? (not in the external php script that is actually doing the serial port listening?)
Wouldnt (doesnt) the AJAX call just 'wait' until the PHP response is complete in one fashion or another? and then it will execute one of the callback functions once the data arrives? (or fails) I was under the impression that is how the AJAX stuff worked?

let the php stuff does its thing... and the ajax call will handle the response when its ready/there is one.

Yes you use the "stty" command, you dont need to understand the parameters, but if you want : http://man7.org/linux/man-pages/man1/stty.1.html
Linux treats serialports as "terrminals" and might do certain things with some special characters, you are just turning all that OFF.

I would consider the arduino send messages back more often, not only when everything it done.
- "recipe recevied"
- "recipe ok" ( or "not ok" )
- "step 1" ( "step 2", etc )
- and then at the end "complete"

However.. for some reason now (and for the last few hours).. I have not been able to get communication back.

Some combination of rebooting,, or capacitor on Arduino to Stop reset.... or 'something' happened.. and I have not been able to connect to port again.

Writing to Arduino has worked flawlessly every time.

If I just send back something static to check/ensure the AJAX callback are working.. and will wait until a response comes (whenever that is)..

like:

sleep(5);
echo 'complete';

the 'web page' gets the response without error every time.

So its not an AJAX/callback response thing..

its 100% the READING aspect/approach.

Random thoughts:

* opening the port in the MAIN php file (where the data gets SENT to Arduino from RPi).
-- does it needs to be closed in the file as well?
-- do I need to be opening it in the external serial_listener.php script? (answer: yes..or it throws error.. perhaps trying to pass an instance of that port via the AJAX $_POST?)

* How did I 'magically' get things working before? but can no longer connect to port reading? or get any data returned?

I can NOT understand why I can SEND data out to Arduino.. but can NOT READ any data..

I open the PORT, (I know this is working because I dont get the NOT OPEN error in my PHP script.. and the SENDING of data TO Arduino works, but the subsequent READ, when the same port is STILL OPEN.. does not return anything)

Here is the MAIN (PHP) page.. that has the content. and submits the data to another PHP script (that does the port opening, and send/receiving).. and returns the data back to the MAIN PHP script.. that has an AJAX call.. and waiting callbacks to handle this response)..

If I hard code something as a response.. it works fine.. even if I add a 10 second delay.. and then hard code a response.. the AJAX callbacks handle it FINE... its the READ of the serial port that is failing.

Main script that has the AJAX handler in it (this not only SENDS data to the Arduino.. which works fine every time,,, but also should handle the RESPOSNE from the same php snippet)

Make the Arduino output much more debug messages (say 5-7 per second) and filter all those debug messages with JavaScript.

ghans

• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

I'm sorry.. I guess I'm not following or understanding your suggestion here?

I only need the Arduino to output ONE response.. (for now) telling me the actions are complete.... so I can update the state of the webpage.

The php while() function is already waiting/listening for ANY response on the PORT... before its being sent.

The while() function executes.. and I'm stuck in it, because it NEVER gets anything..

I updated the Arduino sketch to output the same 'complete' string.. wait for 1/4 of second.. send it again.. wait another 1/4 second.. send another.. and did like 4-5 times... so we'll see if it that helps getting the data back over to the RPi I guess...

Just a few suggestions:
- don't call "stty" every time, because that resets the serial port. Only call it once during bootup, before you start apache/nginx. The scriptfile "/etc/rc.local" is an ideal place for that.
- make sure you're using the right device. "/dev/ttyUSB0" is very unlikely. Normal serial port (aka COM1) is usually mapped to "/dev/ttyS0", but could be "/dev/ttyACM0". Use the "dmesg" command to list all the detected devices, and look for "serial". Try "dmesg | grep serial" or "dmesg | grep dev/tty".
- check the group of that device with "ls -la /dev/tty*", and make sure your webserver's user is in that group (should be "dialout" as perviously mentioned). Don't change the permissions on a device file, because devfs is generated automatically, meaning your change will be lost.
- by default, Linux sends it's console to the serial port too. To avoid interferece, you must turn that off.
- although it shouldn't needed, but with serial console off, you might need to add "enable_uart=1" to the file "/boot/config.txt"
- also with the latest RPi3, there's an interferece with the bluetooth stack, so might need to turn bluetooth off to enable both PL011 and miniAUX UARTs (bluetooth only conflicts with one of them, but I'm not sure which one, search these forums).

Thanks for the reply.. since there was not much direct help.. (just random suggestions it seemed).. I eventually stumbled upon a 'fix'..

which I understand makes things 'less secure'.. but this is a standalone (for fun) project not connected to any network or wifi..etc..

but running this line (as is) from a remote (Putty) terminal:

echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers

seemed to do the trick. So in the end it was never a 'code' things on the LAMP side of things.. but a permissions thing on the 'Raspbian' side of things... IMO..

I tried to 'execute' the "stty" thing on/in the RPi at start up.. bu it never worked..

I execute the "stty" thing in the PHP script now (and yes upon every 'call' [or drink order/submission to be more clear], I suppose I could re-work the app to use AJAX complete.. and no server side submissions/page loads...but I'm not really at the refactoring stage yet, by any means)

it 'does'....and I 'am'.. using: /dev/ttyACM0

I only tried USB0 once.. when I switched from a straight USB cable to a USB/TTL adapter cable...(but that was a short test, and abandoned quickly)

I wish I would have stumbled upon that line above much earlier in this project... because in between all these posts and using that line.. there was much non-sense, and trial-error stuff done to the RPi...

Waiting for 2+ months for some sort of 'solid' direction/help... I had no other choice to keep the project moving forward.

I admire your tenacity. Hopefully you have not been waiting because there are tons of tutorials and blogs on the net about setting up Apache and HHP and setting permissions etc.

Sorry to offer more "random suggestions or half directions" but surely if the problem is that PHP does not have permission to access the serial port the answer is to change ownership or group of the serial port. Or add the web server to whatever group the serial port is in.

I'm guessing that reason you don't get concrete suggestions here is that it's a pretty weird and rare thing to be accessing a serial port from a web server with PHP. Off the beaten track, as it were.

From my searches.. it seems MANY people have used, and are using PHP to access the serial port data.. (most use that same class though, but it isnt needed)

And yes, I agree.. "PHP does not have permission to access the serial port the answer is to change ownership or group of the serial port. Or add the web server to whatever group the serial port is in"....

which is what I have been asking over and over (many places actually)... HOW!?? I started off each thread with the disclaimer I am NOT Linux/CLI literate. (So random key words hold no weight if I dont understand how to apply/run/use them)

"I can write.. but not read... seems like a permission thing".. most of the time people got stuck on the AJAX aspect... and couldnt move beyond that to actually READ and ANSWER the real problem.

I even posted (more or less) my WHOLE projects.. form initial RPI set-up steps (including the permissions/dial out groups, MySQL/Apache permissions applied).. down the to whole front end of HTML/CSS, PHP and AJAX routines.

Even now. I posted that I UNDERSTAND this is a security risk (per se`)......(and that this will not be connected to a network/wifi...its a standalone project)... and how can I NOT use that specific line... but one that is more tailored to be less of a risk?

** I also was a bit unclear as to WHY the echo needed to be run in terminal/Putty?

As you can see, both files are character devices (the leading "c"). Both can be read and written by their owners ("rw-"). The tty0 file is owned by root, and tty1 is owned by user (3rd coloumn). Now the second access differs: although both files belong to the same group (4th coloumn), tty0 can be written by the group, tty1 can't be. What does all this mean?

By default I, as the user "user", I can write to the tty1, because I'm it's owner, therefore owner access rights apply. I can't write to tty0, because I'm neither root nor am I in the "tty" group, only in my own "user" group:

BUT. If anybody (let's say "user2") is in the "tty" group, that doesn't mean they can write to my terminal, because my "tty1" terminal does not have "w" group permission. So the question is, if you list your serial device under /dev, what do you see? What group it belongs to? Is that really "dialout", or something else? Does it have "rw" group permissions?

** I also was a bit unclear as to WHY the echo needed to be run in terminal/Putty?

"echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers"

if I didnt have the ECHO in there.. it didnt work.

"echo" is a command. You enter commands in a terminal
It does nothing else that echoes it's argument back. With the pipe that output is redirected to the "tee" command, and there's two reasons for that. First, tee is called through sudo, which means it will be running with supervisor privileges (required to modify the /etc/sudoers file). Second, it's "-a" argument guarantees that the echo's output will be appended to the file, and you don't accidentaly mess up your sudoers file.
Simply put, it would be enough to have

Whoever wrote that tee soultion though it's simpler to give root permission to tee, and he was right.

Now what's wrong with this. This allows the www-data user to run ANYTHING as supervisor without any authentication. Because your webscript is running under the user "www-data", that means even the slightest issue in your code opens up your ENTIRE system to an attacker without any restrictions.

Let's say you have forgotten to properly escape the shell arguments when you invoke bash from PHP (which I'm pretty sure you have forgotten), and let's say you pass $cmdarg (an otherwise legal and valid) argument to that bash command. In this case a simple query with the
"/index.php?cmdarg=somethinglegal;sudo+rm+-rf+/"
URL would ruin all your work within a blink of an eye. Not to mention it's equally easy to install a backdoor without you even noticing.

Whoever wrote that tee soultion though it's simpler to give root permission to tee, and he was right.

Now what's wrong with this. This allows the www-data user to run ANYTHING as supervisor without any authentication. Because your webscript is running under the user "www-data", that means even the slightest issue in your code opens up your ENTIRE system to an attacker without any restrictions.

I'd dispute there's nothing wrong in that except that it opens your webserver as a massive security hole and a vector for the bad actors to get root access. Once they have root access to your Raspberry they own your whole LAN and every device connected to it.

Other than that, go ahead, give www-data sudo access.

Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

I understand the security risk, and as mentioned a couple times.. this is NOT connected to any sort of network/LAN/WAN, WIFI...etc.. this is a standalone project. But I do get it... (also I am NOT executing any bash scripts.. I got that LINE from a tutorial that was... I am not. I am simply sending serial data to be parsed/chopped up from a hosted webpage to the connected Arduino)

I dont understand all of what was given to me.. so I'll start slowly.

1.) "echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers"

Thank you for explaining about the 'echo' portion... being a PHP developer, I use 'echo' to output stuff to a page..

The "l" (lower case "L") in front means the file is a link to the real file ttyAMA0. The rwxrwxrwx means that the link is visible to anyone, which is standard and doesn't reflect the permissions on the file it points at.

crw-rw---- 1 root dialout 204, 64 Oct 9 07:07 ttyAMA0

Yes, that is your serial port. It is owned by root, and also the group "dialout". The pi user should be a member of that group and will have read/write access to that interface (the second "rw-" applies to group members).

As others pointed out, you have read-write permissions for the group on the serial device, which is exactly what you want.
You only have to add "www-data" to the "dialout" group, reboot and you should be fine without any sudo. (Reboot is required to restart the webserver and it's user session. There are other options, but reboot is the simplest.) If this doesn't work for you, then there's some problem with the "www-data" user's groups. An easy way to check and fix this:

You'll see that group is a simple ':' colon separated database. Each line contains: "group":"x":"id":"comma separated list of users in this group". Look for the line "dialout" and check if "www-data" is listed at the end. If not, then you can manually add it with nano, and save. Don't forget to restart your webserver with a reboot. ("nano" is a very simple, easy to use text editor with keyboard shortcut help at the bottom. If you don't have that, you can try "pico". If even that fails, as a last resort use "vi" which always exists on all UNIXes, but rather tricky to use. Once "vi" loaded, press "i" to enter inserting edit mode. Edit the line, then press "Esc" to return to command mode, and in the bottom command line (prefixed by ":") type "wq!" and press "Enter".)

About removing the sudo. The sudoers file itself is a simple plain text file. I think the easiest way for you is to do

About your network connection: it's good thinking that you don't connect it to the internet if you don't have to. But there's always a chance that some attacker is able to use it's WiFi, so it's best practice to give only the smallest set of access rights to processes.