Simultaneous control of momentary LEDs

Find out how to setup your programmer's software and how to solve many common problems.

Moderator: phalanx

Post Reply
TokTok
Posts: 17
Joined: Tue May 06, 2014 9:17 am

Simultaneous control of momentary LEDs

Post by TokTok » Fri May 16, 2014 5:54 am

Hi all,

Apologies if this sound trivial but currently I’m stuck in terms of figuring out the logic to complete what I suspect is a fairly easy task.

I’m currently turning on my LEDs for a certain amount of time using the output_toggle() method as seen in my code below at the end of my post but I’d like to move on to turning on another relay when I’ve got the first LED currently engaged. So essentially simultaneous operation of the LEDs is what I’m after.

Code: Select all

#include<18F2580.h> 

#include <stdlib.h> 
#include <string.h> 

#fuses XT,PUT,NOBROWNOUT,NOWDT,NOPROTECT,NOLVP 
  
#use delay(clock=4000000) 
#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7, STREAM=HWAREUART, ERRORS) 
#use rs232(baud=19200, parity=N, xmit=PIN_A4, Stream=PCSOFTWAREUART) 

#define REL_1 PIN_A1 
#define REL_2 PIN_A2 
#define REL_3 PIN_B0 
#define REL_4 PIN_B1 
#define REL_5 PIN_A5 

// 
void main() { 
   output_low(REL_1); 
   output_low(REL_2); 
   output_low(REL_3); 
   output_low(REL_4);    
   output_low(REL_5); 

while(1) { 
   int num, i; 

   for(i=0; i<5; i++) { 

       num = i; 
    
      if(num == 1) { 
         output_toggle(REL_1); 
         delay_ms(10000); 
         output_toggle(REL_1); 
      } else if(num == 2) { 
         output_toggle(REL_2); 
      } else if(num == 3) { 
         output_toggle(REL_3); 
         delay_ms(5000); 
         output_toggle(REL_3); 
      } else if(num == 4) { 
         output_toggle(REL_4); 
      }  else if(num == 5) { 
         output_toggle(REL_5); 
         delay_ms(2500); 
         output_toggle(REL_5); 
      } 
   } 
}
How does one go about this in an efficient way? As I come from a java background is there any threading within the CCS library?

My understanding is you could use timers which I tried below but no success:

Code: Select all

#include<18F2580.h>

#include <stdlib.h>
#include <string.h>

#fuses XT,PUT,NOBROWNOUT,NOWDT,NOPROTECT,NOLVP
 
#use delay(clock=4000000) 
#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7, STREAM=HWAREUART, ERRORS) 

#define LED_ONE PIN_B2 
#define LED_TWO PIN_B3

int push_btn_flag;
int millisecs, outs;

#int_timer0
void toggle_LED() {
   if(push_btn_flag == 1) {

	    // At this point in time in the interrupt service routineI would like to count down or up for 5 seconds in here so as to turn off LED_ONE after 5 seconds
	    output_toggle(LED_ONE);
	
		if(millisecs++ == 100) {
	    	output_toggle(LED_ONE);
			millisecs = 0;
		}

        push_btn_flag = 0;
   } else if(push_btn_flag == 2) {

      // At this point in time in the interrupt service routine I would like to count down or up for 10 seconds in here so as to turn off LED_ONE after 10 seconds
      output_toggle(LED_TWO);

		if(millisecs++ == 100) {
	    	output_toggle(LED_TWO);
			millisecs = 0;
		}

        push_btn_flag = 0;
   }
}

void main() {

   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_16);

   enable_interrupts(int_timer0); 
   enable_interrupts(global); 

   output_low(LED_ONE);
   output_low(LED_TWO);

   // Here I essentially want to enable the user to play around with operating the LEDs SIMULTANEOUSLY
   // So say user presses PUSH_BTN_ONE essentially I want it that the push_btn_flag changes and
   // this causes the timer interrupt to start counting down or up based on a specified time i.e. 5 secs

   // Now in the interrupt service routine whilst the counting related to LED one is ongoing if the user were
   // to press PUSH_BTN_TWO then I would like in the interrupt service rountine the counting for LED_TWO 
   // to be started as the push_btn_flag would have been set to two.
   
   while(1) {
      if (input(PIN_B4) == 0){
         delay_ms(10);
         push_btn_flag = 1;
      } else if (input(PIN_A3) == 0){ 
         delay_ms(10);
         push_btn_flag = 2;
      }
   }
}
Edit:
Essentially below is how I would like to use a timer interrupt to provide me with my desired outcome:

Step 1 - In the main() function enable the global interrupts and the specific timer interrupt.

Step 2 - In the interrupt service routine function start watching out for changes i.e. on the push_btn_flag.

The value/state of the push_btn_flag will be changed in the main function when the user presses one of two momentary push button to operate the LEDs for a desired period of time.

So in the interrupt service routine if the push_btn_flag has been set to 1 then LED_ONE is turned on for a specific period of time. Now this specific period of time is what I need the timer ISR to count down and is what I'm stuck on.

The same applies with the turning on of a different LED when the push_btn_flag has been set to 2.

Step 3 - In the main() function watch out for the pressing of the push buttons as explained in step 2 which when pressed changes the push_btn_flag which the timer interrupt service routine is monitoring for change.

Note: My development environment is MPLAB IDE version 8.91.00.00 with my compiler being the CCS C PCWHD compiler version 4.1114.

Any help is appreciated.

TokTok.

User avatar
phalanx
Non-SFE Guru
Posts: 1992
Joined: Sun Nov 30, 2003 8:57 am
Location: Candia, NH

Re: Simultaneous control of momentary LEDs

Post by phalanx » Tue May 20, 2014 5:30 am

Here is how I would approach this. What you need to do is set up a timer that will periodically overflow at a fixed rate (100Hz would be a good place to start). Timer 2 in your PIC has a period register which can be set to make your timer generate interrupts at a periodic rate. Every time your timer generates an interrupt, your service routine will increment a counter and return to your main loop. When a button push is detected in your main loop, you look at the current counter value, add a number to it, and store it in a different location. The number you add to it will be how long you want the LED to stay on: 10 seconds would be 1000 counts at 100Hz. After turning on the LED, your main loop continuously compares the current counter value with the one you just calculated. Once the current timer is greater than or equal to the calculated value, you turn off the LED. You can implement dozens of buttons and LEDs in this manner and they can all use the same time base.

Needless to say, you will have to take into account the interrupt rate and the size of your counter storage variables to suit the resolution and duration of your timing events.

-Bill

Post Reply