Tutorial Netduino Parte 7


 

 Netduino es una plataforma de desarrollo de código abierto integrado similar al Arduino, excepto que utiliza .NET Micro Framework para la programación.  La placa de desarrollo Netduino tiene el mismo factor que Arduino Uno, y por lo tanto la mayoría de los escudos de Arduino son también compatibles con Netduino.  Las placas de desarrollo Arduino se basan en 8 bits microcontroladores Atmel que corren a una velocidad máxima de reloj de 16 MHz en su versión primera. Por otra parte, el hardware Netduino usa potentes procesadores de 32 bits (en el caso de la primera versión un  Atmel SAM7x en Netduino, y STMicro STM32F4 en versiones Netduino Plus) y funciona a una velocidad mucho más rápida (48 MHz a 168 MHz).

El  siguiente tutorial  extraidos de http://embedded-lab.com/blog    tienen como objetivo proporcionar una amplia introducción a la plataforma Netduino  y asegurar que cualquier principiante, estudiante o aficionado, será rápidamente capaz de empezar a usarlo para sus propios proyectos y diseños embebidos. En todos los ejemplos se usa una placa  Netduino Plus ( es la versión mas antigua con NETMF 4,1) se utiliza para ilustrar la salida en estos experimentos.

Como continuación del curso básico de Netduino https://soloelectronicos.com/2015/02/24/tutorial-netduino-parte-6/    en esta   ocasión vamos   a tratar la  gestión de PWM

Pulse Width Modulation (PWM) es un método digital de la entrega de una cantidad variable de energía a una carga, y por lo tanto se puede utilizar para controlar el brillo de un LED o la velocidad de un motor de corriente continua. El control de la potencia, haremos este tutorial colorido usando un Azul Verde Rojo (RGB) LED. Cada segmento (plomo) de RGB-LED obtendrá una señal PWM a través de la clase RGBLED lo que nos permite iluminar el LED RGB con cualquier color definido por RGB. Esta clase también puede generar colores al azar. Utilización de la clase RGBLED, algunos colores estándar también se pueden enviar a un LED RGB.

Configuración de Circuito y Teoría

Para entender PWM, vamos a entender los términos que conforman unas señales de ancho de pulso modulado. El uno es muy importante pues es del ciclo de trabajo. En términos flexibles este ciclo de trabajo es un valor en porcentaje del estado ON en comparación con el estado OFF. A partir de la figura siguiente podemos ver la fórmula para calcular el ciclo de trabajo.

Ahora, vamos a ver como  co-relacionan lo anterior a nuestro proyecto. Digamos que nos gusta para producir un color «gris». Conocemos el valor RGB para el gris es de 128, 128 y 128. Esto significa, si mezclamos el 50% de rojo (50% de 256 es 128), el 50% de verde y 50% de azul, vamos a obtener un color gris . El valor de 50% provino de 128/256 * 100%. Con respecto a la figura anterior, si T = el 50% para la pierna roja, T = el 50% de la pierna verde y T en = 50% de la pata azul de un LED RGB entonces vamos a tener un color gris a partir de un LED RGB- . El valor calculado es nada más que el ciclo de trabajo de un PWM. En la clase RGBLED, que básicamente ajustar el ciclo de trabajo para iluminar el LED RGB con un color deseado.

Asi se muestra  un ciclo de trabajo de hoja de cálculo Excel para entenderlo un poco mejor  y también la explicación de  la clase RGBLED.

 

Las conexiones no son tan difíciles. Pines digitales Netduino, 5, 6, 9 y 10 se pueden configurar como pines PWM, de los cuales vamos a configurar 5, 6 y 9. Las salidas de estos pines son alimentados a la base de un transistor NPN. Cuando el pulso es alta, el transistor entra en modo de saturación y permite el flujo desde el colector al emisor que está conectado nuestro RGB LED. Dado que el LED RGB usado en este tutorial es ánodo común, el plomo ánodo está conectado a + 5v. El diagrama del circuito siguiente muestra la conexión.

La imagen siguiente muestra la configuración de circuito en un circuito y sus conexiones con el Netduino.

 

 

C Programa # .NET

La utilización de la clase RGBLED es muy simple así que vamos a saltar todo por ahora y  centrarnos en la propia clase. El constructor de la clase toma cuatro argumentos, el número de pin para el rojo, verde y azul y  el último argumento es opcional para commonAnode lo cual es cierto por defecto (en el diagrama del circuito que no es demasiado importante si nos fijamos este valor a verdadero o falso).

En este método constructor nuevas instancias de la clase PWM están embalados luego una tabla de colores Hashtable se rellena con el color estándar.

 

public RgbLed(Cpu.Pin redPwmPin, Cpu.Pin greenPwmPin, Cpu.Pin bluePwmPin, bool commonAnode = true)
{
	RedLED = new PWM(redPwmPin);
	GreenLED = new PWM(greenPwmPin);
	BlueLED = new PWM(bluePwmPin);
	LEDs = new PWM[] { RedLED, GreenLED, BlueLED };
 
	CommonAnode = commonAnode;
	ColorTable = new Hashtable();
	ColorTable.Add(0, new byte[] { 0, 0, 0 });		// Off (~~ Black color)
	ColorTable.Add(1, new byte[] { 0, 100, 100 }); 	// Aqua
	ColorTable.Add(2, new byte[] { 0, 0, 100 });	// Blue
	ColorTable.Add(3, new byte[] { 100, 0, 100 });	// Fuchsia
	ColorTable.Add(4, new byte[] { 50, 50, 50 });	// Gray
	ColorTable.Add(5, new byte[] { 0, 50, 0 });		// Green
	ColorTable.Add(6, new byte[] { 0, 100, 0 });	// Lime
	ColorTable.Add(7, new byte[] { 50, 0, 0 });		// Maroon
	ColorTable.Add(8, new byte[] { 0, 0, 50 });		// Navy
	ColorTable.Add(9, new byte[] { 50, 50, 0 });	// Olive
	ColorTable.Add(10, new byte[] { 50, 0, 50 });	// Purple
	ColorTable.Add(11, new byte[] { 100, 0, 0 });	// Red
	ColorTable.Add(12, new byte[] { 75, 75, 75 });	// Silver
	ColorTable.Add(13, new byte[] { 0, 50, 50 });	// Teal
	ColorTable.Add(14, new byte[] { 100, 100, 100 });// Whilte
	ColorTable.Add(15, new byte[] { 100, 100, 0 });	// Yellow
}

Hay tres métodos públicos disponibles para el establecimiento de un color, el Turnit, escribir y métodos RandomColor. Tener color estándar, llamar al método Turnit y pasar el color estándar de color Enum. El método de escritura toma tres argumentos byte para el color rojo, verde y azul. Finalmente, RandomColor calculará número aleatorio para el valor de color rojo, verde y azul.

 

public void TurnIt(Color color)
{
	if (ColorTable.Contains((int)color))
	{
		colorArray = (byte[])ColorTable[(int)color];
		SetColor();
	}
	else
		throw new Exception("Color not found");
}
public void Write(byte red, byte green, byte blue)
{
	colorArray = new byte[] { (byte)(red * 100 / 255), (byte)(green * 100 / 255), (byte)(blue * 100 / 255) };
	SetColor();
}
public void RandomColor()
{
	Random random = new Random();
	colorArray = new byte[] { (byte)random.Next(100), (byte)random.Next(100), (byte)random.Next(100) };
	SetColor();
}
public override string ToString()
{
	colorString = string.Concat("RGB(", colorArray[0], ", ", colorArray[1], ", ", colorArray[2], ")");
	return colorString;
}

Todos los métodos públicos llaman internamente al método privado SetColor.Este  básicamente cambia el ciclo de trabajo de las instancias de PWM para cada pin de lectura, verde y azul.

 

private void SetColor()
{
	if (CommonAnode) colorArray = AdjustPolarityValue(colorArray);
	LEDs[0].SetDutyCycle((uint)colorArray[0]); // Red
	LEDs[1].SetDutyCycle((uint)colorArray[1]); // Green
	LEDs[2].SetDutyCycle((uint)colorArray[2]); // Blue
}
private byte[] AdjustPolarityValue(byte[] colorArray)
{
	return new byte[] { (byte)(100 - colorArray[0]), (byte)(100 - colorArray[1]), (byte)(100 - colorArray[2]) };
}

Aquí está la clase  del diagrama RGBLED :

Salida

Para demostrar el uso de cada tres métodos públicos, hay tres partes en el vídeo. Primero se muestra el color estándar entonces se muestra el espectro de colores de bucle a través de diferentes lazos de color y finalmente un poco de color al azar.

En este código   se busca mostrar algunos colores estándar

 

RgbLed led = new RgbLed(Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D6, Pins.GPIO_PIN_D5, false   );
 
// Display standard colors
led.TurnIt(RgbLed.Color.Red);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Navy);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Purple);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Green);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Maroon);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Blue);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Fuchsia);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Teal);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Yellow);
WaitAndTurnOff(500, led);

Para mostrar diferentes colores se utilizan tres bucles for  en forma de cascada:

 

for (int red = 0; red < 255; red += 50)
{
    for (int green = 0; green < 255; green += 50)
    {
        for (int blue = 0; blue < 255; blue += 50)
        {
            led.Write((byte)red, (byte)green, (byte)blue);
            Debug.Print(led.ToString());
 
            WaitAndTurnOff(100, led);
        }
    }
}

Y para generar los colores al azar (bucle 20 veces)  se utiliza  este código:

 

for (int i = 0; i < 20; i++)
{
    led.RandomColor();
    WaitAndTurnOff(500, led);
}
private static void WaitAndTurnOff(int time, RgbLed led, byte longerOn = 2)
{
    Thread.Sleep(time * longerOn);
    led.TurnIt(RgbLed.Color.Off);
    Thread.Sleep(time);
}

Y  por   último    un vídeo de salida rápida del código de seguridad.

 

Fuente   aqui

Anuncio publicitario

Colorimetro basado en Netduino


En este post  vamos a tratar  de  un original  sensor de color    controlado con  Netduino,Netduino Plus o Netduino Go.

Gracias al sensor de Color de Sparkfun   ADJD-S371-q999 y un Netduino  en este proyectos    se imprimirá el nombre de color HTML (es decir DarkRed) de un objeto que se ve( de hecho esta  aplicacion podria ser particularme  interesante  para las personas  daltónicas , pues basandose en este  sensor, podrian  obtener  un rango de mejora)

He aquí un breve video para demostrar el  fuincionamiento del sensor :

El ADJD-S371 es un 4 canal de sensor RGB + Claro que utiliza el protocolo I2C 2 hilos para comunicar con el microcontrolador. Es un poco complejo  el  dispositivo   pues no se limita a dar el color correcto cuando usted la pida  y necesitaremos  usar el algoritmo de calibración de ganancia,aunque para realizar pruebas sencillas puede utilizar el código descrito en este post

El código fue creado originalmente por Nathan Seidle para el microcontrolador PIC y fue portado y modificado para el Arduino por Marcus de Matter Interactive  y despues  Paul King lo porto en  lenguaje C # para el net Framework Micro..

Haga clic para ampliar
Haga clic para ampliar

El esquema de arriba    muestra el  sencillo circuito con   Netduino,donde  hay que a tener en cuenta, que  se usa un LED externo solo como  fuente de luz  por lo que no hay necesidad de conectar el pin LED en el ADJD-S371-Q999.  En cuanto a los  piuertos  podemos  utilizar cualquiera de las IO pines digitales: sólo tiene que cambiar un poco de código al configurar los puertos de salida. Por último, el LED RGB puede ser conectado a 3.3V o 5V y es posible que tenga que ajustar el tamaño de resistencias para su RGB LED de todos modos.

A continuación   se describe el código en c#   de este demo:

C # Código

1
2
3
4
5
6
using System;
utilizando System.IO.Ports;
using System.Threading;
utilizando Microsoft.SPOT;
utilizando Microsoft.SPOT.Hardware;
utilizando SecretLabs.NETMF.Hardware.Netduino;

Las líneas 1 a 6 definen un espacio de nombres, lo cual permite utilizar las clases o tipos sin tener que escribir el espacio de nombres completo donde existen esos tipos.

Por ejemplo, en lugar de escribir:
SecretLabs . NETMF . Hardware . Netduino . Pins . ONBOARD_LED

Podemos escribir simplemente:
Pins . ONBOARD_LED

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
namespace Squintz. colorímetro
{
Programa clase pública
{
I2C_ADDRESS público static byte = 0x74; / / 7bit
byte static REG_CAP_RED = 0x06;
REG_CAP_GREEN byte static = 0x07;
REG_CAP_BLUE byte static = 0x08;
REG_CAP_CLEAR byte static = 0x09;byte static REG_INT_RED_LO = 0x0A;
REG_INT_RED_HI público static byte = 0x0B;
byte static REG_INT_GREEN_LO = 0x0C;
byte public static REG_INT_GREEN_HI = 0x0D;
byte public static REG_INT_BLUE_LO = 0x0E;
REG_INT_BLUE_HI público static byte = 0x0F;
REG_INT_CLEAR_LO byte static = 0x10;
REG_INT_CLEAR_HI byte static = 0x11;REG_DATA_RED_LO byte static = 0x40;
REG_DATA_RED_HI byte static = 0x41;
REG_DATA_GREEN_LO byte static = 0x42;
REG_DATA_GREEN_HI byte static = 0x43;
REG_DATA_BLUE_LO byte static = 0x44;
REG_DATA_BLUE_HI byte static = 0x45;
REG_DATA_CLEAR_LO byte static = 0x46;
REG_DATA_CLEAR_HI byte static = 0x47;
public static I2CDevice rtc = nueva I2CDevice ( nueva . I2CDevice configuración (I2C_ADDRESS, 100));

byte static [] = readBuffer nuevo byte [1];

Líneas 7 a 33 son constantes definidas en la documentación y sensores de color. Línea 35 crea un nuevo objeto de dispositivo C I 2 llamado rtc. Utilizamos este objeto para enviar realmente los datos de la Netduino al sensor de color. I 2 C es un protocolo de bus que significa que varios dispositivos pueden compartir los mismos cables. Así el objeto I2CDevice nos obliga a darle una dirección de esclavo  para lo cual  se ha definido  como la constante  I2C_Address en la línea 11. El objeto I2CDevice también nos requiere que se especifique un tipo en kilohercios (en este ejemplo se ja usado 100 Khz)

Línea 37 crea una variable de tipo array de bytes  que debe tener en cuenta que solamente estamos inicializando el tamaño de la matriz a 1. El sensor de color no necesita realmente una matriz de bytes, pero el metodo  I2CDevice.CreateReadTransaction requiere una matriz de bytes como uno de sus parámetros y no tiene un método sobrecargado para usar sólo un byte.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public static void Main ()
{
OutputPort redpin = nueva OutputPort (pines GPIO_PIN_D10, cierto.);
OutputPort greenpin = nueva OutputPort (pines GPIO_PIN_D9, cierto.);
OutputPort BluePin = nueva OutputPort (pines GPIO_PIN_D7, cierto.);int cc = 0;
int rojo = 0;
int verde = 0;
int azul = 0;int clearGain;
int colorGain;int num_samples;

int i;

while (true)
{
clearGain = getClearGain ();
set_gain (REG_INT_CLEAR_LO, clearGain);
colorGain = getColorGain ();
set_gain (REG_INT_RED_LO, colorGain);
set_gain (REG_INT_GREEN_LO, colorGain);
set_gain (REG_INT_BLUE_LO, colorGain);

num_samples = 10;

for (i = 0; i <num_samples; i + +)
{
. Programa performMeasurement ();
cc + = get_readout (REG_DATA_CLEAR_LO);
rojo + = get_readout (REG_DATA_RED_LO);
verde + = get_readout (REG_DATA_GREEN_LO);
azul + = get_readout (REG_DATA_BLUE_LO);
}
cc / = num_samples;
rojo / = num_samples;
verde / = num_samples;
azules / = num_samples;

. redpin Escriba (false);
. greenpin Escriba (false);
. BluePin Escriba (false);

if (red> verde && red> blue)
. redpin Escriba (true);
más
if (verde> rojo && verde> azul)
. greenpin Escriba (true);
más
if (azul> rojo && azul> verde)
. BluePin Escriba (true);

. Depuración de impresión («C:» + (byte) (cc >> 2) + «» + «R:» + (byte) (rojo >> 2) + «» + «G:» + (byte) (verde >> 2) + «» + «B» + (byte) (azul >> 2));
. Thread Sleep (500);
}
}

Líneas 38 es el principal punto de entrada para nuestro programa. En las líneas 40 a 42 definen  que 3 puertos de I/O estamos utilizando para controlar un LED RGB. Al añadir el SecretLabs.NETMF.Hardware.Netduino.dll a nuestra lista de recursos y declarándola con la instrucción using de la línea 6 que no tenemos que recordar los números de pin microcontroladores reales. SecretLabs ya ha visto todo esto para nosotros y que nos permitirá usar Pins.xxxxx.(de hecho  con la función completa de código alias intellisense de Visual Studio automáticamente aparece un menú contextual que le permite seleccionar de una lista de pines disponibles).

[* ACTUALIZACIÓN:. Si utiliza el instalador del  SDK SecretLabs  puede iniciar una nueva «Aplicación Netduino», que elimina la necesidad de añadir manualmente las dll a su lista de recursos y también elimina la necesidad de añadir manualmente los SecretLabs usando declaraciones]

En la línea 56 creamos un bucle infinito de modo que nuestro programa no se acaba nunca. Sin este nuestro programa sólo se ejecutará una vez y luego terminaria.

Líneas 58 y 64 es donde se puede ser creativo. La hoja de datos de sensores de color y nota de aplicación son un poco borroso en la explicación de la manera adecuada para calibrar y ajustar la ganancia de su sensor. Sin embargo, se debe establecer la ganancia de cada color antes de que usted solicite el color pues de NO ajustar la ganancia solo  recibiría resultados bajos.

Líneas 65 a la 78 es donde nos muestra los colores mediante el uso de unos métodos de ayuda que usted va a leer a continuación. La clave a destacar aquí es que cuantas más muestras se toma  más estable aparecerán sus números. En este caso se toman  muestras de 10 y se suman los resultados juntos y se dividen por 10 para obtener el valor medio.

Líneas 80 a 93 es donde establecemos el color de nuestra RGB LED. El algoritmo usado es  muy simple para determinar el color más dominan y encender sólo el pin  del LED RGB via experimental

En la línea 95 que llamamos Debug.Print e imprimir los valores de la ventana de resultados de Visual Studios. El valor claro indica una intensidad de luz general que los valores Azul Rojo, Verde, y son la intensidad, como se ve a través de un filtro de luz.

99
100
101
102
public static void performMeasurement ()
{
set_register (0x00, 0x01); / / inicio de detección
}

Ahora empezamos a conseguir profundamente en el protocolo de sensores de color. Para decir el sensor de color para tomar una muestra fijamos el registro 0 × 00 con el valor de 0 × 01. El sensor de color a continuación,  toma una muestra y la almacena.

103
104
105
106
static int get_readout (readRegister byte)
{
volver read_register (readRegister) + (read_register ((byte) (readRegister + 0x01)) << 8);
}

El sensor de color almacena sus valores de color en dos registros de 8 bits. Así. en las líneas 103 a 106, get_readout () toma el primer registro como parámetro y asume el siguiente registro está a sólo 1 más direcciones por encima de ese registro. Así leemos el valor del primer registro y luego leemos el valor del segundo registro y luego cambiamos el valor del segundo registro de 8 bits a la izquierda que nos deja con el pleno entero de 16 bits. Sin embargo, sólo 10 bits se ponen realmente en el entero debido a que los altos registros sólo devuelven los dos bits menos significativos y el bajo registro devuelve 7 Bits.

107
108
109
110
111
112
113
114
115
116
117
public static void set_gain (gainRegister byte, int ganancia)
{
if (ganancia <4,096)
{
byte hi = (byte) (ganancia >> 8);
lo = byte (byte) (ganancia);set_register (gainRegister, lo);
set_register ((byte) (gainRegister + 1), hi);
}
}

Cada color tiene dos de sus propios registros de ganancia. Definimos estos en nuestros constantes en las primeras líneas. Aquí  suponemos que ya que sabemos la dirección del registro del registro inferior, por lo que sólo podemos añadir 1 a la dirección para obtener la dirección del registro superior. Luego asignamos los valores de ganancia a través de la ayuda de set_register ().

118
119
120
121
122
123
124
125
126
public static void set_register (byte r, byte v)
{rtc. Ejecutar ( nueva I2CDevice. I2CTransaction []
{
I2CDevice. CreateWriteTransaction ( nuevo byte [] {r, v})}, 5000);
}

set_register es donde sucede la magia. Aquí creamos una nueva matriz de bytes que contiene dos valores. La primera es r para el registro y el segundo es v por valor. Transmitimos esta matriz de bytes a un nuevo objeto I2CDevice.CreateWriteTransaction y luego pasamos ese objeto con el método rtc.Execute. Usted debe recordar que rtc es nuestro objeto I2CDevice que sabe acerca de la dirección del esclavo de nuestro sensor de color. Así, en pocas palabras nuestra función set_register es donde empaquetamos todo y lo enviamos en su camino.

127
128
129
130
131
132
133
134
135
136
read_register público static byte (byte r)
{
rtc. Ejecutar ( nueva I2CDevice. I2CTransaction [] {
I2CDevice. CreateWriteTransaction ( nuevo byte [] {r})
,
I2CDevice. CreateReadTransaction (readBuffer)
}, 5000);volver readBuffer [0];
}

En líneas 127 a 136  estamos enviando una solicitud de nuestros valores de color. Nos pasamos ‘r’, que es el color que queremos leer. Recuerde que esto ocurre dos veces para cada color con el fin de obtener el valor total. Esperamos 5.000 milisegundos o 5 segundos para que el regreso antes de tiempo de espera.

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
public static int getClearGain ()
{
int gainFound = 0;
int upperBox = 4,096;
int lowerBox = 0;
int media = 0;
int halfValue;mientras que (gainFound == 0)
{
media = ((upperBox – lowerBox) / 2) + lowerBox;
/ / Possbile no más lejos Halfing
if (media == lowerBox)
{
gainFound = 1;
}
más
{
set_gain (REG_INT_CLEAR_LO, medio);
performMeasurement ();
halfValue = get_readout (REG_DATA_CLEAR_LO);si (halfValue> 1000)
{
upperBox = medio;
}
else if (halfValue <1,000)
{
lowerBox = medio;
}
más
{
gainFound = 1;
}
}
}
devolver la mitad;
}

Líneas 137-174 es donde usted puede volver a probar  para perfeccionar sus resultados. Usted tendrá que obtener una forma de obtener un valor de ganancia que compensa la luz ambiental y todos los demás factores ambientales que pueden cambiar la sensibilidad.

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
public static int getColorGain ()
{
int gainFound = 0;
int upperBox = 4,096;
int lowerBox = 0;
int media = 0;
int halfValue;mientras que (gainFound == 0)
{
media = ((upperBox – lowerBox) / 2) + lowerBox;
/ / Possbile no más lejos Halfing
if (media == lowerBox)
{
gainFound = 1;
}
más
{
set_gain (REG_INT_RED_LO, medio);
set_gain (REG_INT_GREEN_LO, medio);
set_gain (REG_INT_BLUE_LO, medio);
performMeasurement ();
halfValue = 0;halfValue = Sistema de Matemáticas Max (halfValue, get_readout (REG_DATA_RED_LO))..;
halfValue = Sistema de Matemáticas Max (halfValue, get_readout (REG_DATA_GREEN_LO))..;
halfValue = Sistema de Matemáticas Max (halfValue, get_readout (REG_DATA_BLUE_LO))..;si (halfValue> 1000)
{
upperBox = medio;
}
else if (halfValue <1,000)
{
lowerBox = medio;
}
más
{
gainFound = 1;
}
}
}
devolver la mitad;
}
}
}

Por último, las líneas 175-220 intenta establecer una ganancia adecuada para cada color. Esto será llamado 3 veces porque cada color tiene una sensibilidad diferente. Usted puede ser creativo aquí y venir con su propio algoritmo que se adapte a su aplicación específica. Si usted tuviera un ambiente controlado, en teoría, esto sería muy simple.

Fuente aqui