¿Por qué el osciloscopio muestra un período de tiempo más largo que mis juegos de códigos?

Así que estoy programando un módulo de cámara de escaneo de línea TSL1401R-LF que lee en una matriz de píxeles de 1 X 128. Me he encontrado con un problema con la precisión de la salida. Básicamente, la cámara se vuelve menos precisa a medida que disminuyen los tiempos de retardo. Para la depuración, lo conecté a un osciloscopio y monitoreé los pulsos SI y CLK enviados al reloj, así como las señales analógicas que provenían de él.

Es por eso que noté que la duración de la señal CLK parecía ser de más de 300 microsegundos. Esto es extraño porque mi código establece la duración en 170 microsegundos. Dado que este es mi primer proyecto eléctrico, no estoy seguro de qué hacer con esto, así que espero que alguien pueda ver mi código y una captura de pantalla del osciloscopio y decirme si lo que veo es natural o no. .

Aquí está el código:

int delayTime = 170;

void timming()
{

  //The timing for the impluses was found through direct experimentation.
  //(Meaing that I played around with different delayTimes until the code worked)

  digitalWriteFast(SI, HIGH);
  delayMicroseconds(delayTime/2);
  digitalWriteFast(CLK, HIGH);
  delayMicroseconds(delayTime/2);
  digitalWriteFast(SI, LOW);
  delayMicroseconds(delayTime/2);
  digitalWriteFast(CLK, LOW);
  delayMicroseconds(delayTime);

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

}

Aquí está la captura de pantalla

ingrese la descripción de la imagen aquí

La línea amarilla es el pulso SI, la azul claro es el pulso CLK y la violeta es la salida analógica.

Esto puede ser útil, especialmente si tiene interrupciones ejecutándose en algún lugar: arduino: delaymicroseconds() . No soy un usuario de arduino, pero probablemente sería mejor usar un temporizador de hardware que active una interrupción.
El período del pulso del reloj parece ser diferente entre los pulsos 1-2 y 2-3. Si delaymicroseconds() es un temporizador de software, entonces su precisión es sospechosa dependiendo de si algo lo interrumpe. Como menciona @Tut, un temporizador de hardware proporcionará un reloj muy repetible. El AVR tiene varias opciones de temporizador para diferentes formas de onda, aunque tendrá que hacer coincidir el temporizador deseado con su cableado.
@Smith Quizás el centro de la pantalla marque el inicio de la ejecución. Entonces es consistente. SI sube, luego CLK alto, luego SI bajo, luego CLK bajo, después de lo cual se alterna CLK.
Parece que la calibración delayMicrosecondsestá desactivada. ¿Está calibrado dinámicamente? Si es así, ¿se supone que debes llamar a algo para calibrarlo?
tal como está escrito, su código siempre será más lento, está haciendo algo que lleva tiempo, luego espera una cierta cantidad de tiempo y luego hace algo que lleva tiempo. las cosas intermedias no son completamente gratuitas. Del mismo modo, es muy probable que el enrutamiento de tiempo tenga una sobrecarga, por lo que es un poco más largo debido al código, la llamada a la función o las fracciones de un período de tiempo en cualquier extremo de la medición. esta no es la forma de hacer una sincronización precisa. desea usar un temporizador y eliminar el costo del código o promediarlo.
tome una marca de tiempo, haga lo que quiere hacer, AGREGUE (o RESTA) A ESA MARCA DE TIEMPO tomó la cantidad de tiempo que desea y/o utilícela como referencia, no tome una nueva marca de tiempo después de lo que quería hacer. cuando el temporizador llegue a la nueva marca de tiempo, repita.
lo que estás haciendo es que el reloj marca las 8:01, luego haces algo que tarda 1 minuto. Entonces miras el reloj 8:02 y esperas 5 minutos a las 8:07, luego haces algo que tarda un minuto, 8:08 esperas 5, sigues acumulando error. Ahora, además de ese error, es posible que tenga algún otro error que es lo que podría estar buscando con este boleto.
Hay algunas buenas bibliotecas Arduino que usan interrupciones para programar eventos cronometrados con precisión, el código tarda en ejecutarse y una vez que el código Arduino se compila para ensamblar, cada línea podría tomar fácilmente decenas de instrucciones de ensamblaje. Echa un vistazo a la biblioteca TaskScheduler.

Respuestas (1)

El problema principal

Parece que el chip está funcionando a una velocidad de reloj más lenta de lo que debería ser. Si delayMicrosecondsasume un reloj de 16 MHz y el chip en realidad está usando su oscilador interno de 8 MHz, por ejemplo, los pulsos se duplicarían en longitud. Podrías comprobar que:

  • El oscilador de cristal está funcionando y en la frecuencia correcta
  • Los bits de fusible del atmega están configurados para usar el oscilador externo
  • No hay conjunto de preescalador

También

La delayMicrosecondsfunción Arduino no es una buena manera de hacer que suceda algo cada 85 uS, y digitalWritetampoco está ayudando en su caso. Si profundiza en la definición de las dos funciones (que son proporcionadas por el proyecto Arduino, no por Atmel, que fabrica el microprocesador real), verá que en realidad son notablemente complicadas. Ahora, el compilador los simplificará bastante, pero incluso entonces te quedarán muchas operaciones, y esas operaciones alargarán el pulso.

Podrías reescribir el código para acelerar las cosas, pero hay una mejor manera. El chip AVR utilizado en Arduino tiene varios temporizadores. Estos se ejecutan en paralelo con la CPU que ejecuta su código, y pueden alternar pines o ejecutar fragmentos cortos de código a intervalos muy precisos. La desventaja es que, aunque los temporizadores son una característica central de los chips AVR, rara vez se usan en el mundo de Arduino. Por lo tanto, tendrá que sumergirse en una documentación menos fácil de usar para descubrir cómo usarlos.

También depende del modelo particular de Arduino: tengo un nano clon chino que puede emitir (usando DigitalWrite) una onda cuadrada de 5us + el us especificado en DigitalWrite como un reloj suizo. Los 5 us agregados son aproximadamente el tiempo requerido para que se promulguen las instrucciones de retraso y escritura. Por otro lado, un Micro original 10 veces más caro no es capaz de hacer eso, con tiempos por todas partes. Quizás sea porque tiene USB integrado dentro del microcontrolador y también tiene que servir para eso. Quizás el OP debería especificar qué está usando Arduino.
Estoy de acuerdo con esta respuesta. El hecho de que el tiempo esté desfasado casi exactamente por un factor de dos sugiere un problema de configuración del reloj.