我使用发送一系列字节的程序通过Serial与Arduino进行通信。
为了让Arduino意识到它正在接收消息而不是垃圾,我用字符'S''T''''R''T'标记了我的字节数组的开头。在此之后,最终将跟随一系列将分配给内部变量的字节(尚未实现)。
Arduino必须按顺序读取每个字节并将其与字节数组进行比较,如果所有字节都以正确的顺序存在,它将继续执行程序的下一部分,否则它将丢弃当前字节并等待更多字节到达。
我试图以最有效和可读的方式实现它,而不是使用一系列嵌套的if语句。
到目前为止,我有:
byte inByte = 0;
byte handShake[] = {'S','T','A','R','T'};
void setup() {
Serial.begin(9600);
}
void loop()
{
while (Serial.available())
{
for (int x =0; x < sizeof(handShake) ; x++)
{
inByte = Serial.read();
Serial.println(x);
if (inByte == handShake[x])
{
if (x == (sizeof(handShake)-1)) {setArduino();}
}
else break;
}
}
}
void setArduino () {
Serial.println("Ready To Set Parameters");
}
然而,这似乎没有超过第二个字节,我不知道为什么。
答案 0 :(得分:1)
解决了这个问题:
以下是答案:
byte inByte = 0;
char handShake[] = {'S','T','A','R','T'};
void setup() {
Serial.begin(9600);
}
void loop()
{
while (Serial.available())
{
for (int x =0; x < sizeof(handShake) ; x++)
{
inByte = Serial.read();
Serial.println(x);
if (inByte == handShake[x])
{
if (x == (sizeof(handShake)-1)) {setArduino();}
while(!Serial.available()) {delay(1);}
}
else {break;}
}
}
}
void setArduino () {
Serial.println("Ready To Set Parameters");
}
这可能不是最有效的方法,但我目前无法看到它的问题。
答案 1 :(得分:1)
更好的答案:这允许循环的其余部分在等待消息完成时进行迭代,如果未收到完整的握手消息,则计数器将重置。
byte inByte = 0;
char handShake[] = {'S','T','A','R','T'};
int messageIndex = 0;
void setup() {
Serial.begin(9600);
}
void loop()
{
while (Serial.available())
{
inByte = Serial.read();
Serial.println(messageIndex);
if (inByte == handShake[messageIndex])
{
messageIndex++;
if (messageIndex == sizeof(handShake)) {messageIndex = 0; setArduino();}
}
else {messageIndex=0;}
}
// Other code while waiting for message to finish
Serial.println("tick");
}
void setArduino () {
Serial.println("Ready To Set Parameters");
}
答案 2 :(得分:0)
您可以尝试计算您的讯息。 CRC是老而好的解决方案。我用它,它对我来说很完美。我不确定你在与哪种设备通信。
//define
const uint32_t Polynomial = 0xEDB88320;
const uint16_t NumBytes = 256;
uint8_t data[NumBytes];
/// compute CRC32
uint32_t crc32_bitwise(const void* data, uint16_t length, uint32_t previousCrc32 = 0)
{
uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF
uint8_t* current = (uint8_t*) data;
while (length--)
{
crc ^= *current++;
for (uint8_t j = 0; j < 8; j++)
{
uint8_t lowestBit = crc & 1;
crc >>= 1;
if (lowestBit)
crc ^= Polynomial;
}
}
return ~crc; // same as crc ^ 0xFFFFFFFF
}
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
何时需要计算CRC
uint32_t crc = crc32_bitwise(data_bytes, sizeof(data_bytes));
data_bytes
是字节数组。
然后您可以在byte data[x]
中获取所有设置或消息并计算CRC。然后,您可以将CRC添加到消息并发送消息byte data[x+sizeof(CRC)]
P.S。使用byte
代替int
。对于前者for(byte x =0; x<sizeof(handShake); x++)