【问题标题】:Java Run Shell Command on Raspberry PiRaspberry Pi 上的 Java 运行 Shell 命令
【发布时间】:2014-10-30 06:22:56
【问题描述】:

我正在尝试在Raspberry Pi 上使用GPIO pins。目前我正在使用ProcessBuilder 来执行命令。但是,每当我运行它时,它总是说:

Exception in thread "main" java.io.IOException: Cannot run program "echo 18 > /sys/class/gpio/export": error=2, No such file or directory
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1041)
        at Testing.initiate(Testing.java:32)
        at Testing.main(Testing.java:8)
Caused by: java.io.IOException: error=2, No such file or directory
        at java.lang.UNIXProcess.forkAndExec(Native Method)
        at java.lang.UNIXProcess.<init>(UNIXProcess.java:135)
        at java.lang.ProcessImpl.start(ProcessImpl.java:130)
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1022)
        ... 2 more

这是我正在使用的代码:

    ProcessBuilder pb = new ProcessBuilder("echo " + gpiopin + " > /sys/class/gpio/export");
    ProcessBuilder pb1 = new ProcessBuilder("echo out > /sys/class/gpio/gpio" + gpiopin + "/direction");
    ProcessBuilder pb2 = new ProcessBuilder("echo 1 > /sys/class/gpio/gpio" + gpiopin + "/value");
    pb.redirectErrorStream(true);
    pb1.redirectErrorStream(true);
    pb2.redirectErrorStream(true);
    Process ps = pb.start();
    Process ps1 = pb1.start();
    Process ps2 = pb2.start();

为什么会这样?另外,如果有更好的方法如何做到这一点?

谢谢

编辑:似乎没有更多错误,但命令没有运行。有人可以看看我的代码以确保我没有愚蠢吗?

import java.util.Scanner;


public class Testing {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        initiate(18);

        while(true) {
            String input = scan.nextLine();

            if(input.equals("on")) {
                System.out.println("on");
                bellOn();
            }else if(input.equals("off")) {
                System.out.println("off");
                bellOff();
            }
        }
    }

    static int gpio = 18;
    static String gp = "" + gpio;
    static boolean initiated = false;

    public static boolean initiate(int gpiopin) throws Exception {
        gpio = gpiopin;
        ProcessBuilder pb = new ProcessBuilder("echo", gp, ">", "/sys/class/gpio/export");
        ProcessBuilder pb1 = new ProcessBuilder("echo", "out", ">", "/sys/class/gpio/gpio" + gp + "/direction");
        //ProcessBuilder pb2 = new ProcessBuilder("echo", "1", ">", "/sys/class/gpio/gpio" + gpiopin + "/value");
        pb.redirectErrorStream(true);
        pb1.redirectErrorStream(true);
        //pb2.redirectErrorStream(true);
        Process ps = pb.start();
        Process ps1 = pb1.start();
        //Process ps2 = pb2.start();
        initiated = true;
        return true;
    }

    public static boolean bellOn() throws Exception {
        if(initiated != true) {
            return false;
        }else{
            ProcessBuilder pb = new ProcessBuilder("echo", "0", ">", "/sys/class/gpio/gpio" + gp + "/value");
            pb.redirectErrorStream(true);
            Process ps = pb.start();
            return true;
        }
    }

    public static boolean bellOff() throws Exception {
        if(initiated != true) {
            return false;
        }else{
            ProcessBuilder pb = new ProcessBuilder("echo", "1", ">", "/sys/class/gpio/gpio" + gp + "/value");
            pb.redirectErrorStream(true);
            Process ps = pb.start();
            return true;
        }
    }
}

【问题讨论】:

  • 在这里找到了一些东西,也许它可以帮助你? stackoverflow.com/questions/10735415/…
  • 似乎没有更多错误,但我认为我在命令中做错了什么。
  • 你应该做类似... new ProcessBuilder("echo " + gpiopin, "&gt;", "/sys/class/...");的事情,我想。
  • 我刚刚在我的主帖中添加了更多代码 - 请看一下
  • 我在 C++ 中执行此操作,但我只是将 /sys/class/gpio 作为文件打开。你不能在Java中做到这一点吗?这样可以省去 ProcessBuilder 的所有麻烦..

标签: java raspberry-pi gpio


【解决方案1】:

这个问题很老,但这是我如何使用WiringPi 库让我的引脚工作。

参考this问题。

下面的代码在 SSH shell 中运行时有效,但在设备重启后无效,重启后作为 cronjob 运行。

public static String cmdCommands()
{
    try 
    {
        //blink LED; works in shell only
        Runtime r = Runtime.getRuntime();
        r.exec("gpio mode 4 out");
        r.exec("gpio write 4 1");
        Thread.sleep(500);
        r.exec("gpio write 4 0");
        Thread.sleep(500);
        return "done";          
    }
    catch(Exception e) 
    {
        return "Exception: " + e.getMessage();
    }
}

为了解决这个问题,我必须使用String[] 并构建命令。在努力寻找修复后非常容易

此处的工作代码示例:

public static String cmdCommands()
{
    try 
    {
        //blink LED
        Runtime r = Runtime.getRuntime();
        r.exec(new String[] {"sudo", "gpio", "mode", "4", "out"});
        r.exec(new String[] {"sudo", "gpio", "write", "4", "1"});
        Thread.sleep(500);
        r.exec(new String[] {"sudo", "gpio", "write", "4", "0"});
        return "done";          
    }
    catch(Exception e) 
    {
        return "Exception: " + e.getMessage();
    }
}

【讨论】:

    【解决方案2】:

    这是我在 C++ 中的做法,我很确定你可以翻译成 Java...

    void ResetCommand::execute() {
        // Perform a hardware reset on the Arduino using GPIO pins
        ofstream fd;
        char buf[255];
    
        cout << "Exporting GPIO Pin 8" << endl;
        fd.open("/sys/class/gpio/export", ios::out);
        fd << "8";
        fd.close();
    
        // Set out direction
        cout << "Setting as output" << endl;
        fd.open("/sys/class/gpio/gpio8/direction", ios::out);
        fd << "out";
        fd.close();
    
        // Blip the reset pin
        cout << "Resetting... " << endl;
        fd.open("/sys/class/gpio/gpio8/value", ios::out);
        fd << 0;
        usleep(1);
        fd << 1;
        fd.close();
    
        // Finished, so free up the pin
        cout << "Releasing " << endl;
        fd.open("/sys/class/gpio/unexport", ios::out);
        fd << "8";
        fd.close();
    }
    

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      相关资源
      最近更新 更多