Skip to main content
Arduino

Return to Answer

Properly terminate the string.
Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81
void setup() {
 Serial.begin(9600);
}
void loop() {
 static char buffer[128];
 static size_t pos;
 if (Serial.available()) {
 char c = Serial.read();
 if (c == '\r') { // line terminator
 buffer[pos] = '0円'; // terminate the string
 Serial.print(F("Arduino received: "));
 Serial.println(buffer); // echo received message
 pos = 0; // reset buffer position
 } else if (pos < sizeof buffer - 1) { // regular character
 buffer[pos++] = c; // buffer it
 }
 }
}
void setup() {
 Serial.begin(9600);
}
void loop() {
 static char buffer[128];
 static size_t pos;
 if (Serial.available()) {
 char c = Serial.read();
 if (c == '\r') { // line terminator
 Serial.print(F("Arduino received: "));
 Serial.println(buffer); // echo received message
 pos = 0; // reset buffer position
 } else if (pos < sizeof buffer) { // regular character
 buffer[pos++] = c; // buffer it
 }
 }
}
void setup() {
 Serial.begin(9600);
}
void loop() {
 static char buffer[128];
 static size_t pos;
 if (Serial.available()) {
 char c = Serial.read();
 if (c == '\r') { // line terminator
 buffer[pos] = '0円'; // terminate the string
 Serial.print(F("Arduino received: "));
 Serial.println(buffer); // echo received message
 pos = 0; // reset buffer position
 } else if (pos < sizeof buffer - 1) { // regular character
 buffer[pos++] = c; // buffer it
 }
 }
}
Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

You don't need to revert to sending single bytes. Line oriented protocols work well with both Arduino and Node.js. The only difficulty is that you have to decide what line terminators you want to use, and then consistently use them.

I tend to use CR for the PC → Arduino stream and CRLF for Arduino → PC. Using different line terminators is kind of odd, but this convention plays well with terminal emulators: the emulator usually sends CR when you hit <Enter>, and expects CRLF in return. Also, Arduino's Print::println() sends CRLF.

Here is a simple test demonstrating this convention. Node.js side:

var SerialPort = require('serialport'),
 port = new SerialPort('/dev/ttyACM0', {
 baudRate: 9600,
 parser: SerialPort.parsers.readline('\r\n')
 });
port.on('open', () => setInterval(() => port.write('Test\r'), 1000));
port.on('data', console.log);

Notice the different line terminators in readline() and write().

The Arduino side:

void setup() {
 Serial.begin(9600);
}
void loop() {
 static char buffer[128];
 static size_t pos;
 if (Serial.available()) {
 char c = Serial.read();
 if (c == '\r') { // line terminator
 Serial.print(F("Arduino received: "));
 Serial.println(buffer); // echo received message
 pos = 0; // reset buffer position
 } else if (pos < sizeof buffer) { // regular character
 buffer[pos++] = c; // buffer it
 }
 }
}

Here you may notice that Arduino has no equivalent of parsers.readline(), so I had to implement it (comparing the incoming character to '\r'). Note that explicit buffering of the incoming message is a standard way of handling line-oriented protocols on Arduino. Stream::readString() does not work well for this purpose, as it waits for incoming bytes until it times out. Stream::readStringUntil() may work better, but I prefer to avoid it just because it returns a String, which relies on heap allocation.

AltStyle によって変換されたページ (->オリジナル) /