Author Topic: Long time loops in PIC Micro  (Read 9483 times)

0 Members and 1 Guest are viewing this topic.

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: Long time loops in PIC Micro
« Reply #25 on: October 19, 2016, 05:13:32 pm »
Don't overthink. Keep it simple until simple no longer works.

main(){
   //setup for Output_A freq1
   //wait 5 minutes
   uint32_t ms = 1000*60*5;
   for( ; ms; ms-- ){
     //check for input
     if( check_input_A ) break;
     __delay_ms(1);
   }
   //setup for Output A freq2
   for( ;; );
}


I do like my for loops self contained when possible :)
main(){
   //setup for Output_A freq1
   //wait 5 minutes
   for( uint32_t ms = 1000*60*5;
       ms && !Input_A;
       __delay_ms(1), ms-- );
   //setup for Output A freq2
   for( ;; );
}
« Last Edit: October 19, 2016, 05:26:44 pm by cv007 »
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Long time loops in PIC Micro
« Reply #26 on: October 19, 2016, 06:31:15 pm »
Thanks again all.

All great suggestions thankfully I'm left with the PWM pin as the unit is already controlled on this.

Baby-steps I think, let me get to grips with simple PWM setup and I'll worry about the rest later. I'm grasping the data sheet slowly and once I've figured out the PWM stuff I'll start on bolting it together.

I got 'v1' with the two speeds in delay_us, I thought my next brainwave would be relatively easy but alas I have much to get to grips with.

Thanks for helping dullard here. I shall go and have a crack at it once I've finished this pint   ^-^

Cheers again,
Ed
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Long time loops in PIC Micro
« Reply #27 on: October 19, 2016, 10:22:09 pm »
Quote
Don't overthink.

I would take a similar approach as well:

Code: [Select]
  do {OutputA_at_Initial_Freq();} while (elapsed_time<5 min);
  while (1) {
    if(!interrupted_by_A()) OutputA_at_another_Freq();
    else OutputA_at_different_Freq();
  }

depending on your hardware implementation approach, each of the modules could be different but gist is the same.

Whether you need fancy hardware pwm will be dependent on your frequency requirements.
================================
https://dannyelectronics.wordpress.com/
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12853
Re: Long time loops in PIC Micro
« Reply #28 on: October 19, 2016, 10:33:53 pm »
I require frequencies of aprox 1kHz, 2kHz and 7kHz (none of which are desired to be very accurate) so as I understand that bit is covered.
So he could bit-bang the output, but doing so while handling software timekeeping would be a PITA.

If short of time once the PWM is up and running, there's no problem with simply using delay_ms() in a superloop for the 5 minute timing, polling the input in the same loop. 

Personally, I'd use Timer 0 in 8 bit mode to implement a sandwich delay so I don't have to worry about the loop overhead, but I'm fussy that way as the tolerance on the 5 minutes certainly doesn't demand it.

The more advanced techniques aren't actually needed for the simple 1 input 1 output case.  They become valuable when the number of inputs and outputs goes up and you need to run independent processes sharing the hardware resources.
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Long time loops in PIC Micro
« Reply #29 on: October 20, 2016, 07:12:13 am »
Quote
Don't overthink.

I would take a similar approach as well:

Code: [Select]
  do {OutputA_at_Initial_Freq();} while (elapsed_time<5 min);
  while (1) {
    if(!interrupted_by_A()) OutputA_at_another_Freq();
    else OutputA_at_different_Freq();
  }

depending on your hardware implementation approach, each of the modules could be different but gist is the same.

Whether you need fancy hardware pwm will be dependent on your frequency requirements.
This is precisely what I want,  as I've stressed a few times it doesn't even need to be accurate in terms of timing,  frequencies can drift 10% without issue and the timing can go a full minute either side.

Basically it's just to trip a motor/pump to pump a little bit quicker to purge the air when it's turned on,  the pump isn't a controlled dose in a critical application.

The 7kHz frequency is just controlled on a button to run the pump even quicker whilst pressed when changing the pumped solution to prime it through.

Thank you all for your input,  I'm quite touched so many have taken time to reply with such in-depth and insightful posts, I certainly do have a lot to learn!

Cheers,
Ed.
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Long time loops in PIC Micro
« Reply #30 on: October 22, 2016, 08:26:17 pm »
Sorry it's Ed again.

Right I've had a play with setting up hardware PWM and I think I've got to grips with it, however I think I've dropped a clacker here.

Can RA0/CMP0 be set to deliver a PWM output?  I was convinced I had an PWM pin to play with (long and short, although my 'scope output looks PWM, it's not a PWM pin.)

Can the Comparitor 0 be used to drive a PWM output or am I talking rubbish here?

Cheers,  as always,
Ed.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12853
Re: Long time loops in PIC Micro
« Reply #31 on: October 22, 2016, 09:20:34 pm »
No.  Your proverbial pooch is screwed and you will have to resort to toggling that pin in software.   The PIC18F1330 comparator module is input only, so even if you added a link to tie a PWM output to a comparator input, the resulting toggling comparator output is only a bit in a SFR, not a signal on a pin.

However all is not lost.  If you write an ISR that simply toggles the pin:
Code: [Select]
void interrupt high_priority HighISR(void){
   LATA^=0x01; //toggle RA0
   PIR3bits.PTIF=0; //Ctear PWM interrupt
}
you can get it to trigger once every PWM cycle giving you half the PWM frequency on RA0.
You don't actually need to enable any of the PWM pins to do this - just set up the timebase and its interrupt:
Code: [Select]
//Set up pin
ADCON1=7; //No analog pins for ADC
CMCON1=7; //No analog pins for Comparator
LATAbits.LATA0=0; //RA0 is output

//Set up interrupt
PTCON0bits.PTOPS=0; //No postscaler
RCONbits.IPEN=1; //Enable interrupt priorities
IPR3bits.PTIP=1; //Assign PWM interrupt to high priority vector
PIE3bits.PTIE=1; //Enable PWM interrupt
INTCONbits.GIEH=1; //Master interrupt enable
That will leave the low priority vector free for your timer ISR for implimenting a tick counter.  However instead of using ei() or di() you must now set/clear INTCONbits.GIEL to enable/disable the low priority interrupts without affecting the squarewave from RA0 being generated by the high priority ISR.

If you need to stop the pin toggling, simply disable PIE3bits.PTIE, then set LATAbits.LATA0 to the desired pin level.  Re-enable  PIE3bits.PTIE  to resume toggling.
« Last Edit: October 22, 2016, 09:54:27 pm by Ian.M »
 
The following users thanked this post: ed_reardon

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12853
Re: Long time loops in PIC Micro
« Reply #32 on: October 22, 2016, 09:53:48 pm »
bump: more code for Ed!

I'd like to know what the original designer was smoking when they selected the PIC18F1330 - a chip specialised for motor control PWM - then failed to hook up the circuit's output to any PWM capable pin!  |O Whatever it was, it must have been the good stuff . . .  :-DD
« Last Edit: October 22, 2016, 09:57:44 pm by Ian.M »
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Long time loops in PIC Micro
« Reply #33 on: October 22, 2016, 11:23:06 pm »
Quote
Can RA0/CMP0 be set to deliver a PWM output? 

For things like that you should do it before finalizing the hardware design - unless the mcu supports pin remapping.

Quote
Can the Comparitor 0 be used to drive a PWM output or am I talking rubbish here?

Yes and no. If the mcu supports interrupt on compare match, and you are not looking for really fast pwm frequencies, it can be done: basically, you set up two compares, and at the first compare, you set the pin and at the 2nd compare, you reset the pin.
================================
https://dannyelectronics.wordpress.com/
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12853
Re: Long time loops in PIC Micro
« Reply #34 on: October 23, 2016, 12:19:51 am »
Quote
Can the Comparitor 0 be used to drive a PWM output or am I talking rubbish here?

Yes and no. If the mcu supports interrupt on compare match, and you are not looking for really fast pwm frequencies, it can be done: basically, you set up two compares, and at the first compare, you set the pin and at the 2nd compare, you reset the pin.
It doesn't.   Microchip PWM modules on the older 8 bit chips only permit interrupting on the period timer reload, not on the duty cycle compare*.   Its possible to use an (E)CCP module to interrupt on compare match when it isn't configured for PWM, but this chip doesn't have any ECCP or CCP modules, only PWM modules.

Hence my recommendation to use the period timer reload interrupt to get half the PWM frequency out.

* You can fake it on PPS capable chips, by internally routing the PWM output to an external interrupt input.
« Last Edit: October 23, 2016, 12:23:38 am by Ian.M »
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: Long time loops in PIC Micro
« Reply #35 on: October 23, 2016, 03:01:31 am »
Can RA0/CMP0 be set to deliver a PWM output?  I was convinced I had an PWM pin to play with
The 18F1330 has 6 pins that can output PWM. Why do you have to use RA0?

 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12853
Re: Long time loops in PIC Micro
« Reply #36 on: October 23, 2016, 04:07:50 am »
Can RA0/CMP0 be set to deliver a PWM output?  I was convinced I had an PWM pin to play with
The 18F1330 has 6 pins that can output PWM. Why do you have to use RA0?

This is a modification to an existing system, basically it's to save me a bit of faff at work!
So he's stuck with the original chip and pinout unless he wants to rework every unit.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Long time loops in PIC Micro
« Reply #37 on: October 23, 2016, 01:38:27 pm »
I took a look at the 18f1330 datasheet and it doesn't have a compare module.

But it does have an interrupt-on-period functionality. So  you can use the pwm module as a timer: load the period register alternately with the duty cycle count and period - duty cycle count.

Essentially what this module does:

Code: [Select]
//my pwm handler
void mypwm(void) {

if (_pwmdc++ & 0x01) { //test for lsb
//lsb = 1 -> reset
PTPER = PWM_PR - PWM_DC; //reset period
PWM_RESET(); //reset pin
} else {
PTPER = PWM_DC; //load dc
PWM_SET(); //set pin
}
}

Now set up the timer to run periodically:

Code: [Select]
ptmr_init(PWM_PS16x | PWM_PEIODIC); //periodic + prescaler
ptmr_setpr(PWM_DC); //initial period is dc
ptmr_act(mypwm); //install user handler
ei(); //enable global interrupts

The code above sets up the pwm module to run in periodic + 16:1 prescaler mode. load the pwm period register with the duty cycle count and install the mypwm routine as the isr handler once the period is reached.

The output waveform, for PWM_PR = 100 and PWM_DC = PWM_PR / 3:
================================
https://dannyelectronics.wordpress.com/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Long time loops in PIC Micro
« Reply #38 on: October 23, 2016, 01:40:11 pm »
the downside with this approach is that since it is done via the isr, you cannot generate fast pwm. 20 - 30 ticks to be your minimum resolution.

BTW, it can be used to generate complimentary output too - not shown here.
================================
https://dannyelectronics.wordpress.com/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Long time loops in PIC Micro
« Reply #39 on: October 23, 2016, 01:47:40 pm »
here is the same code producing complimentary output: positive polarity on RA0 and negative polarity and RA1/RA2.
================================
https://dannyelectronics.wordpress.com/
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12853
Re: Long time loops in PIC Micro
« Reply #40 on: October 23, 2016, 02:10:33 pm »
@Dannyf,
What compiler or library is that for? 
The O.P.'s using Microchip XC8 (or a very late version of its predecessor HiTech C for PIC18) and the calls you are using don't correspond to anything in their standard libraries or the C18 compatibility PLIB. Microchip Code Configurator doesn't support the PIC18F1330 so it cant be that
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Long time loops in PIC Micro
« Reply #41 on: October 23, 2016, 04:38:30 pm »
since the pwm module here is used as a timer, the same can be done easily via a regular timer, with or without compare math.

Here is an example of doing it on the good old TIMER0:

Code: [Select]
ptmr0_init(PWM_PS16x | PWM_PEIODIC); //periodic + prescaler
ptmr0_setpr(PWM_DC); //initial period is dc
ptmr0_act(mypwm); //install user handler
ei(); //enable global interrupts

identical output.

As the whole thing is implemented via the interrupt, the timing is repeatable and the while loop is empty. Once set, the operation is fully transparent to the code and the programmer.
================================
https://dannyelectronics.wordpress.com/
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Long time loops in PIC Micro
« Reply #42 on: October 23, 2016, 06:19:54 pm »
Cheers all,

As said I'm 'upgrading' an existing system with a good few thousand units to look after customer won't allow a new board per unit to make my day a bit smoother!

I'll look at this in the week but thank you all so much for your input.

I guess there is no such thing as an adaptor socket to make a physical pin reconfiguration?

I have motor pulse on RA0, direction on RA1 and speed control on RB0.
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Long time loops in PIC Micro
« Reply #43 on: October 23, 2016, 06:32:48 pm »
If RA0 was set to high-impedance is there any penalty for making a bodge wire on the PIC socket underside from a PWM pin to RA0.

I know it's a bit 'how ya doin' as Dave would say but it's plausable from my cost/time angle?

 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12853
Re: Long time loops in PIC Micro
« Reply #44 on: October 23, 2016, 06:57:25 pm »
As said I'm 'upgrading' an existing system with a good few thousand units to look after customer won't allow a new board per unit to make my day a bit smoother!
I suspected that was the case.
Quote
I guess there is no such thing as an adaptor socket to make a physical pin reconfiguration?

I have motor pulse on RA0, direction on RA1 and speed control on RB0.
If you were going down that road, you'd use a QFN package part on a DIL footprint adapter board.  However the board would be entirely custom. 
If RA0 was set to high-impedance is there any penalty for making a bodge wire on the PIC socket underside from a PWM pin to RA0.

I know it's a bit 'how ya doin' as Dave would say but it's plausable from my cost/time angle?
A bodge wire would let you re-route the real PWM but would be extra work per unit.  Assuming RB4 isn't in use, running it diagonally across the socket would be the simplest option. (or if access to the underside of the board is poor, directly across the top of the chip soldered to the base of its pins).  However there is absolutely no point in changing hardware* for >2K units if it can be done in software, and so far it looks like it can.  Things that could change that would be if the PIC has to simultaneously perform other time-critical functions you haven't mentioned.   

I would personally be entirely satisfied with the toggle arbitrary pin in a high priority PTI  ISR approach if all you need is a 50% duty cycle variable frequency squarewave.  Once set up its nearly as 'fire & forget' as using a PWM pin. The pin output will be jitter free and as accurate as the PIC's clock source and 16 bit period timer allow, and its effect on timekeeping will be negligible amount of extra jitter on the timer interrupt (maybe 20 to 30 Tcy additional latency).

* 2000 x 5 minutes per unit is a month of normal working hours. The software solution should only take a few hours extra to develop ==> a hardware mod just to relocate one PWM doesn't pay for >50 units.
« Last Edit: October 23, 2016, 10:06:25 pm by Ian.M »
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Long time loops in PIC Micro
« Reply #45 on: October 23, 2016, 07:37:45 pm »
That's most helpful, cheers Ian M.

The board (for the PIC element) consists of a PIC looking for the pins I've mentioned above, that's the sum total of its connections - fortunately it's through-hole and easy to remove (90s?)

At the moment it bit-bangs a controller with two speeds either the looped "slow" or when the user presses a button it runs faster until they release.

That's the whole shebang!

It drives an off-the-shelf Stepper driver.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Long time loops in PIC Micro
« Reply #46 on: October 23, 2016, 09:59:30 pm »
with moderate speeds, it is easier to just use an interrupt to flip RA0. By loading different offsets, you can control the frequency of the pulse train.
================================
https://dannyelectronics.wordpress.com/
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf