bluetooth - 如何在同一张 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
解决方案
推荐阅读
- sql - 如何在计算年份时差时包含结束日期?(Postgresql)
- c - 指向指针数组的指针或指向指针的指针数组。它们是否相同以及如何将其与 memcpy、分配和字符串函数一起使用?
- javascript - 通过从 javascript (Flask) 传递数据重新渲染叶图
- reactjs - 在 Webpack 模块联合中导入远程组件/方法
- spring - 两个端点无需配置即可工作 - 显示相同的视图
- c - 从无效函数中检索值
- powershell - 如何在 ExchangeOnlineManagement 模块中导入 PowerShell cmdlet 的子集
- node.js - 使用 setTimeout 使电报发送更多消息
- php - 定义路由和创建 laravel Blade.php 模板
- jjwt - JJwt 初始化太慢。并发系统中的服务器