我使用兩個Arduinos使用newsoftserial和RF收發器將純文本字符串發送給對方。使用Arduino將serial.read()轉換爲可用字符串?
每個字符串的長度可能是20-30個字符。如何將Serial.read()
轉換爲字符串,以便我可以執行if x == "testing statements"
等?
我使用兩個Arduinos使用newsoftserial和RF收發器將純文本字符串發送給對方。使用Arduino將serial.read()轉換爲可用字符串?
每個字符串的長度可能是20-30個字符。如何將Serial.read()
轉換爲字符串,以便我可以執行if x == "testing statements"
等?
從Help with Serial.Read() getting string:
char inData[20]; // Allocate some space for the string
char inChar=-1; // Where to store the character read
byte index = 0; // Index into array; where to store the character
void setup() {
Serial.begin(9600);
Serial.write("Power On");
}
char Comp(char* This) {
while (Serial.available() > 0) // Don't read unless
// there you know there is data
{
if(index < 19) // One less than the size of the array
{
inChar = Serial.read(); // Read a character
inData[index] = inChar; // Store it
index++; // Increment where to write next
inData[index] = '\0'; // Null terminate the string
}
}
if (strcmp(inData,This) == 0) {
for (int i=0;i<19;i++) {
inData[i]=0;
}
index=0;
return(0);
}
else {
return(1);
}
}
void loop()
{
if (Comp("m1 on")==0) {
Serial.write("Motor 1 -> Online\n");
}
if (Comp("m1 off")==0) {
Serial.write("Motor 1 -> Offline\n");
}
}
如果沒有工作,嘗試添加的回答更爲簡單/簡單'inData.trim'()在我們使用arduino控制檯的時候,會有換行符。這個http://stackoverflow.com/questions/24961402/how-to-compare-string-from-serial-read適合我 – 2014-07-25 17:39:31
這不應該工作。循環內的第二個「if」語句永遠不會觸發,因爲您已經從第一個「if」比較中讀取了串行數據。 – 2015-02-03 21:52:33
無限串readed
String content = "";
char character;
while(Serial.available()) {
character = Serial.read();
content.concat(character);
}
if (content != "") {
Serial.println(content);
}
Arduino Leonardo比任何其他閱讀方法更可靠。可能是由於concat引起的內存使用問題,但如果草圖可以接受,它看起來就是這樣做的最佳方式。 – 2012-12-23 15:25:49
+1 - 這是最簡單的方法。 – 2012-12-29 09:38:04
非常有用和簡單。儘管如此,我發現我必須在讀取每個字符的序列之間放置一個小的延遲 - 否則它會將每個字符打印在單獨的行中,而不是拼接在一起。 'void setup(){ Serial.begin(9600); //初始化串口 } void loop() { String content =「」; char character; (Serial.available()){ character = Serial.read(); content.concat(character); 延遲(10); } if(content!=「」)Serial.println(content); } } ' – 2013-03-16 07:56:42
我被問同樣的問題我自己和一些研究之後,我發現類似的東西。
它對我來說就像一個魅力。我用它來遠程控制我的Arduino。
// Buffer to store incoming commands from serial port
String inData;
void setup() {
Serial.begin(9600);
Serial.println("Serial conection started, waiting for instructions...");
}
void loop() {
while (Serial.available() > 0)
{
char recieved = Serial.read();
inData += recieved;
// Process message when new line character is recieved
if (recieved == '\n')
{
Serial.print("Arduino Received: ");
Serial.print(inData);
// You can put some if and else here to process the message juste like that:
if(inData == "+++\n"){ // DON'T forget to add "\n" at the end of the string.
Serial.println("OK. Press h for help.");
}
inData = ""; // Clear recieved buffer
}
}
}
它比最好的更好:-) – Jeevanantham 2014-05-15 04:59:45
這將是比較容易的方式:
char data [21];
int number_of_bytes_received;
if(Serial.available() > 0)
{
number_of_bytes_received = Serial.readBytesUntil (13,data,20); // read bytes (max. 20) from buffer, untill <CR> (13). store bytes in data. count the bytes recieved.
data[number_of_bytes_received] = 0; // add a 0 terminator to the char array
}
bool result = strcmp (data, "whatever");
// strcmp returns 0; if inputs match.
// http://en.cppreference.com/w/c/string/byte/strcmp
if (result == 0)
{
Serial.println("data matches whatever");
}
else
{
Serial.println("data does not match whatever");
}
最好的和最直觀的方法是使用的serialEvent()回調的Arduino與循環()和設置()定義了一起。
我已經建立了一個小型庫,它處理消息接收,但從來沒有時間開放它。 該庫接收\ n終止行,表示命令和任意有效負載,以空格分隔。 你可以調整它來輕鬆使用你自己的協議。
首先,圖書館,SerialReciever.h:
#ifndef __SERIAL_RECEIVER_H__
#define __SERIAL_RECEIVER_H__
class IncomingCommand {
private:
static boolean hasPayload;
public:
static String command;
static String payload;
static boolean isReady;
static void reset() {
isReady = false;
hasPayload = false;
command = "";
payload = "";
}
static boolean append(char c) {
if (c == '\n') {
isReady = true;
return true;
}
if (c == ' ' && !hasPayload) {
hasPayload = true;
return false;
}
if (hasPayload)
payload += c;
else
command += c;
return false;
}
};
boolean IncomingCommand::isReady = false;
boolean IncomingCommand::hasPayload = false;
String IncomingCommand::command = false;
String IncomingCommand::payload = false;
#endif // #ifndef __SERIAL_RECEIVER_H__
要使用它,在你的項目做到這一點:
#include <SerialReceiver.h>
void setup() {
Serial.begin(115200);
IncomingCommand::reset();
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (IncomingCommand::append(inChar))
return;
}
}
要使用接收到的命令:
void loop() {
if (!IncomingCommand::isReady) {
delay(10);
return;
}
executeCommand(IncomingCommand::command, IncomingCommand::payload); // I use registry pattern to handle commands, but you are free to do whatever suits your project better.
IncomingCommand::reset();
}
您可以使用Serial.readString()
和Serial.readStringUntil()
從Arduino上的Serial解析字符串。您可以使用Serial.parseInt()
從串口讀取整數值。
int x;
String str;
void loop()
{
if(Serial.available() > 0)
{
str = Serial.readStringUntil('\n');
x = Serial.parseInt();
}
}
送價值通過串口將my string\n5
,其結果將是str = "my string"
和x = 5
當我嘗試手動讀取字符緩衝區中的串行輸入時,出現了奇怪的電壓波動,但是使用'Serial.readStringUntil()'爲我修復了這一切,並將代碼更具可讀性!謝謝! – 2016-01-27 00:31:43
我測試過了,是的它更容易。然而,與字符緩衝區相比,此操作顯然需要更多時間和延遲。 – 2016-10-09 01:03:25
有趣的是,你能分享一些關於你的發現的更多細節,以及我們在這裏討論的時間有多少差異? 如果你有詳細的數字,我會喜歡它,如果你願意與我們分享。謝謝 ! – 2016-10-09 18:30:25
如果你想讀從串口的消息,你需要單獨我建議應對每一個消息使用如下分隔符將消息分離成部分:
String getMessage()
{
String msg=""; //the message starts empty
byte ch; // the character that you use to construct the Message
byte d='#';// the separating symbol
if(Serial.available())// checks if there is a new message;
{
while(Serial.available() && Serial.peek()!=d)// while the message did not finish
{
ch=Serial.read();// get the character
msg+=(char)ch;//add the character to the message
delay(1);//wait for the next character
}
ch=Serial.read();// pop the '#' from the buffer
if(ch==d) // id finished
return msg;
else
return "NA";
}
else
return "NA"; // return "NA" if no message;
}
這樣,每次使用該函數時都會得到一條消息。
如果你使用連接方法,那麼不要忘記修剪字符串,如果你使用if else方法。
這是一個更強大的實現,可處理異常輸入和競態條件。
它故意使用字符數組而不是String
類型,以提高效率並避免內存問題。它還避免使用readStringUntil()
函數,在輸入到達之前不超時。
原來的問題沒有說明如何定義可變長度字符串,但我會假設它們被一個換行符終止 - 這將變成一個行讀取問題。
int read_line(char* buffer, int bufsize)
{
for (int index = 0; index < bufsize; index++) {
// Wait until characters are available
while (Serial.available() == 0) {
}
char ch = Serial.read(); // read next character
Serial.print(ch); // echo it back: useful with the serial monitor (optional)
if (ch == '\n') {
buffer[index] = 0; // end of line reached: null terminate string
return index; // success: return length of string (zero if string is empty)
}
buffer[index] = ch; // Append character to buffer
}
// Reached end of buffer, but have not seen the end-of-line yet.
// Discard the rest of the line (safer than returning a partial line).
char ch;
do {
// Wait until characters are available
while (Serial.available() == 0) {
}
ch = Serial.read(); // read next character (and discard it)
Serial.print(ch); // echo it back
} while (ch != '\n');
buffer[0] = 0; // set buffer to empty string even though it should not be used
return -1; // error: return negative one to indicate the input was too long
}
這裏是被用於從串行監控讀取命令它的一個例子:
const int LED_PIN = 13;
const int LINE_BUFFER_SIZE = 80; // max line length is one less than this
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
Serial.print("> ");
// Read command
char line[LINE_BUFFER_SIZE];
if (read_line(line, sizeof(line)) < 0) {
Serial.println("Error: line too long");
return; // skip command processing and try again on next iteration of loop
}
// Process command
if (strcmp(line, "off") == 0) {
digitalWrite(LED_PIN, LOW);
} else if (strcmp(line, "on") == 0) {
digitalWrite(LED_PIN, HIGH);
} else if (strcmp(line, "") == 0) {
// Empty line: no command
} else {
Serial.print("Error: unknown command: \"");
Serial.print(line);
Serial.println("\" (available commands: \"off\", \"on\")");
}
}
String content = "";
char character;
if(Serial.available() >0){
//reset this variable!
content = "";
//make string from chars
while(Serial.available()>0) {
character = Serial.read();
content.concat(character);
}
//send back
Serial.print("#");
Serial.print(content);
Serial.print("#");
Serial.flush();
}
警告:有時候您的字符串將會以兩個或更多個部分發送。把一些「消息結束」字符檢查,如果你從按摩連接所有的字符。 – flamaniac 2014-09-26 10:45:53
使用串附加上serial.read運算符()。它比string.concat更好()
char r;
string mystring = "";
while(serial.available())
{
r = serial.read();
mystring = mystring + r;
}
您完成後的字符串保存流(MyString的,在這種情況下),使用字符串函數來提取你在找什麼。
對此的信任去了岩漿。很好的答案,但這裏使用的是C++風格的字符串而不是c風格的字符串。一些用戶可能會發現更容易。
String string = "";
char ch; // Where to store the character read
void setup() {
Serial.begin(9600);
Serial.write("Power On");
}
boolean Comp(String par) {
while (Serial.available() > 0) // Don't read unless
// there you know there is data
{
ch = Serial.read(); // Read a character
string += ch; // Add it
}
if (par == string) {
string = "";
return(true);
}
else {
//dont reset string
return(false);
}
}
void loop()
{
if (Comp("m1 on")) {
Serial.write("Motor 1 -> Online\n");
}
if (Comp("m1 off")) {
Serial.write("Motor 1 -> Offline\n");
}
}
我可以逃脫這樣的:
void setup() {
Serial.begin(9600);
}
void loop() {
String message = "";
while (Serial.available())
message.concat((char) Serial.read());
if (message != "")
Serial.println(message);
}
很多偉大的答案,這裏是我的2美分,確切的功能的問題提出要求。
加上它應該是更容易閱讀和調試。
代碼最多可測試128個字符的輸入。
測試Arduino uno r3(Arduino IDE 1.6。8)
功能性:
命令:
注:請記住根據您的主板轉速來改變波特率。
// Turns Arduino onboard led (pin 13) on or off using serial command input.
// Pin 13, a LED connected on most Arduino boards.
int const LED = 13;
// Serial Input Variables
int intLoopCounter = 0;
String strSerialInput = "";
// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.
pinMode(LED, OUTPUT);
// initialize serial port
Serial.begin(250000); // CHANGE BAUD RATE based on the board speed.
// initialized
Serial.println("Initialized.");
}
// the loop routine runs over and over again forever:
void loop()
{
// Slow down a bit.
// Note: This may have to be increased for longer strings or increase the iteration in GetPossibleSerialData() function.
delay(1);
CheckAndExecuteSerialCommand();
}
void CheckAndExecuteSerialCommand()
{
//Get Data from Serial
String serialData = GetPossibleSerialData();
bool commandAccepted = false;
if (serialData.startsWith("LED.ON"))
{
commandAccepted = true;
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
}
else if (serialData.startsWith("LED.OFF"))
{
commandAccepted = true;
digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW
}
else if (serialData != "")
{
Serial.println();
Serial.println("*** Command Failed ***");
Serial.println("\t" + serialData);
Serial.println();
Serial.println();
Serial.println("*** Invalid Command ***");
Serial.println();
Serial.println("Try:");
Serial.println("\tLED.ON");
Serial.println("\tLED.OFF");
Serial.println();
}
if (commandAccepted)
{
Serial.println();
Serial.println("*** Command Executed ***");
Serial.println("\t" + serialData);
Serial.println();
}
}
String GetPossibleSerialData()
{
String retVal;
int iteration = 10; // 10 times the time it takes to do the main loop
if (strSerialInput.length() > 0)
{
// Print the retreived string after looping 10(iteration) ex times
if (intLoopCounter > strSerialInput.length() + iteration)
{
retVal = strSerialInput;
strSerialInput = "";
intLoopCounter = 0;
}
intLoopCounter++;
}
return retVal;
}
void serialEvent()
{
while (Serial.available())
{
strSerialInput.concat((char) Serial.read());
}
}
這總是對我的作品:)
String _SerialRead = "";
void setup() {
Serial.begin(9600);
}
void loop() {
while (Serial.available() > 0) //Only run when there is data available
{
_SerialRead += char(Serial.read()); //Here every received char will be
//added to _SerialRead
if (_SerialRead.indexOf("S") > 0) //Checks for the letter S
{
_SerialRead = ""; //Do something then clear the string
}
}
}
請你檢查我的回答如下,它比你選擇 – 2014-02-19 05:27:04