KenHorse Posted October 17, 2021 Share Posted October 17, 2021 (edited) I have a script that is called from crontab. : 0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/bin/php /var/www/settime.php I checked back later and notice many instances of php running: root@mypi:~# ps aux |grep settime root 1646 0.0 0.0 1856 380 ? Ss 10:20 0:00 /bin/sh -c /usr/bin/php /var/www/settime.php root 1647 0.0 2.0 75676 19860 ? S 10:20 0:00 /usr/bin/php /var/www/settime.php root 1777 0.0 0.0 1856 352 ? Ss 10:25 0:00 /bin/sh -c /usr/bin/php /var/www/settime.php root 1778 0.0 2.0 75676 19604 ? S 10:25 0:00 /usr/bin/php /var/www/settime.php root 1898 0.0 0.0 1856 340 ? Ss 10:30 0:00 /bin/sh -c /usr/bin/php /var/www/settime.php root 1899 0.1 2.0 75676 19672 ? S 10:30 0:00 /usr/bin/php /var/www/settime.php root 1943 0.0 0.0 4396 544 pts/0 S+ 10:31 0:00 grep settime settime.php is a script that sets an external clock via /dev/ttyUSB0 Obviously I'm doing something wrong as it should run and stop Edited October 17, 2021 by KenHorse Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/ Share on other sites More sharing options...
gw1500se Posted October 17, 2021 Share Posted October 17, 2021 First your crontab is the long way around the barn. Use: */5 * * * * /usr/bin/php /var/www/settime.php Not sure why /bin/sh is involved base on what you've shown. What distro are you running? Since your didn't show the script how do you expect any help? Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591158 Share on other sites More sharing options...
KenHorse Posted October 17, 2021 Author Share Posted October 17, 2021 (edited) This is running Raspian Buster (Debian 10). Sorry, I didn't think the script itself was an issue but here it is: <?php include("global.php"); $senddata = "SetClock" . date("His"); $serial = serial("$senddata"); echo $serial; sleep(1); $senddata = "SetCalendar" . date("mdy"); $serial = serial("$senddata"); echo $serial; exit() //<----recently added to try to force close but no difference ?> In global.php are my serial functions function serial($cmd){ $port = "/dev/ttyUSB0"; $c = exec('stty -F '.$port.' cs8 -parenb -cstopb -echo raw speed 57600'); if(!file_exists($port)) { echo "I am not blocked!"; } else { $f = fopen($port, "w+"); fwrite($f, $cmd."\r"); while(1) { $dataOut = fgets($f); if(strlen($dataOut) > 5) { // echo $dataOut; fclose($f); break; } else { fwrite($f, $cmd."\r"); } } } return $dataOut; } Edited October 17, 2021 by KenHorse Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591159 Share on other sites More sharing options...
kicken Posted October 17, 2021 Share Posted October 17, 2021 Your script is probably getting stuck here: $dataOut = fgets($f); It's waiting for data from your serial device but the device isn't sending any data so the script just hangs there waiting indefinitely. You'll have to add some debug logging or something to figure out why or if that's actually the case. You could also try implementing non-blocking IO and a timeout. 1 Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591160 Share on other sites More sharing options...
KenHorse Posted October 17, 2021 Author Share Posted October 17, 2021 Thanks, I will give it a try Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591161 Share on other sites More sharing options...
gw1500se Posted October 18, 2021 Share Posted October 18, 2021 I've worked with Raspian quite a bit and using serial devices on it can be tricky. Kicken is exactly right. Also depending on the serial device you are using you may need to install specific drivers. This is especially true if you are using a one-wire device over USB. Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591172 Share on other sites More sharing options...
KenHorse Posted October 18, 2021 Author Share Posted October 18, 2021 I've had good luck using FTDI based converters with Raspbian. I've done a few searches about actually using stream_set_blocking function but not having any luck. As I've never worked with it before, are there some examples of its implementation (as in actual code examples)? Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591173 Share on other sites More sharing options...
gw1500se Posted October 18, 2021 Share Posted October 18, 2021 What type interface device are you using? Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591174 Share on other sites More sharing options...
KenHorse Posted October 18, 2021 Author Share Posted October 18, 2021 USB > serial? https://www.amazon.com/Sabrent-Serial-Adapter-Chipset-CB-FTDI/dp/B006AA04K0/ref=sxts_sxwds-bia-wc-drs1_0?cv_ct_cx=usb+ftdi&dchild=1&keywords=usb+ftdi&pd_rd_i=B006AA04K0&pd_rd_r=ddec056b-609e-486c-b2d8-d38beba84201&pd_rd_w=0Ev9e&pd_rd_wg=sCNyr&pf_rd_p=ecbfa24d-f48c-4d5c-83aa-9549f4e7c925&pf_rd_r=ENNAVCF3SFBC582P3EJE&psc=1&qid=1602268074&sr=1-1-f6b8d51f-2c55-4dc3-89ad-0c3639671b2d Works very well with minicom Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591175 Share on other sites More sharing options...
kicken Posted October 18, 2021 Share Posted October 18, 2021 Have you tried using a library instead of diy? I haven't done much work with serial devices and PHP but I do have stuff I could setup and try to generate an example. If I have time later tonight and you haven't resolved the issue already maybe I will dig it out and give it a try. Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591176 Share on other sites More sharing options...
gw1500se Posted October 18, 2021 Share Posted October 18, 2021 This is probably really a raspbian issue so you may want to try the raspberry forum. However, what do you get when you run this script? for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do ( syspath="${sysdevpath%/dev}" devname="$(udevadm info -q name -p $syspath)" [[ "$devname" == "bus/"* ]] && exit eval "$(udevadm info -q property --export -p $syspath)" [[ -z "$ID_SERIAL" ]] && exit echo "/dev/$devname - $ID_SERIAL" ) done Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591177 Share on other sites More sharing options...
KenHorse Posted October 18, 2021 Author Share Posted October 18, 2021 2 hours ago, gw1500se said: This is probably really a raspbian issue so you may want to try the raspberry forum. However, what do you get when you run this script? for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do ( syspath="${sysdevpath%/dev}" devname="$(udevadm info -q name -p $syspath)" [[ "$devname" == "bus/"* ]] && exit eval "$(udevadm info -q property --export -p $syspath)" [[ -z "$ID_SERIAL" ]] && exit echo "/dev/$devname - $ID_SERIAL" ) done /dev/snd/controlC1 - C-Media_Electronics_Inc._USB_PnP_Sound_Device /dev/ttyUSB0 - FTDI_FT232R_USB_UART_AH05WJ52 Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591184 Share on other sites More sharing options...
KenHorse Posted October 18, 2021 Author Share Posted October 18, 2021 (edited) As I said, this converter works just fine with minicom By the way, what prompted me to use this code for serial comm was that I tried using php_serial.class.php (which now appears to be https://packagist.org/packages/hyperthese/php-serial) but it never seemed to work right. I was unaware of the others listed at packagist so perhaps I should give THEM a try.... Edited October 18, 2021 by KenHorse Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591185 Share on other sites More sharing options...
kicken Posted October 18, 2021 Share Posted October 18, 2021 This code worked for me using a VM with ubuntu on it. When reading the results after sending the command it will hang for at least as long as the timeout period before returning results since there's no way to determine when the serial device is done sending data otherwise. <?php $cmd = implode(' ', array_slice($argv, 1)); $device = serialSetup('/dev/ttyS0', 115200, 8); var_dump(serial($device, $cmd ?: 'uname -a')); fclose($device); function serialSetup($device, $baud, $data){ $cmd = sprintf('stty -F %s %d cs%d -echo raw', $device, $baud, $data); exec($cmd, $output, $ret); if ($ret !== 0){ var_dump($output); throw new \RuntimeException('Unable to configure serial device'); } $f = fopen($device, "w+"); if (!$f){ throw new \RuntimeException('Unable to open serial device.'); } stream_set_blocking($f, false); return $f; } function serial($device, $cmd){ fwrite($device, $cmd . "\n"); $result = ''; do { try { $result .= serialRead($device, 5); $timeout = false; } catch (RuntimeException $ex){ $timeout = true; } } while (!$timeout); return $result; } function serialRead($device, $timeout = 30){ $r = [$device]; $w = $e = []; $n = stream_select($r, $w, $e, $timeout, 0); if ($n === 1){ $line = fgets($device) ?: ''; if ($line !== ''){ return $line; } } throw new \RuntimeException('Timeout reading from serial device'); } For the curious, this also sort of works on windows. The timeout cannot be controlled on windows, so you're stuck with the default (around 120 seconds). The stty call needs to be replaced with the following call to mode and of course use the appropriate device name (ie, COM1). The important bit seems to be the to=on parameter in the call to mode, without it windows seems to never timeout on a read and the script would hang indefinitely. $cmd = sprintf('mode %s BAUD=%d PARITY=n DATA=%d to=on', $device, $baud, $data); Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591188 Share on other sites More sharing options...
KenHorse Posted October 19, 2021 Author Share Posted October 19, 2021 (edited) Thanks, I'll give it a try Edited October 19, 2021 by KenHorse Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591202 Share on other sites More sharing options...
KenHorse Posted October 20, 2021 Author Share Posted October 20, 2021 (edited) On 10/18/2021 at 2:58 PM, kicken said: This code worked for me using a VM with ubuntu on it. When reading the results after sending the command it will hang for at least as long as the timeout period before returning results since there's no way to determine when the serial device is done sending data otherwise. <?php $cmd = implode(' ', array_slice($argv, 1)); $device = serialSetup('/dev/ttyS0', 115200, 8); var_dump(serial($device, $cmd ?: 'uname -a')); fclose($device); function serialSetup($device, $baud, $data){ $cmd = sprintf('stty -F %s %d cs%d -echo raw', $device, $baud, $data); exec($cmd, $output, $ret); if ($ret !== 0){ var_dump($output); throw new \RuntimeException('Unable to configure serial device'); } $f = fopen($device, "w+"); if (!$f){ throw new \RuntimeException('Unable to open serial device.'); } stream_set_blocking($f, false); return $f; } function serial($device, $cmd){ fwrite($device, $cmd . "\n"); $result = ''; do { try { $result .= serialRead($device, 5); $timeout = false; } catch (RuntimeException $ex){ $timeout = true; } } while (!$timeout); return $result; } function serialRead($device, $timeout = 30){ $r = [$device]; $w = $e = []; $n = stream_select($r, $w, $e, $timeout, 0); if ($n === 1){ $line = fgets($device) ?: ''; if ($line !== ''){ return $line; } } throw new \RuntimeException('Timeout reading from serial device'); } For the curious, this also sort of works on windows. The timeout cannot be controlled on windows, so you're stuck with the default (around 120 seconds). The stty call needs to be replaced with the following call to mode and of course use the appropriate device name (ie, COM1). The important bit seems to be the to=on parameter in the call to mode, without it windows seems to never timeout on a read and the script would hang indefinitely. $cmd = sprintf('mode %s BAUD=%d PARITY=n DATA=%d to=on', $device, $baud, $data); I changed to /dev/ttyUSB0 and baud rate of 57600 to match my needs. I should receive "+1111" back from the external device. Script is named test root@mypi:~# php test 11111 string(0) "" root@mypi:~# Edited October 20, 2021 by KenHorse Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591247 Share on other sites More sharing options...
gw1500se Posted October 20, 2021 Share Posted October 20, 2021 Not sure how you are reading the data since you didn't post the script but I suspect it is coming back in byte format. If that is the case you need to convert it. Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591248 Share on other sites More sharing options...
KenHorse Posted October 20, 2021 Author Share Posted October 20, 2021 Kicken's script (above). I even quoted it Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591249 Share on other sites More sharing options...
kicken Posted October 20, 2021 Share Posted October 20, 2021 I change the fwrite you had to be followed by "\n" instead of "\r", did you try changing that back? If that doesn't help, you'll have to do some debugging locally and try to figure it out. Works ok for me with my ardiuno loaded with a quick test program to read the analog pins. kicken@ubuntu-dev:/Workspace/serial$ php serial_linux.php read_a0 string(32) "readLength=7 cmd=read_a0 793 " Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591262 Share on other sites More sharing options...
KenHorse Posted October 20, 2021 Author Share Posted October 20, 2021 I didn't catch that change, no. As my device looks specifically for a CR (/r), that might be the issue. I'll give it a shot Quote Link to comment https://forums.phpfreaks.com/topic/314028-calling-a-php-script-from-cron/#findComment-1591263 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.