I'm trying to read from a Serial and Sending this data trough serial Monitor.
Everything works well with this code:
if (Myserial1.available()) {
String data = Myserial1.readStringUntil('\n'); // Read from external port
Serial.print("Datas: ");
Serial.println(data);
}
But I need to read this values every 1 or 5 seconds, and when I try to add a simple delay in this way:
if (Myserial1.available()) {
String data = Myserial1.readStringUntil('\n'); // Read from external port
Serial.print("Datas: ");
Serial.println(data);
delay(1000);
}
That doesn't make sense, you need to read the data when it comes in, not at some arbitrary interval. Have you read this:
If not, I suggest you do, it is an excellent tutorial on how to do serial communications.
On a more general note using delay is asking for trouble because nothing else can happen while delay is delaying. Nothing. No reading a button, no updating a display, no turning an LED on or off. There are tutorials for this too.
Sorry, I explained myself badly.
I need to send data through another function every 1/5 seconds.
and when I save the variable or call the function at a specific time interval those are the data I see.
If you add delays you run the risk of buffer overflows. I think that thay is what is happening.
The correct way to approach this is to always read the incoming data but only send the latest received data when it's time; that implicates use of millis() or another clock source.
Question: how did you manage to get exactly the same timestamps in serial monitor?
The lines of code that you have posted are not the complete sketch.
Your code is badly formatted.
please do these things:
use to auto-formatting feature by pressing ctrl-t
delete the empty lines so that maximum one empty line is in your code between statements
post your complete sketch from the very first to the very last line
run your code and then mark, copy & paste the very actual output from the serial monitor as a code-section
EDIT
declaring a variable inside an if-condition makes this variable local to the scope of the if-condition
String data = MySerial1.readStringUntil('\n'); // Read data
which results in a compiler-error
exit status 1
'data' was not declared in this scope
In general using variables of type String on a microcontroller does often cause problems.
Each time you assign a new value to a variable of type String some new RAM is occupied. In many cases this leads to eating up all memory and then corrupting RAM that is used by other variables.
As an alternative you can use SafeString. The name is program.
data is a local variable, it ceases to exist at the end of the if statement where it is declared.
lastRequestTime is also a local variable, it gets set to 0 every time loop() executes, so the if statement checking for the time interval will always be false.
Using readStringUntil() can be a problem, that function will wait for a newline character before returning, which can slightly interfere with the timing of the send portion of the code (even worse if no newline is received, in which case the function returns when it times out). The use of String can also cause memory problems over the long term. Better to use the receive code in the Serial Input Basics linked to previously, and read the text into a char buffer.
something to send: 1000
something to send: 2000
something to send: 3000
something to send: 4000
hi
something to send: 5000
something to send: 6000
something to send: 7000
something to send: 8000
something to send: 9000
how are ya
something to send: 10000
something to send: 11000
something to send: 12000
something to send: 13000
fine
something to send: 14000
something to send: 15000
something to send: 16000
something to send: 17000
code
unsigned long lastRequestTime = 0;
const unsigned long Interval = 1000;
void loop()
{
unsigned long currentMillis = millis();
if (Serial.available()) {
String str = Serial.readStringUntil('\n');
Serial.println (str); // echo
}
if (currentMillis - lastRequestTime >= Interval) {
lastRequestTime = currentMillis;
Serial.print (" something to send: ");
Serial.println (currentMillis);
}
}
void setup() {
Serial.begin (9600);
}
The usual not explained hard to understand = hard to use non-blocking timing
.
.
commented more structured code with self-explaining names for everything
It uses the SafeString-library which you can install with the Arduino-IDE librarymanager
#include <SoftwareSerial.h>
#include <SafeString.h>
#include "SafeStringReader.h"
// adapt the software-serial Rx/Tx pins to match your hardware
SoftwareSerial MySerial1 (4, 5);
// create a non-blocking Serial-Read-In-object
// buffersize 32 byte
// terminating characters carriage return "\r"
createSafeStringReader(sfReader, 32, "\n");
//sfReader does the same as MySerial1.readStringUntil('\n')
// but in a non-blocking way
boolean stringComplete;
boolean newData = false;
unsigned long myDataSendTimer; // variable used for NON-blocking timing
// create a SafeString with name "data_SS"
// that can hold 32 characters
cSF(data_SS, 32);
void setup() {
Serial.begin(9600);
MySerial1.begin(9600);
Serial.println("Serial begin & mySerial1 begin done");
Serial.println("waiting for characters to be received...");
//sfReader.connect(MySerial1); // make sfReader receive from MySerial1
sfReader.connect(Serial); // make sfReader receive from Serial
}
void loop() {
// sfReader.read() results in true when the terminating character is received
// and you call sfReader.read() for the FIRST time
// all following up calls to sfReader.read() result in false
// until a NEW string is received which means it is the FIRST call
// for the new received string
stringComplete = sfReader.read();
if (stringComplete) {
newData = true; // new data arrived set flag to true
data_SS = sfReader;
myDataSendTimer = millis(); // store actual time in variable myDataSendTimer
}
if (newData) {
// check if 1005 milliseconds have passed by since last sfReader.read(); resulted in true
if ( TimePeriodIsOver(myDataSendTimer, 1005) ) {
// when REALLY 1005 millisconds HAVE passed by
Serial.println(data_SS);
newData = false; // data has been printed reset flag to false
}
}
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}