我成功地将一个整数从处理过程发送到Arduino,但现在我想发送一个由三个整数组成的数组,但我无法使其正常工作。我想使用Arduino创建蜂鸣器反馈,该处理将控制要激活的蜂鸣器。例如,从处理发送的数据应为[1,0,1],这意味着传感器1和3应该开始工作。如果[1,1,1]通过,蜂鸣器应该能够同时启动。
这是我到目前为止的代码: 我试图了解将什么数据发送回Arduino以了解如何使用它,而且我一直获取空值或随机整数。
我正在尝试学习如何做到这一点,如果代码不好,我对此表示歉意。
Arduino
void setup(){
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop(){
if (Serial.available()){
const char data = Serial.read();
char noteBuzzer[] = {data};
for (int i = 0 ; i < sizeof(noteBuzzer); i++) {
}
Serial.print(noteBuzzer[1]);
}
}
正在处理
import processing.serial.*;
String notes[];
String tempo[];
Serial myPort;
String val;
void setup(){
size(200,200);
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
notes = loadStrings("data/notes.txt");
tempo = loadStrings("data/tempo.txt");
}
void draw() {
if (keyPressed == true)
{
if (key == '1') {
println("Start");
readNotes();
}
}
}
void readNotes(){
for (int i = 0 ; i < notes.length; i++) {
println(notes[i]);
//println(tempo[i]);
myPort.write(notes[i]);
delay(int(tempo[i])); //this will be the tempo?
if ( myPort.available() > 0)
{
val = myPort.readStringUntil('\n');
println("Arduino",val);
}
}
}
答案 0 :(得分:0)
如果您的数据是一个总是的数组,且该数组始终包含3个项目,并且每个项目始终为1或0(位),则可以将整个数据存储在一个字节中(并且还有5位备用)。使用Arduino发送和接收字节非常简单。
下面是一个基本草图,向您展示了如何在单个字节中翻转3位:
// the state as a byte
byte buzzerState = 0B000;
void setup(){
textFont(createFont("Courier New",18),18);
}
void draw(){
background(0);
text("DEC: " + buzzerState +
"\nBIN:" + binary(buzzerState,3),10,40);
}
void keyPressed(){
if(key == '1'){
buzzerState = flipBit(buzzerState,0);
}
if(key == '2'){
buzzerState = flipBit(buzzerState,1);
}
if(key == '3'){
buzzerState = flipBit(buzzerState,2);
}
}
// flips a bit at a given index within a byte and returns updated byte
byte flipBit(byte state,int index){
int bit = getBitAt(state,index);
int bitFlipped = 1 - bit;
return setBitAt(state,index,bitFlipped);
}
// returns the integer value of a bit within a byte at the desired index
int getBitAt(byte b,int index){
index = constrain(index,0,7);
return b >> index & 1;
}
// sets an individual bit at a desired index on or off (value) and returns the updated byte
byte setBitAt(byte b,int index, int value){
index = constrain(index,0,7);
value = constrain(value,0,1);
if(value == 1) b |= (1 << (index));
else b &= ~(1 << (index));
return b;
}
使用键“ 1”,“ 2”和“ 3”翻转位。
请注意,在按键操作中,我们总是在更新相同的字节。 文本将首先显示十进制值,然后显示二进制值。
这是发送数据的最有效方法,并且是串行通信中最简单的方法。在Arduino方面,您只需在从Serial.read()
获得的字节上使用bitRead()
。有关二进制/位/字节的更多信息,请确保阅读BitMath Arduino tutorial。二进制一开始看上去似乎很吓人,但是一旦您进行了一些练习,它实际上并没有那么糟糕,这完全值得一读。
这是上面代码的更新版本,该代码将字节发送到第一个可用串行端口上的Arduino(请确保更改Serial.list()[0]
对您的设置有意义,然后按's'发送更新到Arduino:
import processing.serial.*;
// the state as a byte
byte buzzerState = 0B000;
Serial port;
void setup(){
textFont(createFont("Courier New",18),18);
try{
port = new Serial(this,Serial.list()[0],9600);
}catch(Exception e){
e.printStackTrace();
}
}
void draw(){
background(0);
text("DEC: " + buzzerState +
"\nBIN:" + binary(buzzerState,3),10,40);
}
void keyPressed(){
if(key == '1'){
buzzerState = flipBit(buzzerState,0);
}
if(key == '2'){
buzzerState = flipBit(buzzerState,1);
}
if(key == '3'){
buzzerState = flipBit(buzzerState,2);
}
if(key == 's'){
if(port != null){
port.write(buzzerState);
}else{
println("serial port is not open: check port name and cable connection");
}
}
}
// flips a bit at a given index within a byte and returns updated byte
byte flipBit(byte state,int index){
int bit = getBitAt(state,index);
int bitFlipped = 1 - bit;
return setBitAt(state,index,bitFlipped);
}
// returns the integer value of a bit within a byte at the desired index
int getBitAt(byte b,int index){
index = constrain(index,0,7);
return b >> index & 1;
}
// sets an individual bit at a desired index on or off (value) and returns the updated byte
byte setBitAt(byte b,int index, int value){
index = constrain(index,0,7);
value = constrain(value,0,1);
if(value == 1) b |= (1 << (index));
else b &= ~(1 << (index));
return b;
}
这是一个超级基本的Arduino草图:
byte buzzerState;
void setup() {
Serial.begin(9600);
//test LEDs setup
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
}
void loop() {
if(Serial.available() > 0){
buzzerState = Serial.read();
bool bit0 = bitRead(buzzerState,0);
bool bit1 = bitRead(buzzerState,1);
bool bit2 = bitRead(buzzerState,2);
//test LEDs update
digitalWrite(10,bit0);
digitalWrite(11,bit1);
digitalWrite(12,bit2);
}
}
如果将3个LED连接到引脚10、11、12,则应在按“ 1”,“ 2”,“ 3”然后在处理时按“ s”的同时切换它们。
处理二进制文件的一种方法是使用数据的字符串表示形式(例如"00000101"
代表[1,0,1]
)和unbinary()
将String转换为整数值您可以写序列号,但是在索引处获取并设置一个字符会有点烦(并且有可能将该char解析为它的整数值并返回)
当您需要发送多于一个字节的数据时,事情会变得更加复杂,因为您需要处理数据损坏/中断等。在这种情况下,最好根据您的需求来设置/设计通信协议,而这是'如果您刚开始使用Arduino,这很容易,但也不是没有。 Here是一个例子,在线上还有更多。
您可以尝试的一种快速而又肮脏的事情是将数据作为字符串发送,并以新行字符(\n
终止,可以将其缓冲直到在Arduino中然后一次读取4个字节,并丢弃{{1 }}解析时:
例如从Processing发送“ 101 \ n”,代表[1,0,1],然后在Arduino端使用Serial.readStringUntil('\n')
以及charAt()
和toInt()
的组合来访问其中的每个整数字符串。
这是一个示例处理草图:
\n
还有一个基于 Arduino>文件>示例> 04.Communication> SerialEvent 的Arduino:
import processing.serial.*;
// the state as a byte
String buzzerState = "010\n";
Serial port;
void setup(){
textFont(createFont("Courier New",18),18);
try{
port = new Serial(this,Serial.list()[0],9600);
}catch(Exception e){
e.printStackTrace();
}
}
void draw(){
background(0);
text(buzzerState,30,50);
}
void keyPressed(){
if(key == '1'){
buzzerState = flipBit(buzzerState,0);
}
if(key == '2'){
buzzerState = flipBit(buzzerState,1);
}
if(key == '3'){
buzzerState = flipBit(buzzerState,2);
}
if(key == 's'){
if(port != null){
port.write(buzzerState);
}else{
println("serial port is not open: check port name and cable connection");
}
}
}
String flipBit(String state,int index){
index = constrain(index,0,2);
// parse integer from string
int bitAtIndex = Integer.parseInt(state.substring(index,index+1));
// return new string concatenating the prefix (if any), the flipped bit (1 - bit) and the suffix
return state = (index > 0 ? state.substring(0,index) : "") + (1 - bitAtIndex) + state.substring(index+1);
}
注意,这更容易出错,并且使用的数据量是单字节选项的4倍。