Arduino 从串行线读取字符串并进行比较
Arduino read string from serial line and compare
我正在尝试从串行线读取一个字符串并将其与命令列表进行比较。如果字符串是一个有效的命令,Arduino 应该继续做一些事情,并且 return 串行线上的一些信息。
然而,我的监狱总是失败(给我"not a valid command response")。我尝试从 Arduino 串行监视器和 Python 脚本发送 "temp" 这个词。
我的arduino代码:
int sensorPin = 0; // Sensor connected to A0
int ledPin = 13; // Led connected to 13
int reading = 0; // Value read from A0
float voltage = 0; // Voltage we read
float temperatureC = 0; // Temperature we measure
String inputString= ""; // Set string empty
String Temperature = "temp"; // The command we are looking for
boolean stringComplete = false; // See if we are done reading from serial line
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
inputString.reserve(200); // Reserve space for inputString in memory
}
void serialEvent() {
// Read data from serial line until we get a \n.
// Store data in inputString
while (Serial.available()){
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n'){
stringComplete = true;
}
}
}
void loop() {
serialEvent(); // See if there are data on serial line and get it
if (stringComplete){ // If we are done reading on serial line
if (inputString == Temperature){ //WHY YOU FAIL ME?
digitalWrite(ledPin, HIGH);
voltage = (analogRead(sensorPin) * 5.0)/1024.0;
temperatureC = (voltage - 0.5) * 100;
Serial.print(voltage); Serial.println(" volts");
Serial.print(temperatureC); Serial.println(" degrees C");
delay(5000);
digitalWrite(ledPin, LOW);
}
else{
Serial.print("Not a valid command:");
Serial.print(' '+inputString);
}
// Reset so we can wait for a new command
inputString = "";
stringComplete = false;
}
}
首先,我会避免使用 String
对象。在我看来,最好只使用 char 数组。它们更轻便,避免了内存分配和释放。
顺便问一下,如果稍后要为它分配一个新的空字符串,为什么还要保留 space?
无论如何,我认为问题在于您还将新行附加到字符串。此外,在 windows 环境中,新行是 '\r'
后跟 '\n'
,因此在 Win 和 Linux.
中会出现不同的行为
我只是替换
inputString += inChar;
if (inChar == '\n'){
stringComplete = true;
}
和
if ((inChar == '\r') || (inChar == '\n')){
stringComplete = (inputString.length() > 0);
} else {
inputString += inChar;
}
编辑:我还会在 stringComplete 案例中添加一个中断,否则无法检测到多个命令。所以:
if ((inChar == '\r') || (inChar == '\n')){
if(inputString.length() > 0) {
stringComplete = true;
break;
}
} else {
inputString += inChar;
}
尝试
inputString += inChar.trim();
而不是。
inputString += inChar;
我正在尝试从串行线读取一个字符串并将其与命令列表进行比较。如果字符串是一个有效的命令,Arduino 应该继续做一些事情,并且 return 串行线上的一些信息。 然而,我的监狱总是失败(给我"not a valid command response")。我尝试从 Arduino 串行监视器和 Python 脚本发送 "temp" 这个词。
我的arduino代码:
int sensorPin = 0; // Sensor connected to A0
int ledPin = 13; // Led connected to 13
int reading = 0; // Value read from A0
float voltage = 0; // Voltage we read
float temperatureC = 0; // Temperature we measure
String inputString= ""; // Set string empty
String Temperature = "temp"; // The command we are looking for
boolean stringComplete = false; // See if we are done reading from serial line
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
inputString.reserve(200); // Reserve space for inputString in memory
}
void serialEvent() {
// Read data from serial line until we get a \n.
// Store data in inputString
while (Serial.available()){
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n'){
stringComplete = true;
}
}
}
void loop() {
serialEvent(); // See if there are data on serial line and get it
if (stringComplete){ // If we are done reading on serial line
if (inputString == Temperature){ //WHY YOU FAIL ME?
digitalWrite(ledPin, HIGH);
voltage = (analogRead(sensorPin) * 5.0)/1024.0;
temperatureC = (voltage - 0.5) * 100;
Serial.print(voltage); Serial.println(" volts");
Serial.print(temperatureC); Serial.println(" degrees C");
delay(5000);
digitalWrite(ledPin, LOW);
}
else{
Serial.print("Not a valid command:");
Serial.print(' '+inputString);
}
// Reset so we can wait for a new command
inputString = "";
stringComplete = false;
}
}
首先,我会避免使用 String
对象。在我看来,最好只使用 char 数组。它们更轻便,避免了内存分配和释放。
顺便问一下,如果稍后要为它分配一个新的空字符串,为什么还要保留 space?
无论如何,我认为问题在于您还将新行附加到字符串。此外,在 windows 环境中,新行是 '\r'
后跟 '\n'
,因此在 Win 和 Linux.
我只是替换
inputString += inChar;
if (inChar == '\n'){
stringComplete = true;
}
和
if ((inChar == '\r') || (inChar == '\n')){
stringComplete = (inputString.length() > 0);
} else {
inputString += inChar;
}
编辑:我还会在 stringComplete 案例中添加一个中断,否则无法检测到多个命令。所以:
if ((inChar == '\r') || (inChar == '\n')){
if(inputString.length() > 0) {
stringComplete = true;
break;
}
} else {
inputString += inChar;
}
尝试
inputString += inChar.trim();
而不是。
inputString += inChar;