1

I want to read the MCU GPIO pin status and store it to an array of 10 numbers repeatedly. When the array is full, it should left shift the value and store the new value to a [9]th subscript position and continue.

How can i implement this as code in Embedded C ?

user5071535
  • 1,312
  • 8
  • 25
  • 42
Emlinux
  • 39
  • 2
  • 13

3 Answers3

2

Given that you're only storing 1 bit each time, an array isn't the only solution:

static uint16_t buffer = 0;

void gpio_add(bool pin_value)
{
    buffer >>= 1;
    if(pin_value) {buffer |= 0x0200;}
}

bool gpio_get_entry(uint8_t index)
{
    return !!(buffer & (1 << index));
}

Note that if you're taking this approach, you may as well store either 8 or 16 values.

If the purpose of this is to implement a simple debouncer (i.e. to determine if the pin level has remained stable for a while), then we can simply see if buffer is zero or 0x3FF.

Steve Melnikoff
  • 2,620
  • 1
  • 22
  • 24
  • This approach can also be used when designing fast-executing median filters for the removal of spikes/burst noise. You can use the various possible combinations of the result variable as an index to a lookup table, where each item is true or false. Or you could sort the bits/count the number of ones. – Lundin Aug 13 '15 at 06:38
  • Hi @Steve Melnikoff, Thanks for your reply. yeah, I need this to store and check the button_pin_status for debouncing. Please suggest me the process. Thanks. – Emlinux Aug 24 '15 at 05:14
0

If I understood well, it should look like something like this:

void insert(int* arr, int size, int value){
    int i = 0;
    for(int i=0; i < size-1; i++){
        arr[i] = arr[i+1];
    }
    arr[size-1] = value;
}

With size, the size of you're array (10 for you). You should initialize you're array with 0 or -1 to be sure. However I don't know the difference between ansi C and embedded C. Maybe "for(int i = ;...)" doesn't work and you'll have to create the variable i just before. Not sure if that's what you wanted.

Asoub
  • 2,273
  • 1
  • 20
  • 33
  • Hi Asoub, Thanks for your reply. I am already getting some value at GPIO pin of mcu [input = gpio_pin_read] and I want it to store in in array of 10 numbers. every time when I read the pin value, it should store it to the array......something like a[0].....a[1]....a[2]........atleast 10 values. my main point is how to store it in a array... – Emlinux Aug 11 '15 at 07:53
  • Do you use a clock or events for each read ? or something else ? How do you read those values ? – Asoub Aug 11 '15 at 08:04
  • You'll want to use a circular buffer instead of moving all the data each time. Also, this doesn't address how to design the actual port read, which is the tricky part of the question. – Lundin Aug 13 '15 at 06:29
  • I don't think moving ten values is so costly, but a circular buffer might, in fact, be more flexible. I don't know if the problem was about how to design it so events would fullfil the buffer and retreive values, in a more global way. – Asoub Aug 13 '15 at 08:29
0

Not sure what you mean exactly by 'Embedded C', but I write C for embedded systems, and I'd use something like the following. (The GpioPrint() function is really only for (my) debugging.)

#include <stdio.h>
#include <string.h>

// Returns the size of a[].
#define ARRAY_SZ(a) (sizeof a / sizeof a[0])

// Holds MCU-GPIO pin values.
typedef struct
{
    unsigned a[10]; // replace unsigned with your 'pin value' type
    unsigned n;     // values are in a[0..n-1]
} Gpio_t;

// Initialise the pin value store.
static void GpioInit(Gpio_t *gpio)
{
    gpio->n = 0;
}

// Add the new value to the pin store, removing the oldest if the store
// is full.
static void GpioAdd(Gpio_t *gpio, unsigned newVal)
{
    if (gpio->n < ARRAY_SZ(gpio->a))
    {
        gpio->a[gpio->n++] = newVal;
    }
    else
    {
        memmove(&gpio->a[0], &gpio->a[1], (gpio->n - 1) * sizeof gpio->a[0]);

        gpio->a[gpio->n - 1] = newVal;
    }
}

// Output the pin store contents.
static void GpioPrint(const Gpio_t *gpio)
{
    unsigned i;

    for (i = 0; i < gpio->n; i++)
    {
        printf("%2u: %10u\n", i, gpio->a[i]);
    }
}

// Test the functions.
int main(void)
{
    Gpio_t   gpio;
    unsigned newVal;

    GpioInit(&gpio);

    // Add 20 values to the pin store, checking the contents after each
    // addition.
    for (newVal = 0; newVal < 20; newVal++)
    {
        printf("add %u:\n", newVal);

        GpioAdd(&gpio, newVal);
        GpioPrint(&gpio);
    }

    return 0;
}
matth1j
  • 31
  • 5