如何制作 Arduino 运行 脚本

How to make Arduino run a script

我是一名软件开发人员,但我是 Arduino 和电子世界的新手。
我想构建一个将两者结合起来的简单项目,非常感谢从哪里开始的任何帮助。

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

我已经看过一些关于如何使用按钮和 LED 的教程,所以
我感兴趣的主要是 Arduino 与 mac 之间的通信方式,反之亦然。尤其是如何使它 运行 成为我 mac.

上的脚本

不知道它是否会像对我一样帮助你,但这个问题显示了一个简单的例子,说明如何在 android 应用程序

中使用带有简单按钮的脚本

Run script with android app

希望对您有所帮助

您应该查看 Serial class 和示例(通过 File > Examples > Commmunication

您需要在 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);
  }
}

请注意,您的设置中可能有不同的引脚号,并且根据按钮的接线方式,您将在条件检查 currentButtonState.

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

Serial.begin(9600);

以波特率 9600 开始串行通信。您需要在另一端匹配此波特率以确保正确通信。

Serial.write();

将向端口发送数据。

serialEvent()

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

serialEvent() doesn’t work on the Leonardo, Micro, or Yún.

serialEvent() and serialEvent1() don’t work on the Arduino SAMD Boards

serialEvent(), serialEvent1()``serialEvent2(), and serialEvent3() don’t work on the Arduino Due.

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

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

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

您的脚本将与此类似(伪代码)

open serial connection ( port name, baudrate = 9600 )
poll serial connection
   if there is data
      run the script you need
      script finished executing, therefore send data back via serial connection

请务必查看 Interfacing with Software 以找到有关您选择的脚本语言的指南

更新

这是一个使用 Processing to interface with the arduino using it's Serial library 的简单示例。所以在 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)
} 

希望这是一个有用的概念证明。随意使用任何其他具有可用串行库的语言而不是 Processing。语法可能略有不同(可能在 process/command 的 运行 上更多),但概念是相同的。

更新 上面的示例可以通过在 Arduino 端不使用命令来简化触摸:

  • 从 Arduino 发送到 Processing 的串行数据较少,减少了通信时间和通信干扰的几率
  • 该应用程序在计算机上运行,​​因此在软件方面更改命令更简单,而不是每次都必须更改 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' 是一个任意的单个字符,可以是其他字符,只要它在串行发送端和接收端都是相同的字符即可)

此外,请记住 launch() returns Proccess 这对于从已启动的软件中获取更多信息很有用。

我在 Linux 中找到了解决方法。它有点乱,但它有效。我使用 Coolterm 将 arduino 的串行输出捕获到一个文本文件,我写了一个小的 python 脚本来读取文件(或者简单地说,在我的例子中,如果文件不为空则执行我想要的命令) .