Tutorial on the basics of using the "buffer" instruction?

I am encountering the "buffer" instruction for the first time, and can't find a nice tutorial explaining how this instruction is used. I understand it can get very complicated in the C++ language. All I need for the moment is basic introductory information so I can see how the instruction is supposed to work. Here is the current sketch I am studying. Note that my understanding got derailed where I have put the "?" in the comments I have added. The only reason I got this far is that the author of the book was indicating what he was doing. But he did not go into decent description of this step, so I have no idea what all the variations of "buffer" might be, or how to use them. As is all too common, no listing in the Arduino Reference, and I could not find anything useful while searching all the library files in the Arduino 0022 installation on my PC. I also cannot find anything useful trying to search online for "arduino - buffer". Similar searching for "C++ buffer" did not do me any good either. I get the impression the buffer instruction is embedded into some part of the Arduino IDE, but that is all I can figure out.

//MotionSensor/Buffering/Buffering.pde

const unsigned int X_AXIS_PIN = 2; // Declare constants:
const unsigned int Y_AXIS_PIN = 1;
const unsigned int Z_AXIS_PIN = 0;
const unsigned int NUM_AXES = 3;
const unsigned int PINS[NUM_AXES] = {    //[ brackets ] are used to indicate the number of elements in an array. Here, since NUM_AXES was set to the value of 3, we are saying the same thing as PINS[3], which means
                                         //the array constant "PINS" has 3 elements. These 3 elements are then declared in the next line, as the X, Y, and Z_AXIS_PIN. 



  X_AXIS_PIN, Y_AXIS_PIN, Z_AXIS_PIN
};
const unsigned int BUFFER_SIZE = 16;
const unsigned int BAUD_RATE = 9600;

int buffer[NUM_AXES][BUFFER_SIZE];      // here we are declaring the variable "buffer" as an integer array with 3 values, and ?? (how does [BUFFER_SIZE] apply in this line??
int buffer_pos[NUM_AXES] = { 0 };      //??

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

int get_axis(const int axis) {
  delay(1);
  buffer[axis][buffer_pos[axis]] = analogRead(PINS[axis]);
  buffer_pos[axis] = (buffer_pos[axis] + 1) % BUFFER_SIZE;  
  
  long sum = 0;
  for (int i = 0; i < BUFFER_SIZE; i++)
      sum += buffer[axis][i];
      return round(sum / BUFFER_SIZE);
}

int get_x() { return get_axis(0); }
int get_y() { return get_axis(1); }
int get_z() { return get_axis(2); }

void loop() {
  Serial.print(get_x());
  Serial.print(" ");
  Serial.print(get_y());
  Serial.print(" ");
  Serial.println(get_z());
}

buffer is a 2 dimensional array - http://www.arduino.cc/en/Reference/Array

NUM_AXES and BUFFER_SIZE are its dimensions

so for every one of the 3 axis there is an array of 16 values.

It's not an instruction. It's just a variable name.

That code makes a 2 dimensional array and calls it "buffer". It could have called it "my_array" and it would worked the same.

as to where you have put the?? well you are declaring an array their. it is not necessary were you would (put the info in) my terminology is not great. anyway i think that might just declare all the elementals of the array to 0. i don't know.? does it compile?

I am encountering the "buffer" instruction for the first time, and can't find a nice tutorial explaining how this instruction is used.

You won't find any information on a such an instruction because there is none. A 'buffer' is a block of memory that is used for the temporary storage of data. For example you may be using some sort of serial interface to gather data from a sensor and you may be manipulating that data before displaying it. You would use a pair of pointers to deal with the buffer. One pointer would be used by the part of your program that gets data from the sensor to determine where (in the buffer) to put the next piece of incoming data. A second pointer would be used by the part of your program that manipulates the data to determine where to retrieve (from the buffer) the next piece of information to work on. You want to make sure that the second pointer never overtakes the first and you want to make sure that both pointers wrap around to the beginning of the buffer when they reach the upper limit.

Don

1 Like

Thank you ALL for the information! It is sometimes easier to learn something AFTER what you 'thought you knew' is shown to be incorrect. Such is the case here. I got caught on this sort of thing once before, so this time as I read "buffer" is not an instruction in your replies, I thought "why did I not see that"? Then I thought "what would I NEED to notice to prevent this mistake again?" I think the answer is rather obvious. One would not need to "declare" a legitimate instruction. :slight_smile:

So the fact that the lines

int buffer[NUM_AXES][BUFFER_SIZE];      
int buffer_pos[NUM_AXES] = { 0 };

both start with "int" (the integer declaration instruction) and end with ";" should now clue me into the fact that a variable is being declared here. Functions usually end with "()". I hope not to make this same mistake again. :slight_smile:

Thanks again for the help!

EVP:
as to where you have put the?? well you are declaring an array their. it is not necessary were you would (put the info in) my terminology is not great. anyway i think that might just declare all the elementals of the array to 0. i don't know.? does it compile?

Yes, it compiles and runs OK. I was just going back through it to put those comments in as part of my learning process. I like to review the working sketch (from the book I am reading) and then explain to myself what each line of code is doing. Even when the book's author does a good job of explaining it, I find it sticks in my memory better if I put it into my own words. If I can't, it means I don't yet understand that line of code.

Thanks.

I have another question about this same sketch. In the line:

int get_axis(const int axis) {

he is declaring an integer variable named "get_axis", which is returning a value. What I don't see is the use of "const" within the (const int axis). If I understand this, he is defining the parameters of the value being returned, saying it is a constant, and in integer, and will be referred to by the name "axis". But........ constants, as I know them (like in the beginning lines of the sketch) use UPPERCASE names, and variables use lower case names. (I may have read that is a 'preference' and not a rule, please clarify.) So if he is again 'declaring a constant' in this situation, why not use "AXIS" instead of "axis"? Or is it just a matter of personal preference?

he is declaring an integer variable named "get_axis"

Nope. The parenthesis indicate that "get_axis" is a function (that returns an "int").

"const" modifies the parameter "axis" (and only the parameter). It indicates to the compiler that "get_axis" will never modify the parameter. In other words, this is not allowed (give it a try)...

int get_axis(const int axis) 
{
  axis = 13;

Programmers do this to help ensure their code is free from bugs and to help indicate how "axis" is used. Imagine that "get_axis" is very large (several pages). Let's say the coder foolishly created a variable named "axs". Late one night the coder is madly typing away and, somewhere in the middle of the large complex "get_axis", accidentally uses "axis" instead of "axs". Later code that relied on "axis" would stop working. This scenario can actually be very difficult to debug. By making "axis" a "const", the compiler does not allow "axis" to be modified. The mistake would be caught at compile time.

As a side-effect, "const" parameters can often be optimized.

Ah! Shot down by my own failure to watch those () and ; AGAIN. Hopefully I'll get it "someday".

Thanks for setting me straight!

:slight_smile:

In the above sketch (and in the next version I am working on now) in the following lines:

int buffer[NUM_AXES][BUFFER_SIZE];      
int buffer_pos[NUM_AXES] = { 0 };

Why is the value of { 0 } surrounded by braces?

buffer_pos is the pointer variable for the [NUM_AXES] buffer he made, right? He is setting it to zero here (I recall what one of you said above about keeping close track on the buffer and pointer values not 'looping' around onto themselves). I don't see any reference in the buffer tutorial on that link one of you mentioned to using braces when setting this value to zero. What does that mean?

Zoandar:
Why is the value of { 0 } surrounded by braces?

It creates a list of initializers...

int some_primes[5] = { 2, 3, 5, 7, 11 };

If the list is too short (not enough values), the compiler uses zeros for the remaining values.

He is setting it to zero here

He is and it is not necessary. Global / static data is automatically initialized to zero. But, there is no harm either.

Things like that are usually done to indicate an assumption made by the coder. In other words, when he wrote the "buffer_pos" code he assumed that all the elements would be initialized to zero. If they are not initialized to zero, the code will not work correctly. It's sort-of like a comment.

buffer_pos is the pointer variable for the [NUM_AXES] buffer he made, right?

buffer_pos is not a pointer type, it is a simple "int" array.

Thanks, both of you. I was mistaken in my recollection of what I had read in the book. What he actually says is "we define an array of buffer positions" in regard to that line. I presume "initializers" means "buffer positions" in the post from Coding Badly?

But I am still unclear on the braces. How is this different than just using

int buffer_pos[NUM_AXES] = 0 ;

I would like to be able to remember what the braces "mean" here. Since I was unable to find " = { 0 }" anywhere else in lengthy Google searches of Arduino and C websites, I get the feeling this may be an "uncommon" use of this syntax.

buffer positions

buffer positions is not the same as buffer pointers.

For "position", read "index".

Zoandar:
But I am still unclear on the braces. How is this different than just using

int buffer_pos[NUM_AXES] = 0 ;

...does not compile. For a simple data-type (like an "int") only one value is needed to initialize it because it can only store one value...

int iNeedOneValue = 13;

For an array data-type (like an array of "int") more than one value is needed to initialize it because it can store multiple values. The braces are used to define the list of values used to initialize the array...

int iNeedFive[5] = { 97, 1678, 6, 169, 769 };

iNeedFive[0] is initialized to 97; iNeedFive[1] is initialized to 1678; etcetera.

I would like to be able to remember what the braces "mean" here.

You are telling the compiler, here's a list a values I want you to use to initialize my array.

Since I was unable to find " = { 0 }" anywhere else in lengthy Google searches of Arduino and C websites, I get the feeling this may be an "uncommon" use of this syntax

I suspect " = { 0 }" is rather uncommon for global / static data. It is somewhat common for local / automatic arrays.

Since I was unable to find " = { 0 }" anywhere else in lengthy Google searches of Arduino and C websites, I get the feeling this may be an "uncommon" use of this syntax

It would be reasonably common. You need to search in the context of initializing arrays. Otherwise you find a lot of stuff about soccer scores.

Whilst Coding Badly is correct that static variables are automatically set to zero, automatic variables aren't*. So this could be a reasonable way of initializing an array in a function:

void foo ()
{
int buffer_pos[NUM_AXES] = { 0 };  // start with all zero

// blah blah
}

*Edit: He didn't imply they were.

Again thank you all for the information. But I think the "magic bullet" may have just come from a single word in your post, when you just said " // start with all zero".

For whatever reasons this was not clear to me before, what he is doing with this rather cryptic instruction is setting ALL THREE of the array elements to ZERO in ONE STATEMENT. Correct?

If I am right, then, knowing that he had defined the constant NUM_AXES equal to 3, in this sketch interchanging these statements would both have the exact same effect:

int buffer_pos[NUM_AXES] = { 0 };  // start with all zero

int buffer_pos[NUM_AXES] = { 0, 0, 0 };  // start with all zero

I eagerly await confirmation. :slight_smile: (While I look at that link for array initialization - thank you!)

YES!!! Your link just verified the above. I wish the book's author had mentioned this, because it looks to be a VERY handy function. However, it also seems that he could just as simply used

int buffer_pos[NUM_AXES] ;  // start with all zero

OR

int buffer_pos[NUM_AXES] = {};  // start with all zero

Thanks!!! :grin:

... this rather cryptic instruction is setting ALL THREE of the array elements to ZERO in ONE STATEMENT. Correct?

Yes, setting the entire array to zero. More specifically, everything beyond the stated initializers. So to be pedantic, you requested the first position to be initialized to zero, and the compiler initialized the rest to zero for you, as you have stated that the array is to be initialized in the first place (by using "= ...").

Zoandar:
However, it also seems that he could just as simply used

int buffer_pos[NUM_AXES] ;  // start with all zero

OR

int buffer_pos[NUM_AXES] = {};  // start with all zero

Your first example won't work with "auto" variables. That is, if they are defined inside a function. So it is dangerous to do that, because you might copy and paste them (from a statically defined place to inside a function). Also it relies upon you remembering that static variables are automatically initialized.

Your second example works but personally I think it is a bit cryptic.

I prefer:

int buffer_pos[NUM_AXES] = { 0 };  // start with all zero

Your second example works but personally I think it is a bit cryptic.

I prefer:

int buffer_pos[NUM_AXES] = { 0 };  // start with all zero

The important thing to keep in mind here is still that the number of explicitly valued positions in the array is limited to the number of explicit initializers provided. The rest of the positions in the array may or may not be valued with 0.

Prove this to yourself by changing where this statement is positioned (global, in a function, with and without the static keyword, etc.) and change the initial value to something other than 0, like 37. Then, use a for loop to print the index and value for each position in the array.

When the number of explicit initializers is less than the size of the array, the array values will NOT all be whatever (single) initializer is provided.