Atiny Wavelength capture

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

Im trying to get a wavelength value & save it to the internal eeprom, to be read via a programmer later. The problem is the 8bit registers in the Atiny45 aren't big enough to handle the length of time. So i have tried to use the overflow & count each one until i reach the end of the wavelength.
I have had a look around but im not entirely sure how to search for what im after.
Im including the capture part to see if anyone can shed some light on what im doing wrong. I cant seem to get it working properly.

Thanks

#define F_CPU 8000000

volatile uint8_t Capture;
volatile uint16_t PulseWidth;		//Kept in memory, not forgotten until re-written
volatile uint8_t TimeOut = 62;		//62 = 0.50592 second. (((1/(F_CPU/Prescaler)) * 255) * 62) = 0.50592
volatile uint8_t prev,curr;
volatile uint8_t startup_count = 2;
volatile uint8_t pulse = 0;


ISR(TIMER0_OVF_vect)
{
	//Stop de-incrementing if it is zero. Done as a precaution
	if (TimeOut)
	{
		TimeOut--;

		if (TimeOut == 0)
		{
			startup_count = 2; // Reset the capture machine
			pulse = 0;
		}
	}
}

ISR(PCINT0_vect)
{
	//Store here to get the most accurate time.
	curr = TCNT0;

	// Because i want to count the wavelength i only trigger each time its set
	if (bit_is_set(PINB, 0))
	{		
		//If pulsewidth is within 0 - 255 TCNT0 timer use this code
		if(TimeOut == 62)
		{
			PulseWidth = curr - prev;
		}
		else
		{	//Pulsewidth is over two timers
			//First add (255 - prev) because its the first portion from prev to 255
			//Second add (((62 - 1) - TimeOut) * 255)
			//(62 - 1) 1 removed due to the first overflow cant be counted or it will be 255 out
			//TimeOut) * 255) add all of the overflows towards final time
			//Third add curr as its the remaining 0 to curr
			PulseWidth = ((255 - prev) + (((62 - 1) - TimeOut) * 255) + curr;
		}
		
		prev = curr;
		
		//The first two captures will be thrown away because they will be wrong.
		if (startup_count)
		{
			startup_count--;
		}
		else
		{
			Capture = 1;
		}
	}
}

int main(void)
{
	//Setup Pin Change Interrupt
	PCMSK |= (1<<PCINT0);	//Enable this pin only (PB0)
	GIMSK |= (1<<PCIE);		//Enable Pin change interrupt
	
	//Setup Timer
	TCCR0B |= (1<<CS02);	//256 prescaler
	TIMSK |= (1<<TOIE0);	//Enable Overflow interrupt
	
	sei();					//Enable interrupts

	for(;;)
	{
		if (Capture)
		{
		    TimeOut = 62;			//Reset timeout feature
		    Capture = 0;			//Reset flag for next capture.
		    cli();					//Disabling interrupts stops atomicity. No chance to reading while writing.
		    pulse = PulseWidth;		//Disabled interrupts around this for fastest possible capture times.
		    sei();
		    
	    }
		
		//If TimeOut == 0 store to eeprom etc
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not able to understand how your code works. I give up.

If your main() can be blocked for one or two signal periods, you might try simple

//pseudocode 
volatile uint8_t ovf_count;

ISR(timer_overflow)
{
   ovf_count++;
}

main
{
   while(1)
   {
      wait for input=0;
      wait for input=1;
      start timer;
      wait for input=0;
      wait for input=1;
      stop timer;
      
      period = (ovf_count * 256) + TCNTx;
      TCNTx = 0;     // clear timer
      ovf_count = 0;
   }
}

Otherwise you can detect the edges with PCINT interrupt.