我写了一个简单的代码,用于使用蓝牙串行端口发送int值。
发射机:
#include <SoftwareSerial.h>
#include "PWM.hpp"
PWM PWM(2);
SoftwareSerial BTSerial(8,9);
void setup()
{
Serial.begin(9600);
Serial.println("Go");
BTSerial.begin(9600);
BTSerial.write("AT+INQrn");
delay(10000);
BTSerial.write("AT+CONN1rn");
delay(100);
PWM.begin(true);
}
void loop()
{
int pwmValue = PWM.getValue();
Serial.println(pwmValue);
BTSerial.write(pwmValue);
delay(100);
}
变送器部分Serial.println
输出正确:
1500
但在接收器部分不是。这是接收器的代码:
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8, 9);
void setup() {
Serial.begin(9600);
BTSerial.begin(9600);
BTSerial.write("AT+NAME=Remotern");
}
void loop() {
if (BTSerial.available()) {
int pwmValue = BTSerial.read();
Serial.println(pwmValue);
}
Serial.println
的错误输出是:
220
我认为问题出在类型转换上。
SoftwareSerial::read
返回单字节读取。 如果你检查十六进制的预期1500
,它是0x05DC
,它的下半字节是0xDC
正好是十进制220
。
使用write()
的多字节变体,您可以使用:
BTSerial.write(&pwmValue, sizeof pwmValue);
对于接收,您需要一个循环:
union {
int i;
char c[0];
} pwmValue;
int receivedBytes = 0;
void loop() {
if (BTSerial.available()) {
pwmValue.c[receivedBytes] = BTSerial.read();
receivedBytes++;
if (receivedBytes == sizeof pwmValue) {
Serial.println(pwmValue.i);
receivedBytes = 0;
}
}
}
在文档 https://github.com/PaulStoffregen/SoftwareSerial/blob/master/SoftwareSerial.cpp 中,您可以看到这两个函数都适用于uint_8t - 保证有 8 位(1 字节(。这最多可容纳 256 个值,因此1500 mod 256 是 220。
看起来库准备只传输字符大小的数据,因此您需要在两种大小上转换更大的数字。
对于发送 int:
int n = pwmValue;
while (n > 0) {
int digit = n % 10;
n = n / 10;
BTSerial.write(digit);
}
对于接收 int:
int n = 0; //future result
int decs = 1;
int temp;
while ((temp = BTSerial.read()) != -1) {
n += temp * decs;
decs *= 10;
}