View previous topic :: View next topic |
Author |
Message |
sahu77
Joined: 08 Sep 2011 Posts: 202
|
time delay problem |
Posted: Tue Oct 25, 2011 2:23 pm |
|
|
I'm facing problem time delay during dual ADC i\p at same time.
Code: |
int ProcessMains(void)
{
ch_0 = getchreading(0);
Process_ch_0(); // Do something with ch_0 o\p lod sence
if (ch_0>800) // lod 130 % Wait 6 min
Delay60000ms
return(OVER_LOD_SENCE);
ch_1 = getchreading(1);
Process_ch_1(); // Do something with ch_1 o\p volt
if (ch_1>1000)
return(HIGH_VOLTAGE);
if (ch_1<950)
return(NORMAL_VOLTAGE);
} |
both ADC apply same time. All is well. But problem is here Delay60000ms, when mcu go delay mode 6 min during delay mode if ch_1 do something, it is not work. _________________ sahu |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Oct 25, 2011 2:47 pm |
|
|
What does an 'if statement' execute?.
The next code statement _only_. You need some bracketting in this code or it has not got a hope.
Then your syntax is wrong in several other places. What is 'Delay6000ms'?. This is not the syntax for a 6minute delay in CCS.
Basically the whole syntax shown is 'wrong'.
Try getting a C primer. and restarting.
Best Wishes |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Tue Oct 25, 2011 3:37 pm |
|
|
Hi,
In addition to the 'C' syntax issues already noted, I think (??) the OP is reporting that all program activity is halted during the 6 minute delay. This, of course, is exactly what you would expect with the delay_ms instruction. The proper way to handle a long delay is to break it up into smaller "nuggets" that cumulatively combine to the desired longer delay. Other operations can be handled in between the shorter delay periods.
If this is not what you mean, perhaps you can rephrase the entire question?
John |
|
|
sahu77
Joined: 08 Sep 2011 Posts: 202
|
|
Posted: Wed Oct 26, 2011 11:35 am |
|
|
Code: | if (ch_0>800) // lod 130 % Wait 6 min
Delay60000ms
return(OVER_LOD_SENCE) |
Actually I want if (ch_0>800) mcu wait 6 min,
if (ch_0>800) yet 6 min, then return(OVER_LOD_SENCE)
if (ch_0<800) during 6 min. it will go predefine return abc case _________________ sahu |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Thu Oct 27, 2011 2:25 pm |
|
|
Hi,
As I mentioned, if you want to perform other operations during your 6 minute delay, you can't simply call delay_ms(60000); because all other operations will be suspended during the delay. You'll need to create your own delay routine that consists of a smaller delay called repeatedly with a check of Ch0 between calls.
Make sense?
John |
|
|
sahu77
Joined: 08 Sep 2011 Posts: 202
|
|
Posted: Fri Oct 28, 2011 11:53 am |
|
|
Code: | /*************************************************************************
Function Delay 1 min
Delay 1 sec repeat up to 60 times
****************************************************************************/
void Delay_1_min(void)
{
for (x=1; x<61; x++)
{
delay_ms(1000);
} |
this add to ch_0 >800
like
Code: | if (ch_0>800)
Delay_1_min(); // wait up to 1 min
return(OVER_LOD_SENCE); |
above method is OK ? _________________ sahu |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Fri Oct 28, 2011 12:28 pm |
|
|
It doesn't matter HOW you construct your 'delay for 6 minutes' function with varous delay_ms() variations, ALL will be in an 'exclusive countdown timer' loop and the PIC will NOT be able to do anything else( like read other ADC channels, do comparisons, etc.The PIC will just do nothing but delay until 6 minutes has been reached.
It sounds like what you want to do is read the ADC, then during the next 6 minutes read another ADC channel, do an IF statement, and then at the end of 6 minutes, IF the first channel is no good, send an 'overload' statement.
If that's the overall logic, look at the software RTC in the 'code library'. It allows you to setup an ISR that will set a 'flag' that your main code will see. Your main code could be setup to read all the ADC channels,display them,control LEDs,etc. and make the comparisons and when 6 minutes is up, take the appropriate action(turn on LEDS, display 'error codes', etc.
Having the program with a 6 minute inline delay is really,really bad programming and not what I think you really want to do.At the very least have an LED toggle every few seconds to show you the PIC hasn't stopped running! |
|
|
sahu77
Joined: 08 Sep 2011 Posts: 202
|
|
Posted: Tue Nov 01, 2011 11:02 am |
|
|
temtronic wrote: | It doesn't matter HOW you construct your 'delay for 6 minutes' function with varous delay_ms() variations, ALL will be in an 'exclusive countdown timer' loop and the PIC will NOT be able to do anything else( like read other ADC channels, do comparisons, etc.The PIC will just do nothing but delay until 6 minutes has been reached.
It sounds like what you want to do is read the ADC, then during the next 6 minutes read another ADC channel, do an IF statement, and then at the end of 6 minutes, IF the first channel is no good, send an 'overload' statement.
If that's the overall logic, look at the software RTC in the 'code library'. It allows you to setup an ISR that will set a 'flag' that your main code will see. Your main code could be setup to read all the ADC channels,display them,control LEDs,etc. and make the comparisons and when 6 minutes is up, take the appropriate action(turn on LEDS, display 'error codes', etc.
Having the program with a 6 minute inline delay is really,really bad programming and not what I think you really want to do.At the very least have an LED toggle every few seconds to show you the PIC hasn't stopped running! |
Sir my English very bad, as I know. If you don't mind can you give example.
pl _________________ sahu |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Tue Nov 01, 2011 11:13 am |
|
|
Here is an example of how to keep time using an ISR posted yesterday:
http://www.ccsinfo.com/forum/viewtopic.php?t=46630
Here is one I have used for years:
Code: |
void Timer1_int()
{
set_timer1(TIMER1START); // timerstart is set according to your osc frequency to get 10ms intervals
// *****
// count the 10ms intervals
if (--_10mscntr < 1)
{
_10mscntr = 100; // reset for one second
} // if --10mscntr < 1
// *****
if (_delay1 > 0) // 10ms intervals
_delay1--;
if (_delay2 > 0)
_delay2--;
if (_delay3 > 0)
_delay3--;
}
//Code in Main:
if _delay1 <=0 then
{
}
|
Set the _delay1 counter (INT16 variable) to the number of 10ms
intervals you require (example 600= 6 seconds) then test the variable in
the main loop. When it gets to zero then the delay has completed. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
sahu77
Joined: 08 Sep 2011 Posts: 202
|
|
Posted: Wed Nov 02, 2011 12:01 pm |
|
|
dyeatman wrote: | Here is an example of how to keep time using an ISR posted yesterday:
http://www.ccsinfo.com/forum/viewtopic.php?t=46630
Here is one I have used for years:
Code: |
void Timer1_int()
{
set_timer1(TIMER1START); // timerstart is set according to your osc frequency to get 10ms intervals
// *****
// count the 10ms intervals
if (--_10mscntr < 1)
{
_10mscntr = 100; // reset for one second
} // if --10mscntr < 1
// *****
if (_delay1 > 0) // 10ms intervals
_delay1--;
if (_delay2 > 0)
_delay2--;
if (_delay3 > 0)
_delay3--;
}
//Code in Main:
if _delay1 <=0 then
{
}
|
Set the _delay1 counter (INT16 variable) to the number of 10ms
intervals you require (example 600= 6 seconds) then test the variable in
the main loop. When it gets to zero then the delay has completed. |
it will start , when power on , ok
but my problem when ADC reach >800 delay start hear _________________ sahu |
|
|
Geomod
Joined: 02 Nov 2011 Posts: 1
|
|
Posted: Wed Nov 02, 2011 2:53 pm |
|
|
If you want to make some other task while you're waiting for the 6 minute time, I suggest to implement the RTOS that's the simplest way to do that.
I doubt the RTOS is able to schedule a task every 6 min, but you can (as someone told you before) split the pause in a task and increment a counter until you get your 6 min.
Hope it helps.
BTW: If you understand spanish very well I could give you a link with a tutorial on the CCS RTOS which is really simple and fast. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Wed Nov 02, 2011 4:04 pm |
|
|
OK, so when the ADC Value exceeds 800 then set the _Delay1 value to the
desired delay and monitor in the main loop until it reaches zero (or reaches
the desired number during the countdown). _________________ Google and Forum Search are some of your best tools!!!! |
|
|
sahu77
Joined: 08 Sep 2011 Posts: 202
|
|
Posted: Tue Dec 13, 2011 1:02 pm |
|
|
now i use like this
Code: | unsigned char ten_minutes = 0;
/*****************************************************************************
Timer1 Interrupt, executed every 10 ms
****************************************************************************/
#INT_TIMER1
void TIMER1_isr(void)
{
// Increment time_elasped to keep track of ms
time_elasped++;
if (time_elasped == 100) //high voltage cut led blink frequency @ 1000 ms
{
seconds++;
//...
time_elasped = 0;
}
if(Seconds == 60)
{
Minutes++; Seconds=0; ten_minutes++;
if(Minutes == 60) Minutes=0;
}
}
// ...
int ProcessMains_volt(void)
{
ch_0 = getchreading(0);
Process_ch_0(); // Do something with ch_0 o\p lod sence
if (ch_0>800) // lod > 130 % Wait 10 min sence now
{
ten_minutes = 0;
while(ten_minutes < 10)
{
ch_0 = getchreading(0);
Process_ch_0();
Process_ch_1();
// ...
}
return(OVER_LOD_SENCE);
}
// ...
} |
its meaning
Code: | int ProcessMains_volt(void)
{
ch_0 = getchreading(0);
Process_ch_0(); // Do something with ch_0 o\p lod sence
if (ch_0>800) // lod > 130 % Wait 10 min sence now
{
ten_minutes = 0;
while(ten_minutes < 10)
{
ch_0 = getchreading(0);
Process_ch_0();
Process_ch_1();
// ...
}
return(OVER_LOD_SENCE); |
when ch0 reach>800 & wait 10 min
then work
Code: | while(ten_minutes < 10)
{
ch_0 = getchreading(0);
Process_ch_0();
Process_ch_1();
// ...
} |
its work till ch0 reach>800 & it not
Code: | return(OVER_LOD_SENCE); |
Hope you understood my question and help me. _________________ sahu |
|
|
|