如何让Arduino运行脚本

如何让Arduino运行脚本,arduino,Arduino,我是一名软件开发人员,但我对Arduino和电子行业都是新手。 我想建立一个简单的项目,结合两者,并真的感谢任何帮助从哪里开始 最后一个项目应该是Arduino,带有一个按钮和一个LED,当点击按钮时,我想在我的mac上运行一个脚本,然后如果脚本成功完成,我想打开LED 我已经看过一些关于如何使用按钮和LED的教程,所以 这里我感兴趣的主要事情是如何从Arduino到mac进行通信,反之亦然。特别是如何让它在我的mac电脑上运行脚本。不知道它是否会像我一样帮助你,但这个问题展示了一个简单的例子,

我是一名软件开发人员,但我对Arduino和电子行业都是新手。
我想建立一个简单的项目,结合两者,并真的感谢任何帮助从哪里开始

最后一个项目应该是Arduino,带有一个按钮和一个LED,当点击按钮时,我想在我的mac上运行一个脚本,然后如果脚本成功完成,我想打开LED

我已经看过一些关于如何使用按钮和LED的教程,所以

这里我感兴趣的主要事情是如何从Arduino到mac进行通信,反之亦然。特别是如何让它在我的mac电脑上运行脚本。

不知道它是否会像我一样帮助你,但这个问题展示了一个简单的例子,说明如何在android应用程序中通过简单的按钮使用脚本

希望对您有所帮助

您应该查看和示例(通过
文件>示例>通信

您需要在Arduino端编写一些代码,以便在按下按钮时通过串行发送数据(以便触发脚本)和接收数据(脚本完成时)来控制LED

以下是Arduino方面的一个粗略示例:

const int btnPin = 12;//button pin
const int ledPin = 13;

int lastButtonState;

void setup(){ 
  //setup pins
  pinMode(btnPin,INPUT_PULLUP);
  pinMode(ledPin,OUTPUT);
  //setup communication
  Serial.begin(9600);
}

void loop() {
  int currentButtonState = digitalRead(btnPin);//read button state
  if(lastButtonState != currentButtonState && currentButtonState == LOW){//if the state of the pin changed
    Serial.write(currentButtonState);//send the data
    lastButtonState = currentButtonState;//update the last button state
    //turn on LED
    digitalWrite(ledPin,HIGH);
  }
}
void serialEvent(){//if any data was sent
  if(Serial.available() > 0){//and there's at least 1 byte to look at
    int data = Serial.read();//read the data
    //do something with it if you want
    //turn off the LED
    digitalWrite(ledPin,LOW);
  }
}
请注意,您的设置中可能有不同的pin码,并且根据按钮的接线方式,您将在检查
currentButtonState
的条件中查找
LOW
HIGH

就沟通而言,有几个关键要素:

Serial.begin(9600);
以波特率9600开始串行通信。您需要在另一端匹配此波特率,以确保正确通信

Serial.write()

将向端口发送数据

serialEvent()
在Arduino中预定义,并在新串行数据到达时调用。 注意这会在Arduino Uno(和其他较简单的板)上自动调用,但不会在其他板上调用:

serialEvent()在Leonardo、Micro或Yún上不起作用

serialEvent()和serialEvent1()在Arduino SAMD板上不起作用

serialEvent()、serialEvent1()``serialEvent2()和serialEvent3()在Arduino到期日上不起作用

在脚本方面,您没有提到语言,但原理是一样的:您需要知道端口名和波特率,才能从mac建立通信

(您可以在
loop()
中手动调用
serialEvent()
,作为解决方法。有关更多详细信息,请参阅)

该端口是用于上载Arduino代码的端口(类似于
/dev/tty.usbmodem####
),在这种情况下,波特率为9600。您应该能够在ArduinoIDE中使用串行监视器进行测试

您的脚本将是大致相同的(伪代码)

请务必查看所选脚本语言的“查找指南”

更新

下面是一个使用它的。在Arduino这边,这里有一个简单的草图:

const int btnPin = 12;//button pin
const int ledPin = 13;

boolean wasPressed;

char cmd[] = "/Applications/TextEdit.app\n";

void setup(){ 
  //setup pins
  pinMode(btnPin,INPUT_PULLUP);
  pinMode(ledPin,OUTPUT);
  //setup communication
  Serial.begin(9600);
}

void loop() {
  int currentButtonState = digitalRead(btnPin);//read button state
  if(!wasPressed && currentButtonState == LOW){//if the state of the pin changed
    Serial.write(cmd);//send the data
    wasPressed = true;//update the last button state
    //turn on LED
    digitalWrite(ledPin,HIGH);
  }
  if(currentButtonState == HIGH) wasPressed = false;
}
void serialEvent(){//if any data was sent
  if(Serial.available() > 0){//and there's at least 1 byte to look at
    int data = Serial.read();//read the data
    //do something with it if you want
    //turn off the LED
    digitalWrite(ledPin,LOW);
  }
}
在处理方面:

import processing.serial.*;

void setup(){
  try{
    Serial arduino = new Serial(this,"/dev/tty.usbmodemfa141",9600);
    arduino.bufferUntil('\n');//buffer until a new line is encountered
  }catch(Exception e){
    System.err.println("Error opening serial connection! (check cables and port/baud settings!");
    e.printStackTrace();
  }
}
void draw(){}
void serialEvent(Serial s){
  String[] command = s.readString().trim().split(",");//trim spaces, split to String[] for args
  println(command);//see what we got
  open(command);//run the command
  s.write("A");//send a message back to flag that the command is finished (turn LED off)
} 
希望这是一个有用的概念证明。可以使用任何其他语言,使用串行库代替处理。语法可能略有不同(可能更多地取决于进程/命令的运行),但概念是相同的

更新通过在Arduino侧不使用命令,可以简化上述示例:

const int btnPin = 12;//button pin
const int ledPin = 13;

int lastButtonState;

void setup(){ 
  //setup pins
  pinMode(btnPin,INPUT_PULLUP);
  pinMode(ledPin,OUTPUT);
  //setup communication
  Serial.begin(9600);
}

void loop() {
  int currentButtonState = digitalRead(btnPin);//read button state
  if(lastButtonState != currentButtonState && currentButtonState == LOW){//if the state of the pin changed
    Serial.write(currentButtonState);//send the data
    lastButtonState = currentButtonState;//update the last button state
    //turn on LED
    digitalWrite(ledPin,HIGH);
  }
}
void serialEvent(){//if any data was sent
  if(Serial.available() > 0){//and there's at least 1 byte to look at
    int data = Serial.read();//read the data
    //do something with it if you want
    //turn off the LED
    digitalWrite(ledPin,LOW);
  }
}
  • 从Arduino到处理的串行数据较少,减少了通信时间和通信干扰的几率
  • 该应用程序在计算机上运行,因此在软件方面更改命令比每次更改Arduino代码并重新上传更简单
阿杜伊诺:

const int btnPin = 12;//button pin
const int ledPin = 13;

boolean wasPressed;

void setup(){ 
  //setup pins
  pinMode(btnPin,INPUT_PULLUP);
  pinMode(ledPin,OUTPUT);
  //setup communication
  Serial.begin(9600);
}

void loop() {
  int currentButtonState = digitalRead(btnPin);//read button state
  if(!wasPressed && currentButtonState == LOW){//if the state of the pin changed
    Serial.write('R');//send the data
    wasPressed = true;//update the last button state
    //turn on LED
    digitalWrite(ledPin,HIGH);
  }
  if(currentButtonState == HIGH) wasPressed = false;
}
void serialEvent(){//if any data was sent
  if(Serial.available() > 0){//and there's at least 1 byte to look at
    int data = Serial.read();//read the data
    //do something with it if you want
    //turn off the LED
    digitalWrite(ledPin,LOW);
  }
}
处理:

import processing.serial.*;

String[] command = {"/Applications/TextEdit.app", "myText.txt"};

void setup() {
  try {
    Serial arduino = new Serial(this, "/dev/tty.usbmodemfa141", 9600);
  }
  catch(Exception e) {
    System.err.println("Error opening serial connection! (check cables and port/baud settings!");
    e.printStackTrace();
  }
}

void draw() {
}

void serialEvent(Serial s) {
  if (s.read() == 'R') {
    launch(command);//run the command
    s.write("A");//send a message back to flag that the command is finished (turn LED off)
  }
} 
(顺便说一句,“R”是任意的单个字符,只要在串行发送和接收端都是相同的字符,就可以是其他字符)


另外,头脑简单的返回对于从发布的软件中获取更多信息非常有用。

我在Linux中找到了一个解决方法。虽然有点凌乱,但效果不错。我使用Coolterm将arduino的串行输出捕获到一个文本文件中,并编写了一个小python脚本来读取该文件(或者,在我的例子中,如果文件不是空的,则执行我想要的命令)。

感谢您的解释!关于脚本,我如何让Arduino运行它?在您的示例中,脚本已经在运行并轮询Arduino以获取新数据,就像某种侦听器应用程序一样。为什么要从Arduino显式运行脚本?就像您从终端运行“/myscript.sh”(作为一个附带问题,您可以直接从Arduino代码运行linux终端命令吗?)。我已经更新了关于触发Arduino命令的答案。如果您需要的命令可以运行小型Linux系统(400MHz CPU,64MB RAM),那么可以使用提供进程和控制台类以轻松处理.sh脚本的。如果答案有用,请随意标记并投票;)