¿Siempre necesita registrar los píxeles antiguos cuando lee de una cámara?

Estoy escribiendo un programa para trabajar con un módulo de exploración lineal TSL1401R-LF. Funciona leyendo en una matriz de píxeles de 1 X 128. Logré que la cámara funcione correctamente y mi readPixels()método puede leer los píxeles con precisión.

Sin embargo, me veo obligado a ejecutar un timming()método anterior a mi readPixels()método o, de lo contrario, el programa falla. Prácticamente timming()hace exactamente lo mismo que el readPixels()método, excepto que no almacena los valores de salida. Cuando lo comento y solo uso, readPixels()mi imagen se satura y solo obtengo valores de 1023 incluso cuando un objeto oscuro está en el camino de las cámaras.

Esto podría tener más sentido al mirar el código real:

void timming()
{

  digitalWriteFast(SI, HIGH);
  delayMicroseconds(10);
  digitalWriteFast(CLK, HIGH);
  delayMicroseconds(10);
  digitalWriteFast(SI, LOW);
  delayMicroseconds(10);
  digitalWriteFast(CLK, LOW);
  delayMicroseconds(10);

  for(int i = 0; i < 129; i++)
  {
    digitalWriteFast(CLK, HIGH);
    delayMicroseconds(delayTime);
    digitalWriteFast(CLK, LOW);
    delayMicroseconds(delayTime);
  }

}

void readPixels()  
{
  digitalWriteFast(SI, HIGH);
  delayMicroseconds(10);
  digitalWriteFast(CLK, HIGH);
  delayMicroseconds(10);
  digitalWriteFast(SI, LOW);
  delayMicroseconds(10);
  digitalWriteFast(CLK, LOW);
  delayMicroseconds(10);

  for(int i = 0; i < 128; i++)
  { 
    digitalWriteFast(CLK, HIGH);
    pixelsArray1[i]=analogRead(Cam1Aout);
    pixelsArray2[i]=analogRead(Cam2Aout);
    pixelsArray3[i]=analogRead(Cam3Aout);
    delayMicroseconds(delayTime);
    digitalWriteFast(CLK, LOW);
    delayMicroseconds(delayTime);
  }

  digitalWriteFast(CLK, HIGH);
  delayMicroseconds(delayTime);
  digitalWriteFast(CLK, LOW);
  delayMicroseconds(delayTime);

  delayMicroseconds(20);
}

TL;RD

Básicamente, lo que pregunto es si hay una manera de hacer que mi programa funcione sin tener que usar el timming()método.

Hoja de datos: http://datasheet.elcodis.com/pdf/58/61/586128/tsl1401r-lf.pdf

Vuelva a agregar el enlace de la hoja de datos. Hay otras formas: algunas cámaras tienen un pulso de obturador; alargue o acorte según las condiciones de luz, para evitar saturar sus píxeles. Pero no sé si tu sensor lo hace.
Lo agregué, la explicación sobre el tiempo de integración está en las páginas 8 y 9. Ahí es donde me dijeron que hiciera el cronometraje de n+1 píxeles al inicio.
Por lo que puedo ver, no se trata de cronometrar los píxeles antiguos, sino de controlar el tiempo de integración. La interfaz "simple" tiene un costo: tienes que saltar a través de aros para controlar todo a través de solo 2 pines. Hay mejores formas que loop/digitalWrite, pero normalmente involucrarían hardware de propósito especial o un FPGA. Si está atascado con un Arduino, aún puede controlar el tiempo de integración ajustando el tiempo de retardo por separado para los primeros 18 ciclos (reinicio) y el resto (integración). O cronometrarlos lo más rápido que pueda, luego esperar un tiempo apropiado antes del siguiente cuadro.
@BrianDrummond eso es lo que pensé al principio también, pero se supone que reducir el tiempo de integración oscurecerá los píxeles ya que el sensor tiene menos tiempo para cargarse. Lo sé porque a medida que hice delayTimemás pequeño obtuve valores cada vez más bajos. Entonces, si el timming()método es solo para aumentar el tiempo de integración, entonces no debería obtener un valor saturado. ¿Bien? Lo siento si no lo entiendo, es la primera vez que trabajo con una cámara.
El método timing() está ahí para DISMINUIR el tiempo de integración. De lo contrario, los píxeles han estado integrándose e integrándose e integrándose e integrándose e integrándose durante el tiempo que sea desde la última vez que hizo readPixels().
No tengo idea de cuán lentos son los 384 AnalogReads en un Arduino, pero supongo que ... lentos. Por lo tanto, el método de tiempo ( timming()) es presumiblemente mucho más rápido y proporciona un tiempo de integración mucho más corto (sin saturación) que la readPixels()función anterior.
@RichardCrowley, ¿cómo puede ser ese el caso si el tiempo de integración solo comienza después de los primeros 18 ciclos de reloj?
@BrianDrummond Mi analogRead está optimizado y no toma tanto tiempo.
El comportamiento real del chip parece estar en desacuerdo con la teoría de "comienza después de los primeros 18 ciclos de reloj". O tal vez "comienza después" significa algo diferente de lo que pensamos que significa.
@RichardCrowley, ¿puede ampliar lo que quiere decir? La hoja de datos establece que el tiempo de integración es desde el pulso CLK 19 hasta el siguiente pulso SI.
¿De dónde provino este código de timing() y readPixels()? Tal vez debería consultar (o al menos citar) esta fuente para revelar el resto de la imagen. No veo ninguna mención de un método de sincronización () en la hoja de datos.
@RichardCrowley Si va a la página 9 en la hoja de datos y lee el primer párrafo, verá que es una buena práctica ejecutar el reloj (n + 1) veces después del primer pulso SI.

Respuestas (1)

Sospecho que la respuesta es bastante simple: ejecute readPixels() dos veces seguidas. Tal como está, si no ejecuta timing(), cuando ejecuta readPixels(), el 1401 ha estado ahí integrándose durante un tiempo desconocido (pero muy largo), por lo que, por supuesto, sus valores de píxeles están saturados. Entonces, timing() restablece los integradores de píxeles a cero, y luego readPixels() puede adquirir datos correctamente. Sin embargo, ejecutar readPixels() la primera vez tendrá el mismo efecto.

Por supuesto, cuando haga esto, deberá ignorar el primer conjunto de valores producidos por readPixels(), ya que serán un 1023 uniforme.

Entonces, la respuesta a su pregunta sobre el título es, por supuesto.

Pero, ¿no es una forma de detener el tiempo de integración al final del proceso readPixels()para que los valores no se saturen? También sabe de qué está hablando la hoja de datos cuando dice que el tiempo de integración termina en el pulso positivo de MANTENER.
No. La integración se detiene durante los 18 ciclos de reloj que siguen a la recepción de un pulso SI. Eso es todo. El resto del tiempo los integradores están integrando. Depende del usuario (usted) controlar el tiempo de integración. Si los píxeles se están saturando, reduzca la iluminación. Si no lo hace, simplemente ignore los resultados del primer readPixels(). Esta no es una cámara flexible de clase alta. Tiene una interfaz mínima, por lo que obtienes una gama muy limitada de modos operativos (es decir, uno). En la hoja de datos, "Retener" también se denomina "Restablecimiento del sistema" en la Figura 10.
¿No podría simplemente enviar un impulso al SI al final del readPixels()método?
Bien quizás. La hoja de datos no está disponible. Pero, ¿qué tienes en contra de un ciclo de lectura ficticio?
Básicamente está duplicando el tiempo de ejecución total de mi programa. Estoy tratando de hacerlo rápido para poder obtener una alta velocidad de fotogramas.
Pero solo necesita ejecutar la lectura ficticia una vez, cuando inicia el programa. Después de eso, sigue ejecutando readPixel(). Por lo tanto, su secuencia será, readPixel() (ficticio), readPixel() (usar datos), readPixel() (usar datos), etc. Al inicio, el sensor ha estado sentado allí integrándose durante mucho tiempo. Pero una vez que comienza a ejecutarse, el tiempo de integración es solo el retraso entre fotogramas. Entonces, la primera lectura es basura, pero después de eso no debería tener problemas.