View previous topic :: View next topic |
Author |
Message |
global
Joined: 01 Feb 2005 Posts: 21 Location: Paris
|
sensor interrupt |
Posted: Tue Apr 26, 2005 4:45 am |
|
|
Hello,
I have sensors on pins of my PIC 18LF458.
For example if a light sensor detects light, it returns 1, then i'll have to send an alarm.
Most of the time it should be at state 0, if everything is ok.
Could the group help me to do that ?
I don't know if had better to use interrupts or to put something like :
Code: |
if(light_sensor_pin) send_alert();
|
This should be done as often as possible. Is it better to consider that when the sensor returns 1 it is an interrupt ?
Many thanks. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Tue Apr 26, 2005 6:08 am |
|
|
We need more of a description of the "sensors" to which you are referring.
To get inputs you need to use the input() function (see page 110 of the manual)
I assume this is a school project of some kind?
If you are just detecting a light level from a photocell you don't need to use interrupts because there should be no fast response time requirements. Regular polling in a background routine should do the trick.
1. What version of compiler are you using?
2. What pins are you using?
3. How is the "sensor" coinnected?
4. What are you going to do when you detect the light?
We are not here to write your code for you but will make some suggestions about how you might proceed once we know more about what you are trying to do. |
|
|
global
Joined: 01 Feb 2005 Posts: 21 Location: Paris
|
|
Posted: Tue Apr 26, 2005 6:19 am |
|
|
Quote: |
1. What version of compiler are you using?
2. What pins are you using?
3. How is the "sensor" coinnected?
4. What are you going to do when you detect the light?
|
1. Version 3.15, i have the latest one but i am still using this one for the moment.
2. Just interrupts pins on the PIC
3. I am supposed to detect levels 0 or 1 whatever the sensor is if it works this way
4. I said i'll have to send an alarm that's done not simply with a buzzer but it is more complicated you don't need to know that.
I thought i was clear :
do i better use interrupt or is there something more efficient to "read" this pin as often as possible.
I had a great answer from Gizz, thank you !
Quote: |
You should
1) read the data sheet of the PIC you are using to find out which pins use interrupts to detect level change
2) Work out how often you can poll the pin instead
3) Work out how long your '1' state will remain at the input pin - if it is a button / microswitch it might be 100ms, or less.... if it is from a ring indicator on a modem it may be 1 second....
4) Choose a method to use, interrupt or poll.
If you use interrupts you must (if I remember correctly) read the port to clear the interrupt. You should be aware that the CCS interrupt latency is in the order of several milliseconds, so don't expect to time things or do lots of stuff quickly with interrupts without going to assembler.
|
I just don't know if interrupts is the best way to o this ...
Could you show me what is "Regular polling in a background routine"
I think this should be ok ...
There is for example a light sensor in a box.
If we open this box (what we are not supposed to do), the sensor should be on 1 so i should send an alarm to say that the box is opened !
If we are authorized to do open it, we can open it but the sensor whatever it is 1 because there is light won't send alarm.
So most of the time the box is closed so sensor is 0.
That is pretty much what i want to do. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Tue Apr 26, 2005 6:59 am |
|
|
OK.
1. What sensor are you using? Is is a photocell or photodiode for example?
2. If it is a photcell what is the part number or resistance value range?
This is a simple light sensor and it will not be changing that rapidly so using interrupts is major overkill. Polling in a simple loop will be more than plenty.
If you use Port B which has Schmidt Trigger input buffers you should be able to use a couple of resistors for biasing and connect the sensor to the Pin. In that case the input() function should work just fine to sense high or low (light or dark). Technically you can sense it in either direction without problems(i.e. low input is a 1 or high input is a 1). All you have to do there is invert the input value.
Now, if we know more about the sensor we can suggest how to hook it up and go from there... |
|
|
global
Joined: 01 Feb 2005 Posts: 21 Location: Paris
|
|
Posted: Tue Apr 26, 2005 7:57 am |
|
|
Ok, then.
I found my way for the moment i may only use input() function.
Thanks for your help.
I may ask ou some more questions when i'll go through changes in my program because the hardware and protocol may change as well =)
Best regards. |
|
|
global
Joined: 01 Feb 2005 Posts: 21 Location: Paris
|
|
Posted: Wed Apr 27, 2005 7:36 am |
|
|
Hello,
i found a way to read the state of my sensor, if it is 1 it switches on LED_1, if not it switches off LED_1.
I want to switch on LED_1 only if the sensor is 1 during 3 seconds.
I did this but no result, this simple program alone is not working, it seems to be stopped by the while function :
Code: |
if (!input(SENSOR_PIN))
{
//while (!input(SENSOR_PIN));
//delay_ms(3000);
output_high(LED_1);
} else output_low(LED_1);
|
If the group could help me.
Last edited by global on Wed Apr 27, 2005 8:19 am; edited 2 times in total |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Apr 27, 2005 7:54 am |
|
|
First, you are going to have to use a timer. I would set up timer2 to give me an interrupt every so often. He is a rough example of how you could do it.
Code: |
int timeout;
#int_timer2
void timer2(void)
{
if (timeout)
timeout--;
}
void main(void)
{
// Init timer2 and anything else
while(1)
{
if (!input(SENSOR_PIN))
{
if (!timeout)
output_high(LED_1);
}
else
{
timeout = THREE_SECONDS;
output_low(LED_1);
}
}
} |
|
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Wed Apr 27, 2005 3:31 pm |
|
|
Removed
Last edited by dyeatman on Thu Apr 28, 2005 5:39 am; edited 1 time in total |
|
|
global
Joined: 01 Feb 2005 Posts: 21 Location: Paris
|
|
Posted: Thu Apr 28, 2005 3:02 am |
|
|
Hello,
thanks for your help, but i think that dyeatman didn't read my post.
I said everything is ok for the led it is doing what i want to do.
The only thing left is that i have to check if the sensor is one during 3 seconds for example i'll say the sensor is on 1. If it is less i won't consider the signal.
I know that the sensor is responding.
I just need to wait for the input during 3 seconds to be sure that the sensor is effectively on 1, and that is not just a ba contact.
The LED is just connected to a pin of the PIC and the sensor as well.
Is there any solution more simple that timers, or could someone modify my while thing to be ok ?
Here is my code for 3 sensors waiting for 3 s to switch on the led :
Code: |
if (!input(SENSOR_1))
{
while (!input(SENSOR_1));
delay_ms(3000);
output_high(LED_1);
} else output_low(LED_1);
if (!input(SENSOR_2))
{
while (!input(SENSOR_2));
delay_ms(3000);
output_high(LED_2);
} else output_low(LED_2);
if (!input(SENSOR_3))
{
while (!input(SENSOR_3));
delay_ms(3000);
output_high(LED_3);
} else output_low(LED_3);
|
|
|
|
global
Joined: 01 Feb 2005 Posts: 21 Location: Paris
|
|
Posted: Fri Apr 29, 2005 2:26 am |
|
|
Any idea ?
If you have any suggestion, you are welcome ...
Thanks ! |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Apr 29, 2005 6:43 am |
|
|
Quote: | Is there any solution more simple that timers, or could someone modify my while thing to be ok ? |
The timer based solution given by Mark is very flexible because it allows you to create a program capable of continuing it's normal tasks and just now and then check for the timeout to have occurred. This is what a previous poster meant with Background Polling.
Modifying your original program so it will not use timers will either block your program for the full 3 seconds or create a design which is terrible when compared to the timer based solution.
Why don't you want to use the timer based method? Is it because you already used all three timers? From a previous thread I know you have a 100ms timer as well, just add Marks code to your existing interrupt routine. So what is the problem?
I use the same timer based method given by Mark for about 20 timeout counters in my application, also running on a PIC18LF458. All my 20 counters are running on the same single 100-ms timer interrupt.
Here again Mark's example but now for multiple timeout counters:
Code: | #define INTS_PER_SECOND 10 // A 100ms. timer generates 10 interrupts per second
#define THREE_SECONDS (3 * INTS_PER_SECOND)
#define TIMED_OUT 0
int8 Sensor1Timeout;
int8 Sensor2Timeout;
int8 Sensor3Timeout;
#int_timer2
void timer2(void)
{
// The timeout counters below are counting down to zero i.s.o. counting upwards because the processor
// can check very efficiently (1 instruction) for the end value being reached.
if (Sensor1Timeout != TIMED_OUT)
Sensor1Timeout--;
if (Sensor2Timeout != TIMED_OUT)
Sensor2Timeout--;
if (Sensor3Timeout != TIMED_OUT)
Sensor3Timeout--;
// You can add other code here if you want to, for example for many more timers...
}
void main(void)
{
// Init timer2 and anything else
while(1)
{
if (!input(SENSOR_PIN))
{
if (Sensor1Timeout == TIMED_OUT)
output_high(LED_1);
}
else
{
// Reset timer and LED to initial state
Sensor1Timeout = THREE_SECONDS;
output_low(LED_1);
}
}
} |
|
|
|
global
Joined: 01 Feb 2005 Posts: 21 Location: Paris
|
|
Posted: Fri Apr 29, 2005 9:07 am |
|
|
Thank you this is great !!!
A last question :
What is " Init timer2 and anything else " ?
I don't know how to do that is it more less what is already on posts of the forum ?
Thank you ! |
|
|
global
Joined: 01 Feb 2005 Posts: 21 Location: Paris
|
|
Posted: Mon May 02, 2005 6:42 am |
|
|
Hello,
i tested the ckielstra's code but I don't know what is wrong , this is not working, could someone check it with me ?
Thanks =) |
|
|
|