CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Using 12F1840 to control r/c servo
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

PostPosted: Fri Feb 21, 2020 3:33 am     Reply with quote

Hi both

I did not know about the 400 Hz mode - my googling always talked about the 20ms gap. I have looked at your example. I would need to use timer1 as the 1840 doesn't have a timer3 and, as you say, tickle the values for my clock frequency.

Thanks again for the help.

Brian
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Fri Feb 21, 2020 3:43 am     Reply with quote

Yes, your chip uses Timer1 for the CCP.

Use 400Hz mode. Seriously every modern RC uses this. If it doesn't work
you can go slower, but the servo will run better (smoother, faster updates,
and often give more torque), with the faster updates. This is the
required rate for 'digital servos'.
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

PostPosted: Fri Feb 21, 2020 5:19 am     Reply with quote

Hi Ttelmah

I have now reworked your example to use timer1 for the CCP and timer2 for the off time and using 400Hz. It is a miniature digital servo I am using, mainly because I can program its speed. It needs to run slowly between the 2 pulse values of 33% and 59%.
Unfortunately, I am not at home until April, so I can't program the PIC and try it until then!

Thanks again for your help - I have learned a lot!

Brian
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

PostPosted: Fri Apr 10, 2020 2:28 pm     Reply with quote

Hi all,
Now back at home, I have been playing with the 1840 to drive the servo and, hey, it works perfectly!

Now to the next problem:
The 1840 must also flash a pair of leds as an aircraft strobe.
Up to this point, I have done this in the for loop within main. This works, but any other polling of inputs has to wait until the current strobe cycle has finished.
Here is the code I used in the for loop within main:
Code:

output_low(Strobes); 
delay_ms(150);         
output_high(Strobes);   
delay_ms(150);         
output_low(Strobes);   
delay_ms(150);         
output_high(Strobes);   
delay_ms(1000);         


I then had the idea to use timer0. At 16 MHz and setup_timer_0(T0_INTERNAL|T0_DIV_256);
This should overflow every 16 and a bit us, so a delay of 150 ms needs about 9 overflows and 1000 ms needs about 61.
So my interrupt function looks like this:
Code:

#INT_TIMER0
void delay_pulse(void)
{
 delay_counter++;
 if(delay_1 == true)
  {
   if(delay_counter >= 9 && get_timer0() == 254)
    {
     delay_counter = 0;
     delay_1 = false;
     delay_2 = true;
     output_high(Strobes);
     set_timer0(254);
     return;
    }
  }
   if(delay_2 == true)
    {
     if(delay_counter >= 9 && get_timer0() == 254)
      {
       delay_counter = 0;
       output_low(Strobes);
       delay_2 = false;
       delay_3 = true;
       set_timer0(254);
       return;
      }
    }
   if(delay_3 == true)
    {
     if(delay_counter >= 9 && get_timer0() == 254)
      {
       delay_counter = 0;
       output_high(Strobes);
       delay_3 = false;
       delay_4 = true;
       set_timer0(254);
       return;
      }
    }
   if(delay_4 == true)
    {
     if(delay_counter >= 61 && get_timer0() == 254)
      {
       delay_counter = 0;
       output_high(Strobes);
       delay_4 = false;
       set_timer0(254);
       return;
      }
    }
}


It is called from within the main loop by:
Code:

 if(LPulseCount < 650) //when strobe switch selected on transmitter
    {
     delay_counter = 0;
     
     output_low(Strobes);
     enable_interrupts(INT_TIMER0);
     enable_interrupts(GLOBAL);

At this point, only delay_1 is true; the rest are false.

It appears as thought the interrupt function is not being called at all.
I thought I now understood timers, but obviously not!!
The LEDs come on and stay on.

Can anyone shed light on my failings please?

Thanks

Brian
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 10, 2020 8:21 pm     Reply with quote

The following program will interrupt at approximately a 150ms interval.
Code:

#include <12F1840.h>
#use delay(internal=16M)

#define LED_PIN  PIN_A2

#int_timer0
void t0_isr(void)
{
static int8 count = 0;

count++;
if(count == 9)
  {
   count = 0;
   output_toggle(LED_PIN);
  }

}

//=========================
void main(void)
{
output_low(LED_PIN);

setup_timer_0(T0_INTERNAL | T0_DIV_256);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);

while(TRUE);   
}
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

PostPosted: Sat Apr 11, 2020 7:05 am     Reply with quote

Hi PCM Programmer
Thank you for your sample code. As expected, it works fine.
In order to get the double flash, followed by a long pause, I have modified the code as follows:
Code:

#INT_TIMER0
void t0_isr(void)
{
  count++;
 //end of a cycle
 if(count >= 75)
  {
   count = 0;
   output_low(Strobes);
   return;
  }
 // toggle state every 160 ms approx
 if(count == 9 || count == 18 || count == 27)
  output_toggle(Strobes);
}


I then notice some irregularities in the LED flashing. Within this PIC, I am also using timer1 and 2 to control a servo, so I don't know if this might be the cause of the problem.

I am turning on/off the strobes by enabling/disabling INT0.

It appears not to be possible to prioritise interrupts, as on PIC18 devices.

Any suggestions please?

Thanks again for your help.

Brian
temtronic



Joined: 01 Jul 2010
Posts: 9093
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Apr 11, 2020 8:59 am     Reply with quote

Couple of comments.....

Could you use just one timer as the 'main heartbeat' ? Within the ISR have a counter for RC servo position and another for strobes ?

There's a SW RTC in the code library that uses this approach for 'time'.
http://www.ccsinfo.com/forum/viewtopic.php?t=26177


A lot depends on what else the PIC has to do.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Apr 11, 2020 10:56 am     Reply with quote

You could do it like temtronic says, or you could do it like I have below.

It's better just to lay everything out. It's easier to understand.
Code:

#include <12F1840.h>
#use delay(internal=16M)

#define LED_PIN  PIN_A2

#define LED_DELAY 9  // 9 * 16.384 = 147.5 ms
// 256/9 = 28.44 so allowable max count = 28

int8 count = 0;

// One interrupt every 16.384 ms. 
#int_timer0
void t0_isr(void)
{
count++;

if(count == LED_DELAY)     output_high(LED_PIN);
if(count == 2 * LED_DELAY) output_low(LED_PIN);
if(count == 3 * LED_DELAY) output_high(LED_PIN);
if(count == 4 * LED_DELAY) output_low(LED_PIN);
if(count == 10 * LED_DELAY) count = 0;
// 10-4 = 6.  (6 +1) * 147.5ms = 1032 ms between LED blink intervals
}

//=========================
void main(void)
{
output_low(LED_PIN);

setup_timer_0(T0_INTERNAL | T0_DIV_256);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);

while(TRUE);   
}
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

PostPosted: Sat Apr 11, 2020 11:04 am     Reply with quote

What a clever idea - I hadn't thought of that.
I have now binned timer0 and controlled the strobes from inside timer1.

It's simple and works brilliantly!

Thank you so much for your suggestion.

Brian
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group