PiSlingers library for AHRC competitions

IRObjDetector.cpp

Committer:
mpanetta
Date:
2012-11-03
Revision:
2:a9351d7f92b4
Parent:
1:695f4f4442d3

File content as of revision 2:a9351d7f92b4:

#include "IRObjDetector.h"
#include "tlc5916.h"

#define DWELL_TIME 25       // Time to wait between enabling IR transmitter LED and reading ADC result, in us.

void
IRObjDetector::scan(void)
{
    int i;
    uint32_t max = 0;
    int32_t  tmp = 0;
    
    //data[7] = ain.read_u16() >> 8; // Read the ambient level and store in last data slot.
    //data[7] = ain.read_u16(); // Read the ambient level and store in last data slot.    
    
    // Average 4 readings of ambient.
    tmp += ain.read_u16();
    tmp += ain.read_u16();
    tmp += ain.read_u16();
    tmp += ain.read_u16();
    
    // Store ambient level in last data slot.
    data[7] = tmp / 4;
    
    // Set the IR leds one at a time and read the reflection.    
    for (i = 0; i < 7; i++)
    {
        // Write the value to enable the LED
        tlc5916.write_reg(1 << i);
        // Enable the selected LED.
        tlc5916.enable();
        // Wait for output to stabilize
        wait_us(DWELL_TIME);
        // Read ADC value and subtract off ambient.
        //tmp = (ain.read_u16() >> 8) - data[7];
        //tmp = ain.read_u16() - data[7];
        // Average 4 readings
        tmp = 0;
        tmp += ain.read_u16();
        tmp += ain.read_u16();
        tmp += ain.read_u16();
        tmp += ain.read_u16();
        
        // Take reading and subtract off ambient.
        tmp = (tmp / 4) - data[7];
        
        if (tmp < 0)
        { 
            data[i] = 0;
            tmp     = 0;
        }
        else
            data[i] = tmp >> 8;
            
        // Disable the selected LED.
        tlc5916.disable();
        
        if (tmp > max) max = tmp;
    }
    
    calc_centeroid();
    
    brightness = max;

#if 0
    brightnessBins[currentBin++] = brightness;

    // Calculate running average over BRIGHTNESS_BINS bins.
    minBrightness = 0xFFFF;
    avgBrightness = 0;
    maxBrightness = 0; 
    for (int i = 0; i < BRIGHTNESS_BINS; i++)
    {   
        tmp = brightnessBins[i];
        if (minBrightness > tmp) minBrightness = tmp;
        avgBrightness += tmp;
        if (maxBrightness < tmp) maxBrightness = tmp;
    }
    avgBrightness = avgBrightness / BRIGHTNESS_BINS;    

    if (currentBin >= BRIGHTNESS_BINS)
        currentBin = 0;
#else
    avgBrightness = brightness;
#endif
}

float
IRObjDetector::get_weighted_avg_brightness(void)
{   
    if (debug != NULL)
    {
        debug->printf("IRObjDetector: Calculating weighted average.\r\n");
        debug->printf("IRObjDetector: minBrightness = 0x%4.4x\r\n", minBrightness);
        debug->printf("IRObjDetector: avgBrightness = 0x%4.4x\r\n", avgBrightness);
        debug->printf("IRObjDetector: minBrightness = 0x%4.4x\r\n", maxBrightness);
    }
    return (float)(avgBrightness) / (float)0xffff;
}

void
IRObjDetector::calc_centeroid(void)
{
    int i;
    
    uint32_t low;
    float sumA, sumB;
    
    low = 0xffff;
    for (i = 0; i < 7; i++)
    {
        if (data[i] < low) low = data[i];
    }
    
    sumA = sumB = 0;
    
    // Generate sums for centeroid data
    for (i = 0; i < 7; i++)
    {
        sumB += (data[i] - low) * (i + 1);
        sumA += data[i] - low;
    }
    
    // Get 'center' bin by taking the highest bin count and dividing by number of bins.
    float offset = 28/7;
    
    centeroid = sumB / sumA;  // Generate centroid (approximate location of object) which is a number between 1 an nBins (7 in our case)
    centeroid -= offset; // Offset the centeroid around center bin, now the centeroid is a number between 1-offset and offset-1 (-3 to 3 in our case)
}

float
IRObjDetector::get_centeroid(void)
{
    return centeroid;
}

uint16_t
IRObjDetector::get_raw_brightness(void)
{
    return brightness;
}

uint16_t
IRObjDetector::get_min_brightness(void)
{
    return minBrightness;
}

uint16_t
IRObjDetector::get_avg_brightness(void)
{
    return avgBrightness;
}

uint16_t
IRObjDetector::get_max_brightness(void)
{
    return maxBrightness;
}