As I have been playing with the Arduino hardware platform, I have become more and more convinced of its usefulness. I generally appreciate all efforts to standardize in hardware and am excited about the large community this platform has received.
I quickly realized that were I to use this for my projects I would need an efficient storage of bytes that I couldn’t find in the community libraries as well as a buffered serial write which also hadn’t been implemented to my knowledge. I created these libraries and decided to share them here if anyone would be interested in using them.
These are the properties of the ByteBuffer library:
- Provides an efficient storage of bytes in a circular bytebuffer (stored as an array)
- Provides access to data from the head and tail of the buffer (get() and getFromBack(), putInt() and putIntInFront() etc.)
- Provides a nice way of converting bytes into larger datatypes, example: put(b1); put(b2); put(b3); put(b4); long data = getLong();
- Convenient method to have a one process write values to the end of a buffer and have another process handle bytes from the beginning of the buffer whenever it gets around to it
This project is now hosted on Google Code
https://code.google.com/p/arduino-buffered-serial/
Example usage
#include <ByteBuffer.h> /* Silly program that emulates buffered processing using a circular bytebuffer */ ByteBuffer buffer; void setup() { // Initialize the buffer with a capacity for 256 bytes buffer.init(256); // Init serial just to debug Serial.begin(9600); } int cnt = 0; void loop() { cnt++; // Every 100th update if( cnt%100 == 0 ){ buffer.clear(); buffer.put(200); // Put one byte at end buffer.putInt(2000); // Put one int at end buffer.putLong(20000); // Put one long at end buffer.putFloatInFront(200000); // Put one float at beginning } // Every 100th update (20 updates offset) if( (cnt+20)%100 == 0 ){ Serial.println("Received following bytes"); while( buffer.getSize() > 0 ) Serial.println(buffer.get(), DEC); Serial.println(""); } }

There are 2 things I don’t understand:
- purpose of float_bytes pointer, there is malloc for 2 floats in init(), but I don’t see it anywhere else.
- why is there no free(data) and free(float_bytes) in clear()
Thanks
Hi ebw
Thanks for your comment, the float_bytes pointer was actually a relic and not needed anymore. I used to use it to convert floats into bytes. I have removed it now.
The reason why free(data) is not inside clear() is because clear() should be called whenever the user of the buffer wants to put the buffer into its original state (flushing all data inside of it).
Your question made it clear to me that I wasn’t allowing users to free(data) so I created a method called deAllocate() which allows users to destroy buffers if they need to and retrieving the memory.
I also put little comments on the function of each method into the header file.
Best,
Siggi
Thanks for the explanations. The name of the method clear() make more sense now.
Best Regards
This might be an easy one, but how would I go about manipulating the buffer like I would an array?
For example, data logging – lets say I have a circular buffer running to collect a window of data (in bytes) very quickly and I wanted to take a “snapshot” of that data and then do things with it (scale, etc) and then save it somewhere.
Any ideas? Thank you very much for the help.
The buffer is backed by an array, I haven’t implemented this function, but copying the current contents of one buffer to another one wouldn’t be too hard. You would simply need to copy the contents of the backing buffer (and possibly not even all the data, only the amount of bytes that live between the start and length pointers) as well as copy the pointers for start and length. That would accomplish taking a snapshot of the current buffer.
Scaling a buffer might be a bit tougher because a buffer doesn’t know intrinsically what types of data it contains (for example it could contain 3 bytes, a float and an int). In the case of mixed types, scaling wouldn’t work, but if all the data was of the same type, scaling would simply mean doing a for loop through the buffer and multiplying ever instance in it with a scaling factor.
Currently there is a method that allows you to “peek” at a byte at an arbitrary index in the buffer, but there is no method that allows you to manipulate a byte at an arbitrary position (or simply write to it). This would need to be implemented and shouldn’t be too hard (if you use peek as an example) these methods might also need to be extended for the type of data you have in mind (int float etc) if it is not bytes.
Generally I advise against too much calculation on the embedded device though, if you can have advanced operations like multiple multiplications etc happen on the host computer and simply have the arduino do data sampling and communications, I think you could save a lot of dev time and possible errors.
Hope this helps
Hey, thanks for the info! Sounds like I’ll do the manipulation on the host computer.
Ok, just to clarify, since I will only be working with bytes I would use the “peek” method and “peek” at each byte to copy to another array?
for (int i=0; i <= 255; i++){
anotherarray[i] = peek(i);
}
now "anotherarray" has everything in the buffer? sorry I am still a little new to this stuff.
Yeah, a quick and dirty way to do this would b to do what you are doing except maybe do this instead:
for (int i=0; i < buffer.getSize(); i++){
anotherarray[i] = buffer.peek(i);
}
A more efficient implementation would be to copy the underlying byte[] data object for the buffer but currently it is declared private in the library with no explicit access. A slight modification to the library code could give access to it for this type of copying.
The thing is that peek(index) has a slight overhead of having to calculate the requested position in the buffer for every byte (this might be unnecessary for your purposes)
Excellent, thank you very much, I’ll give it a try. Your other projects are pretty awesome by the way.
I just tried to use the libary but with the Arduino IDE 1.00 you have to replace
#include “WProgram.h”
to
#if defined(ARDUINO) && ARDUINO >= 100
#include “Arduino.h”
#else
#include “WProgram.h”
#endif
in the ByteBuffer.h and the ByteBuffer.cpp
(from http://markus.jabs.name/2011/12/arduino-kennt-wprogram-nicht-mehr/)
Hope it helps someone.
Greetings!
Thanks Benjamin, I have now incorporated this change in the libraries
I looked at the code and it looks like it is big endian data format. This would be consistent with network endianness. Am I seeing this right? I am planning on using this code to build another protocol on top that uses big endian numbers.
yes Demolishun, I believe that to be the case