Show Posts
Pages: [1]
1  Topics / Science and Measurement / Re: precise RPM counter - micros()/interrupt/serial problem? on: March 30, 2013, 10:28:24 am
Afremond,
correct me if I'm wrong, but I think you lose 0.5us in line where you divide t1time with two if the number stored in counter is odd.
Code:
t1time = (t1temp - t1last) >> 1;
You shift all the bits in t1time to the right one bit, so what happens to one (1) stored in LSB, if the number in t1time is odd?
2  Topics / Science and Measurement / Re: precise RPM counter - micros()/interrupt/serial problem? on: March 30, 2013, 08:29:06 am
Hi,

I finally got around in testing afremonts code. It worked just fine, but I still had the same issue - those cca. 500us delay from time to time. I then hooked my Arduino to function generator to test it out and the code works like a charm. So the problem was not the code but the sensor. I found in the datasheet that the sensors response time is <=0.5ms, so this is what is causing all the problems. It would not be that big of a deal if the sensor delay was always the same, but it’s not. So sometimes it takes 460us to respond, sometimes less, sometimes more, and this is making the period jump up and down. There are two solutions to the problem that I could think off. The first is to buy a sensor that is much faster (30us or less – 5RPM error at 3000RPM), the second is to count the number of rotations in a given interval – say 10s and dividing the time by number of counts – but this would only work well for “higher” frequencies, lower the frequency bigger the error.
3  Topics / Science and Measurement / precise RPM counter - micros()/interrupt/serial problem? on: March 21, 2013, 11:17:08 am
Hey guys,
I’m building an RPM counter for counting RPM of a fan at work. I'm using Arduino Duemillanove(Atmega328) and an optical sensor. The sensor senses light reflecting of a reflective sticker on one of the fan blades, it outputs a logical high(5V), and each time it shines on the sticker a logic low(0V).  So my way of approaching the problem was to use interrupts to catch the logic low from the sensor. I found a lot of stuff on rpm counters using Arduino, but all of which seem to originate from this post: http://playground.arduino.cc/Main/ReadingRPM
I don’t like the idea to measure 20 or so revolutions and average them out to get a smooth number flow. I would rather measure a period of one cycle as precise as possible. So my way of tackling the problem is to measure time in interrupt routine using micros(). Each time interrupt occurs time is measured and previous time subtracted from it to get a period of one cycle. The problem is that the period time jumps from 20000us to 19500us and back at 3000RPM. This then relates to around 70RPM error. The code I wrote is below:

Code:
#define baudrate 115200

char PERCommand[] = "PER?";
char SerialCommand[10];
int SerialDelay;
byte cnt = 0;
unsigned long time[2] = {0,0};
volatile unsigned long per = 0;

void setup() {
Serial.begin(115200);
        SerialDelay = (10000000/baudrate)+50;
attachInterrupt(0, handler, FALLING);
}

void loop() {
  if(Serial.available() > 0) {
//    detachInterrupt(0);
    GetCommand();
    CompareAndReturn();
//    attachInterrupt(0, handler, FALLING);
  }
}

void GetCommand() {
  while(Serial.available() > 0 && cnt < 9) {
    char c = Serial.read();
    SerialCommand[cnt] = c;
    SerialCommand[cnt+1] = '\0';
    cnt++;
    delayMicroseconds(SerialDelay);
  }
  cnt = 0;
}

int CompareAndReturn() {
  if(strcmp(PERCommand, SerialCommand) == 0) {
    Serial.print(per);
  } else { 
      error();
  }
}

int error() {
  Serial.print(-1);
  while(Serial.available() > 0){
    Serial.read();
    delayMicroseconds(SerialDelay);
  }
  return(0);
}

// ISR
void handler() {
time[1] = micros();
per = time[0] - time[1];
time[0] = time[1];
}

I tried to comment out GetCommand() and CompareAndReturn() functions and just putting there a Serial.print() function to return period(I was wondering if the serial communication could be the problem), I also tried detachInterrupt(), but it's just not working properly.
Is there another way to tackle the problem?
If anyone knows what the problem could be please do help.

Cheers,
Jure
 
Pages: [1]