Data I send to the serial port from the Arduino Uno can be viewed exactly as expected in the Arduino serial monitor, but when reading the data from PHP through serproxy in my WAMP environment I am getting some missing or extra characters (often a character that looks like a question mark inside of a black diamond, for example).
I've found similar questions posted, but all of the answers fell short. Often solutions were given for Linux only, or solved only part of the many challenges it takes to even get Windows to read (not write) from a serial port.
I tried the following to get PHP to simply read any serial data:
I first tried the php_serial class suggested, but quickly found out it only allows writing on Windows, and the answer for one of the other stack overflow questions (Serial Communication Arduino to PHP) suggested replacement code only for the Linux portion of the code, not Windows.
The article at Serial comm with PHP on Windows also mentions limited capacity on Windows for php_serial class and suggests an alternative serial extension (also mentioned here and here), but this would not load on my WAMP environment with PHP 5.4.12 VC9 build when I used the correct matching extension version, added the extension to the correct php.ini, and restarted the server. I received a "Module win_serial is not compiled into PHP" after following all of the steps. If anyone else has had this issue please let me know as I would be willing to look into this again.
Finally, I tried using a program called serproxy which redirects network sockets to and from serial ports. This does work with the caveat that I added a 10uF capacitor on the Arduino's GND and RESET pins to prevent reseting on new serial connections as mentioned at PHP serial port data return from Arduino.
So now, I have my Arduino sending data to my computer via the USB cable, and so long as I am monitoring the data in Arduino's serial monitor, everything looks as it should. The moment I echo out that same data in PHP I begin to see extra or missing data along with the stream. So sending the text "AOK AOK AOK" sometimes becomes "OK?Pz[R" or something similar when echoed out of my PHP script.
Things I've tried to get clean serial data from PHP socket_read():
Messed around with various mb_convert_encoding (like 'ASCII' or 'utf-8')
Setting parity of serial data. I tried setting it to "EVEN" in serproxy config and DOS (ran command of "mode COM4: BAUD=9600 PARITY=E data=8 stop=1 XON=off TO=on" and recieved a valid response/output that command worked as expected)
Verified baud rate is set to 9600 in PHP code and serproxy config
Attempted simple trimming and/or regular expressions to filter out noise, but it doesn't help as some normal alphanumeric characters are randomly mixed in the output as well
Having modified some example socket code for TCP/IP from php.net, I have a PHP script that writes 2048 bits of data from the serial port via serproxy. This page is called via jQuery from another page every 10th of a second and the echoed content is loaded into the contents of a on my main page.
My end goal is to send a stream of either 1's or 0's to be sent to my PHP script to indicate that a should toggle it's background color. I would prefer to be certain those 1's or 0's were not just randomly echoed among the extra characters and truly came from the serial stream itself.
Does anyone know if serproxy is the cause of the adding or removing the unwanted data that I'm seeing in PHP?
The fact that the serial monitor is showing the correct data indicates to me that it's something in the way PHP is receiving or parsing the data.
I'm running out of ideas on what else I could check. Maybe another pair of eyes on this will bring to light something I've overlooked or did incorrectly.
Please see my code below for specific examples below:
serial.html
<!DOCTYPE html>
<head>
</head>
<body>
<div id="serial" name="serial" class="serial"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
serial_output.php
<?php
// Set service port to 5334 for serproxy
$service_port = 5334;
// Using localhost address
$address = '127.0.0.1';
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}
// Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
}
// Read 2048 bits of data from socket and convert encoding to ASCII
$out = mb_convert_encoding(socket_read($socket, 2048), 'ASCII');
// Filter out anything that is not "AOK"
if(preg_match("/AOK/", $out)){
echo 1;
} else {
// Else output raw data so we can see what was actaully sent
echo $out;
}
// Closing socket...
socket_close($socket);
?>
main.js
// Set #serial background color to red when receiving a "1"
function setBgColor(){
var serial = $('#serial');
// Set #serial background color to red when receiving a "1"
if($('#serial').html() == "1") {
serial.css('background-color','red');
} else {
// Set #serial background to white if we did not receive a "1"
serial.css('background-color', 'white');
}
}
var intervalId = window.setInterval(function(){
$('#serial').load('serial_output.php');
setBgColor();
}, 100);
arduino_serial.ino
#include <avr/pgmspace.h>
void setup() {
// Initialize serial and wait for port to open:
// Currently I have parity on my serial port set to "EVEN" hence SERIAL_8E1
Serial.begin(9600, SERIAL_8E1);
}
void loop() {
Serial.println("AOK");
}