Serial.print Word and Variable in One Transmission

Hi all,

I have a very quick question!

How do I Serial.print a word and a variable in one Serial transmission?

Like this (Except needs to be rewritten correct Arduino way!)

  Serial.print ("time",ago1); //send the minutes since received over BT

Thanks,

Zeb

ZebH:
Hi all,

I have a very quick question!

How do I Serial.print a word and a variable in one Serial transmission?

Like this (Except needs to be rewritten correct Arduino way!)

  Serial.print ("time",ago1); //send the minutes since received over BT

Thanks,

Zeb

Serial.print("time");
Serial.print(ago1);

What advantage do you think you'll have by putting it all in one statement? It won't make things any faster or more efficient. Serial data goes out one character at a time no matter how many statements you use to write it.

If you're just lazy and don't want to write then create a macro, but beware the many caveats that come with macros. Best practice would be to just use two lines of code.

#define PRINT_TWO_LINES(x,y) Serial.print(x); Serial.print(y);

Hi Delta_G,

Why it needs to be in 1 transmission is it is sending via an HM-10, so when the phone receives the message it needs something to distinguish lat, long, time.

I have tried writing a variable like you said:

int time1 = 0; //variable for storing the word "time" and how long ago the message was received
void LastMessage(){
  /*If Last Message Button Clicked on Phone App*/
  ago1 = (millis() - rxtime1) /1000 / 60; //the variable that stores how long ago the packet was received = the millis now minus the millis when the packet was received then convert this into minutes
  delay (500);

  time1 = ("t", ago1);
  delay (20);

  Serial.print ("Alerts"); //send the minutes since received over BT
  delay(500);

  Serial.print (time1); //send the minutes since received over BT
  delay(500);
  
  Serial.print (lat1); //send the Latitude over BT
  delay (500);
 
  Serial.print (lng1); //send the Longitude over BT
  delay(500);
 
  }

The variable is sent correctly, but the letter "t" is not included when the message is sent!

Why might this be? Is it because I initialized the variable as "int"?

Thanks very much,

Zeb

ZebH:
Why it needs to be in 1 transmission is it is sending via an HM-10, so when the phone receives the message it needs something to distinguish lat, long, time.

That information doesn't change the situation one bit. If you need to distinguish lat, long, time, then you just need to format your data to allow it to be separated into its components (try separating it with a unique character like a comma). You seem to be attempting to do this by separating the transmissions with delays, but that is a horrible way to go about it.

ZebH:
I have tried writing a variable like you said:

...

ZebH:

time1 = ("t", ago1);

Read what Delta_G wrote again. In no way did they recommend you to do this. It will never work. If you want to understand what is happening in that code, study how the comma operator works:
https://en.cppreference.com/w/cpp/language/operator_other#Built-in_comma_operator

ZebH:
Hi Delta_G,

Why it needs to be in 1 transmission is it is sending via an HM-10, so when the phone receives the message it needs something to distinguish lat, long, time.

The HM-10 won't know the difference if you use one line or write each character with it's own Serial.write. The characters go out one at a time either way. If you sniffed the data line you wouldn't be able to tell the difference. When you call Serial.print the stuff you're printing gets added to a buffer and gets sent out by an interrupt. If you call another Serial print right after then that gets tagged onto the end of that buffer just the same as it would have if you had written one line.

I promise, there's no difference.

I have tried writing a variable like you said:

I never said anything like that. I was talking about writing a macro. Completely different thing.

First off, an int variable just hold numbers. It won't hold text. And secondly, you can't have a single variable holding two values like that. You could write a class or a struct or something that has more than one value in it, but that's a completely different thing and I only mention it because some pedant is going to say that it is technically possible. While that's true, it won't help you at all.

Because of the way the comma operator works this:

time1 = ("t", ago1);

is the same as:

time1 = ago1;

Seriously, what you need to do here is not worry about having it all in one line. Just use two separate print statements. It will not make any difference to the receiver.

What I was talking about with the macro is this:

#define PRINT_TWO_LINES(x,y) Serial.print(x); Serial.print(y);

And then in your code write:

PRINT_TWO_LINES("time" , x)

And the preprocessor will turn that into:

Serial.print("time"); Serial.print(x);

Still two lines but you got to be lazy and write one.

But this comes with some dangers. Macros aren't like functions. There are some bad things that can happen if you use them and don't understand them.

This macro would really not be best practice. Best practice would be to just write two separate print statements.

Zeb, serial transmits 1 BIT at a time (nowhere near as fast as possible) and assembles the byte at the receiving end.

At 115200 baud it takes 1388 16MHz cycles per byte transmitted.

When you print, the chars/bytes go to the serial output buffer where they get sent from over time (1388 cycles per) after your print statement with one exception: if you fill the buffer and print has more chars to send it will wait until space clears enough to get the whole print into the buffer -- something necessary but you don't want your sketch hanging like that so don't overfill the buffer! The higher the baud rate, the faster the buffer will empty, why to not use 9600 by default.

You can easily print more before the first byte is sent.

Serial is very slow in Arduino time.

Baud rate is bit rate. Default Arduino serial sends a start bit, 8 data bits and a stop bit. Baud/10 is the serial byte speed.

Hi all,

Sorry about my misunderstanding!

When I try to run the code it gives an error
"expected ')' before ';' token"
about this line of code:

  #define time1 ("t", ago1);

The "define" line is put just before the void setup section but after the variables are initialized. Should I post all of my code?

What am I doing wrong?

Thanks for all your help and patience!

Zeb

Again, that is NOT at all what I wrote. Damn, I'm sorry I even mentioned it. The macro thing I wrote IS NOT WHAT YOU WANT. DON'T DO IT. YOU DON'T UNDERSTAND MACROS. THEY WILL CAUSE YOU PROBLEMS IF YOU DON'T UNDERSTAND THEM.

Also know that Macro gets turned into TWO print statements by the preprocessor. So you're not getting anything from it except a way to be lazy. You're still using print twice with it.

What you want to do is to write two separate print lines. I don't know how many different ways I can say that. You want to write two separate print lines. Just like I have been telling you this whole thread. You think you need it all in one line. But you are wrong about that.

Hi Delta_G,

OK I will stick to using 2 Serial.prints since it works.

Do you know of any helpful links to learn about macros?

I am working on a school project and am still a beginner in programming but I would like to expand my knowledge and learn as I go!

Thank you all for your help and patience!

Thanks again,

Zeb

ZebH:
Do you know of any helpful links to learn about macros?

www.google.com

ZebH:
Do you know of any helpful links to learn about macros?

This gives a quick overview of macros and other preprocessor directives:
http://www.cplusplus.com/doc/tutorial/preprocessor/
The most important thing to understand about preprocessor directives is that they are very useful tools that allow you to do things you could not do by any other means, but they also have the potential to make your code extremely difficult to understand and troubleshoot. For this reason, I recommend only using preprocessor directives when there is no other alternative.

Thanks very much pert! (Especially for all your help and patience!)

Thanks again,

Zeb

You do know that AVR chip Arduinos only move or work on one byte at a time?

You could write a function to do it. I'm not sure if you know about writing your own functions.

  Serial.print ("time",ago1); //send the minutes since received over BT

not tested

void printLabelAndValue( char *label, byte minutes )
{
  Serial.print( label ); // should include any spacing
  Serial.print( minutes, DEC );
  return;
}

..... and later in code

  printLabelAndValue( "time", ago1 );  // the function does the job, no need to macro

Dangerous ground there…

Hi GoForSmoke,

Yes I have learnt how to write functions thanks to Delta_G!

Thanks for your example that's just what I wanted.

And no I did not know that the chip itself only moved at 1 byte at a time, but now I know!

Thanks again,

Zeb

Delta_G gave you info on macros, which are NOT functions.

Functions make debugging easier if anything. They are safer and saner.

Hi GoForSmoke,

Sorry I wasn't clear what I meant, Delta_G taught me how to use functions in another post a few weeks ago!

Thanks for all you help!

Zeb