首页 > 解决方案 > 如何在同一张 arduino 卡上设置 2 个串行条目(USB shield 主机/蓝牙)?

问题描述

我正在尝试使用 arduino 让 ACM/USB 与蓝牙的软件串行端口一起工作,但是结合这两个代码会导致两个功能都中断。

起初,我为应用程序的蓝牙部分开发了代码,我能够正确发送和解释通过软件串行(在引脚 10 和 11 上)发送的命令。

之后,我添加了一个 arduino USB shield,以便将其连接到 MRC12 USB 条形码扫描仪。经过一番摆弄之后,我设法编写了一个代码,该代码能够接收使用 ACM 发送的数据,然后将其打印到串行端口(连接的计算机)以进行调试。

分别这样做会导致两个代码都正常工作,但是当我尝试这样做时,代码停止工作。

这是带有设置的蓝牙控制代码的一部分。这个检测是否发送了管理代码并触发响应。

char data; //Recived data will get stored in this variable
int i = 0; //count pour tabnumbers
int e = 0; //count pour firstchar
String test;
String win = "0000";
const int PowerPin1 = 4;
const int PowerPin2 = 5;

// software serial #1: RX = digital pin 10, TX = digital pin 11
SoftwareSerial portBluetooth(10, 11);

void setup() //The setup function will only run once, after each powerup.It initializes and sets the initial values
{
  Serial.begin(9600); //Sets the baud for serial data transmission (Bits Per Second)
  portBluetooth.begin(9600);
  pinMode(PowerPin1, OUTPUT);
  pinMode(PowerPin2, OUTPUT);
}

void loop() {

  if (portBluetooth.available()) //Here We're checking whether data is available or not
  {
    test = ""; //store assembled string
    data = ""; //store incoming data
    delay(50);

    while (portBluetooth.available()) {
      data = portBluetooth.read(); //Data received

      if ((byte) data == 13) {
        if (test.equals(win) == true) {
          portBluetooth.println("secret code acknowledged: opening all doors, sending current loaded numbers to serial");
          for (int k = 0; k < TabSize; k++) {
            portBluetooth.println("import: " + ImpTab[k]);
            portBluetooth.println("export: " + ExpTab[k]);
          }

          digitalWrite(PowerPin1, LOW);
          digitalWrite(PowerPin2, LOW);
          delay(5000);

          digitalWrite(PowerPin1, HIGH);
          digitalWrite(PowerPin2, HIGH);
        } else if (test.equals("1111")) {
          portBluetooth.println("secret code acknowledged: clearing tracking number list");
          for (int k = 0; k < TabSize; k++) {
            ImpTab[k] = "";
            ExpTab[k] = "";
          }
        }
      } else {
        test.concat(data);
        portBluetooth.println(test);
      }
    }
  }
}

代码的其他一些功能已被删除,但这应该可以让您了解它是如何工作的。

这是管理 USB 输入的部分。屏蔽无法本地设置串行通信,我使用 ACM 来完成。这个比较复杂(可能是问题的根源),这里是积分代码。

#include <cdcacm.h>
#include <usbhub.h>

#include "pgmstrings.h"

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

class ACMAsyncOper : public CDCAsyncOper
{
public:
    uint8_t OnInit(ACM *pacm);
};

uint8_t ACMAsyncOper::OnInit(ACM *pacm)
{
    uint8_t rcode;
    // Set DTR = 1 RTS=1
    rcode = pacm->SetControlLineState(3);

    if (rcode)
    {
        ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
        return rcode;
    }

    LINE_CODING lc;
    lc.dwDTERate    = 9600;
    lc.bCharFormat  = 0;
    lc.bParityType  = 0;
    lc.bDataBits    = 8;

    rcode = pacm->SetLineCoding(&lc);

    if (rcode)
        ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);

    return rcode;
}

USB     Usb;
//USBHub     Hub(&Usb);
ACMAsyncOper  AsyncOper;
ACM           Acm(&Usb, &AsyncOper);

void setup()
{
  Serial.begin( 9600 );
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  Serial.println("Start");

  if (Usb.Init() == -1)
      Serial.println("OSCOKIRQ failed to assert");

  delay( 200 );
}

void loop()
{
    Usb.Task();

    if( Acm.isReady()) {
       uint8_t rcode;



       delay(50);

        /* reading the USB
        /* buffer size must be greater or equal to max.packet size */
        /* it it set to 64 (largest possible max.packet size) here, can be tuned down
        for particular endpoint */
        uint8_t  buf[64];
        uint16_t rcvd = 64;
        rcode = Acm.RcvData(&rcvd, buf);
         if (rcode && rcode != hrNAK)
            ErrorMessage<uint8_t>(PSTR("Ret"), rcode);

            if( rcvd ) { //more than zero bytes received
              for(uint16_t i=0; i < rcvd; i++ ) {
                Serial.print((char)buf[i]); //printing on the screen
              }
            }
        delay(10);
    }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
}

结合这两个代码在理论上看起来很容易,我只是添加了所有必要的配置,然后在蓝牙检查后稍作停顿添加了 USB 部分。

我希望代码先做一个,然后再做另一个,并产生类似的结果。代码编译正确,但上传后整个过程中断。设置“启动”打印正常,但随后代码开始进入传入的蓝牙信号,尽管蓝牙卡是惰性的,并且打印了很多空格。我也无法通过串行接口通过蓝牙发送或接收任何东西,即使通过常规println

标签: bluetootharduinousbserial

解决方案


推荐阅读