【问题标题】:Receiving multiple chars at once with Software Serial使用软件序列一次接收多个字符
【发布时间】:2024-01-19 05:46:02
【问题描述】:

我有一个 Arduino Uno R3 和一个蓝牙伴侣。 将 Mate 链接到 Arduino 硬件串行(引脚 0,1)时,我可以从连接的设备一次发送多个字符,但是当我尝试使用软件串行(例如使用引脚 4,2)做同样的事情时,我只得到第一个字符和其余字符都搞砸了。

我的代码:

#include <SoftwareSerial.h>  

int bluetoothTx = 4;  
int bluetoothRx = 2;  

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

void setup() 
{
  Serial.begin(115200);  
  bluetooth.begin(115200);  
}

void loop()
{
  if(bluetooth.available())
  {
    Serial.print((char)bluetooth.read());  
  }
}

例如,如果我从我的 android 设备发送这个字符:abcd,我会在串行监视器中得到这个:a±,ö

这个使用硬件串行的代码(我将我的蓝牙连接到引脚 0 和 1)工作得很好:

void setup()
{
  Serial.begin(115200);  
}

void loop()
{
  if(Serial.available())
  {
    Serial.print((char)Serial.read());  
  }
}

我什至尝试更改波特率,但没有帮助

如果我一个一个发送字符,它可以正常工作,但我希望能够将它们作为字符串发送。

【问题讨论】:

  • 首先尝试将 SoftwareSerial 上的波特率缩小到尽可能低的水平。如果问题解决了,那么您就知道您遇到了 bit-banging 的限制。
  • 看来这里的指南支持我的理论:learn.sparkfun.com/tutorials/using-the-bluesmirf/…
  • 另一件要考虑的事情。该板以 16MHz 运行,周期时间为 62.5ns。在 115200bps 时,单个位的宽度为 8.6uS(约 140 个周期)。假设对于 RX,您需要对每个位进行 8 次采样才能正确地对其进行构图。同时,您必须处理更改 TX 的输出状态。在运行您的应用程序代码的同时。如果帧有点乱码也就不足为奇了。
  • 再次检查您的 RX 引脚是否支持引脚更改中断:arduino.cc/en/Reference/softwareSerial。此链接还推荐 Paul Stoffregen 的 AltSoftSerial 库作为更强大的替代方案。
  • 你是对的,它与波特率有关,我用正确的代码创建了一个答案。

标签: bluetooth arduino software-serial


【解决方案1】:

您可以尝试在打印之前缓冲字符串。

看下面的答案:Convert serial.read() into a useable string using Arduino?

【讨论】:

    【解决方案2】:

    正如@hyperflexed 在 cmets 中所指出的,这是一个与波特率相关的问题。 我必须将波特率降至 9600 才能使其工作。

    这是有效的代码:

    #include "SoftwareSerial.h";
    int bluetoothTx = 4;
    int bluetoothRx = 2;
    
    SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
    
    void setup()
    {
      Serial.begin(9600);
      delay(500);
      bluetooth.begin(115200);
      delay(500);
      bluetooth.print("$$$");
      delay(500);
      bluetooth.println("U,9600,N");
      delay(500);
      bluetooth.begin(9600);
    }
    
    void loop()
    {
      if(bluetooth.available()) {
        char toSend = (char)bluetooth.read();
        Serial.print(toSend);
      }
    
      if(Serial.available()) {
        char toSend = (char)Serial.read();
        bluetooth.print(toSend);
      }
    }
    

    为了更改波特率,我不得不进行一些很大的延迟以确保命令被执行,否则它将无法工作。

    【讨论】: