sizeof returns 6

I need to produce an LCD print function in C# for a microchip PIC. I need that print function to extract the characters out of a given String one at the time. It is for an I2C LCD. I am testing this function in aruino and I ran into a small problem.

int BufLen;

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  String text = "";

  if (Serial.available()) {         // if I sent text
    while (Serial.available()) {    // if the buffer still contains bytes
      text += (char)Serial.read();  // read de bytes as char and add them to the string text
      delayMicroseconds(60);        // needed to prevent code from leavign the while loop to soon  
    }
    LCDprint(text);                // print function with argument text 
  }
}

void LCDprint(String text)
{
  for (int i = 0; i < sizeof text ; i++) { // I tried sizeof(text) and sizeof text, no difference
    Serial.print(text[i]);                 // I only get 6 characters maximum regardles of text's true length
  }
  Serial.println();
 // Serial.println(text);                // this line does print well
}

I have a problem with the sizeof function, it keeps returning 6 instead of the correct number of characters and I dont know why that is. If I type “1234567890” I only see “123456”

If I use Serial.println(text); instead of printing one char at the time I do get the correct text on the monitor.

how do I get the real size of my String? for use in the for-loop

If you were passing a char* then you would use strlen. I think the String class has a length() method, but I don't use the String class for much since it tends to waste memory and microcontrollers don't have much to waste.

      delayMicroseconds(60);        // needed to prevent code from leavign the while loop to soon

\ Nonsense. Proper reading of serial data does NOT require any delays.

@PaulS

String text = "";

  if (Serial.available()) {        
    while (Serial.available()) {   
      text += (char)Serial.read();  
      delayMicroseconds(60);        
    }
  }

I always use these lines of code to capture a String send from my monitor of a variable length. I am gonna to send Strings of a variabele length as argument in my print function
If I have a constant length of say 6 bytes than I would use: if (Serial.available() == 6) for instance. I know I can also use serial.peek() to scan for a certain character before reading the buffer

Without this delay, the program would be done with the while loop when the next byte is still to be received. And as my program has nothing else to do, it does not even remotely matter one tiny bit that I use a delay.

Your comment is just a mere complaint without any form of a constructive critism, alternative or a good tip/advice << that is called: hating.

So unless you want to help on this forum and can provide me with an alternative, good tip or something, stop bitching about my code and go be productive.

Delta_G: If you were passing a char* then you would use strlen. I think the String class has a length() method, but I don't use the String class for much since it tends to waste memory and microcontrollers don't have much to waste.

text.length() has solved the problem, thank you.

Without this delay, the program would be done with the while loop when the next byte is still to be received. And as my program has nothing else to do, it does not even remotely matter one tiny bit that I use a delay.

Someday, it might, and then you are hosed. It’s far better to use an end-of-packet marker, and read data, storing it if appropriate, using the data only when the end-of-packet marker arrives.

Your comment is just a mere complaint without any form of a constructive critism, alternative or a good tip/advice << that is called: hating.

Nonsense. There are plenty of threads on how to properly read serial data. Your band-aid solution is close to the bottom of the list of options in preferred order.

bask185:
I need to produce an LCD print function in C# for a microchip PIC. I need that print function to extract the characters out of a given String one at the time. It is for an I2C LCD. I am testing this function in aruino and I ran into a small problem.

int BufLen;

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  String text = “”;

if (Serial.available()) {        // if I sent text
    while (Serial.available()) {    // if the buffer still contains bytes
      text += (char)Serial.read();  // read de bytes as char and add them to the string text
      delayMicroseconds(60);        // needed to prevent code from leavign the while loop to soon 
    }
    LCDprint(text);                // print function with argument text
  }
}

void LCDprint(String text)
{
  for (int i = 0; i < sizeof text ; i++) { // I tried sizeof(text) and sizeof text, no difference
    Serial.print(text[i]);                // I only get 6 characters maximum regardles of text’s true length
  }
  Serial.println();
// Serial.println(text);                // this line does print well
}





I have a problem with the sizeof function, it keeps returning 6 instead of the correct number of characters and I dont know why that is. If I type "1234567890" I only see "123456"

If I use Serial.println(text); instead of printing one char at the time I do get the correct text on the monitor.

how do I get the real size of my String? for use in the for-loop

It is interesting that using only a 60 microsecond delay is enough inter-character delay.
Because I calculate that one character takes …
10 / 115200 = 86.8 microseconds
Apparently, the Total Execution time of all three of these lines of code …

   while (Serial.available()) {
      text += (char)Serial.read();
      delayMicroseconds(60);
   }

add up to create enough Total Inter-Character Delay to prevent dropping of any characters?

EDIT: changed from 9 bits to 10 bits

Because I calculate that one character takes ... 9 / 115200 = 78.125 microseconds

10 / 115200

One start/eight data/one stop.

Was I constructive enough in my criticism?

Nonsense. Proper reading of serial data does NOT require any delays.

Well, that is just a half ass answer if you don't qualify it with the additional conditions to make it "proper".

Not using delay makes it "proper", duh. It's not like there aren't enough resources to find out how to do it properly.

Groove: 10 / 115200

One start/eight data/one stop.

Was I constructive enough in my criticism?

Oops, I forgot about the Start Bit, I was just using "8-N-1". But now, 10 / 115200 = 86.8 microseconds. Now doesn't that make the minimum required Inter-Character delay even longer? The issue is worse than I originally thought. The code waits only 60 uS but the next character takes almost 87 uS to arrive?

The "Total Loop Delay" appears to be even more "sensitive" to ... a) The exact CPU Execution Time of the three loop instructions b) Compiler Optimizations c) Library changes d) CPU Clock Speed

@Groove, Why the bad attitude towards me?

Groove: Was I constructive enough in my criticism?

mrsummitville:
@Groove,
Why the bad attitude towards me?

I doubt that was aimed at you but rather the OP who was bitching about the answer from @PaulS not including all the stuff he could go read for himself.

Delta_G: I doubt that was aimed at you but rather the OP who was bitching about the answer from @PaulS not including all the stuff he could go read for himself.

Correct.

PaulS:
It’s far better to use an end-of-packet marker, and read data, storing it if appropriate, using the data only when the end-of-packet marker arrives

I litterly said the exact same thing but with other words “I know I can also use serial.peek() to scan for a certain character before reading the buffer”. captain obivious :wink: :smiley:

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  String text = "";

  if (Serial.available()) {        
    while (Serial.peek() != '@') { // works but is not entirely bug free.. yet
      if (Serial.available()) {        // if you type hello@ you should see just hello, ......most of the time, that is
        text += (char)Serial.read();
      }
    }
    while (Serial.available()) Serial.read();
    LCDprint(text);
  }
}

void LCDprint(String text)
{
  for (int i = 0; i < text.length() ; i++) {
    Serial.print(text[i]);
  }
  Serial.println();
}

mrsummitville:
Oops, I forgot about the Start Bit, I was just using “8-N-1”.
But now, 10 / 115200 = 86.8 microseconds.
Now doesn’t that make the minimum required Inter-Character delay even longer?
The issue is worse than I originally thought.
The code waits only 60 uS but the next character takes almost 87 uS to arrive?

The “Total Loop Delay” appears to be even more “sensitive” to …
a) The exact CPU Execution Time of the three loop instructions
b) Compiler Optimizations
c) Library changes
d) CPU Clock Speed

The delay of 60us is indeed long enough, a while ago I found this number by trial and error. 50us is too short.

but eh, can we stop now, I said I got my answer in post #4 and we aready at #13. Thanks for the assistance :wink:

bask185: The delay of 60us is indeed long enough, a while ago I found this number by trial and error. 50us is too short.

It depends on the baud rate.

At 115200 a character arrives every 87us or so. Your 60us only works because of other delays you have no control over. And if you slowed the baud down it wouldn't work anymore.

Not using delay makes it "proper", duh.

Really? As the serial buffer fills slower than the arduino empties the buffer, I don't think simply removing the delay will work.

bask185: I need to produce an LCD print function in C# for a microchip PIC.

I am amused that no-one has picked you up on this. This is the Arduino forum. Microchip has their own one.

However since what you posted looks like Arduino code, I'll just confirm that PaulS is right. Your use of delay() to get incoming serial data is incorrect. Serial data is asynchronous, there is no guarantee that it arrives in a particular time frame. Since other posters are asking for a "more helpful" response, here is one:

http://www.gammon.com.au/serial

“Your use of delay() to get incoming serial data is incorrect” Seriously? bite me, I mean really.

In the OP I asked one single question: “how do I get the real size of my String? for use in the for-loop”.
That is all I wanted to know.

The only thing I wanted here was that people would take a look at LCD.print() function instead of my simple way to read an example string of text for use in the function. I will only use the print function for the microcontroller. And I wont use any Serial command when I use a PIC.

Starting to talk about how wrong I read serial data is called: going off-topic.

Than I said in this order:
“I am gonna to send Strings of a variabele length as argument in my print function”, (<< what matters, I could also have done lcd.print(“I got my answer now”); to test sizeof but I thought it was more fun to send text myself.)
“text.length() has solved the problem, thank you.”
“but eh, can we stop now, I said I got my answer in post #4 and we aready at #13. Thanks for the assistance”
And yet here we are with another person going entirely off-topic after I said 2 times that I got my answer and that I am done.

But if you have to go off-topic and I also mentioned this in the OP. I will use an I2C LCD. PICs can also do I2C communication. I already deciphered the I2C bus, I know what bytes to send with the PIC in order to get characters on the LCD.

I just asked for a little help about the C# function sizeof which works on both platforms.
The print function’s sole purpose is to get the characters out of a RANDOM string of text
(which I happen to send via the serial monitor solely for test purpose) and transform the characters to the 2 required bytes for to send over the I2C bus.

And besides does it matter that I use a delay for a program? No it doesn’t, the arduino doesnt have stepper motors to drive, the arduino is not multiplexing an LED matrix and the arduino doesnt have to monitor an I2C bus as a slave.

I just needed to know to get the ammount of characters out of a String, that is all.

Don’t get me wrong, I mean no disrespect and I am glad that people want to help, but helping is answering one’s question and not:
complaining,
going off-topic or
complaining even more more after it has been said times that the OP is DONE twice!!

And for the record, I do not require any help to figure out how to read Serial data properly.

char c;
String text = "";

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  if (Serial.available()) {  // if a byte is in buffer
    c = Serial.read();       // read the byte
    
    if (c == '@') {          // compare byte to end marker            
      Serial.println(text);     // in case of end marker print print the text 
      text = "";                // empty text
    } else {
      text += c;               // if byte is not endmarker, add the character to the text
    }
  }                             // If I would be able to close dis topic I would have down so after post #4
}

bask185: Don't get me wrong, I mean no disrespect and I am glad that people want to help, but helping is answering one's question and not: complaining, going off-topic or complaining even more more after it has been said times that the OP is DONE twice!!

Sorry.

Sometimes people appreciate it if you spot other problems in their code, other than the one they personally noticed.

For example, if you had written elsewhere:

if (a = 3)

When you meant:

if (a == 3)

Would you complain that pointing it out is off-topic? Perhaps you would, others would say "hey, thanks! I didn't notice that. You just saved me hours of work".

bask185: And for the record, I do not require any help to figure out how to read Serial data properly.

char c;
String text = "";

void setup() {   Serial.begin(115200); }

void loop() {   if (Serial.available()) {  // if a byte is in buffer     c = Serial.read();      // read the byte         if (c == '@') {          // compare byte to end marker                  Serial.println(text);    // in case of end marker print print the text       text = "";                // empty text     } else {       text += c;              // if byte is not endmarker, add the character to the text     }   } }

Nice joke.

More comments would be OFF TOPIC.