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

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.

Having read this reply and that of PaulS, I agree your preference leaves the best 'bread crumbs', which I usually find to my liking. :slight_smile:

Thanks!

PaulS:

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.

Being a beginner, I find that when one relies on something happening 'automatically' and, worse, with little or no understanding of the same, it opens the door to the possibility of long and frustrating sessions trying to figure out why some end result isn't happening. Black box technology is, for me, a frustrating thing which is never fully trusted or understood. This happens to be the actual motivation I had toward Arduino. The first description of it I read spelled it out as a better alternative to a beginner approach in the world of electronics, as opposed to attemtping to learn enough about the world of discrete component interaction to be able to design and build in a hobby environment. Having traveled both paths, I find this to be quite true, although the programming involved 'can' be just as steep a learning curve, depending mostly upon the teacher being pursued. :slight_smile:

That said, I wanted to learn enough about this particular issue so that I can instantly recognize the next time I see it. And knowing what I do now, thanks to you good folks, I see his use of { 0 } as likely the best choice considering the other options just discussed. I did read in that array initialization article about the cautions you presented. Given that this sketch has only a 3 element array in this scope, might it not have been better overall to just use { 0, 0, 0 }, which I would instantly have understood?

Still, learning about using the line he did was a worthwhile lesson.

Thanks!

Given that this sketch has only a 3 element array in this scope, might it not have been better overall to just use { 0, 0, 0 }, which I would instantly have understood?

Yes. Explicitly providing the wrong number of initializers is not a good practice.