<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LeafLabs Garden &#187; Topic: Can I change the timer overflow inside the interrupt?</title>
		<link>http://forums.leaflabs.com/topic.php?id=74337</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Fri, 22 Jan 2016 00:14:16 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://forums.leaflabs.com/search.php</link>
		</textInput>
		<atom:link href="http://forums.leaflabs.com/rss.php?topic=74337" rel="self" type="application/rss+xml" />

		<item>
			<title>jappiemike on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105419</link>
			<pubDate>Sun, 01 Jun 2014 06:13:49 +0000</pubDate>
			<dc:creator>jappiemike</dc:creator>
			<guid isPermaLink="false">105419@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I'm looking for a timer interval of at least 100hz for the longest screen write interval so the matrix looks &#34;solid&#34;, so it's not very fast but it needs to be consistent or the illusion falls apart. The reason for the varying intervals is to reduce the load on the MPU from 256 cycles to 8 cycles through the wonders of BAM. I do intend to take out all the serial prints in the final code they are just there for debugging at the moment.&#60;br /&#62;
Cheers,&#60;br /&#62;
Mike
&#60;/p&#62;</description>
		</item>
		<item>
			<title>ala42 on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105418</link>
			<pubDate>Sat, 31 May 2014 11:58:34 +0000</pubDate>
			<dc:creator>ala42</dc:creator>
			<guid isPermaLink="false">105418@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;As I wrote above, use timer.setOverflow(tar[bam]-1);
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105417</link>
			<pubDate>Fri, 30 May 2014 11:54:26 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">105417@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;jappiemike - &#60;em&#62;&#34;... I did notice that the program runs faster when I open the serial window in the IDE to watch the values which is unexpected&#34;&#60;/em&#62;&#60;/p&#62;
&#60;p&#62;That is very likely because SerialUSB.print() blocks waiting to output. If practical, remove all uses of SerialUSB from your program.&#60;/p&#62;
&#60;p&#62;&#60;em&#62;&#34;...  took out the final timer.refresh(); ... seem to be getting a varying time between pulses now ... &#34;&#60;/em&#62;&#60;br /&#62;
IIRC the libmaple code configures the timers so that the overflow register is buffered (by a 'preload register'), so it isn't updated until there is another 'update event' (see 15.3.1 &#34;Time-base unit&#34; of RM0008 for more details).&#60;br /&#62;
&#60;code&#62;timer.refresh()&#60;/code&#62; should only wiggle some control bits in a timer register to get the timer to update its overflow register. I can't figure out if the update event is supposed to be set by the interrupt routine. &#60;/p&#62;
&#60;p&#62;If you take all of the code out of the interrupt handler, and put it in loop, and replace the handler with something simple (as I wrote in &#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=74337#post-105404)&#34; rel=&#34;nofollow&#34;&#62;http://forums.leaflabs.com/topic.php?id=74337#post-105404)&#60;/a&#62; does it work correctly?&#60;/p&#62;
&#60;p&#62;What range of frequencies do you need?&#60;br /&#62;
How accurate does it need to be?&#60;br /&#62;
If the fastest is about a 100 microseconds or more, with some jitter, you could leave the timer interrupting at a constant rate, and do the rest of the work in loop().
&#60;/p&#62;</description>
		</item>
		<item>
			<title>jappiemike on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105416</link>
			<pubDate>Tue, 27 May 2014 19:03:13 +0000</pubDate>
			<dc:creator>jappiemike</dc:creator>
			<guid isPermaLink="false">105416@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hello all,&#60;br /&#62;
 so I took out the final timer.refresh(); in the ISR and it seems to be working now, although the documentation seems to indicate you need to use it. I'll do some more checking with my ChronoVu but I seem to be getting a varying time between pulses now. I also had the tar values backwards and I've reverted to 2800 as the prescaler. I did notice that the program runs faster when I open the serial window in the IDE to watch the values which is unexpected. Thanks for your help.&#60;br /&#62;
Cheers&#60;br /&#62;
Mike
&#60;/p&#62;</description>
		</item>
		<item>
			<title>jappiemike on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105415</link>
			<pubDate>Tue, 27 May 2014 18:38:56 +0000</pubDate>
			<dc:creator>jappiemike</dc:creator>
			<guid isPermaLink="false">105415@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hello ala43,&#60;br /&#62;
I changed the prescale to 1000 and changed the tar values to&#60;br /&#62;
volatile int tar[]={32000,16000,8000,4000,2000,1000,500,250}; //{128,64,32,16,8,4,2,2};&#60;br /&#62;
and still didn't see a change in the frequency.&#60;br /&#62;
Cheers&#60;br /&#62;
Mike
&#60;/p&#62;</description>
		</item>
		<item>
			<title>jappiemike on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105414</link>
			<pubDate>Tue, 27 May 2014 18:17:44 +0000</pubDate>
			<dc:creator>jappiemike</dc:creator>
			<guid isPermaLink="false">105414@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;OK Here is the full code listing such as it is.&#60;br /&#62;
`#include &#38;lt;timer.h&#38;gt;&#60;br /&#62;
#define LED_RATE 2800    //  2800 is best rate&#60;br /&#62;
/*&#60;br /&#62;
 a prescale 7200&#60;br /&#62;
 1=2.5 khz&#60;br /&#62;
 100=49.5 hz&#60;br /&#62;
 200=24.9 hz&#60;br /&#62;
 300=16.6 hz&#60;br /&#62;
 400=12.5 hz&#60;br /&#62;
 500=10.0 hz&#60;br /&#62;
 a prescale of 2880&#60;br /&#62;
 128=99.6 hz&#60;br /&#62;
 64=197.7 hz&#60;br /&#62;
 32=389.4 hz&#60;br /&#62;
 16=756.0 hz&#60;br /&#62;
 8=1.428 khz&#60;br /&#62;
 4=2.570 khz&#60;br /&#62;
 2=4.284 khz&#60;br /&#62;
 1=6.426 khz&#60;/p&#62;
&#60;p&#62; a prescale of 720&#60;br /&#62;
 1=25 khz&#60;br /&#62;
 100=495 hz&#60;br /&#62;
 200=249 hz&#60;br /&#62;
 300=166 hz&#60;br /&#62;
 400=125 hz&#60;br /&#62;
 500=100 hz&#60;/p&#62;
&#60;p&#62; a prescale 288&#60;br /&#62;
 500=250 hz&#60;br /&#62;
 1000=125 hz&#60;br /&#62;
 2000=62 hz&#60;br /&#62;
 3000=41 hz&#60;br /&#62;
 4000=31 hz&#60;br /&#62;
 5000=25 hz&#60;br /&#62;
 */&#60;/p&#62;
&#60;p&#62;// We'll use timer 2&#60;br /&#62;
HardwareTimer timer(2);&#60;br /&#62;
volatile byte Lar[10];&#60;br /&#62;
volatile int tar[]={128,64,32,16,8,4,2,2};&#60;br /&#62;
volatile int  bam;&#60;/p&#62;
&#60;p&#62;void setup() {&#60;/p&#62;
&#60;p&#62;  // Set up the LED to blink&#60;br /&#62;
  pinMode(BOARD_LED_PIN, OUTPUT);&#60;br /&#62;
  pinMode(30, OUTPUT);&#60;br /&#62;
  pinMode(31, OUTPUT);&#60;br /&#62;
  pinMode(32, OUTPUT);&#60;br /&#62;
  pinMode(33, OUTPUT);&#60;br /&#62;
  pinMode(34, OUTPUT);&#60;br /&#62;
  pinMode(35, OUTPUT);&#60;br /&#62;
  pinMode(36, OUTPUT);&#60;br /&#62;
  pinMode(37, OUTPUT);&#60;br /&#62;
  //SerialUSB.begin(9600);&#60;/p&#62;
&#60;p&#62;  // Pause the timer while we're configuring it&#60;br /&#62;
  timer.pause();&#60;/p&#62;
&#60;p&#62;  // Set up period&#60;br /&#62;
  timer.setPrescaleFactor(LED_RATE); // in microseconds&#60;br /&#62;
  // Set up an interrupt on channel 1&#60;br /&#62;
  timer.setChannel1Mode(TIMER_OUTPUT_COMPARE);&#60;br /&#62;
  timer.setCompare(TIMER_CH1, 1);  // Interrupt 1 count after each update&#60;br /&#62;
  timer.setOverflow(1);&#60;br /&#62;
  timer.attachCompare1Interrupt(handler_led);&#60;/p&#62;
&#60;p&#62;  // Refresh the timer's count, prescale, and overflow&#60;br /&#62;
  timer.refresh();&#60;/p&#62;
&#60;p&#62;  // Start the timer counting&#60;br /&#62;
  timer.resume();&#60;/p&#62;
&#60;p&#62;}&#60;/p&#62;
&#60;p&#62;void loop() {&#60;br /&#62;
  // delay(1000);&#60;br /&#62;
  SerialUSB.println(&#34;START UP&#34;);&#60;br /&#62;
  for(int a=0;a&#38;lt;8;a++)&#60;br /&#62;
  {&#60;br /&#62;
    Lar[a]=255;  // sets the LED on&#60;br /&#62;
    delay(50);&#60;br /&#62;
    SerialUSB.println(&#34; **&#34;);&#60;br /&#62;
    Lar[a]=0;   // sets the LED off&#60;br /&#62;
    delay(50);&#60;br /&#62;
    SerialUSB.println(&#34; ***&#34;);&#60;br /&#62;
  }&#60;br /&#62;
  SerialUSB.println(&#34;Done Testing LEDs&#34;);&#60;br /&#62;
  for(int a=0;a&#38;lt;255;a+=10)&#60;br /&#62;
  {&#60;br /&#62;
    for(int b=0;b&#38;lt;8;b++)&#60;br /&#62;
    {&#60;br /&#62;
      Lar[b]=a;&#60;/p&#62;
&#60;p&#62;      SerialUSB.print(Lar[b]);&#60;br /&#62;
      SerialUSB.print(&#34; &#34;);&#60;br /&#62;
      delay(50);&#60;br /&#62;
    }&#60;br /&#62;
    SerialUSB.println(&#34; *&#34;);&#60;br /&#62;
  }&#60;/p&#62;
&#60;p&#62;  for(int a=0;a&#38;lt;8;a++)&#60;br /&#62;
  {&#60;br /&#62;
    Lar[a]=0;    // sets the LED off&#60;br /&#62;
  }&#60;br /&#62;
  delay(100);&#60;br /&#62;
}&#60;/p&#62;
&#60;p&#62;void handler_led(void) {&#60;br /&#62;
  digitalWrite(13,LOW);&#60;br /&#62;
  for(int s=0;s&#38;lt;8;s++) // work along LED columns&#60;br /&#62;
  {&#60;br /&#62;
    if(bitRead(Lar[s],bam)==1)&#60;br /&#62;
    {&#60;br /&#62;
      digitalWrite(30+s,LOW); // on&#60;br /&#62;
//digitalWrite(13,LOW);&#60;br /&#62;
    }&#60;br /&#62;
    else&#60;br /&#62;
    {&#60;br /&#62;
      digitalWrite(30+s,HIGH); // off&#60;br /&#62;
   //   digitalWrite(13,HIGH);&#60;br /&#62;
    }&#60;br /&#62;
  }&#60;br /&#62;
    if(bam++==7)&#60;br /&#62;
    {&#60;br /&#62;
      bam=0;&#60;br /&#62;
    }&#60;br /&#62;
    timer.setOverflow(tar[bam]);&#60;br /&#62;
    timer.refresh();&#60;br /&#62;
    digitalWrite(13,HIGH);&#60;br /&#62;
//toggleLED();&#60;br /&#62;
}&#60;br /&#62;
 I think the frequency is off by a factor of 2 because of toggle() only changes every 2nd pass through the interrupt. I've changed it to digitalWrites to get a more accurate idea. I've hooked my ChronoVu up to pin 13 and the frequency doesn't change from when the ISR exits until it enters it again at about 40us. I did notice that none of the timer keywords are syntax colored in my code, does this indicate a problem? As far as I know bitread is a macro according to the documentation.&#60;br /&#62;
Cheers&#60;br /&#62;
Mike
&#60;/p&#62;</description>
		</item>
		<item>
			<title>ala42 on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105413</link>
			<pubDate>Tue, 27 May 2014 18:01:22 +0000</pubDate>
			<dc:creator>ala42</dc:creator>
			<guid isPermaLink="false">105413@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;The counter counts one step more than you think is does, as you can easily see from your measurements:&#60;br /&#62;
4=2.570 khz&#60;br /&#62;
2=4.284 khz&#60;br /&#62;
(4+1)*2570 / (2+1) = 4283.3&#60;br /&#62;
So you should use timer.setOverflow(tar[bam]-1);&#60;br /&#62;
Besides that, use a smaller prescaler and larger counter values.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105412</link>
			<pubDate>Tue, 27 May 2014 14:14:05 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">105412@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;jappiemike - In future, would you please post &#60;strong&#62;all&#60;/strong&#62; the (relevant) code?&#60;br /&#62;
There is no way we could adequately understand the code.&#60;/p&#62;
&#60;p&#62;'1' at 'a prescale of 2880' does look weird. So does '1' at 'a prescale 7200', shouldn't that be close to 4.9KHz, not 2.5KHz?&#60;/p&#62;
&#60;p&#62;However, 6.426KHz represents quite a lot of instructions, about 11,000.&#60;br /&#62;
I'd guess that the handler code should run in 10-30 microseconds unless something is blocking or bitRead is amazingly complex.&#60;/p&#62;
&#60;p&#62;What frequency do you need for '1'?&#60;br /&#62;
I'd suggest running a performance test/benchmark, to see how fast the code is actually able to run.&#60;br /&#62;
Don't use the interrupt handler, instead put all the code in loop(). (You might want to disable SerialUSB, and not use it, to reduce jitter.)
&#60;/p&#62;</description>
		</item>
		<item>
			<title>jappiemike on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105405</link>
			<pubDate>Mon, 26 May 2014 19:31:34 +0000</pubDate>
			<dc:creator>jappiemike</dc:creator>
			<guid isPermaLink="false">105405@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hello GBulmer,&#60;br /&#62;
I have used a frequency meter on the #13 pin and got these readings&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;a prescale 7200
 1=2.5 khz
 100=49.5 hz
 200=24.9 hz
 300=16.6 hz
 400=12.5 hz
 500=10.0 hz
 a prescale of 2880
 128=99.6 hz
 64=197.7 hz
 32=389.4 hz
 16=756.0 hz
 8=1.428 khz
 4=2.570 khz
 2=4.284 khz
 1=6.426 khz&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;I did note the last reading was off and suspect this is where the interrupt starts to fall down and will use two 2s in the final code.&#60;br /&#62;
The final code, if I can get it to work, will send the data out via SPI to some shift registers so this is just trying to get the routine to work in the first place.&#60;br /&#62;
Cheers&#60;br /&#62;
Mike
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105404</link>
			<pubDate>Mon, 26 May 2014 11:16:35 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">105404@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;jappiemike - what evidence do you have that this code can work anyway?&#60;/p&#62;
&#60;p&#62;Setting the timer overflow to 1, 2, 4, 8, and 16 (maybe even 32?) seems far too short to get back out of the interrupt handler, especially with the call of &#60;code&#62;toggleLED();&#60;/code&#62;. So that looks very suspicious to me.&#60;/p&#62;
&#60;p&#62;I'd probably take all the working code out of the interrupt handler, and put it into loop, then reduce the interrupt handler to something like:&#60;br /&#62;
&#60;code&#62;volatile int triggered = 0;&#60;/code&#62;&#60;br /&#62;
&#60;code&#62;void handler_led() { triggered = 1; }&#60;/code&#62;&#60;br /&#62;
and the main loop() would have:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;void looop() {
    if (triggered) {
        triggered = 0;   // assumes this code is quick enough
        // body of interrupt handler
    }
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;A couple of small points:&#60;br /&#62;
1. In &#60;code&#62;for(volatile int s=0;s&#38;lt;8;s++)&#60;/code&#62;, &#60;code&#62;volatile&#60;/code&#62; is not necessary. &#60;code&#62;s&#60;/code&#62; is on the stack and local to the &#60;code&#62;for&#60;/code&#62; loop, so it can't be accessed (validly) by concurrent activity.&#60;/p&#62;
&#60;p&#62;2. &#60;code&#62;if(bam++==7) { bam=0; }&#60;/code&#62; could be coded as &#60;code&#62;bam = (bam+1) &#38;amp; 0x7&#60;/code&#62;
&#60;/p&#62;</description>
		</item>
		<item>
			<title>jappiemike on "Can I change the timer overflow inside the interrupt?"</title>
			<link>http://forums.leaflabs.com/topic.php?id=74337#post-105403</link>
			<pubDate>Mon, 26 May 2014 06:38:38 +0000</pubDate>
			<dc:creator>jappiemike</dc:creator>
			<guid isPermaLink="false">105403@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hi, I'm trying to  implement a BCM routine for an LED matrix and am having trouble with the changing of the interrupt frequency by changing the overflow number from inside the interrupt routine.  Here is my code&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;volatile int tar[]={128,64,32,16,8,4,2,1};
volatile static int  bam;
void handler_led(void) {
  for(volatile int s=0;s&#38;lt;8;s++) // work along LED columns
  {
    if(bitRead(Lar[s],bam)==1)
    {
      digitalWrite(30+s,LOW); // on
      //digitalWrite(13,LOW);
    }
    else
    {
      digitalWrite(30+s,HIGH); // off
      //   digitalWrite(13,HIGH);
    }
  }
    if(bam++==7)
    {
      bam=0;
    }
    timer.setOverflow(tar[bam]);
    timer.refresh();
    toggleLED();
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;The tar array hold the overflow numbers and if I change them inside the loop() at compile time the interrupt works fine but I work my way along the array in the interrupt it fails. LAr[] is an array holding the LED values and bam is a variable to step along the array. I haven't put my logic analyser on it yet (it's at work) to see whats happening. I have read the forum questions but none are changing the overflow from inside the ISR but the documentation seems to indicate I can do this. Can I do this or is it a bug in the timer routines?&#60;br /&#62;
Cheers&#60;br /&#62;
Mike
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
