View previous topic :: View next topic |
Author |
Message |
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
Pulse train gap |
Posted: Fri Sep 04, 2009 10:18 am |
|
|
Hi All,
Please excuse I have created a new topic which was broken here:
http://www.ccsinfo.com/forum/viewtopic.php?t=39975
Continuing it, I have a trouble implementing a logic. I have attached a diagram. Now, in IR_pulse there's a pulse train. As seen in the diagram, an initial pulse train activates the output at A1, B1, A2, B2 which I have implemented with the use of EXT_ISR. But I can not seem to activate the same output when 2nd pulse train arrives. The logic should also conform that the gap between the pulse train be maintained and watched. If the gap is smaller than the given, it must not activate the output. If it's matching or more, it must activate the output at EXT_INT_EDGE(H_TO_L). Somehow my code does not seem to be working here.
Code: |
#INT_EXT
void ext_isr()
{
return;
}
void signal_led(s)
{
while(s != 0)
{
output_high(PIN_B2);
delay_ms(50);
output_low(PIN_B2);
delay_ms(50);
s--;
}
return;
}
void fault_indication(int8 i)
{
while(i != 0)
{
output_high(PIN_B3); //Glows LED showing malfunction in relay.
delay_ms(200);
output_low(PIN_B3);
delay_ms(200);
i--;
}
}
boolean verify()
{
signal_led(2);
delay_ms(check_time);
if(!input(IR_detect)) //Making sure Hand is still present
{
return(true);
}
else if(input(IR_detect))
{
fault_indication(5);
return(false);
}
}
void step(d,d1,steps)
{
int i;
for (i = 0; i < steps; i++) //Move forward
{
output_a(0b0011);
delay_ms(d);
output_a(0b0010);
delay_ms(d);
output_a(0b0110);
delay_ms(d);
output_a(0b0100);
delay_ms(d);
output_a(0b1100);
delay_ms(d);
output_a(0b1000);
delay_ms((3*d)/2);
//output_a(0b1001);
//delay_ms(2*d);
//output_a(0b0001);
//delay_ms(2*d);
}
for (i = 0; i < steps; i++) //Move backward
{
//output_a(0b1001);
//delay_ms(d1);
//output_a(0b1000);
//delay_ms(d1);
output_a(0b1100);
delay_ms(d1);
output_a(0b0100);
delay_ms(d1);
output_a(0b0110);
delay_ms(d1);
output_a(0b0010);
delay_ms(d1);
output_a(0b0011);
delay_ms(d1);
output_a(0b0001);
delay_ms(d1);
}
}
void main()
{
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);
while(TRUE)
{
int j;
enable_interrupts(INT_EXT);
sleep();
disable_interrupts(INT_EXT);
if(!verify())continue;
step(75,50,1); //Actuator moves forward and backward.
l: for(j = 0; j < 30; ) //making sure abt the pulse train gap.
{
if(input_state(IR_detect) != 1)
{
delay_ms(15);
j++;
}
else goto l;
}
}
} |
|
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
Re: Pulse train gap |
Posted: Fri Sep 04, 2009 10:44 am |
|
|
ferrousduke wrote: |
Code: |
l: for(j = 0; j < 30; ) //making sure abt the pulse train gap.
{
if(input_state(IR_detect) != 1)
{
delay_ms(15);
j++;
}
else goto l;
}
|
|
I don't know if that's valid syntax in C (or even a good idea) and don't have my C book handy.
How about trying this instead:
Code: |
j = 0;
while (j < 30) //making sure abt the pulse train gap.
{
if(input_state(IR_detect) != 1)
{
delay_ms(15);
j++;
}
}
|
_________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Fri Sep 04, 2009 11:43 pm |
|
|
This is all I m getting after the changes.
and this if I increase number of pulses maintaining the gap.
|
|
|
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Sun Sep 06, 2009 8:46 am |
|
|
Can someone please help ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 06, 2009 3:45 pm |
|
|
Part of the reason for no replies is:
1. You didn't tell us anything about the IR device that you're using.
You need to provide a link to a data sheet for the device, which shows
full timing specifications.
2. Your coding methods are not the greatest. Most people don't want
to look at code that contains 'goto' statements. For example, you have
a routine that does that, and it could be re-written like this:
Code: |
// Wait for IR_detect to be continuously at a low level
// for 450 ms. Check it at 15 ms intervals.
// If it goes high during that time, restart the test.
while(1)
{
// Break out of this loop if IR_detect goes high
// and re-start the test.
for(j = 0; j < 30; j++)
{
if(input_state(IR_detect))
break;
delay_ms(15);
}
// If IR_detect was low for 450 ms continuously,
// then exit the while() loop
if(j == 30)
break;
} |
There might be a better way to do it, but at least it doesn't use goto.
3. You didn't give us full details on what the output pulses should be,
and what they are used for.
4. You should tell us your PIC, compiler version, and #fuses, #use delay
and other statements. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Mon Sep 07, 2009 4:50 pm |
|
|
And some more details about those graphs... in the world of scope's -- we'd like to know the time/div
It looks like the code changes I gave you got you out of being stuck, but maybe the time delay is a little long now?
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Tue Sep 08, 2009 12:02 am |
|
|
bkamen wrote: | And some more details about those graphs... in the world of scope's -- we'd like to know the time/div
It looks like the code changes I gave you got you out of being stuck, but maybe the time delay is a little long now?
-Ben |
Somehow it did. but I am getting stumped somewhere in ext_isr.
IN the graph:
IR_pulse - Input stream of IR. Gap can be variable. I have put the whole stream only for simulation purposes.
signal_led - when an object is detected, it signals twice.
After some delay A1, B1, A2, B2 are the motor signals. |
|
|
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Tue Sep 08, 2009 12:06 am |
|
|
Quote: | There might be a better way to do it, but at least it doesn't use goto.
3. You didn't give us full details on what the output pulses should be,
and what they are used for.
4. You should tell us your PIC, compiler version, and #fuses, #use delay
and other statements. |
Perhaps, the goto statement in my code was the result of long frustration. Anyways, I changed my code to the advised one by you. Somehow, I feel that there's something wrong with ext_isr too. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Sep 08, 2009 8:41 am |
|
|
Quote: | 6.11.3 WAKE-UP USING INTERRUPTS
When global interrupts are disabled (GIE cleared) and
any interrupt source has both its interrupt enable bit
and interrupt flag bit set, one of the following will occur:
• If the interrupt occurs before the execution of a
SLEEP instruction, the SLEEP instruction will com-
plete as a NOP. Therefore, the WDT and WDT
postscaler will not be cleared, the TO bit will not
be set and PD bits will not be cleared.
• If the interrupt occurs during or after the execu-
tion of a SLEEP instruction, the device will imme-
diately wake-up from SLEEP. The SLEEP
instruction will be completely executed before the
wake-up. Therefore, the WDT and WDT
postscaler will be cleared, the TO bit will be set
and the PD bit will be cleared. | Short version: clear the interrupt directly before calling the sleep function.
Code: | boolean verify()
{
signal_led(2);
delay_ms(check_time);
if(!input(IR_detect)) //Making sure Hand is still present
{
return(true);
}
else if(input(IR_detect))
{
fault_indication(5);
return(false);
}
} | Bug: It is possible for this function to return without setting a return value.
Change to: Code: | boolean verify()
{
signal_led(2);
delay_ms(check_time);
if(!input(IR_detect)) //Making sure Hand is still present
{
return TRUE;
}
fault_indication(5);
return FALSE;
} |
Tip: Code: | void foo()
{
return;
} | A return command at the end of a void function is doing nothing and can be omitted, saving a line of code (two times in your code). |
|
|
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Wed Sep 09, 2009 6:27 am |
|
|
Hi Carlo,
Thanks for the reply. I am working on some corrections. I did not get about disabling interrupt(INT_EXT) before sleep().. or maybe I misunderstood?
Code: | #INT_EXT
void ext_isr()
{
return;
} |
Are you saying that I should omit this routine itself? This is to make sure I don't activate the output as soon as I get interrupt. That interrupt H_TO_L shall remain for some period of time. Thats where verify() comes into picture. I am working on some other variants of dealing with IR_signal. |
|
|
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Wed Sep 16, 2009 9:46 am |
|
|
Hello All,
I am using PICKIT2 PX-200 to program my PIC16F648A. Now the problem is while the programmer is connected to PIC and PC, my code works as I want. Once I disconnect PX-200 from PIC and let it run on external power supply, a part of my code does not work.
http://www.evrshop.com/pdf/IE-PX200.pdf
Code: |
#include "16F648A.h"
#fuses HS,NOWDT,NOPROTECT,NOLVP
#include <stdio.h>
#include <math.h>
#use delay(clock = 4000000)
#define IR_detect PIN_B0
#define relay_check PIN_B1
void step(int8 d, int8 d1, int8 steps);
boolean verify(void);
void fault_indication(int8 i);
void signal_led(int8);
#INT_EXT
void ext_isr()
{
signal_led(2);
}
void signal_led(s)
{
while(s != 0)
{
output_high(PIN_B2);
delay_ms(50);
output_low(PIN_B2);
delay_ms(50);
s--;
}
// return;
}
void fault_indication(int8 i)
{
while(i != 0)
{
output_high(PIN_B3); //Glows LED showing malfunction in relay.
delay_ms(200);
output_low(PIN_B3);
delay_ms(200);
i--;
}
}
boolean verify()
{
delay_ms(check_time);
if(!input(IR_detect))//Making sure Hand is still present
{
return TRUE;
}
else if(input(IR_detect)) fault_indication(5);
return FALSE;
}
void step(d,d1,steps)
{
int i;
for (i = 0; i < steps; i++) //Move forward
{
output_a(0b0010);
delay_ms(d);
output_a(0b0110);
delay_ms(d);
output_a(0b0100);
delay_ms(d);
output_a(0b1100);
delay_ms(d);
output_a(0b1000);
delay_ms(d);
output_a(0b1001);
delay_ms(d);
output_a(0b0001);
delay_ms(d);
output_a(0b0011);
delay_ms(d);
}
for (i = 0; i < steps; i++) //Move backward
{
output_a(0b0001);
delay_ms(d1);
output_a(0b1001);
delay_ms(d1);
output_a(0b1000);
delay_ms(d1);
output_a(0b1100);
delay_ms(d1);
output_a(0b0100);
delay_ms(d1);
output_a(0b0110);
delay_ms(d1);
output_a(0b0010);
delay_ms(d1);
output_a(0b0011);
delay_ms(d1);
}
}
void main()
{
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);
while(TRUE)
{
enable_interrupts(INT_EXT);
sleep();
delay_ms(100);
disable_interrupts(INT_EXT);
if(!verify())continue;
step(2.5,2.5,100); //Actuator moves forward and backward.
delay_ms(100); //Just a delay of 300 mS before the next hand comes in.
while(input_state(IR_detect));//Make sure that the hand is removed before the next shot.
}
} |
This is the part that does not work.. I mean motor turns in one direction but it turns a bit in the other and stops. The backward motion decreases gradually as I repeat the process. and then at the end it turns in one direction and does not return at all.
Code: | for (i = 0; i < steps; i++) //Move backward
{
output_a(0b0001);
delay_ms(d1);
output_a(0b1001);
delay_ms(d1);
output_a(0b1000);
delay_ms(d1);
output_a(0b1100);
delay_ms(d1);
output_a(0b0100);
delay_ms(d1);
output_a(0b0110);
delay_ms(d1);
output_a(0b0010);
delay_ms(d1);
output_a(0b0011);
delay_ms(d1);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 16, 2009 11:09 am |
|
|
Quote: |
void step(int8 d, int8 d1, int8 steps);
step(2.5,2.5,100);
|
You are trying to give floating point parameters to the step() function
when it has been declared as using unsigned 8-bit integers.
This won't work as expected.
There may be more problems. I just glanced at the code. |
|
|
|