Does the program stall and wait for Serial.readBytesUntil() to complete or is this command interrupt driven?
It's a blocking function. It just sits there waiting until the terminator character is detected, the determined length has been read, or it times out. The default timeout is 1000 ms but you can change it via Serial.setTimeout():
Thank you.
That's what I thought or was afraid of.
adwsystems:
or was afraid of.
Why You can easily work around that by modifying Robin2's example #2 in Serial Input Basics. You can even add a non-blocking timeout if needed.
Because the program was written by someone else using readBytesUntil(). The functionality I need to add needs to use serialEvent(), so I will have to rewrite the majority of the program including parsing and retesting the modified existing functionality. It is what it is.
Although I have never used serial event, it should be straight forward; mix it with Robin's code and you should be done.
Why the need for serial event? Do you have any blocking code?
Yes. Serial.readBytesUntil()
There will be "commands" coming in the serial port at any random time therefore Serial.readBytesUntil() cannot be used.
No, that's not what I meant. Any others (e.g. a for loop that takes ages due to complex calculations)? If not, I have great difficulty understanding why you need serial event unless the current code also uses it and it's the easiest adjustment.
Let me ask this:
What happens if I add one Serial.readBytesUntil() to the program to wait for serial input; not knowing when the input will be received?
adwsystems:
Let me ask this:What happens if I add one Serial.readBytesUntil() to the program to wait for serial input; not knowing when the input will be received?
It will wait until its timeout expires for the "until" character and then it will return. I think the default timeout is 1 second.
You have received a lot of advice that you do not seem to have been able to make use of so you need to post your complete program so we can understand what you are having a problem with.
...R
It will wait till the requested character is received. If it's already received, there will not be a delay. If the requested character is not received within the given time, it will result in corrupted data and a delay.
It's all the things that you don't want but I guess that you already figured that out.
sterretje:
It's all the things that you don't want but I guess that you already figured that out.
I have other things to do during the timeout period.
Robin2:
You have received a lot of advice that you do not seem to have been able to make use of so you need to post your complete program so we can understand what you are having a problem with....R
Actually I haven't received any "advice...to make use of". I have received valuable information on the operation of the Serial.readBytesUntil() function.
At this time, the program is still a work in progress. I'm working to convert the PLX-DAQ sample program from Serial.readBytesUntil() to serialEvent(), to add it in to an existing program. Using Serial.readBytesUntil() to wait for commands via the serial port will have a large detrimental impact on the execution of the current program.
adwsystems:
Actually I haven't received any "advice...to make use of".
Maybe read reply #3 again.
sterretje:
Maybe read reply #3 again.
OK. Read it again. Still haven't received any "advice...to make use of". Reply #3 is almost irrelevant at Robin2 doesn't like serialEvent() and provides no examples to that end.
Thanks for the link though. I do like read other solutions, even if irrelevant, as they may provide an idea to morph and use myself.
adwsystems:
OK. Read it again. Still haven't received any "advice...to make use of". Reply #3 is almost irrelevant at Robin2 doesn't like serialEvent() and provides no examples to that end.
This sounds like a problem for every solution.
Post your complete program and then maybe someone can suggest something useful.
...R
I don't know if Robin likes serial event or not. And it does not matter.
The principle behind his examples is that it's non-blocking. So you have time to do other stuff till the full message is received and hence no need to use serial event. The only reason, as I stated in reply #7 is if your current code uses it and it's easier to implement in which case you can mix and match.
Robin2:
This sounds like a problem for every solution.Post your complete program and then maybe someone can suggest something useful.
...R
Careful what you ask for.
/*
int i = 0;
void setup() {
// open serial connection
Serial.begin(9600);
//Serial.println("CLEARDATA"); // clears sheet starting at row 2
Serial.println("CLEARSHEET"); // clears sheet starting at row 1
// define 5 columns named "Date", "Time", "Timer", "Counter" and "millis"
Serial.println("LABEL,Date,Time,Timer,Counter,millis");
// set the names for the 3 checkboxes
Serial.println("CUSTOMBOX1,LABEL,Stop logging at 250?");
Serial.println("CUSTOMBOX2,LABEL,Resume log at 350?");
Serial.println("CUSTOMBOX3,LABEL,Quit at 450?");
// check 2 of the 3 checkboxes (first two to true, third to false)
Serial.println("CUSTOMBOX1,SET,1");
Serial.println("CUSTOMBOX2,SET,1");
Serial.println("CUSTOMBOX3,SET,0");
}
void loop() {
// simple print out of number and millis. Output e.g.,: "DATA,DATE,TIME,TIMER,4711,13374,AUTOSCROLL_20"
Serial.println( (String) "DATA,DATE,TIME,TIMER," + i++ + "," + millis() + ",AUTOSCROLL_20" );
// alternative writing method:
/* Serial.print("DATA,DATE,TIME,TIMER,");
Serial.print(i++); Serial.print(",");
Serial.println(millis());
Serial.print(","); Serial.println("SCROLLDATA_20"); */
// clear some cells in Excel (rectangle range from B10 to D20)
if(i==100)
Serial.println("ClearRange,B,10,D,20");
// do a simple beep in Excel on PC
if(i==150)
Serial.println("BEEP");
// read a value (in this case integer) from Excel (from a sheet by name)
if(i==200)
{
Serial.println("CELL,GET,FROMSHEET,Simple Data,E,4"); // ==> request value from sheet
// Serial.println("CELL,GET,E4"); ==> short version to read from active sheet in Excel
int readvalue = Serial.readStringUntil(10).toInt(); // get response. Note: the '10' is important! Always use but never change ;-)
Serial.println( (String) "Value of cell E4 is: " + readvalue); // result displayed in Excel DirectDebugWindow to double check
}
// check value of custombox1 on PLX DAQ in Excel and if
// checkbox is checked then send the command to pause logging
if(i==250)
{
Serial.println("CUSTOMBOX1,GET");
int stoplogging = Serial.readStringUntil(10).toInt();
// this information can be seen in the direct debug window on PLX DAQ in Excel
Serial.println( (String) "Value of stoplogging/checkbox is: " + stoplogging);
if(stoplogging)
Serial.println("PAUSELOGGING");
}
// get a true random number from the computer
if(i==300)
{
Serial.println("GETRANDOM,-4321,12345"); // between -4321 to 12345
int rndseed = Serial.readStringUntil(10).toInt();
Serial.println( (String) "Got random value '" + rndseed + "' from Excel" );
// Note: this information is not posted to the Excel sheet because "DATA" is missing
// instead this information can be seen in the direct debug window
}
// and now resume logging
if(i==350)
{
Serial.println("CUSTOMBOX2,GET");
int resumelogging = Serial.readStringUntil(10).toInt();
if(resumelogging)
Serial.println("RESUMELOGGING");
}
// post to specific cells on default sheet as well as named sheet
if(i==400)
{
Serial.println("CELL,SET,G10,400 test 1 string"); // default sheet active in PLX DAQ Excel
Serial.println("CELL,SET,ONSHEET,Simple Data,G,11,400 test 2 string"); // named sheet available in PLX DAQ Excel
}
// and for forced quit of Excel with saving the file first
if(i==123)
{
Serial.println("CUSTOMBOX3,GET");
if(Serial.readStringUntil(10).toInt()) {
Serial.println("SAVEWORKBOOKAS,450-Lines-File");
Serial.println("FORCEEXCELQUIT");
}
else
Serial.println("No forced Excel quit requested!");
}
}
OK. Here is the start of my program. I haven't been able to add my code because the blocking commands keep fouling it up. So I need to remove all the blocking commands. Hmmm...Sounds like the point of the post #1.
I haven't a clue how this helps answer the original question. But if you would like to help rewrite, thanks.
Although on an aspect more to the original post, does Serial.readBytesUntil() get interrupted while waiting by ISRs?
Delta_G:
Really, an even better solution would be to have all the serial handling code in its own function and call it from the top or bottom of loop every time. Then instead of having to write the non-blocking receive out in each of those blocks, you could just use a boolean flag to let them know when their data was ready.
Even better, why not combine the non-blocking code into one entire subroutine and have that routine automatically executed when data is available?
Automatically executed as in interrupt driven, not via a polled function call.
Delta_G:
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (; {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
See where serialEventRun gets called? That calls serialEvent if Serial.available() returns greater than 0. IT doesn't do anything magic and IMHO it makes the code harder to maintain because it is being called by this "hidden" function. Weren't you against all of that the other day? There's never any case where you *need* to us serialEvent.
Seems like we have just had this conversation. In a previous post I was informed serialEvent() was interrupt driven. You have shown proof to the contrary.
If Arduino.h is calling serialEventRun() and Serial.available() is called in loop(), then isn't the same thing being checked twice?
adwsystems:
In a previous post I was informed serialEvent() was interrupt driven.
Post a link to the post that said that.
Right through this Thread people have been telling you that it is not - including in my Serial Input Basics
adwsystems:
Careful what you ask for.
I don't see any serialEvent() or readBytesUntil() in the code in that Reply
...R