Hello,
I need to understand the behavior of readStringUntil().
My code when i use readStringuntil('\n'):
#include <scpiparser.h>
#include <Arduino.h>
#include <SPI.h>
#include "SdFat.h"
SdFat SD;
struct scpi_parser_context ctx;
scpi_error_t identify(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t print_value(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t print1_value(struct scpi_parser_context* context, struct scpi_token* command);
File NewFile;
void setup()
{
struct scpi_command* measure;
struct scpi_command* value;
/* First, initialise the parser. */
scpi_init(&ctx);
/*
* After initialising the parser, we set up the command tree. Ours is
*
* *IDN? -> identify
* :MEASure
* :PRInt -> print_value
* :VALue
* :PRInt1? -> print1_value
*/
scpi_register_command(ctx.command_tree, SCPI_CL_SAMELEVEL, "*IDN?", 5, "*IDN?", 5, identify); //Initialise SameLevel function of Identify
measure = scpi_register_command(ctx.command_tree, SCPI_CL_CHILD, "MEASURE", 7, "MEAS", 4, NULL); // Command tree first child with main header name
value = scpi_register_command(ctx.command_tree, SCPI_CL_CHILD, "VALUE", 5, "VAL", 3, NULL);
scpi_register_command(measure, SCPI_CL_CHILD, "PRINT", 5, "PRI", 3, print_value); // Command tree subchild to the first child
scpi_register_command(value, SCPI_CL_CHILD, "PRINT1?", 7, "PRI1?", 5, print1_value); // Command tree subchild to the first child
pinMode(15, OUTPUT);
Serial.begin(9600);
Serial.println("Type any character to start");
while (Serial.read() <= 0) {}
Serial.print("Initializing SD card...");
Serial.println();
pinMode(SDCARD_SS_PIN, OUTPUT);
if (!SD.begin(SDCARD_SS_PIN)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
NewFile = SD.open("commands3.txt"); // open existing file
if (NewFile) {
for(int i = 0; i<3; i++){
char my_buffer[256];
String line = NewFile.readStringUntil('\n'); //Read from the SD card
Serial.print("Line read from the sd card is :"); Serial.print(line);
int llength = line.length();
//llength = llength - 1;
Serial.println(llength);
line.toCharArray(my_buffer,256);
Serial.println("my_buffer:");
//Serial.println(my_buffer);
for(int j =0; j < strlen(my_buffer); j++)
{
Serial.print(j);
Serial.print(") ");
Serial.println(my_buffer[j]);
}
Serial.println("=============");
if(llength > 0)
{
scpi_execute_command(&ctx, my_buffer,llength);
}
delay(100);
}
}
}
void loop()
{
}
/*
* Respond to *IDN?
*/
scpi_error_t identify(struct scpi_parser_context* context, struct scpi_token* command)
{
scpi_free_tokens(command);
Serial.println("MKR ZERO");
return SCPI_SUCCESS;
}
/*
* Respond to the command :MEASURE:PRINT
*/
scpi_error_t print_value(struct scpi_parser_context* context, struct scpi_token* command)
{
scpi_free_tokens(command);
Serial.println("Level 1 reached");
return SCPI_SUCCESS;
}
/*
* Respond to the command :VALUE:PRINT1?
*/
scpi_error_t print1_value(struct scpi_parser_context* context, struct scpi_token* command)
{
scpi_free_tokens(command);
Serial.println("Level 2 reached");
return SCPI_SUCCESS;
}
Which gives a output :
Initializing SD card...
initialization done.
Line read from the sd card is :*IDN?
6
my_buffer:
0) *
1) I
2) D
3) N
4) ?
5)
=============
Line read from the sd card is ::MEASURE:PRINT
15
my_buffer:
0) :
1) M
2) E
3) A
4) S
5) U
6) R
7) E
8) :
9) P
10) R
11) I
12) N
13) T
14)
=============
Line read from the sd card is ::VALUE:PRINT1?14
my_buffer:
0) :
1) V
2) A
3) L
4) U
5) E
6) :
7) P
8) R
9) I
10) N
11) T
12) 1
13) ?
=============
Level 2 reached
Here , I read 3 commands written on a new line from commands3.txt file . It reads a extra character from the line (which is blank space).
I have tried withreadStringuntil('\r'): and the results are:
Initializing SD card...
initialization done.
Line read from the sd card is :*IDN?5
my_buffer:
0) *
1) I
2) D
3) N
4) ?
=============
MKR ZERO
Line read from the sd card is :
:MEASURE:PRINT15
my_buffer:
0)
1) :
2) M
3) E
4) A
5) S
6) U
7) R
8) E
9) :
10) P
11) R
12) I
13) N
14) T
=============
Line read from the sd card is :
:VALUE:PRINT1?15
my_buffer:
0)
1) :
2) V
3) A
4) L
5) U
6) E
7) :
8) P
9) R
10) I
11) N
12) T
13) 1
14) ?
=============
Again it takes a blank space which is obvious because it is carraige return and writes at the first position of next line.
My temporary fix is to add :
llength = llength - 1;
and a don't care character in the last command , so that it truncates it.
and after this it works fine..
but , is there any other way to fix it.