0

現在、cronジョブを使用して、arduinoにアクアポニックスシステムを循環させるperlスクリプトを作成していますが、perlスクリプトが意図したとおりに動作しないことを除いて、すべて問題ありませんdie

これが私のcronジョブです:

*/15 * * * * /home/dburke/scripts/hal/bin/main.pl cycle

以下は私のperlスクリプトです:

#!/usr/bin/perl -w
# Sample Perl script to transmit number
# to Arduino then listen for the Arduino
# to echo it back

use strict;
use Device::SerialPort;
use Switch;
use Time::HiRes qw ( alarm );
$|++;
# Set up the serial port
# 19200, 81N on the USB ftdi driver
my $device = '/dev/arduino0';
# Tomoc has to use a different tty for testing
#$device = '/dev/ttyS0';

my $port = new Device::SerialPort ($device)
    or die('Unable to open connection to device');;
$port->databits(8);
$port->baudrate(19200);
$port->parity("none");
$port->stopbits(1);

my $lastChoice = ' ';
my $signalOut;
my $args = shift(@ARGV);
# Parent must wait for child to exit before exiting itself on CTRL+C
if ($args eq "cycle") {
                open (LOG, '>>log.txt');
                print LOG "Cycle started.\n";
                my $stop = 0;
                sleep(2);
                $SIG{ALRM} = sub {
                        print "Expecting plant bed to be full; please check.\n";
                        $signalOut = $port->write('2'); # Signal to set pin 3 low
                        print "Sent cmd: 2\n";
                        $stop = 1;
                };
                $signalOut = $port->write('1'); # Signal to arduino to set pin 3 High
                print "Sent cmd: 1\n";
                print "Waiting for plant bed to fill...\n";
                print LOG "Alarm is being set.\n";
                alarm (420);
                print LOG "Alarm is set.\n";
                while ($stop == 0) {
                        print LOG "In while-sleep loop.\n";
                        sleep(2);
                }
                print LOG "The loop has been escaped.\n";
                die "Done.";
                print LOG "No one should ever see this.";
    }
    else {
        my $pid = fork();
        $SIG{'INT'} = sub {
            waitpid($pid,0) if $pid != 0; exit(0);
        };

        # What child process should do
        if($pid == 0) {
            # Poll to see if any data is coming in
            print "\nListening...\n\n";
            while (1) {
                my $incmsg = $port->lookfor(9);
                # If we get data, then print it
                if ($incmsg) {
                    print "\nFrom arduino: " . $incmsg . "\n\n";
                }
            }
        }
        # What parent process should do
        else {
                    sleep(1);
                    my $choice = ' ';
                    print "Please pick an option you'd like to use:\n";
                    while(1) {
                        print " [1] Cycle  [2] Relay OFF  [3] Relay ON  [4] Config  [$lastChoice]: ";
                        chomp($choice = <STDIN>);
                        switch ($choice) {
                                case /1/ {
                                        $SIG{ALRM} = sub {
                                                        print "Expecting plant bed to be full; please check.\n";
                                                        $signalOut = $port->write('2'); # Signal to set pin 3 low
                                                        print "Sent cmd: 2\n";
                                                        };
                                        $signalOut = $port->write('1'); # Signal to arduino to set pin 3 High
                                        print "Sent cmd: 1\n";
                                        print "Waiting for plant bed to fill...\n";
                                        alarm (420);
                                        $lastChoice = $choice;
                                }
                                case /2/ {
                                        $signalOut = $port->write('2'); # Signal to set pin 3 low       
                                        print "Sent cmd: 2";
                                        $lastChoice = $choice;
                                }
                                case /3/ {
                                        $signalOut = $port->write('1'); # Signal to arduino to set pin 3 High
                                        print "Sent cmd: 1";
                                        $lastChoice = $choice;
                                }
                                case /4/ {
                                        print "There is no configuration available yet. Please stab the developer.";
                                }
                            else        { print "Please select a valid option.\n\n";}
                        }
                   }
           }
}

実行するps -efと、次の出力が見つかります。

dburke   15294 15293  0 14:30 ?        00:00:00 /bin/sh -c /home/dburke/scripts/hal/bin/main.pl cycle
dburke   15295 15294  0 14:30 ?        00:00:00 /usr/bin/perl -w /home/dburke/scripts/hal/bin/main.pl cycle

プロセスは 1 つだけであるべきではありませんか? サイクル引数を受け取り、フォークがサイクル引数のifブロックの外にあるにもかかわらず、フォークしていますか?

ステートメントで死なない理由はありdie "Done.";ますか?コマンド ラインから正常に実行され、'cycle' 引数が正常に解釈されます。cron で実行すると正常に実行されますが、プロセスが停止することはなく、各プロセスがシステムを循環し続けていない間、システムの負荷が非常に速く上昇するため、何らかの形でループしているように見えます。

さらに詳しい情報が必要な場合は、お尋ねください。みんなありがとう!

4

1 に答える 1

0

問題は、私のスクリプトが元々cycleブロックを の中にカプセル化してforkいて、何らかの理由で、私には知られていないプロセスを開いたままにしていたことだと思われます (おそらく子?)。フォークcycleからブロックを取り出すと、問題が修正されました。これで、指定された時間に実行され、サイクルが完了した後に正しく終了し、より便利なもののために CPU 負荷が残ります。:)

私の質問にコメントしてくださった皆様、ありがとうございます。あなたの提案は、私が問題を解決するのに役立ちました。

于 2012-09-28T21:56:55.407 に答える