我有一个非常奇怪的问题,如果从 Windows XP Home sp3 或 Elementary OS Luna(Ubuntu Linux 的发行版)编译并上传到 Arduino,该草图的性能会有所不同。
除其他事项外,该草图从串行连接(蓝牙)读取一个字节并将其写回串行监视器。
这是我从 WinXP 编译草图时得到的结果:我通过 BT 连接字符串从“1”到“7”每次发送一次。这些字符串的 ASCII 码减少了 48,以将字符串转换为字节。结果是正确的,指针数组中的函数也被正确调用。
这是我从 Linux 得到的信息。我将每个字符串从“1”到“7”发送了 4 次,以查看结果与我需要获得的内容无关,并且与相同的输入数据不一致:例如,当我发送字符串“2”时,我得到104 106 106 104..... 相同的字节 106 是用来自 BT 的不同字符串写入的。 此外,这些函数没有被调用,因此这意味着这不是 Serial.print 问题。
我确定这是一个编译问题,因为一旦将草图上传到 Arduino,如果我在 WinXP 或 Linux 中使用串行监视器,它就会以相同的方式执行(无论正确与否)。
这是草图
#include "Arduino.h"
#include <SoftwareSerial.h>
#include <Streaming.h>
#define nrOfCommands 10
typedef void (* CmdFuncPtr) (); // this is a typedef to command functions
//the following declares an arry of 10 function pointers of type DigitFuncPtr
CmdFuncPtr setOfCmds[nrOfCommands] = {
noOp,
leftWindowDown,
leftWindowUp,
bootOpen,
cabinLightOn,
cabinLightOff,
lockOn,
lockOff,
canStart,
canStop
};
#define cmdLeftWindowDown 1
#define cmdLeftWindowUp 2
#define cmdBootOpen 3
#define cmdCabinLightOn 4
#define cmdCabinLightOff 5
#define cmdLockOn 6
#define cmdLockOff 7
#define cmdCanStart 8
#define cmdCanStop 9
#define buttonPin 4 // the number of the pushbutton pin
#define bluetoothTx 2
#define bluetoothRx 3
int buttonState = 0; // variable for reading the pushbutton status
int androidSwitch=0;
byte incomingByte; // incoming data
byte msg[12];
byte msgLen=0;
byte msgIdMsb=0;
byte msgIdLsb=0;
//const byte cmdLeftWindowDown;
SoftwareSerial bluetooth(bluetoothTx,bluetoothRx);
void setup()
{
//Setup usb serial connection to computer
Serial.begin(115200);
//Setup Bluetooth serial connection to android
bluetooth.begin(115200);
//bluetooth.print("$$$");
randomSeed(analogRead(10));
delay(100);
//bluetooth.println("U,9600,E");
//bluetooth.begin(9600);
//time=0;
}
void loop() {
msgIdLsb=random(1,255);
msgIdMsb=random(0,5);
msg[0]=msgIdMsb;
msg[1]=msgIdLsb;
msgLen=random(9);
msg[2]=msgLen;
for (int x=3;x<msgLen+3;x++) {
msg[x]=random(255);
}
for (int x=3+msgLen;x<11;x++) {
msg[x]=0;
}
msg[11]='\n';
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
if ((buttonState == HIGH)||(androidSwitch==HIGH)) {
for (int x=0;x<12;x++) {
Serial<<msg[x]<<" ";
bluetooth.write(uint8_t(msg[x]));
}
Serial<<endl;
}
//Read from bluetooth and write to usb serial
if(bluetooth.available())
{
incomingByte = bluetooth.read()-48;
Serial<<incomingByte<<endl;
if (incomingByte<nrOfCommands)
setOfCmds[incomingByte]();
}
delay(10);
}
void noOp(void)
{
Serial<<"noOp"<<endl;
};
void leftWindowDown(void)
{
Serial<<"leftWindowDown"<<endl;
};
void leftWindowUp(void)
{
Serial<<"leftWindowUp"<<endl;
};
void bootOpen(void)
{
Serial<<"bootOpen"<<endl;
};
void cabinLightOn(void)
{
Serial<<"cabinLightOn"<<endl;
};
void cabinLightOff(void)
{
Serial<<"cabinLightOff"<<endl;
};
void lockOn(void)
{
Serial<<"lockOn"<<endl;
};
void lockOff(void)
{
Serial<<"lockOff"<<endl;
};
void canStart(void)
{
androidSwitch=HIGH;
};
void canStop(void)
{
androidSwitch=LOW;
};
任何帮助都会非常有帮助。 预先感谢。
我想你正在使用arduino ide;如果不是,以下某些内容可能不适用。
首先,找出ide在编译和链接代码时使用的构建目录的位置。 [找出答案的一种方法是在编译期间暂时打开详细输出。 (单击“文件”、“首选项”、“编译期间显示详细输出”。)单击“验证”按钮编译代码,然后查看输出第一行中 -o 选项后面的路径。] 例如,在 Linux 系统上构建目录路径可能类似于
/tmp/build3877126492387157498.tmp
。 在该目录中,查找编译期间创建的 .cpp 文件。
在两个系统上找到草图的 .cpp 文件后,将它们复制到一个系统上,以便您可以比较它们并检查差异。 如果它们不同,则一个或另一个 ide 可能已损坏,或者可能发生不正确的包含。
如果 .cpp 文件不同,请比较编译标志、头文件等。我认为两个系统上的标志和 AVR 头文件应该相同,但可能的例外是 MSW 文件在换行符后可能有回车符人物。 还要检查 gcc 版本。 [我没有可以尝试的 MSW 系统,但我假设两个系统上都使用 gcc 进行 AVR 交叉编译。 如果我错了请纠正我。]
如果 .cpp 文件匹配,则测试生成的二进制文件以找出它们的不同之处。 (例如,如果草图文件是
Blink21x.ino
,则二进制文件可能是Blink21x.cpp.elf
或Blink21x.cpp.hex
。)如果两个系统上都有.elf文件[我不知道MSW系统是否会生成.elf ] 在Linux系统上使用avr-objdump
生成反汇编版本的代码:
avr-objdump -d Blink21x.cpp.elf > Blink21x.cpp.lst
然后使用
diff
来定位两个反汇编文件之间的差异。 如果差异是由于源代码的编译方式(而不是库中的差异)造成的,则 .lst 文件中提供了足够的信息来识别源代码行。 (在后一种情况下,.lst 文件中给出了足够的信息来识别哪些库例程不同。)
如果 MSW 系统上没有 .elf 文件,您可以尝试比较 .hex 文件。 从差异的位置,您可以在 Linux 系统 .elf-disassemble 文件中找到相关行,并从中识别出您的代码行或库例程。