
Median filtered & triggered + buffered RGB readings
Dependencies: mbed rgb_sensor_buffer
main.cpp@7:bc856471c871, 2014-07-08 (annotated)
- Committer:
- meriac
- Date:
- Tue Jul 08 16:07:50 2014 +0000
- Revision:
- 7:bc856471c871
- Parent:
- 6:3f5ea82fdf62
Reduce detection treshold to increase detection likelihood
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
meriac | 0:c41a5885f681 | 1 | /* Discrete RGB color sensor |
meriac | 0:c41a5885f681 | 2 | * |
meriac | 0:c41a5885f681 | 3 | * - uses single-channel light-dependent resistor (via ADC) |
meriac | 0:c41a5885f681 | 4 | * and a RGB LED. |
meriac | 0:c41a5885f681 | 5 | * - compensates background light |
meriac | 0:c41a5885f681 | 6 | * |
meriac | 0:c41a5885f681 | 7 | * Copyright (c) 2014 ARM Limited |
meriac | 0:c41a5885f681 | 8 | * |
meriac | 0:c41a5885f681 | 9 | * Licensed under the Apache License, Version 2.0 (the "License"); |
meriac | 0:c41a5885f681 | 10 | * you may not use this file except in compliance with the License. |
meriac | 0:c41a5885f681 | 11 | * You may obtain a copy of the License at |
meriac | 0:c41a5885f681 | 12 | * |
meriac | 0:c41a5885f681 | 13 | * http://www.apache.org/licenses/LICENSE-2.0 |
meriac | 0:c41a5885f681 | 14 | * |
meriac | 0:c41a5885f681 | 15 | * Unless required by applicable law or agreed to in writing, software |
meriac | 0:c41a5885f681 | 16 | * distributed under the License is distributed on an "AS IS" BASIS, |
meriac | 0:c41a5885f681 | 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
meriac | 0:c41a5885f681 | 18 | * See the License for the specific language governing permissions and |
meriac | 0:c41a5885f681 | 19 | * limitations under the License. |
meriac | 0:c41a5885f681 | 20 | */ |
meriac | 0:c41a5885f681 | 21 | |
meriac | 0:c41a5885f681 | 22 | #include <mbed.h> |
meriac | 0:c41a5885f681 | 23 | #include "rgb_sensor_buffer.h" |
meriac | 0:c41a5885f681 | 24 | |
meriac | 7:bc856471c871 | 25 | #define DEBUG |
meriac | 7:bc856471c871 | 26 | |
meriac | 7:bc856471c871 | 27 | #define RGB_TRESHOLD 220 |
meriac | 0:c41a5885f681 | 28 | #define COUNT(x) (sizeof(x)/sizeof(x[0])) |
meriac | 0:c41a5885f681 | 29 | #define RGB_VALUES 512 |
meriac | 0:c41a5885f681 | 30 | |
meriac | 0:c41a5885f681 | 31 | /* serial console */ |
meriac | 0:c41a5885f681 | 32 | static TRGB g_buffer[RGB_VALUES]; |
meriac | 0:c41a5885f681 | 33 | static int g_median[RGB_VALUES]; |
meriac | 0:c41a5885f681 | 34 | static Serial console(USBTX, USBRX); |
meriac | 0:c41a5885f681 | 35 | |
meriac | 0:c41a5885f681 | 36 | #ifdef DEBUG |
meriac | 0:c41a5885f681 | 37 | static void rgb_print(const TRGB &color) |
meriac | 0:c41a5885f681 | 38 | { |
meriac | 0:c41a5885f681 | 39 | int i; |
meriac | 0:c41a5885f681 | 40 | |
meriac | 0:c41a5885f681 | 41 | console.printf("\t["); |
meriac | 0:c41a5885f681 | 42 | for(i=0; i<COUNT(color.data); i++) |
meriac | 0:c41a5885f681 | 43 | console.printf("%s%4i", i?",":"", color.data[i] / RGB_OVERSAMPLING); |
meriac | 0:c41a5885f681 | 44 | console.printf("]"); |
meriac | 0:c41a5885f681 | 45 | } |
meriac | 0:c41a5885f681 | 46 | #endif/*DEBUG*/ |
meriac | 0:c41a5885f681 | 47 | |
meriac | 0:c41a5885f681 | 48 | static int median_compare(const void* a, const void *b) |
meriac | 0:c41a5885f681 | 49 | { |
meriac | 0:c41a5885f681 | 50 | return *((int*)a) - *((int*)b); |
meriac | 0:c41a5885f681 | 51 | } |
meriac | 0:c41a5885f681 | 52 | |
meriac | 0:c41a5885f681 | 53 | static bool median(TRGB &color, int count) |
meriac | 0:c41a5885f681 | 54 | { |
meriac | 0:c41a5885f681 | 55 | int channel, i; |
meriac | 0:c41a5885f681 | 56 | |
meriac | 0:c41a5885f681 | 57 | if(count<=0) |
meriac | 0:c41a5885f681 | 58 | return false; |
meriac | 0:c41a5885f681 | 59 | |
meriac | 0:c41a5885f681 | 60 | /* sort all three RGB channels to get median */ |
meriac | 0:c41a5885f681 | 61 | for(channel=0; channel<3; channel++) |
meriac | 0:c41a5885f681 | 62 | { |
meriac | 0:c41a5885f681 | 63 | for(i=0; i<count; i++) |
meriac | 0:c41a5885f681 | 64 | g_median[i] = g_buffer[i].data[channel]; |
meriac | 0:c41a5885f681 | 65 | |
meriac | 0:c41a5885f681 | 66 | qsort(&g_median, count, sizeof(g_median[0]), &median_compare); |
meriac | 0:c41a5885f681 | 67 | |
meriac | 0:c41a5885f681 | 68 | color.data[channel] = g_median[count/2]; |
meriac | 0:c41a5885f681 | 69 | } |
meriac | 0:c41a5885f681 | 70 | |
meriac | 0:c41a5885f681 | 71 | return true; |
meriac | 0:c41a5885f681 | 72 | } |
meriac | 0:c41a5885f681 | 73 | |
meriac | 0:c41a5885f681 | 74 | |
meriac | 0:c41a5885f681 | 75 | int main() { |
meriac | 5:91ca771eff16 | 76 | int res; |
meriac | 3:a4e4f4414533 | 77 | double magnitude; |
meriac | 0:c41a5885f681 | 78 | TRGB color; |
meriac | 0:c41a5885f681 | 79 | |
meriac | 0:c41a5885f681 | 80 | console.baud(115200); |
meriac | 0:c41a5885f681 | 81 | |
meriac | 0:c41a5885f681 | 82 | /* R,G,B pins and ADC for light dependent resistor */ |
meriac | 0:c41a5885f681 | 83 | RGB_SensorBuffer rgb(p23,p24,p25,p20); |
meriac | 0:c41a5885f681 | 84 | |
meriac | 0:c41a5885f681 | 85 | /* needed for time measurement */ |
meriac | 0:c41a5885f681 | 86 | Timer timer; |
meriac | 0:c41a5885f681 | 87 | |
meriac | 0:c41a5885f681 | 88 | while(1) { |
meriac | 0:c41a5885f681 | 89 | |
meriac | 0:c41a5885f681 | 90 | /* start four channel RGB conversion */ |
meriac | 0:c41a5885f681 | 91 | timer.reset(); |
meriac | 0:c41a5885f681 | 92 | timer.start(); |
meriac | 0:c41a5885f681 | 93 | |
meriac | 0:c41a5885f681 | 94 | res = rgb.trigger(g_buffer, COUNT(g_buffer), RGB_TRESHOLD); |
meriac | 0:c41a5885f681 | 95 | |
meriac | 0:c41a5885f681 | 96 | /* stop time measurement */ |
meriac | 0:c41a5885f681 | 97 | timer.stop(); |
meriac | 0:c41a5885f681 | 98 | |
meriac | 0:c41a5885f681 | 99 | if(res<=0) |
meriac | 0:c41a5885f681 | 100 | { |
meriac | 0:c41a5885f681 | 101 | console.printf("// failed to capture RGB values (%i)\r\n", res); |
meriac | 0:c41a5885f681 | 102 | while(1); |
meriac | 0:c41a5885f681 | 103 | } |
meriac | 0:c41a5885f681 | 104 | |
meriac | 0:c41a5885f681 | 105 | /* calculate RGB median */ |
meriac | 0:c41a5885f681 | 106 | median(color, res); |
meriac | 0:c41a5885f681 | 107 | /* print normalized median */ |
meriac | 4:a4538586c75e | 108 | magnitude = sqrt( |
meriac | 4:a4538586c75e | 109 | ( (double)color.ch.red * color.ch.red )+ |
meriac | 4:a4538586c75e | 110 | ( (double)color.ch.green * color.ch.green )+ |
meriac | 4:a4538586c75e | 111 | ( (double)color.ch.blue * color.ch.blue ) |
meriac | 4:a4538586c75e | 112 | ); |
meriac | 2:f72e7a4d7395 | 113 | console.printf("\t[%1.4f,%1.4f,%1.4f,%5i], // %i values in %ims (%i/s)\n\r", |
meriac | 3:a4e4f4414533 | 114 | color.ch.red / magnitude, |
meriac | 3:a4e4f4414533 | 115 | color.ch.green / magnitude, |
meriac | 3:a4e4f4414533 | 116 | color.ch.blue / magnitude, |
meriac | 3:a4e4f4414533 | 117 | (int)((magnitude / RGB_OVERSAMPLING)+0.5), |
meriac | 0:c41a5885f681 | 118 | res, |
meriac | 0:c41a5885f681 | 119 | timer.read_ms(), |
meriac | 0:c41a5885f681 | 120 | (res*1000UL)/timer.read_ms() |
meriac | 0:c41a5885f681 | 121 | ); |
meriac | 0:c41a5885f681 | 122 | |
meriac | 0:c41a5885f681 | 123 | #ifdef DEBUG |
meriac | 5:91ca771eff16 | 124 | int i; |
meriac | 0:c41a5885f681 | 125 | console.printf("\r\nvar test = [\r\n", |
meriac | 0:c41a5885f681 | 126 | res, |
meriac | 0:c41a5885f681 | 127 | timer.read_ms(), |
meriac | 0:c41a5885f681 | 128 | (res*1000UL)/timer.read_ms()); |
meriac | 0:c41a5885f681 | 129 | |
meriac | 0:c41a5885f681 | 130 | for(i=0; i<res; i++) |
meriac | 0:c41a5885f681 | 131 | { |
meriac | 0:c41a5885f681 | 132 | rgb_print(g_buffer[i]); |
meriac | 0:c41a5885f681 | 133 | console.printf(i<(res-1) ? ",\r\n":"];\r\n\r\n"); |
meriac | 0:c41a5885f681 | 134 | } |
meriac | 0:c41a5885f681 | 135 | #endif/*DEBUG*/ |
meriac | 0:c41a5885f681 | 136 | |
meriac | 0:c41a5885f681 | 137 | } |
meriac | 0:c41a5885f681 | 138 | } |