The frequency slows down continously but takes time to spped up!

Hi guys,

You helped me to solved some problems of the code but now I got stuck somewhere else! :stuck_out_tongue_closed_eyes:

As you know I had decided to use our buddy, "Serial Monitor" to change the frequency of blinking.

Here is the final code as follows.

volatile boolean l;
//unsigned int integerValue=0;  // Max value is 65535
//char incomingByte;

void TC0_Handler()
{
  
    long dummy=REG_TC0_SR0; // vital - reading this clears some flag    --- Status REG
                            // otherwise you get infinite interrupts
    l= !l;
    //REG_TC0_CCR0=0b101; //Start counter
}


//void setFrequen


void setup(){
  Serial.begin(57600);
  pinMode(13,OUTPUT);
   
}


void loop(){
    
       digitalWrite(13,l);

          

 if (Serial.available() > 0) {   // something came across serial
 
   char buffer[] = {' NUL',' NUL',' NUL',' NUL',' NUL',' NUL',' NUL',' NUL',' NUL'}; 

 Serial.readBytesUntil('\n', buffer, 20);
int  incomingValue = atoi(buffer);

   Serial.println(incomingValue);
   pinMode(2,OUTPUT);    // port B pin 25  
  analogWrite(2,255); 
   REG_PIOB_PDR = 1<<25; // disable PIO, enable peripheral
  REG_PIOB_ABSR= 1<<25;
     REG_TC0_CMR0=0b00000000000010011100010000000000;
  REG_TC0_IER0=0b00010000; 
  
  REG_TC0_RC0 = incomingValue*1000000;
  NVIC_EnableIRQ(TC0_IRQn);
 }
  
 
    
    
       
}

This works perfectly and each time when I put a new value for "incomingValue", it changes the frequency by changing the amount of "REG_TC0_RC0".

But I can only count up. What does this mean. I mean as follows:

1
8
20
40
80
100

Then I can see the frequency slows down and the LED beats slower and this change is instantly ..... But what if I go this way

1
8
1

Surprisingly it does change it instantly .... from 1 to 8 it is immediately but from 8 to 1 it takes 2 minutes!!!

I look for "COUNT DOWN/UP" in the datasheet and found the following register:

REG_TC0_SMMR0

which is responsible for count down and up

but I guess the problem is something else...

I am totally confused!

The problem is the "Serial monitor" and the way I used the buffer or NO! The problem is the Register configuration itself?

What do you think?

Any idea about this?

I really appreciate your kind and prompt reply in advance! :slight_smile:

This works perfectly

It doesn't even compile.

Pete

Please try again. I just edited two minor mistake.

It still doesn't compile. Why not post the working code?

Pete

No this works properly. Check out the IDE you work with.

Thanks anyway.

henrimontreal:
No this works properly. Check out the IDE you work with.

Thanks anyway.

sketch_apr08a.cpp: In function 'void TC0_Handler()':
sketch_apr08a:9: error: 'REG_TC0_SR0' was not declared in this scope
sketch_apr08a.cpp: In function 'void loop()':
sketch_apr08a:42: error: 'REG_PIOB_PDR' was not declared in this scope
sketch_apr08a:43: error: 'REG_PIOB_ABSR' was not declared in this scope
sketch_apr08a:44: error: 'REG_TC0_CMR0' was not declared in this scope
sketch_apr08a:45: error: 'REG_TC0_IER0' was not declared in this scope
sketch_apr08a:47: error: 'REG_TC0_RC0' was not declared in this scope
sketch_apr08a:48: error: 'TC0_IRQn' was not declared in this scope
sketch_apr08a:48: error: 'NVIC_EnableIRQ' was not declared in this scope

To me, that doesn't look like it works perfectly....

This is strange but I use an ARDUINO IDE on mac and it works!

And I have got it from here:

So there must be something wrong on your IDEs.

So there must be something wrong on your IDEs.

Whatever, but I won't be exploring that.

Henri, what board and IDE are you using ?

Doesn't compile for me:

sketch_apr08b.ino: In function 'void TC0_Handler()':
sketch_apr08b:9: error: 'REG_TC0_SR0' was not declared in this scope
sketch_apr08b.ino: In function 'void loop()':
sketch_apr08b:42: error: 'REG_PIOB_PDR' was not declared in this scope
sketch_apr08b:43: error: 'REG_PIOB_ABSR' was not declared in this scope
sketch_apr08b:44: error: 'REG_TC0_CMR0' was not declared in this scope
sketch_apr08b:45: error: 'REG_TC0_IER0' was not declared in this scope
sketch_apr08b:47: error: 'REG_TC0_RC0' was not declared in this scope
sketch_apr08b:48: error: 'TC0_IRQn' was not declared in this scope
sketch_apr08b:48: error: 'NVIC_EnableIRQ' was not declared in this scope

It would help to specify what board you have selected, this isn't supposed to be a guessing game.

And please don't use the variable name "l".

Can you see the difference between:

foo = 1;  // the number one
foo = l;  // lower-case L

I can't, easily.

Henri, what board and IDE are you using ?

I use Arduino Due and IDE is 1.5.2.

It would have been easier if you had said that in the first place.

You need to reset the counter whenever you change the period. What can go wrong is, if you shorten the period, the counter might have already gone past the new period value, and then it won't trigger the interrupt until it has counted all the way to 0xFFFFFFFF, wrapped around to 0 and got to the new period value - which is why it takes a while to speed up.

The line REG_TC0_CCR0=0b101; restarts the counter. You need to put it just after REG_TC0_RC0 = incomingValue*1000000;

stimmer:
You need to reset the counter whenever you change the period. What can go wrong is, if you shorten the period, the counter might have already gone past the new period value, and then it won't trigger the interrupt until it has counted all the way to 0xFFFFFFFF, wrapped around to 0 and got to the new period value - which is why it takes a while to speed up.

The line REG_TC0_CCR0=0b101; restarts the counter. You need to put it just after REG_TC0_RC0 = incomingValue*1000000;

Stimmer! You are awesome! The problem got solved! Special thank to you! :slight_smile:

Now, I have one more question and I wonder if you or anyone who reads this can kindly answer to it. As you can see here and the page 871 and 872 of Datasheet for Arduino Due (AT91SAM), there are some special pins to enable the Timer.

Here we use TC0 Channel 0 and pins 2 1nd 13.

I tried Pin 61 and 62 (For PA2 and PA3 for the AT91SAM ) and TC0 channel 1 to get another independent frequency. For example

instead of REG_TC0_SR0 I have used REG_TC0_SR1. But this approach seems doesn't work properly. Do I need to apply other changes?

Do you know how I can get a couple of unique and completely independent frequency out of this?

Thank you for your help.