Go Down

Topic: Timers (Read 1 time) previous topic - next topic

weinerschizel

What is the finest resolution timer available on the arduino AND
How do you interface with it?

I'm trying to integrate position from an accelerometer.  So the higher resolution the timer the better.

Thanks!

mem

All the timers have the same resolution, with a prescale of 0 the resolution is the clock period (62.5ns for a standard 16mhz arduino). Note that timer1 is a 16bit counter, timer2 is 8 bit (timer0 also 8 bit but is used by the millis() function.

What resolution do you want, what is the maximum period you need to measure, and what triggers the start and stop times?

weinerschizel

A read to the TWI triggers the start and stop times.  I want as high of resolution as possible because that dictates the error on my discrete integral.

Thanks!

mem

Quote
A read to the TWI triggers the start and stop times.

any data available, any read, or a read of a specific amount of data?

I don't understand from what you said how a timer gets started and stopped.

Perhaps it would help if you clarified what time periods your application is working in (what are the shortest and longest times you want to measure and what is the minimum accuracy you need).

And what is it that you are reading using TWI?

weinerschizel

#4
Sep 22, 2008, 10:48 pm Last Edit: Sep 22, 2008, 10:49 pm by weinerschizel Reason: 1
Here's my code:

Code: [Select]
#undef int()
#include <stdio.h>
#include <Wire.h>

#define X_Axis_Address 0x28
#define Y_Axis_Address 0x2A
#define Z_Axis_Address 0x2C
#define MaxPacketLength 30

unsigned int long StartTime;
unsigned int long ElapsedTime;
byte sync = 0;
char Packet[MaxPacketLength];
int x_val = 0;
int y_val = 0;
int z_val = 0;
 
void setup( void )
{
 Wire.begin();
 Serial.begin(9600);
 
 Wire.beginTransmission(0x1D);
 Wire.send(0x20);
 
 Wire.send(0x87);
 Wire.endTransmission();
}

void loop()
{  
 int start = TCNT1;
 static int stop = 0;
 
 x_val = Accel( X_Axis_Address );
 y_val = Accel( Y_Axis_Address );
 z_val = Accel( Z_Axis_Address );

 sprintf( Packet,
     "%d,%d,%d,%d",
     x_val,
     y_val,
     z_val,
     stop - start );

 CheckSum( Packet );
 stop = TCNT1;
}

void CheckSum( char Packet[] )
{
 byte sum = 0;
 
 for( int i = 0; i < strlen(Packet); i++ ) sum += Packet[i];
 
 sum = ~sum + 1;

 Serial.print( Packet );
 Serial.print( "*" );
 Serial.println( sum, HEX );
}

int Accel( byte address )
{
 byte val_l, val_h;
 int val;  

 Wire.beginTransmission(0x1D);
 Wire.send( address + 1 );
 Wire.endTransmission();

 Wire.requestFrom(0x1D,1);

 if(Wire.available())
   val_h = Wire.receive();

 Wire.beginTransmission(0x1D);

 Wire.send( address );

 Wire.endTransmission();
 Wire.requestFrom(0x1D, 1);

 while(Wire.available())
   val_l = Wire.receive();

 val   = val_h;
 val <<= 8;
 val  += val_l;
 
 return val;
}


I need to know the period in between reads of the accelerometer.  And as accurate as possible.

dcb

I use a few strategies for accurate timing in the mpguino (for monitoring fuel injector pulse lengths)

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1221706885

Two that come to mind are scheduling the reads with your own timer isr at pre-defined intervals

Or using something like microSeconds and elapsedMicroseconds to figure out the interval.

There are a lot of other approaches too I'm certain.

Syvwlch

I dunno, seems like a lot of effort for little reward, IMHO.

Let's see how bad the error is if you mismeasure the time by one millisecond using millis().

For one G acceleration, the error on speed for one mS error on time is not quite one cm/s, and the error on position is 5 microns. (9.8m/s/s for 0.001 second and 0.5*9.8m/s/s for 0.001 second squared, respectively)

Accelerometers are quite accurate for short durations, and position dead reckoning drifts not due to error on delta time but simply because of integration's tendency to amplify small errors over time.

IOW, I suspect you get much more inaccuracy from noise in the sensor than from the error on how long the measurement took.

If the measurement takes a lot less than a couple mS to be done, then you could perform X measurements, measurement how long that took and divide by X.

At the very least, I would see how much accuracy I got that way before trying to measure durations under the millisecond, since that requires extra work without necessarily helping much.
----------
Mathieu

Jeroen

Hey Weinerschizel,

I'm wondering if you managed to obtain (useful) distance information by integrating the accelerometer's output. I'm trying to do the same, and hopefully you can supply me with some working code :)

Kind regards, J.

Go Up