Shorten my loops

Hi everyone!
Is there any way of shortening my overlapping loops expression in code below:

while (client.connected())
	{
		while (client.available() > 0)
		{
			char c = client.read();
			if (c == '#')
			{
				while (c != '\n')
				{
					// append till end of line
					c = client.read();
					hashtag_buffer[index] = c; // appending characters to buffer array
					index++;
				}
				hashtag_buffer[index - 2] = 0; // removing end line characters
			}
		}
	}

like, some fancy c++ syntax ? :slight_smile:

Why do you feel the need to shorten it?

Have look at the code in the 2nd example in Serial Input Basics. I believe it is doing the same sort of thing however it does so without blocking the Arduino waiting for data.

Note that it only uses WHILE for the quick process of getting all the characters that are already in the input buffer.

...R

Goto preferences.txt and change editor.tab.size setting to 4.

that is likely to lead to disappointment

 while (c != '\n') {
   // append till end of line
   c = client.read();
...

as you are reading from the client without ensuring the data is there, ready to be read

As a side note:
For thishashtag_buffer[index - 2] = 0; // removing end line characters the convention (does the same thing) is to write it ashashtag_buffer[index - 2] = '\0'; // removing end line charactersto show you are indeed using the NULL char to terminate your cString

Robin2:
Why do you feel the need to shorten it?

As I'm getting more into programming, seeing three while loops after one another, gives me impression that i'm doing something wrong or not efficient enough.

Robin2:
Have look at the code in the 2nd example in Serial Input Basics.

Thanks!! this looks just perfect!

DKWatson:
Goto preferences.txt and change editor.tab.size setting to 4.

:D:D

J-M-L:
that is likely to lead to disappointment

 while (c != '\n') {

// append till end of line
  c = client.read();
...



as you are reading from the client without ensuring the data is there, ready to be read

I thought that this line while

(client.available() > 0)

ensures that there is data to read. But I guess, yeah, this just means that there are data, not exclusively after #

atis-sedlenieks:
I thought that this line while

(client.available() > 0)

ensures that there is data to read. But I guess, yeah, this just means that there are data, not exclusively after #

yes you have at least 1 byte available but you don’t know if the whole line will make it there quickly enough

ohh and what's the best way to know if whole line is ready for WHILE loop? Delay ?

atis-sedlenieks:
ohh and what's the best way to know if whole line is ready for WHILE loop? Delay ?

NOOoooooo :slight_smile:

just see how it's done in Serial Input Basics tutorial --> you go read and extract whatever is available when it arrives. never try to second guess timing of something asynchronous with a delay or whatever

You can collapse the two outer loops:

while (client.connected() && client.available() > 0)
		{

C and C++ guarantee that if the expression on the left of the && is false, the expression on the right will not be evaluated. That way you can safely put:

    client = server.available();
    while (client && client.connected() && client.available() > 0)
        {

If there is no client ready and server object returns a NULL (zero) pointer. The first sub-expression in the ‘if’ will stop the other two sub-expressions from calling through a NULL pointer.

Note: I believe ‘client.available()’ will always return a non-zero value on the first call because ‘server’ doesn’t return a client until it has received data sent by the client. :frowning:

johnwasser:
That way you can safely put:

    client = server.available();

while (client && client.connected() && client.available() > 0)
        {

That won't make it work any better but it will make it harder to debug.

...R

I’ve been dealing with this problem all day… :confused:
I have php web page that’s pulling number from instagram, hashtag count.
So it just outputs plain number- example: #67 or #5077816
depending on hashtag I’m interested in.

So i have connected arduino GSM and it pulls this information via GPRS. All works fine until i want to convert that char array to integer or long integer.
In the code below all breaks at atoi(hashtag_result_str.c_str()) place:
It kind of restarts or jumps back to setup{}.
feels like some memory issue

	while (client.connected())
	{
		while (client.available() > 0)
		{
			char c = client.read();
			if (c == '#')
			{
				while (c != '\n')
				{
					// append till end of line
					c = client.read();
					hashtag_buffer[index] = c; // appending characters to buffer array
					index++;
				}
				hashtag_buffer[index - 2] = '\0'; // removing end line characters
			}
		}
	}
	// ////////////////parser END/////////////
	// ////converting to INT///////////
	String hashtag_result_str(hashtag_buffer);
	Serial.println("Hashtag STR result in function: " + hashtag_result_str);

	int hashtag_result_int = atoi(hashtag_result_str.c_str());
	Serial.println("Hashtag INT result in function: " + hashtag_result_int);

	// test if 67 function below
	if (hashtag_result_int < 100)
	{
		Serial.println(hashtag_result_int + "< 100");
	}
	else
	{
		Serial.println("fail..");
	}

The funny thing is, it kind of worked at one point :smiley: i managed to convert hashtag_result_str to integer and return value from this function.
But after trying to clean code it broke again…

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

Robin2:
Just use cstrings - char arrays terminated with '\0' (NULL).

Oh, ok, thanks for the info! I'll try to void String in future :slight_smile:

But, if i do conversion like this:

char hashtag_buffer[100]; //declared before setup{}

while (client.connected())
	{
		while (client.available() > 0)
		{
			char c = client.read();
			if (c == '#')
			{
				while (c != '\n')
				{
					// append till end of line
					c = client.read();
					hashtag_buffer[index] = c; // appending characters to buffer array
					index++;


				}
				//hashtag_buffer[index - 2] = '\0'; // removing end line characters
			}
		}
	}

int hashtag_result_int = atoi(hashtag_buffer.c_str());

i get an non-class error: error: request for member 'c_str' in 'hashtag_buffer', which is of non-class type 'char [100]'

atis-sedlenieks:
i get an non-class error: error: request for member 'c_str' in 'hashtag_buffer', which is of non-class type 'char [100]'

that's because you do: int hashtag_result_int = atoi(hashtag_buffer.c_str());
your buffer is already a cString, so you can call atoi() on the buffer directlyint hashtag_result_int = atoi(hashtag_buffer);

(you are still reading the client data without testing if there is anything there)

J-M-L:
your buffer is already a cString, so you can call atoi() on the buffer directlyint hashtag_result_int = atoi(hashtag_buffer);

I did try that right away, but i cannot Serail.println hashtag_result_int it just restarts arduino or somethnig.
Like, it jumps to the setup and then continues..

J-M-L:
(you are still reading the client data without testing if there is anything there)

yeah.. haven't figured out that one yet. :slight_smile:
the simple integer conversion took all day and still not working :frowning:

Print what you are trying to convert ... it might be garbage ...

J-M-L:
Print what you are trying to convert ... it might be garbage ...

I did, it's just number 67
When it comes from client.read() ir did this, to test data

c = client.read();
Serial.println(c);
Serial.println(c, HEX);
Serial.println(c, DEC);

i get:

6 (my char)
36 (HEX)
54 (DEC)
7 (char)
37 (HEX)
55 (DEC)
     (char)
D  (HEX)
13(DEC)
    (char)
A (HEX)
10 (DEC)

the last two array items i replace with '\0' with:

hashtag_buffer[index - 2] = '\0'; // removing end line characters

You print what comes - print what’s in the buffer just to be sure you don’t mess up with indexes (did not look at the code)

ok, so i kind of figured out, that when I serial.print my integer like:

int hashtag_result_int = atoi(hashtag_buffer);
	Serial.println("hashtag_result_int:"+ hashtag_result_int);

it stalls or something..

if i print just:

Serial.println(hashtag_result_int);

everything is ok. interesting...

when you do the + thingy in Serial.print you are actually trying to concatenate Strings (with a capital S, the class) which does not work that way (you are actually telling the compiler to print something that would be somewhere in memory + an offset). I'm pretty sure the compiler would give you a

[color=orange] warning: offset outside bounds of constant string[/color]

which you probably ignored (bad idea)

Either you write it by forcing the use of Strings

int hashtag_result_int = atoi(hashtag_buffer);
Serial.println(String("hashtag_result_int:") + hashtag_result_int);

or more simply and less memory intensive

int hashtag_result_int = atoi(hashtag_buffer);
Serial.print("hashtag_result_int:");
Serial.println (hashtag_result_int);

or even better if you want to store the text in flash memory

int hashtag_result_int = atoi(hashtag_buffer);
Serial.print(F("hashtag_result_int:"));
Serial.println (hashtag_result_int);