init
This commit is contained in:
89
examples/p_cbuffer_example.c
Normal file
89
examples/p_cbuffer_example.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Penguin's Circular Buffer Example -- Turning a noisy bell curve into a less
|
||||
noisy bell curve
|
||||
|
||||
Here's an example of using the circular buffer library for sensor data:
|
||||
|
||||
Let's say I have a sensor that gives me temperature at 1khz (using ideals so
|
||||
it is exactly 1khz) If this sensor was only giving me raw analog data, I
|
||||
might want to do some processing on these values so that I can make sure the
|
||||
values are as clean as possible. The more samples we have, the closer we are
|
||||
to the actual value. The faster we gather samples, the closer we get to
|
||||
representing our data in realtime.
|
||||
|
||||
Using the sample rate, I can decide on a sampling window (in seconds) and an
|
||||
OSR (Oversampling Rate). The larger the buffer size, the more memory I need,
|
||||
so it is useful to find a happy medium between a large buffer and clean
|
||||
values.
|
||||
|
||||
A sampling window is the window of time in which we can accept values for an
|
||||
average value. Depending on your application, a sampling window may need to
|
||||
be extremely small or maybe not so small. A rocket going extremely fast using
|
||||
some sensor for real time controls will want an extremely small sampling
|
||||
window as well as a lot of measurements for both clean, near noiseless data
|
||||
and as close to realtime data as possible.
|
||||
|
||||
The sampling window is usually an engineering requirement given that can
|
||||
match the sampling rate of the sensor with the following: sampling window (in
|
||||
seconds) = 1 / frequency Here, the OSR is simply 1.
|
||||
|
||||
So at 1khz sample rate, let's say I decide I only need a 0.125 second sample
|
||||
window and I want to clean up some noisy data. We can now use this equation:
|
||||
OSR = frequency * sample window (in seconds)
|
||||
|
||||
All of these have ignored real world slowdowns like the time it takes to do
|
||||
math on lower end hardware, interrupts slightly delaying the math, etc
|
||||
Without wanting to do some hard analysis on whatever hardware we're using, I
|
||||
usually take my frequency and half it to ensure timing requirements are met,
|
||||
like so:
|
||||
|
||||
OSR = frequency / 2 * sample window
|
||||
|
||||
Please note: In applications that require real real-time data, this is not a
|
||||
good way of doing things.
|
||||
|
||||
*/
|
||||
|
||||
#include "p_cbuffer.h"
|
||||
|
||||
DEFINE_CBUFFER(int);
|
||||
#define CBUFFER_SIZE (6)
|
||||
|
||||
void display(cbuffer_int_t* cbuffer)
|
||||
{
|
||||
printf("Cbuffer:\n");
|
||||
for (int ind = 0; ind < cbuffer->msize; ind++)
|
||||
{
|
||||
printf("[%d]: %d\n", ind, cbuffer->buffer[ind]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
cbuffer_int_t cbuffer;
|
||||
int data[CBUFFER_SIZE];
|
||||
|
||||
cbuffer_int_init(&cbuffer, data, CBUFFER_SIZE);
|
||||
cbuffer.push(&cbuffer, 1);
|
||||
cbuffer.push(&cbuffer, 2);
|
||||
cbuffer.push(&cbuffer, 3);
|
||||
cbuffer.push(&cbuffer, 4);
|
||||
cbuffer.push(&cbuffer, 5);
|
||||
printf("Is cbuffer filled? %s\n",
|
||||
cbuffer.is_filled(&cbuffer) ? "Yes" : "No");
|
||||
cbuffer.push(&cbuffer, 6);
|
||||
printf("Is cbuffer filled? %s\n",
|
||||
cbuffer.is_filled(&cbuffer) ? "Yes" : "No");
|
||||
display(&cbuffer);
|
||||
cbuffer.push(&cbuffer, 7);
|
||||
display(&cbuffer);
|
||||
printf("Emptying cbuffer...\n");
|
||||
printf("Is cbuffer filled? %s\n",
|
||||
cbuffer.is_filled(&cbuffer) ? "Yes" : "No");
|
||||
cbuffer.empty(&cbuffer);
|
||||
cbuffer.push(&cbuffer, 8);
|
||||
display(&cbuffer);
|
||||
printf("Is cbuffer filled? %s\n",
|
||||
cbuffer.is_filled(&cbuffer) ? "Yes" : "No");
|
||||
}
|
||||
50
examples/p_queue_example.c
Normal file
50
examples/p_queue_example.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "p_queue.h"
|
||||
|
||||
DEFINE_QUEUE(int);
|
||||
|
||||
#define SIZE_QUEUE (256)
|
||||
|
||||
queue_int_t queue;
|
||||
int buffer[SIZE_QUEUE];
|
||||
|
||||
void display(queue_int_t* queue)
|
||||
{
|
||||
if (queue->csize == 0)
|
||||
{
|
||||
printf("queue is empty\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Queue:\n");
|
||||
int i = queue->head;
|
||||
for (int j = 0; j < queue->csize; j++)
|
||||
{
|
||||
printf("[%d]: %d ", i + j, queue->data[(i + j) % queue->msize]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argv, char** argc)
|
||||
{
|
||||
queue_int_init(&queue, buffer, SIZE_QUEUE);
|
||||
|
||||
// queue.enqueue(&queue, 10);
|
||||
queue.empty(&queue);
|
||||
printf("csize: %d\n", queue.csize);
|
||||
queue.enqueue(&queue, 20);
|
||||
queue.enqueue(&queue, 30);
|
||||
queue.enqueue(&queue, 40);
|
||||
display(&queue);
|
||||
queue.enqueue(&queue, 10);
|
||||
|
||||
int val = 0;
|
||||
queue.dequeue(&queue, &val);
|
||||
queue.dequeue(&queue, &val);
|
||||
|
||||
display(&queue);
|
||||
|
||||
queue.empty(&queue);
|
||||
|
||||
display(&queue);
|
||||
}
|
||||
Reference in New Issue
Block a user