Triggered ADC readings

Dependencies:   rgb_sensor

Dependents:   rgb_sensor_buffer_example rgb_sensor_detection

rgb_sensor_buffer.cpp

Committer:
meriac
Date:
2014-07-08
Revision:
2:8fbb1cd0c2d9
Parent:
0:bbd86bfe6577

File content as of revision 2:8fbb1cd0c2d9:

/* Discrete RGB color sensor (buffered)
 *
 * - 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.
 */

/* initialize globally */
#include <mbed.h>
#include "rgb_sensor_buffer.h"

RGB_SensorBuffer* RGB_SensorBuffer::m_global = NULL;

RGB_SensorBuffer::RGB_SensorBuffer(PinName red, PinName green, PinName blue, PinName adc)
    :RGB_Sensor(red,green,blue,adc)
{
    /* allow only one instance */
    if(m_global)
    {
        m_initialized = false;
        return;
    }

    m_global = this;
    m_initialized = true;
}

bool RGB_SensorBuffer::__callback(const TRGB &color)
{
    return m_global ? m_global->callback(color) : false;
}

bool RGB_SensorBuffer::callback(const TRGB &color)
{
    int avg;

    if(!m_buffer)
        return false;

    avg = (color.ch.red + color.ch.green + color.ch.blue)/(3*RGB_OVERSAMPLING);

    if(!m_buffer_pos)
    {
        /* wait for trigger */
        if(avg<=m_treshold)
            return true;            
    }
    else
        /* wait for termination */
        if(avg>m_treshold)
            m_buffer_spurious=0;
        else
        {
            m_buffer_spurious++;
            
            /* ignore spurious blobs */
            if(m_buffer_spurious>=RGB_SENSOR_BUFFER_SPURIOUS_COUNT)
            {
                m_buffer_pos -= m_buffer_spurious;
                m_buffer_spurious = 0;

                if(m_buffer_pos<RGB_SENSOR_BUFFER_MIN)
                {
                    m_buffer_pos = 0;
                    return true;
                }
                return false;
            }
            else
                return true;
        }

    /* record color */
    if(m_buffer_pos<m_count)
        m_buffer[m_buffer_pos++] = color;

    /* finish after buffer is full */
    return m_buffer_pos<m_count;
}

int RGB_SensorBuffer::trigger(TRGB* rgb, int count, int treshold)
{
    if(!m_initialized)
        return -1;

    /* remember settings */
    m_buffer = rgb;
    m_buffer_pos = m_buffer_spurious = 0;
    m_count = count;
    m_treshold = treshold;

    return (capture(__callback) && wait()) ? m_buffer_pos : -2;
}