Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] Simultaneous control of momentary LEDs

Status
Not open for further replies.

TokTok12

Junior Member level 2
Joined
May 6, 2014
Messages
20
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
281
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:
#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:
#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.
 
Last edited:

Okay so microprocessor are single core processors so threading is possible but concurrent execution is not. With that being said they are still very fast and can do what you want.

What you want to do is something like this:
#define number_of_ticks 500
int button1_flag, button2_flag;

void timer1_interrupt_routine() {
if (led == ON) {
if (button1_flag == 0) {
led1 = OFF;
}
else {
--button1_flag;
}

if (led2 == ON) {
if (button2_flag == 0) {
led2 = OFF;
}
else {
--button2_flag;
}
}

void main (void) {
setup_timer1();
enable_global_interrupts;

while(1) {
if (button1 == pressed) {
button1_flag = number_of_ticks;
led1 = ON;
}

if (button2 == pressed) {
button2_flag = number_of_ticks;
led2 = ON;
}
}
}

To set the led duration change the number of ticks and the timer1 overflow rate. Note the duration may me more or less than 1 tick based on the status of timer1 when the led was activated. Which is still pretty accurate.

I hope this helps.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top