当前位置: 首页 > 知识库问答 >
问题:

将阵列数据从处理发送到Arduino

昌博易
2023-03-14

我成功地将一个整数从处理发送到Arduino,但现在我想发送一个由三个整数组成的数组,但我无法让它工作。我想使用Arduino创建一个蜂鸣器反馈,哪个处理将控制激活哪个蜂鸣器。例如,从处理发送的数据应该是[1,0,1],这意味着传感器1和3应该开始工作。蜂鸣器应该能够同时激活,以防[1,1,1]通过。

这是我到目前为止的代码:我试图理解什么数据被发送回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); 
     } 
 }

}

共有1个答案

杜霍英
2023-03-14

如果数据是一个总是有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”键翻转位。

请注意,在keypress中,我们总是更新相同的字节。文本将首先显示十进制值,然后显示二进制值。

这是发送数据最有效的方式,也是串行通信中最简单的方式。在Arduino端,您只需对从串行获取的字节使用bitRead()。read()。有关二进制/位/字节的更多信息,请务必阅读BitMath Arduino教程。二进制一开始可能看起来很吓人,但只要你稍微练习一下,它就真的没那么糟糕了,完全值得知道。

下面是上述代码的更新版本,它通过第一个可用的串行端口将字节发送到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"for[1,0,1])和un二进制()将该字符串转换为您可以写入串行的整数值,但在索引处获取和设置字符(并可能将该字符解析为它的整数值并返回)会有点烦人

当您需要发送超过一个字节的内容时,事情会变得更加复杂,因为您需要处理数据损坏/中断等。在这种情况下,最好根据您的需求设置/设计通信协议,如果您刚开始使用Arduino,这并不容易,但也不是不可能。这是一个例子,网上还有很多。

您可以尝试的一个快速而肮脏的方法是,将该数据作为以新行字符(\n)结尾的字符串发送,您可以将其缓冲到Arduino中,然后一次读取4个字节,在解析时丢弃\n

例如,从处理发送“101\n”,表示[1,0,1],然后在Arduino端使用Serial.read字符串直到('\n')charAt()toInt()的组合来访问该字符串中的每个整数。

下面是一个处理示意图示例:

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

还有一个基于Arduino的Arduino

/*
  Serial Event example

 When new serial data arrives, this sketch adds it to a String.
 When a newline is received, the loop prints the string and
 clears it.

 A good test for this is to try it with a GPS receiver
 that sends out NMEA 0183 sentences.

 Created 9 May 2011
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SerialEvent

 */

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);

  // test LEDs setup
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {
    Serial.println(inputString);
    // process string
    bool bit0   = inputString.charAt(2) == '1';
    bool bit1   = inputString.charAt(1) == '1';
    bool bit2   = inputString.charAt(0) == '1';

    //test LEDs update
    digitalWrite(10,bit0);
    digitalWrite(11,bit1);
    digitalWrite(12,bit2);


    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

注意:这更容易出错,使用的数据是单字节选项的4倍。

 类似资料:
  • 问题内容: 我有一个在我和它是一个连接到。当我单击时,我想说“ 单击按钮”。 这可能吗? 我知道两个连接到同一对象的对象可以轻松地相互通信并相互发送数据。但是对象可以将数据发送到对象中吗 编写自己的程序并将其附加到程序上是更好的编程吗?然后,我可以简单地让两个片段相互发送数据。 抱歉,如果这不是StackOverflow的正确类型。我是新手,因此无法在此问题上找到清晰的解释。 提前致谢! 问题答案

  • 我有客户端代码运行在javascript试图发送html内容到自定义处理程序。 客户端代码如下所示: 处理程序代码为: 问题在于,使用Chrome浏览器时,处理程序获取的消息(txt_内容)不完整。我得到的字符串的最大长度是:524288 当我在资源管理器中运行时,我会得到完整的消息(长度=567130)。 我在这里看到了一个类似的问题,但没有得到回答(设置maxAllowedContentLen

  • 问题内容: 我有这个小点击计数器。我想将每次单击都包含在mysql表中。有人可以帮忙吗? 万一有人想看看我做了什么: 这是phpfile.php,出于测试目的,将数据写入txt文件 问题答案: 您的问题中定义的JavaScript不能直接与MySql一起使用。这是因为它不在同一台计算机上运行。 JavaScript在客户端(在浏览器中)运行,并且数据库通常在服务器端存在。您可能需要使用中间服务器端

  • 问题内容: 如何将JSON数据从浏览器中的Javascript发送到服务器,并由PHP在其中进行解析? 问题答案: 我在这里获得了很多信息,所以我想发布我发现的解决方案。 问题: 从浏览器上的Javascript获取JSON数据到服务器,然后让PHP成功解析它。 环境: Windows上的浏览器(Firefox)中的Javascript。LAMP服务器作为远程服务器:Ubuntu上的PHP 5.3

  • 我正在尝试在我的网站上实现一个拖放文件上传器。文件被删除后立即上传,我想生成一个URL与flask将弹出在预览。我正在使用Dropzone.js。在dropzone的文档中,提供了一个示例,作为将数据从服务器发回并在文件上载后显示的指南。https://github.com/enyo/dropzone/wiki/faq#i-want-to-display-additution-informatio

  • 我有一个包含EditText的片段,当我单击该EditText时,会出现一个DatePicker对话框来选择日期。 FragmentFile 对话框片段 问题是我不知道如何将数据(选定日期)从DialogFraank传递到片段? 我读了一些主题,但这并没有帮助我感到困惑(抱歉再次提出这个问题)。 主题1主题2