Median filtered & triggered + buffered RGB readings

Dependencies:   mbed rgb_sensor_buffer

main.cpp

Committer:
meriac
Date:
2014-07-08
Revision:
7:bc856471c871
Parent:
6:3f5ea82fdf62

File content as of revision 7:bc856471c871:

/* Discrete RGB color sensor
 *
 * - uses single-channel light-dependent resistor (via ADC)
 *   and a RGB LED.
 * -  compensates background light
 *
 * Copyright (c) 2014 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <mbed.h>
#include "rgb_sensor_buffer.h"

#define DEBUG

#define RGB_TRESHOLD 220
#define COUNT(x) (sizeof(x)/sizeof(x[0]))
#define RGB_VALUES 512

/* serial console */
static TRGB g_buffer[RGB_VALUES];
static int g_median[RGB_VALUES];
static Serial console(USBTX, USBRX);

#ifdef DEBUG
static void rgb_print(const TRGB &color)
{
    int i;

    console.printf("\t[");
    for(i=0; i<COUNT(color.data); i++)
        console.printf("%s%4i", i?",":"", color.data[i] / RGB_OVERSAMPLING);
    console.printf("]");
}
#endif/*DEBUG*/

static int median_compare(const void* a, const void *b)
{
        return *((int*)a) - *((int*)b);
}

static bool median(TRGB &color, int count)
{
    int channel, i;

    if(count<=0)
        return false;

    /* sort all three RGB channels to get median */
    for(channel=0; channel<3; channel++)
    {
        for(i=0; i<count; i++)
            g_median[i] = g_buffer[i].data[channel];

        qsort(&g_median, count, sizeof(g_median[0]), &median_compare);

        color.data[channel] = g_median[count/2];
    }

    return true;
}


int main() {
    int res;
    double magnitude;
    TRGB color;

    console.baud(115200);

    /* R,G,B pins and ADC for light dependent resistor */
    RGB_SensorBuffer rgb(p23,p24,p25,p20);

    /* needed for time measurement */
    Timer timer;

    while(1) {

        /* start four channel RGB conversion */
        timer.reset();
        timer.start();

        res = rgb.trigger(g_buffer, COUNT(g_buffer), RGB_TRESHOLD);       

        /* stop time measurement */
        timer.stop();
    
        if(res<=0)
        {
            console.printf("// failed to capture RGB values (%i)\r\n", res);
            while(1);
        }

        /* calculate RGB median */
        median(color, res);
        /* print normalized median */
        magnitude = sqrt(
            ( (double)color.ch.red   * color.ch.red   )+
            ( (double)color.ch.green * color.ch.green )+
            ( (double)color.ch.blue  * color.ch.blue  )
        );
        console.printf("\t[%1.4f,%1.4f,%1.4f,%5i], // %i values in %ims (%i/s)\n\r",
            color.ch.red   / magnitude,
            color.ch.green / magnitude,
            color.ch.blue  / magnitude,
            (int)((magnitude / RGB_OVERSAMPLING)+0.5),
            res,
            timer.read_ms(),
            (res*1000UL)/timer.read_ms()
        );

#ifdef DEBUG
        int i;
        console.printf("\r\nvar test = [\r\n",
            res,
            timer.read_ms(),
            (res*1000UL)/timer.read_ms());

        for(i=0; i<res; i++)
        {
            rgb_print(g_buffer[i]);
            console.printf(i<(res-1) ? ",\r\n":"];\r\n\r\n");
        }
#endif/*DEBUG*/

    }
}