go_away

Author Topic: Pulse Width  (Read 1055 times)

0 Members and 1 Guest are viewing this topic.

Offline scorp84Topic starter

  • Beginner
  • *
  • Posts: 2
  • Helpful? 0
Pulse Width
« on: April 01, 2012, 04:23:08 AM »
Hello Everyone!

I have been facing a problem of measuring pulse width using arduino nano board. The pulses are very short 5 to 15 microseconds duration and they are coming at a frequency of 1 Hz. My code is listed below but all I am getting is that I can read the pulses after every 1 microsecond or more, means if I apply 2 microsecond width it can measure it and then if it is 2.2 or 2.3 it will still display 2 or even if it is 2.5 and so on until it reaches near to 3 microsecond then it would display either 2.5 or 3. So my results are not accurate and I need help with my code, I have just joined this forum after watching that someone previously answered this but the code was different so I hope that I would get some help from here. I would be grateful to all of you. here is my code


Code: [Select]
#include<stdlib.h>

unsigned int pulse_counts = 0;

unsigned int count = 0;
void setup()
{
  Serial.begin(9600);
//  Serial.println("pulse width measurment");

  pinMode(3, INPUT); 
}

void loop()
{
  count = 0;
  pulse_counts++;
  while ((PIND & B00001000) == B00000000); // wait for HIGH
  while ((PIND & B00001000) == B00001000) count++; // start counting until LOW

  float usec = 1.0 * count * 6/12;
 
 


 For serial output display - Uncomment this
 
  Serial.print("Count = ");
  Serial.print(pulse_counts);
  Serial.print(" , Width = ");
  Serial.print(usec, 2);
  Serial.println ("  microseconds");


//  delay(1000);
}

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Pulse Width
« Reply #1 on: April 01, 2012, 05:56:35 AM »
Code: [Select]
  count = 0;
  pulse_counts++;
  while ((PIND & B00001000) == B00000000); // wait for HIGH
  while ((PIND & B00001000) == B00001000) count++; // start counting until LOW

If you just wait for high, you could miss the start of a pulse, because the pulse may already be happening when you start waiting for it. Try making sure the line is low first, then start waiting for it to go high.

Also be aware that floating point arithmetic is going to slow things down, see if you can do whatever you're doing with integer arithmetic.

Joe

Offline scorp84Topic starter

  • Beginner
  • *
  • Posts: 2
  • Helpful? 0
Re: Pulse Width
« Reply #2 on: April 01, 2012, 06:11:28 AM »
I have the code now by using timer and interrupts but still the results are not good :( anyone can help me with this code now?


Code: [Select]
#define ICP PINB0
//Variables holding three timestamps
  volatile uint16_t ov_counter, rising, falling;
//capture Flag
  volatile unsigned int flag = 0;
  volatile uint32_t counts;
  volatile uint16_t time;
  int val = 0;     // variable to store the read value
  int lastPulse = LOW;
  int count = 1;
//Initialize timer
  float pulse_width= 0.0;

//capture ISR
ISR(TIMER1_CAPT_vect)
{

//if(ICP)
//if (digitalRead(8) == HIGH)

if ((PINB & B00000001) == B00000001)

            {

            //save start time

            rising=ICR1;

            //set to trigger on falling edge

            //TCCR1B&=~(1<<ICES1);
             TCCR1B &= 0xBF;
            //reset overflow counter

            ov_counter=0;

   }

else

            {

            //save falling time

            falling=ICR1;
            TCNT1 = 0;
            //rising edge triggers next
           
           //TCCR1B|=(1<<ICES1);
            TCCR1B |= 0x40;
           
            counts=(uint32_t)falling-(uint32_t)rising + (uint32_t)ov_counter;
       
            /*you can convert coutns to seconds and send to LCD*/
 
           
             }
}
//Overflow ISR
ISR(TIMER1_OVF_vect)
{
//increment overflow counter
ov_counter++;
}

void setup()
{
  Serial.begin(9600) ;
  delay(100);
  Serial.println("test");
//Set Initial Timer value
TCNT1=0;
//First capture on rising edge
TCCR1B|=(1<<ICES1)| (1<<CS10) | (1<<ICNC1);
//TCCR1B|=(1<<ICES1)| (1<<CS10);
//Enable input capture and overflow interrupts
TIMSK1|=(1<<ICIE1)|(1<<TOIE1);
//Enable global interrutps
sei();
}


void loop()
{

   val = digitalRead(8);   // read the input pin
            if (val != lastPulse)
   {
   
               lastPulse = val;
               
              if (val == LOW)   
          {       
           
             //   cli();
                pulse_width = counts*4;
                Serial.print("width = ");
                Serial.print(pulse_width);
                Serial.print("  count = ");
                Serial.println(count++);
                                //clear overflow counters;
                ov_counter=0;

                //clear interrupt flags to avoid any pending interrupts
            //    TIFR1=(1<<ICF1)|(1<<TOV1);
                //enable input capture and overflow interrupts
             //   TIMSK1|=(1<<ICIE1)|(1<<TOIE1);
           //   highCounter++;
             
            //    sei();

              }
         
   }


   
 
}


 


Get Your Ad Here