Society of Robots - Robot Forum
Software => Software => Topic started by: scorp84 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
#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);
}
-
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
-
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?
#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();
}
}
}