如何使Arduino运行脚本 [英] How to make Arduino run a script

查看:99
本文介绍了如何使Arduino运行脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我已经看过一些有关如何使用按钮和LED的教程
我在这里感兴趣的主要事情是如何从Arduino到Mac进行通信,反之亦然.尤其是如何使其在Mac上运行脚本.

解决方案

您应该查看序列类和示例(通过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的条件下在LOWHIGH值中查找.

在交流方面,有一些关键要素:

Serial.begin(9600);

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

Serial.write();

将数据发送到端口.

serialEvent()

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

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

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

serialEvent(),serialEvent1()``serialEvent2()和serialEvent3()在Arduino Due上不起作用.

在脚本方面,您没有提到该语言,但是原理是相同的:您需要知道端口名称和波特率才能通过Mac建立通信.

(您可以在loop()中手动调用serialEvent()作为解决方法.有关更多详细信息,请参见与软件接口,以找到有关您的脚本语言的指南选择

更新

这是一个使用处理的快速示例,它使用

此外,请记住 launch()返回 解决方案

You should look into the Serial class and the examples (via File > Examples > Commmunication)

You will need to write a bit of code on the Arduino side to send data via Serial when the button is pressed (so you can trigger your script) and receive data (when the script is done) to control the LED.

Here is a rough example on the Arduino side:

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);
  }
}

Be aware you may have different pin numbers in your setup and depending on how the button wired, you will either look for a LOW or HIGH value in the in the condition checking the currentButtonState.

In terms of the communication there are a few key elements:

Serial.begin(9600);

Starts Serial communication with baud rate 9600. You will need to match this baud rate on the other end to ensure correct communication.

Serial.write();

Will send data to the port.

serialEvent()

is predefined in Arduino and gets called when new Serial data arrives. Note that this gets called automatically on a Arduino Uno (and other simpler boards), however this doesn't get called on other boards:

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.

On the script side, you haven't mentioned the language, but the principle is the same: you need to know the port name and baud rate to establish communication from your mac.

(You can manually call serialEvent() in loop() as a workaround. For more details see the Arduino Reference)

The port is what you used to upload the Arduino code (something like /dev/tty.usbmodem####) and in this particular case the baud rate is 9600. You should be able to test using Serial Monitor in the Arduino IDE.

Your script will be something along there lines (pseudo code)

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

Be sure to checkout the Interfacing with Software to find guide on the scripting language of your choice

Update

Here's a quick example using Processing to interface with the arduino using it's Serial library. So on the Arduino side, here's a minimal sketch:

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);
  }
}

and on the Processing side:

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)
} 

Hope this is a helpful proof of concept. Feel free to use any other language with a serial library available instead of Processing. The syntax may differ just a tad (probably more on the running of the process/command), but the concept is the same.

Update The example above can be simplified a touch by not having the command on the Arduino side:

  • there's less data sent on Serial from Arduino to Processing reducing communication time and the odds of communication interference
  • the app runs on a computer hence changing the command is simpler to do on software side as opposed to having to change the Arduino code and re-upload each time.

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);
  }
}

Processing:

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)
  }
} 

(btw, 'R' is an arbitrary single character, can be something else as long it's the same char on both Serial send and receive sides)

Also, bare in mind launch() returns Proccess which can be useful to get more information from the software launched.

这篇关于如何使Arduino运行脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆