0
\$\begingroup\$

I am trying to measure pulse length, with ICP (input capture pin) on Atmega8, coming from this circuit:Schematic. PINB0 is ICP pin on AVR.

This is (most of) the code:

volatile uint8_t num_interrupts = 0; //number of input capture interrupts.
volatile BOOL write_glcd = FALSE; //write to LCD. 
volatile uint8_t tim1_num_ovf = 0; //number of overflowes for timer1.
volatile uint16_t test[50]; //holds time elapsed since last TIMER1_CAP interrupt

int main(void)
{
    DDRC |= (1<<PINC3);
    PORTC &= ~(1<<PINC3);
    DDRB &= ~(1<<PINB0); //icp pin as input
    PORTB |= (1<<PINB0); //pull-up on icp pin
    TIMSK = ((1<<TICIE1)|(1<<TOIE1)); //enable timer1 overflow and input capture interrupts.
    TCCR1B = (1<<CS10); //1x prescaler, input capture on falling edge.
    cli(); //disable interrupts.

    start_LC();

    while(1){
        if (write_glcd) {
            cli(); // disable interrupts

            for (uint8_t i = 0; i < num_interrupts; i++) {
                glcd_clear_y((uint8_t[]) {4, 5, 7}, 3);
                glcd_write_num_xy(test[i], FALSE, 8, 0, 4);
                //glcd_write_num_xy(((test[i] & 0xFF0000) >> 16) * (UINT16_MAX + 1UL), FALSE, 8, 0, 5);
                _delay_ms(1000);
            }

            _delay_ms(2000);
            write_glcd = FALSE;
            start_LC();
        }        
    }
void start_LC(void)
{
    PORTC |= (1<<PINC3); //pull output high, it induces some oscillations in LC tank circuit.
    num_interrupts = 0;
    write_glcd = FALSE;
    tim1_num_ovf = 0;
    _delay_ms(10); //wait for oscillations in LC tank circuit to dissipate
    TCNT1 = 0;
    sei(); //enable interrupts.
    PORTC &= ~(1<<PINC3); //induce oscillations.
}
ISR(TIMER1_OVF_vect)
{
    tim1_num_ovf += 1;
}
ISR(TIMER1_CAP_vect)
{
    test[num_interrupts] = ICR1;// | ((uint32_t)tim1_st_ovf << 16UL)); //commented out, just for now, timer1 ovf interrupts doesnt happen, so its ok.
    num_interrupts += 1;
    tim1_num_ovf = 0;
    TCNT1 = 0;
}

The problem is, I get some relatively random data written to LCD. Something like this:

  • 55
  • 48
  • 42
  • 39
  • 16
  • 12
  • 22
  • 65

write_glcd gets set in TIMER2_OVF ISR after every second (which is based on number of TIMER2 overflow interrupts), the code is not included here.

As I understand these numbers were suppose to be time in TIMER1 ticks it takes between TIMER1_CAPT interrupts, so between two falling edges of the signal. But as I measure the frequency on the oscilloscope I get around 370kHz (constant), so, why do the values differ so much? I understand they differ by a small factor, but those values below 30, just dont make sense...

Thanks in advance!

P.S.

Sorry for the bad schematic, but I cant use the inbuilt schematic editor for some reason...

\$\endgroup\$
  • \$\begingroup\$ Why not use the built-in comparator to trigger ICP instead? \$\endgroup\$ – Ignacio Vazquez-Abrams Sep 13 '14 at 14:46
  • \$\begingroup\$ I didn't know that was possible, thanks for the info. I will try it out. But I have a feeling there is a problem somewhere in the code. \$\endgroup\$ – Golaž Sep 13 '14 at 14:49
  • \$\begingroup\$ You are aware no-doubt that the L and C tuned circuit are highly likely to to produce a series of oscillations decaying to zero and that your code must decipher the series of pulses coming from the comparator into something meaningful? \$\endgroup\$ – Andy aka Sep 13 '14 at 15:02
  • \$\begingroup\$ Ofcourse, but the frequency of the oscillations should stay the same, no? \$\endgroup\$ – Golaž Sep 13 '14 at 15:04
  • \$\begingroup\$ @IgnacioVazquez-Abrams I am getting the same random values, every second or third is like 3-6 times smaller than the others. \$\endgroup\$ – Golaž Sep 13 '14 at 15:07
1
\$\begingroup\$

Are you aware that the L and C tuned circuit are highly likely to to produce a series of oscillations decaying to zero and that your code must decipher the series of pulses coming from the comparator into something meaningful?

Maybe you are also aware that the L and C energy produces a decaying sinewave centred around 0V and this could damage damage your comparator - the LM393 has an absolute input voltage of -0.3 volts and if exceeded could cause the device permanent damage. At the very least it will screw up the signal you hope to measure.

If you wish to keep the signal as intact as you can (such as in a metal detection application) you'd be wise to put a series resistor between comparator input and tuned circuit then bias this at about half Vcc with half Vcc on the other comparator input.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ The output from the LC circuit is at its lowest point around -0.2V. The other thing is, the output from the comparator is ok, the time between the edges is more or less the same. But I will try it anyway. \$\endgroup\$ – Golaž Sep 13 '14 at 15:11
  • 1
    \$\begingroup\$ @Golaž the output is only at -0.2V because the comparator input is taking a load of energy and clamping it. \$\endgroup\$ – Andy aka Sep 13 '14 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.