When to use VOLATILE?

Is there a good practice rule when using VOLATILE? I seems if I set my char c = client.read() as VOLATILE it works better than if I don't.

I'm getting HTML data posted to me very quickly and I'm doing string compares to parse and find the chars I need. Using VOLATILE, seems to let me do this, otherwise, I get garbage sometimes.

How is this implemented in the AVR/Arduino platform?

When data is shared with an interrupt service routine.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1261124850

But I’m not using interrupts. I’m reading bytes from the Ethernet Shield as fast as they come and do string compares. So for some reason, using volatile is lets me keep up.

If you'd like more help, you'll have to provide more information. Posting your Sketch (please use code tags) would be a good start.

My sketch is pretty big which won't translate well in bits and pieces... I'm just trying to understand how the volatile qualifier is used. My guess is that the reason why it's helping me out is because when I read in bytes from the buffer then do a compare, using volatile keeps it in memory rather than stored to a register. The data is coming in fast and I'm looping every byte and reading ahead too. That's my only guess... just wanted to know for sure.

I'm looping every byte and reading ahead too.

Reading ahead, before the serial data has arrived? Neat trick. Care to show how your doing that?

You're not ready for those details yet... ;)

Joking aside, what I meant by "read ahead" is not reading data before it arrives, because we all know that is technically impossible, but I have a "read ahead" parser so I can pick which data I want to keep and throw out the stuff I don't. The data changes rapidly which is why I think the volatile qualifier helps... or is it just by chance...

The data changes rapidly which is why I think the volatile qualifier helps... or is it just by chance...

We will never know unless you post the code. No code, then only vague answers can follow.

Lefty

OK, I’ll put you to the test then… ;D

Here is an example of a readTo function. I want to detect (“read to”) a particular incoming string. Seems like removing volatile from the read causes issues… timing coincidences?

void readTo(Client client, String str)
{
unsigned long startTime = millis();
volatile boolean found = false;

while (((millis() - startTime ) < 3));

while (client.available()){
volatile char c = client.read();
if (c == str.charAt(0)){
found = true;
for (int i=1; i<str.length(); i++){
c = client.read();
if (c != str.charAt(i)){
found = false;
break;
}
}
if (found){
return;
}
}
}
}

Sorry, looks all greek to me. ;)

Lefty

Well, joking aside.. The program starts with a fancy way to say delay(3) and then uses the standard method to check the occurance of a specific string in a stream without backtracking.

However I see no reason why VOLATILE should have any influece on the program's behaviour...

VOLATILE has nothing to do with interruupts - it has no chance there! - but with the calling of routines. E.g. a called routine might know the address of a local variable from the calling routine and access it.

If not declared VOLATILE, that variable might not have the value as assumed when reading the program text. The compiler rarely keeps variables in registers over external routine calls, however it can know when a local variable is no longer used (and will be discarded anyhow at the end of the routine) and thus might not store to it in the first place...

Another example: a good optimizing compiler will discard code like:

if (x!=x) {....}

If x is declared volatile it will at least generate the code, for what reason ever...

I'm using that method of "delay" because delay(3) is blocking, isn't it?

So VOLATILE fixing anything in this example may just be coincidence... I'll remove it and test again and see if I can repro each time.

The major issue I'm having seems to be related to timing or buffers. The arduino is acting as a server and when a client (via Ethernet Shield) connects and posts data, I read it. The data at times is over 8k so I read in the bytes and process it, storing only about 350 bytes of it.

I'm using a MEGA, so it shouldn't be a RAM usage issue (I'm checking it at the end of each disconnect)

…because delay(3) is blocking, isn’t it?

Yes, but your code is “blocking”, too :wink:
This here is directly copied from the library:

void delay(unsigned long ms)
{
      unsigned long start = millis();
      while (millis() - start <= ms);
}

hahaha… geez. Thanks for catching that. :-/

VOLATILE has nothing to do with interruupts

But it is very useful (in many cases essential) in the management of variables accessed in both interrupt service routines and mainline code.