Electronic – arduino – Why does the Oscilloscope show a longer period of time than the code sets

arduinocameraclockoscilloscope

So I'm programming a TSL1401R-LF line scan camera module that reads in a a 1 X 128 array of pixels. I've run into a problem with the accuracy of the output. Basically the camera becomes less accurate as the delay times decrease. For debugging I hooked it up to an oscilloscope and monitored the SI and CLK pulses sent to the clock as well as the analog signals coming from it.

That's why I noticed the the duration of the CLK signal appeared to be over 300 microseconds long. This is strange because my code sets the duration to 170 microseconds. Since this is my first electrical project I'm not sure what to make of this so I'm hoping someone can take a look at my code and a screenshot of the oscilloscope and let me know if what I'm seeing is natural or not.

Here is the code:

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);
  }

}

Here is the screenshot

enter image description here

The yellow Line is the SI pulse, the light blue is the CLK pulse and the purple is the analog output.

Best Answer

The main problem

It looks like the chip is running at a slower clock speed than it should be. If delayMicroseconds assumes a 16MHz clock and the chip is actually using it's 8MHz internal oscillator, for example, the pulses would double in length. You could check that:

  • The crystal oscillator is running and at the correct frequency
  • The atmega's fuse bits are set to use the external oscillator
  • There is no prescaler set

Also

The Arduino delayMicroseconds function is not a good way of making something happen every 85uS, and digitalWrite is not helping your case either. If you go digging into the definition of the two functions (which are provided by the Arduino project, not by Atmel, who make the actual microprocessor) you'll see that they are actually remarkably complicated. Now, the compiler will simplify them quite a lot, but even then you'll be left with a lot of operations, and those operations will lengthen the pulse.

You could rewrite the code to speed things up, but there is a better way. The AVR chip used in the Arduino has several timers on it. These run in parallel with the cpu which runs your code, and they can toggle pins or run short pieces of code at very precise intervals. The downside is that although the timers are a core feature of the AVR chips, they are rarely used in the Arduino world. So you'll have to go diving into some less user-friendly documentation to figure out how to use them.