micros() smallest unit 112 ?

I'm measuring pulse widths using micros()
It looks like the smallest increment is 112 units. Eg it goes from 3136 to 3248 in one step. I need a more accurate measurement. Any suggestions ?

   while(analogRead(5) < 200) {}                  // Wait for rising edge
   RPMStartTime=micros();       
   while(analogRead(5) >= 200) {}                 // wait till falling edge
   while(analogRead(5) < 200) {}                  // Wait for rising edge
   RPMEndTime=micros();                        
   RPMDuration=RPMEndTime-RPMStartTime;

I think that here your limitation is in analogRead(), which is pretty much known to be rather slow.

Umm, use an ARM processor. If you need it that fast then I think the arduino is not going to quite cut it.

Mowcius

The analog read is just the trigger, the micro() should still measure micros.

According to the manual

the value returned is always a multiple of four

I'm reading multiples of 112. Strange number but that is what it is.

Time
9520  
9408  
8736  
7504  
6832  
6384  
5824
5376

Are you reading all them and then printing them? Or is there serial print in the middle? Saving as a variable?

It probably does a multiple of 4 but you can't very easily measure this.

Have you tried taking timings on the overhead of the calls IE :

  RPMStartTime=micros();      
    RPMEndTime=micros();                        
   RPMDuration=RPMEndTime-RPMStartTime;
  RPMStartTime=micros();   
analogRead(5) ;   
    RPMEndTime=micros();                        
   RPMDuration=RPMEndTime-RPMStartTime;

if the first returns 112 then you know its the minimum, the second will tell you the overhead of 1 analog read!

Etc!

I read the time, send the data, wait 1/10 second and start again.

I have been capturing data over a few days and it is always multiple of 112.

Data from a really slow input signal Around 10 Hz.

75712  
81200  
81200  
81312  
80192  
80192 
80304 
80192  
79072  
77168  
70224

I tried this and it is multiples of 4 !!!!

   RPMStartTime=micros();      
   delay(1000);  
   RPMEndTime=micros();      
   Serial.println(RPMEndTime-RPMStartTime);
1001056
1001352
1000324
1001352
1000324
1001352
1000324

Most strange?? Is it possible that Analog conversions are only done at a specific clock period and not any clock period hence the unique number 112?

I tried your suggestion

  RPMStartTime=micros();
    RPMEndTime=micros();
   RPMDuration=RPMEndTime-RPMStartTime;

Minimum 4

  RPMStartTime=micros();
analogRead(5) ;
    RPMEndTime=micros();
   RPMDuration=RPMEndTime-RPMStartTime;

Minimum 112

I don't mind adding 112 onto my timing period but why is it multiples of 112 and not multiples of 4 +112 ?

Ill try the timing with digital input next. My signal generator would not trigger a high (5 volts ) so I uses the analog input.

Thanks for the help.

The analog read is just the trigger, the micro() should still measure micros.

Your problem is that analogRead is not instantaneus. It needs 14 ADC cycles of 64 machine cycles to sample and measure input voltage. This adds up to 56 microseconds. In contrast, a digital read is immediate (a single machine cycle + function call overhead).

The following minimum resolutions would apply when sampling pulse duration:

  • Using analogRead: 56us * 2
  • Using digitalRead: about 2us * 2
  • Using direct port I/O: sub microsecond

The absolute minimum resolution for the AtMega microcontroller is a single machine cycle (62.5 nano seconds at 16Mhz).

My day job has interfered with my Ardrino programming.

Your problem is that analogRead is not instantaneus. It needs 14 ADC cycles of 64 machine cycles to sample and measure input voltage. This adds up to 56 microseconds. In contrast, a digital read is immediate (a single machine cycle + function call overhead).

I'm not sure I understand this properly

I have two rising edges, not related to each other at all. I understand that the Analog read takes 56 microseconds to read the data. So from the sample to result is 112 micros(). If I use 2 analog reads, the sample timing will be the same for both but why is the period between the two samples always multiples of 112.

Does the processor logic process the program from top to bottom or as in some PLC's, scan all the ladder logic and the only write the changes at the end of the scan.

The time difference should be multiples of 56us (minimum 112) unless;

  • you have an 8MHz board (in which case it will be multiples of 112, minimum 224).

or

  • time between pulses is so that you will always end up with an even number of analogRead's.