Circular_Buffer

Interesting - that was shown as used in post #107 on a CB >> Circular_Buffer<uint16_t, 2048> hz; :: hz.pop_front(HzArray, HzSamples);

When the note says the flush wasn't working.
 
you are correct, flush is not used on CBA, only effective on CB :)
post 107 code shows he is in fact using CB

sorry, re-read, okay yeah the command can be called on CB, but wont do anything really, its for CBA only, he must remove the overload or switch to CBA, depending on his setup

looks like he only needs CB, so he has to do a for loop and read/pop/pop_front/pop_back into a local array as needed
 
But that was a CB then? .flush was giving dupe stats and using the line in #126 worked?

Flush and clear are shown in ReadMe under : Methods for circular array buffer … same as for Methods for circular ring buffer

So would this work to clear the data from a CB in a CBA? :: hz.front()[ tIC ].clear();
 
i could add an array feature to CB like what turtler tried to do using overload, internally the library would create a temp buffer to fill it with the circular queue and feed that to the user
 
Starting to get a little lost, however could be because of jetlag.
The issue with my system is that HzSamples is different value for every 10 deg segment and can vary from 2048 samples to 10 samples, depending how fast the people are cycling. If I am using push.back, should I just use pop.back to get the samples that filled the CB during that 10 degree segment? My current method seems to work, because I flush it every single time, but only after I transfer it to another array (HzArray).
What do you mean by overload?
 
if you only want to sample last 10 entries you should use 16 instead of 2048, the oldest entries will be overwritten when added to queue, im on my phone ill be home to help out better soon :)
 
No, I sometimes have 2048 values, this happens when the cyclists do a standing start and are pedaling slow, but producing a lot of torque (high Hz values). However as the cyclists speed up, they are producing less torque (lower Hz), which means I might only have 10 Hz samples for every 10 degree segment of the pedal revolution. Trust me is confusing and annoying, since I also have to write this data to an SD card every 10 degree segment, which makes it hard because getting 512 byte chunks to write to sd card took a bit of time to figure out.
Thanks again, learning a lot.
 
in CB you can use the ::peek(index) feature, where you could peek in a for loop for example to read entries in the circular buffer queue.

Since you are using CB and not CBA, front() wont be used, peek() will be used. note that this doesn’t remove the entries, but allows you to peek into the buffer to see what is in there.

Lets say you create a CB of 15 entries, to read from 9-14 (if it’s full), you can for loop ::peek(9) to peek(14)
if your buffer is only half full, peek will wrap around and start reading the the front. If this isn’t obvious you should also check size before requesting “too many” from peek, else you’ll read out of bounds im sure :)
 
i was re looking over post 107 and
Code:
hz.pop_front(HzArray, HzSamples);
      hz.flush();//was getting repeat hz

the reason you got repeat values was because you never read every byte inside the queue which dequeues it. flush did indeed work as intended, but if you have 2000 entries for example, you must pop it via pop/read/pop_front 2000 times, or simply flush/clear to clear it. pop_front(buf,size) is ONLY used for CBA, so when you ran that it actually did nothing, basically ignored your request, thus making you think it had repeat values, which it did, because they were still there :)
if you pop_front() (without any overload), a single byte will be removed from the front of the queue, so you’ll be left with 1999 items. hope all is clear now :)

is your intention to copy the buffer to an array to feed it to the SD? you’ll need a for loop to read()/pop()/pop_front() the data into the array then so it will both populate your array and also clear out the circular buffer at same time.
 
Now I am getting confused. The system I am using now seems to be working great and don't get repeat values. From your github readme you have this listed under Circular Buffers:
T pop_front(T *buffer, uint16_t length) { return readBytes(buffer,length); } // read the front of the queue into a buffer and remove it
I just want to make sure my program is running as quick as possible so no data is missed, so adding in a loop to read out 2048 values seems like it would take longer than using memmove, which I think pop_front uses.
My exact intention is to read the buffer to an array (but only as many values as I had for that 10 degree segment), and repeat over and over.
I just looked at the data I have been collecting and I don't have repeat values any more and I use pop_front(buffer, length).
 
yes you are correct i completely forgot, pop_front in CB works differently than in CBA, but they do pretty much same thing.

the CBA (array version) uses memmove completely as the arrays are fixed.
the CB (circular buffer version) uses memmove ONLY if the data doesn’t wrap around, if it does, it’ll fallback to a for loop instead. So it’s working as expected for you :)
 
Last edited:
This will also work if you want to index a bunch of circular buffers directly, without pointing to them using the CBA's front() method

Code:
  Circular_Buffer<uint16_t, 2048>xx[2];


  xx[0].push_back(0x06);
  xx[0].push_back(0x07);
  xx[0].push_back(0x08);

  xx[1].push_back(0x02);
  xx[1].push_back(0x03);
  xx[1].push_back(0x04);
  xx[1].push_back(0x05);

  Serial.println("\tIndex [0]");
  Serial.print("Size: "); Serial.println(xx[0].size());
  Serial.println(xx[0].read());
  Serial.println(xx[0].read());
  Serial.println(xx[0].read());

  Serial.println("\tIndex [1]");
  Serial.print("Size: "); Serial.println(xx[1].size());
  Serial.println(xx[1].read());
  Serial.println(xx[1].read());
  Serial.println(xx[1].read());
  Serial.println(xx[1].read());

Output:
Code:
	Index [0]
Size: 3
6
7
8
	Index [1]
Size: 4
2
3
4
5
 
Last edited:
Added new feature for Circular_Buffer (CBA): isEqual

This will confirm if your queues already contain the buffer your passing in. bool 1 is returned if a match is found, otherwise 0 is returned for not found.
 
New feature added to Circular Buffer Arrays: findRemove.

This has the same capability as find and replace methods, however, instead of finding or replacing, this actually removes the item from the queue. This method shifts all the consumer entries upwards via memmove afterwards and doesn't touch the producer endpoint.

An example was added to demonstrate the use:

https://github.com/tonton81/Circula...findRemove_Example/CBA_findRemove_Example.ino

CANquitto is the first to use it for an active node listing, removing inactive nodes.
 
Last edited:
@tonton81 - I cloned your Circular Buffer library and ran circular_buffer_example.ino. Everything seemed to work fine except print_test.print and print_test.println.

Here is a stripped down version with the same results:
Code:
#include "circular_buffer.h"


Circular_Buffer<uint16_t, 32> c5;
Circular_Buffer<uint32_t, 32, 250> print_test;

void setup() {
  Serial.begin(1);
  delay(2000);
  Serial.println("----------------------");

  for ( uint16_t i = 0; i < 34; i++ ) c5.write(i);
  while ( c5.size() > 0 ) {
    Serial.println(c5.read());
  } Serial.println("OK");
  
  print_test.print("Hello World");
  print_test.print("  ");
  print_test.println("Teensy here!");

Serial.print("print_test.size() = ");
Serial.println(print_test.size(),DEC);

  while ( print_test.size() > 0 ) {
    Serial.print((char)print_test.read());
  } Serial.println("OK");
}

void loop() {

}

Here is the output:
Code:
----------------------
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
OK
print_test.size() = 0
OK

print_test.size() is returning 0 and none of the strings are being printed. I check through the CB thread but did not see anything about this issue.
Have I missed something?

Thanks

EDIT: I have tried several version of Arduino and TD's.
 
The .write and .read are on c5. That would take it empty.

But the size print showing "print_test.size() = 0" is on print_test:
Code:
Serial.print("print_test.size() = ");
Serial.println(print_test.size(),DEC);

And that shows zero after three print_test.print()'s?
 
The .write and .read are on c5. That would take it empty.

But the size print showing "print_test.size() = 0" is on print_test:
Code:
Serial.print("print_test.size() = ");
Serial.println(print_test.size(),DEC);

And that shows zero after three print_test.print()'s?

You are right! Not enough sleep I guess. The print_test.read() has not been performed yet before print_test.size is tested and returns 0.
 
print_test is a multidinensional array. The print functions are for the circular buffers not circular arrays, it stays at 0 because the function aborts. This is expected
 
Tonton81,

I just cloned your repo and tried to compile the circular_buffer_example sketch for a Teensy 3.2. I got a compile error as follows:

circular_buffer_example.ino.elf section `.bss' will not fit in region `RAM'

and

region `RAM' overflowed by 912 bytes

Any clues to what I am doing wrong? If it helps, I got the same error in both VS2019 CE/Visual Micro and the Arduino IDE

TIA,

Frank
 
Never mind - I figured it out. The RAM requirements for the example just barely exceeded the available 64K on the T3.2, but plenty of room on a T3.5 ;-)

Code:
Program circular_buffer_example size: 19,832 bytes (used 4% of a 524,288 byte maximum) (10.74 secs)
Minimum Memory Usage: [COLOR="#FF0000"]66500[/COLOR] bytes (25% of a 262136 byte maximum)
Maybe the example should use

Code:
Circular_Buffer<uint16_t, 1024> cb;
or
Circular_Buffer<uint32_t, 32, 200> print_test;

instead? Especially since the only thing the 'print_test' section of the example does is demonstrate that the 'print()' function fails when applied to a circular array ;-).

Frank
 
Last edited:
So I'm studying the output from the example, trying to figure out what's going on, but I gotta say it's a bit of a slog.

It appears that the c5 section is supposed to be demonstrating what happens when data is written past the 'end' of a circular buffer

Code:
  for ( uint16_t i = 0; i < 34; i++ ) c5.write(i);
  while ( c5.size() > 0 ) 
  {
    Serial.println(c5.read());
  } 
  Serial.println("OK");

but I kinda expected the first two lines of the printout to be 32 and 33 followed by 2,3.... 31 not 2 and 3. What am I missing here? Am I just applying linear thinking to a circular buffer? :)

The example creates cb, cb2, cb3, cb4 & (ignoring print_test) c5, and I assume each object was created to demonstrate a particular aspect of your circular buffer structure. Maybe a one-line comment on each line describing what each object will be used to demonstrate, and a couple of explanatory lines at the start of each demonstration section?

TIA,

Frank
 
Back
Top