|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 29, 2020 3:02 am |
|
|
colesha wrote: |
How can i best handle it? |
Here is one way to do it. In this program, the isr runs all the time.
It can be re-written so the isr only runs when needed.
In the program below, you turn on the LED by calling the turn_on_led()
function with the desired run time in seconds. The isr counts off the
number of seconds and then turns off the LED.
I think you are using a 16F887. I don't have a working one so I used a
16F877 instead. Test program:
Code: | #include<16F877.h>
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=20M)
#use rs232(baud=9600, UART1, ERRORS)
#define INTS_PER_SECOND 76
#define LED_PIN PIN_B0
int8 led_seconds_timer = 0;
//--------------------------
#INT_TIMER0
void t0_isr(void)
{
static int8 int_count = INTS_PER_SECOND;
int_count--;
if(int_count == 0) // Has 1 second passed ?
{
int_count = INTS_PER_SECOND; // If so, reload counter
if(led_seconds_timer) // Is the LED timer running ?
{
led_seconds_timer--; // If so, decrement it
if(led_seconds_timer == 0) // Is it done ?
{
output_low(LED_PIN); // If so, turn off the LED
}
}
}
}
//--------------------------------
// This function turns on the LED and sets the
// number of seconds that it will stay on.
void turn_on_led(int8 seconds)
{
output_high(LED_PIN); // Turn on the LED
led_seconds_timer = seconds; // Start the LED timer
}
//======================
void main()
{
output_low(LED_PIN); // LED is initially off
setup_timer_0(T0_INTERNAL | T0_DIV_256);
set_timer0(0);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
turn_on_led(5); // Run LED for 5 seconds
while(TRUE);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Wed Jul 29, 2020 4:21 am |
|
|
and the key 'point' here is that the main program can keep running,
scanning the keys etc., and override the LED settings and time settings
if required. Instead of sitting 'in' a wait, the wait is being done by the
counter in the interrupt. |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Wed Jul 29, 2020 1:22 pm |
|
|
Thanks, temtronic, PCM programmer and Ttelmah.
Let me do it as you have suggested.
True am using a 16F877 as PCM programmer has stated.
Will give you feedback on the progress.
Thanks |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Sat Aug 01, 2020 2:16 am |
|
|
PCM programmer wrote: | colesha wrote: |
How can i best handle it? |
Here is one way to do it. In this program, the isr runs all the time.
It can be re-written so the isr only runs when needed.
In the program below, you turn on the LED by calling the turn_on_led()
function with the desired run time in seconds. The isr counts off the
number of seconds and then turns off the LED.
I think you are using a 16F887. I don't have a working one so I used a
16F877 instead. Test program:
Code: | #include<16F877.h>
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=20M)
#use rs232(baud=9600, UART1, ERRORS)
#define INTS_PER_SECOND 76
#define LED_PIN PIN_B0
int8 led_seconds_timer = 0;
//--------------------------
#INT_TIMER0
void t0_isr(void)
{
static int8 int_count = INTS_PER_SECOND;
int_count--;
if(int_count == 0) // Has 1 second passed ?
{
int_count = INTS_PER_SECOND; // If so, reload counter
if(led_seconds_timer) // Is the LED timer running ?
{
led_seconds_timer--; // If so, decrement it
if(led_seconds_timer == 0) // Is it done ?
{
output_low(LED_PIN); // If so, turn off the LED
}
}
}
}
//--------------------------------
// This function turns on the LED and sets the
// number of seconds that it will stay on.
void turn_on_led(int8 seconds)
{
output_high(LED_PIN); // Turn on the LED
led_seconds_timer = seconds; // Start the LED timer
}
//======================
void main()
{
output_low(LED_PIN); // LED is initially off
setup_timer_0(T0_INTERNAL | T0_DIV_256);
set_timer0(0);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
turn_on_led(5); // Run LED for 5 seconds
while(TRUE);
} |
|
Hello,
This code worked perfectly as expected thanks.
Can i use the same interrupt to say like, if i want the menu to be displayed, one has to press and hold the menu key for 3 secs, then the menu will display or i have to set a similar code for specifically the menu key? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 01, 2020 9:09 am |
|
|
colesha wrote: |
Can i use the same interrupt to say like, if i want the menu to be displayed, one has to press and hold the menu key for 3 secs, then the menu will display or i have to set a similar code for specifically the menu key? |
Yes, you can use the same interrupt. It runs continuously. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Sat Aug 01, 2020 10:54 am |
|
|
and (of course), there is nothing to stop you having multiple separate
counters all operated by the one interrupt. |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Tue Aug 11, 2020 4:56 pm |
|
|
Ttelmah wrote: | and (of course), there is nothing to stop you having multiple separate
counters all operated by the one interrupt. |
Hello guys, it seems i just can't figure this out. I have tried it several times but not getting off the hook. I have come up with one but not working as i like it to. If i first press the button on PIN_A3 once then i press and hold the button on PIN_A2 for 5 seconds, the LED will come off. To turn it on, I have to press again button on PIN_A3 first once, always.
I just want only button on A2 to be pressed and held for 5 seconds so that the Led can come off.
Below is what i have
Code: |
#include<16F877.h>
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=20M)
//#use rs232(baud=9600, UART1, ERRORS)
#define INTS_PER_SECOND 76
#define LED_PIN PIN_C2
int8 button_seconds_timer = 0;
//--------------------------
#INT_TIMER0
void t0_isr(void)
{
static int8 int_count = INTS_PER_SECOND;
int_count--;
if(int_count == 0) // Has 1 second passed ?
{
int_count = INTS_PER_SECOND; // If so, reload counter
if(input(PIN_A2)==0) // Is the button timer running ?
{
button_seconds_timer--; // If so, decrement it
if(button_seconds_timer == 0) // Is it done ?
{
output_low(LED_PIN); // If so, turn off the LED
}
}
}
}
//--------------------------------
// This function turns on the LED and sets the
// number of seconds that it will stay on.
void turn_on_led(int8 seconds)
{
output_high(LED_PIN); // Turn on the LED
button_seconds_timer = seconds; // Start the button timer
}
//======================
void main()
{
output_low(LED_PIN); // LED is initially off
setup_timer_0(T0_INTERNAL | T0_DIV_256);
set_timer0(0);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(input(PIN_A3)==0) // Menu key
turn_on_led(5); // Wait 5 seconds to turn on LED
output_high(PIN_C0);
delay_ms(100);
output_low(PIN_C0);
delay_ms(100);
}
}
|
Some assistance please |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Wed Aug 12, 2020 6:21 am |
|
|
If button_seconds_timer is at zero, then it will take 25.6 seconds for the decrement to get it back to zero again. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 12, 2020 9:27 pm |
|
|
Quote: | If i first press the button on PIN_A3 once then i press and hold the button on PIN_A2 for 5 seconds, the LED will come off. To turn it on, I have to press again button on PIN_A3 first once, always.
I just want only button on A2 to be pressed and held for 5 seconds so that the Led can come off. |
Can you re-state this more clearly ? I can't figure out exactly what you want. |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Thu Aug 13, 2020 4:10 am |
|
|
PCM programmer wrote: | Quote: | If i first press the button on PIN_A3 once then i press and hold the button on PIN_A2 for 5 seconds, the LED will come off. To turn it on, I have to press again button on PIN_A3 first once, always.
I just want only button on A2 to be pressed and held for 5 seconds so that the Led can come off. |
Can you re-state this more clearly ? I can't figure out exactly what you want. |
I have a push button connected on pin A2. I want to use this push button to turn off an led, but only if i press and hold it for say 5 seconds. Then the led shall be turned off (i intend to use this code to enter a menu screen only if the user presses and holds the menu button for 5 seconds).
Now back to the code i have posted.
I included this in the ISR so that the counter can start when this button is pressed.
Code: | if(input(PIN_A2)==0) // Is the button timer running ?
{
button_seconds_timer--; // If so, decrement it
|
However in my main, it won't work if i only call this function:
But if i write it like this and add another push button, it will work only if i first press the newly added button once. (i.e press button 2 once, then press and hold button 1 for 5 seconds, thus the led will turn off. Again press button 2 once the led will come on and then press button 1 for 5 seconds, led will go off, always thats the routine).
Code: |
if(input(PIN_A3)==0) // Menu key
turn_on_led(5); // Wait 5 seconds to turn on LED |
I want to use only button 1 to achieve this, just like you press and hold down a computer power button for some seconds if you what to force it to shut down without following the normal shutdown process.
Thanks again. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 13, 2020 1:06 pm |
|
|
You still didn't completely state your goal, so I'll do it:
1. If you push button A3 momentarily, the LED will go on.
2. If you push and hold button A2 for 5 seconds continuously, then the LED
will go off.
If that's not it, then say so. |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Thu Aug 13, 2020 2:06 pm |
|
|
PCM programmer wrote: | You still didn't completely state your goal, so I'll do it:
1. If you push button A3 momentarily, the LED will go on.
2. If you push and hold button A2 for 5 seconds continuously, then the LED
will go off.
If that's not it, then say so. |
Yes, that is what the code i currently posted do exactly, but it is not my final goal.
Let me state my final goal below:
The code shall be used to enter the menu screen on LCD (am first testing it as an LED in this case).
Quote: | 2. If you push and hold button A2 for 5 seconds continuously, then the LED
will go off. |
This is the only action i want to execute, i don't need button A3
Overall goal to be put in the final project is:
1. If you push and hold the menu button (button A2) for 5 seconds continuously, the menu or settings menu shall be displayed on the LCD so that you can input the desired system settings, then exit the menu when your done.
2. If you push the menu button (button A2) momentarily, the menu/settings screen shall not be displayed on the LCD, only the LCD back-light shall be turned on for 30s so that you can clearly read what is on the LCD (maybe during night time), then the back-light will be turned off.
So i don't need button A3.
Hope it is quite better now. |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Wed Dec 09, 2020 9:40 am |
|
|
PCM programmer wrote: | colesha wrote: |
How can i best handle it? |
Here is one way to do it. In this program, the isr runs all the time.
It can be re-written so the isr only runs when needed.
In the program below, you turn on the LED by calling the turn_on_led()
function with the desired run time in seconds. The isr counts off the
number of seconds and then turns off the LED.
I think you are using a 16F887. I don't have a working one so I used a
16F877 instead. Test program:
Code: | #include<16F877.h>
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=20M)
#use rs232(baud=9600, UART1, ERRORS)
#define INTS_PER_SECOND 76
#define LED_PIN PIN_B0
int8 led_seconds_timer = 0;
//--------------------------
#INT_TIMER0
void t0_isr(void)
{
static int8 int_count = INTS_PER_SECOND;
int_count--;
if(int_count == 0) // Has 1 second passed ?
{
int_count = INTS_PER_SECOND; // If so, reload counter
if(led_seconds_timer) // Is the LED timer running ?
{
led_seconds_timer--; // If so, decrement it
if(led_seconds_timer == 0) // Is it done ?
{
output_low(LED_PIN); // If so, turn off the LED
}
}
}
}
//--------------------------------
// This function turns on the LED and sets the
// number of seconds that it will stay on.
void turn_on_led(int8 seconds)
{
output_high(LED_PIN); // Turn on the LED
led_seconds_timer = seconds; // Start the LED timer
}
//======================
void main()
{
output_low(LED_PIN); // LED is initially off
setup_timer_0(T0_INTERNAL | T0_DIV_256);
set_timer0(0);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
turn_on_led(5); // Run LED for 5 seconds
while(TRUE);
} |
|
Hello PCM Programmer,
How can i get this code work with 18f4550?
Its not compiling
thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 09, 2020 10:00 am |
|
|
It compiles OK for me. I changed the #include line for the PIC to use
18F4550.h and got this result:
Quote: |
Compiling C:\Program Files\...\PCH_Test on 09-Dec-20 at 08:00
Memory usage: ROM=1% RAM=1% - 1%
0 Errors, 0 Warnings.
Build Successful.
Loaded C:\Program Files\...\PCH_Test.cof.
BUILD SUCCEEDED: Wed Dec 09 08:00:31 2020
|
|
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Wed Dec 09, 2020 10:20 am |
|
|
PCM programmer wrote: | It compiles OK for me. I changed the #include line for the PIC to use
18F4550.h and got this result:
Quote: |
Compiling C:\Program Files\...\PCH_Test on 09-Dec-20 at 08:00
Memory usage: ROM=1% RAM=1% - 1%
0 Errors, 0 Warnings.
Build Successful.
Loaded C:\Program Files\...\PCH_Test.cof.
BUILD SUCCEEDED: Wed Dec 09 08:00:31 2020
|
|
It compiled, thanks.
However, the timer doesn't seem to be working as expected. Instead of the led comes on for 5 seconds, its on permanently.
Can you assist with it, please? |
|
|
|
|
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
|