CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

How to use a delay function?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

How to use a delay function?
PostPosted: Thu Nov 15, 2007 11:32 am     Reply with quote

I need to to use a delay function in the following code to make the data that is being sent over the rs232 receive correctly. Problem is that everytime i repeat the while loop i have to sent some value but the delay function of 20ms affects the response time of my pic so much that it shows on the lcd. Is there a better way to delay a certain if function without it delaying all other functions?? A simple thing like blinking an LED every second would basically let the pic only run 1 cycle every second??

Code:
if(weapon > 190){
   output_high(pin_B2);
   PutCC1000(PREAMBLE);
   PutCC1000(0X0B);
   PutCC1000(0X0B);
   PutCC1000(0X0B);
           putc('Y');
         delay_ms(20);
         putc(10);
         delay_ms(20);
         putc(weapon);
         delay_ms(20);
         putc('Z');
         delay_ms(20);
}
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Nov 15, 2007 12:46 pm     Reply with quote

Quote:

Is there a better way to delay a certain if function without it delaying all other functions??

The key is to use any built-in timer to handle the equal-time scheduled events.

Something like this, not tested.

Code:


  setup_timerx(......);// Set Timerx for an interrupt every 20ms

if(weapon > 190){
   output_high(pin_B2);
   PutCC1000(PREAMBLE);
   PutCC1000(0X0B);
   PutCC1000(0X0B);
   PutCC1000(0X0B);
           putc('Y');
           set_timerx(0);
           enable_interrupt(INT_TIMERx);
           enable_interrupt(GLOBAL);
           timed_putc = 1;
}


#INT_TIMERx
void timed_events()
{
   switch(timed_putc)
     {  case 1: putc(10);        timed_putc = 2; break;
        case 2: putc(weapon);    timed_putc = 3; break;
        case 3: putc('Z');       timed_putc = 4; break;
        case 4: disable_interrupt(INT_TIMERx);   break;
     }
}



Humberto


Last edited by Humberto on Thu Nov 15, 2007 1:07 pm; edited 1 time in total
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

PostPosted: Thu Nov 15, 2007 1:02 pm     Reply with quote

Thanks. What will happen then if i have two functions during the cycle that calls the interupt? If the interupt is still busy being executed while i call it again via another if statement, will the system not become unstable??
I have 3 analogs and sometimes i need to send 3 different values, depending on where the 3 analogs is during one cycle as well as what the value is in that cycle??
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Nov 15, 2007 1:14 pm     Reply with quote

While an interrupt is handled, by no way it will be affected by another interruptds
until it finished.
The aproach I gave you should work in background, it is according your first answer.
I do not see your whole code and how do you handle the events, but if you are dealing
with multiple events, you could use different timers.
To consider all the posibilities we will know more details of your project.


Humberto
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

PostPosted: Thu Nov 15, 2007 1:53 pm     Reply with quote

Here is the part where i have the different functions. I don't want to post the whole code as it is a university subject where all the students will use my code. I have this pic comunicating with a cc1000 as well as a LCD.
Code:

//////////////////////////////////////////////////////////////////
while(1){
///////////////////////////////weapon//////////////////////////

delay_ms(50);

set_adc_channel(3);
delay_us(20);
weapon = read_adc();

if(weapon > 190){
   output_high(pin_B2);
   PutCC1000(PREAMBLE);
   PutCC1000(0X0B);
   PutCC1000(0X0B);
   PutCC1000(0X0B);
           putc('Y');
         delay_ms(20);
         putc(10);
         delay_ms(20);
         putc(weapon);
         delay_ms(20);
         putc('Z');
         delay_ms(20);
}
    else
      if(weapon <85){
      output_high(pin_B4);
      PutCC1000(PREAMBLE);
      PutCC1000(0X0C);
       PutCC1000(0X0C);
       PutCC1000(0X00);
          putc('Y');
         delay_ms(20);
         putc(20);
         delay_ms(20);
         putc(weapon);
         delay_ms(20);
         putc('Z');
         delay_ms(20);
}
       else
         if(weapon < 191 && weapon > 84){
            output_low(pin_B4);
            output_low(pin_B2);
 
}
       
////////////////////////////////////left and right//////////////////////////////////////////////
set_adc_channel(2);   
delay_us(20);
value1 = read_adc();

if(value1 > 170 ){
   output_high(pin_A4);
   output_low(pin_B5);
   output_low(pin_B3);
   PutCC1000(PREAMBLE);
   PutCC1000(0x1A);
    PutCC1000(0x1A);
    PutCC1000(value1);
           putc('Y');
         delay_ms(20);
         putc(30);
         delay_ms(20);
         putc(value1);
         delay_ms(20);
         putc('Z');
         delay_ms(20);
   }
   else
       if((value1 > 150 && value1 < 171)||(value1 > 69 && value1 < 91  )){
      output_low(pin_A4);
      output_low(pin_B5);
      output_low(pin_B3);
        PutCC1000(PREAMBLE);
       PutCC1000(0x1B);
        PutCC1000(0x1B);
        PutCC1000(0x00);
         
}
        else
         if(value1 < 70 ){
         output_high(pin_A5);
         output_low(pin_B5);
         output_low(pin_B3);
         PutCC1000(PREAMBLE);
         PutCC1000(0x1C);
            PutCC1000(0x1C);
            PutCC1000(0x00);
                    putc('Y');
               delay_ms(20);
               putc(40);
               delay_ms(20);
               putc(value1);
               delay_ms(20);
               putc('Z');
               delay_ms(20);
         }
//////////////////////////////forward reverse/////////////////////////////////////////////////

if(value1 > 90 && value1 <151){
output_low(pin_A4);
output_low(pin_A5);
set_adc_channel(1);
delay_us(20);
value = read_adc();

   if(value > 0 && value < 116  ) {
   output_low(pin_B5);
   output_high(pin_B3);
   PutCC1000(PREAMBLE);
   PutCC1000(0x3A);
    PutCC1000(0x3A);
    PutCC1000(140-value);
            putc('Y');
         delay_ms(20);
         putc(50);
         delay_ms(20);
         putc(140-value);
         delay_ms(20);
         putc('Z');
         delay_ms(20);
   }
   else
       if(value > 115 && value < 161  ) {
         
         output_low(pin_B5);
         output_low(pin_B3);
         }
         else
               if(value > 160) {
         output_low(pin_B3);
         output_high(pin_B5);
         PutCC1000(PREAMBLE);
         PutCC1000(0x3B);
            PutCC1000(0x3B);
            PutCC1000(value-131);
                    putc('Y');
                   delay_ms(20);
               putc(60);
               delay_ms(20);
               putc(value-131);
               delay_ms(20);
               putc('Z');
               delay_ms(20);
         }


}
if((weapon<191&&weapon>84)&&(value1 > 90 && value1 <151)&&(value > 115 && value < 161)){
            PutCC1000(PREAMBLE);
         PutCC1000(0xBB);
            PutCC1000(0xBB);
            PutCC1000(0x00);
            putc('Y');
           delay_ms(20);
           putc(111);
           delay_ms(20);
           putc(weapon);
           delay_ms(20);
           putc('Z');
           delay_ms(20);


Here is the part of the code for the pic connected to the LCD,.

Code:
#include <16F886.H>
#fuses INTRC,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NODEBUG
#use delay(clock = 4000000)

#use RS232 (STREAM=serial,BAUD=19200,XMIT=PIN_C6,RCV=PIN_C7)

#include "flex_lcd.c"

int pack_offset = 0;
int packet_in[4] = {0,0,0,0};

int speed = 0;
int dir = 0;
int x = 0;
int weapon=0;

#int_rda         //serial interupt service routine
void serial_isr() {

   byte rcv_char;
   int x;

   if (kbhit()) {                  //char ready on uart to come in
      rcv_char = getc();
      if(rcv_char == 'Y'){
         pack_offset = 0;
      }
      packet_in[pack_offset] = rcv_char;
       if( (rcv_char == 'Z') && (packet_in[0] == 'Y') ){   
         dir = packet_in[1];
         speed = packet_in[2];
            
       //delay_ms(500);
            }
   
      pack_offset++;
   }  //kbhit
}   
//==========================
void main()
{

int x;
enable_interrupts(INT_RDA);         // Enable Serial Reception Interrupt
enable_interrupts(GLOBAL);         //Enable interupts global


lcd_init();  // Always call this first.
lcd_gotoxy(1,1);
lcd_putc("\f  PLEASE WAIT!!");
lcd_gotoxy(1,2);
lcd_putc("  INITIALISING!");
delay_ms(1000);





while(1){

delay_ms(200);
            if(dir==10){
            lcd_gotoxy(1,2);
            lcd_putc("LID MOVING DOWN ");
          //   printf(LCD_PUTC, "%u",speed);
         }
           
            if(dir==20)
            {
            lcd_gotoxy(1,2);
            lcd_putc("LID MOVING UP    ");
            }
             
             if(dir==111)
            {
            lcd_gotoxy(1,1);
         lcd_putc("MOTION INACTIVE  ");
         lcd_gotoxy(1,2);
            lcd_putc("WEAPONS INACTIVE ");
            }
             
             if(dir==30)
            {
            lcd_gotoxy(1,1);
         lcd_putc("TURN LEFT        ");
                    
            lcd_gotoxy(13,1);
            x=((speed-170)*2)+15;
            printf(LCD_PUTC, "%u",x);
            lcd_gotoxy(16,1);
            lcd_putc("% ");
            }
            else
             if(dir==40)
            {
            lcd_gotoxy(1,1);
         lcd_putc("TURN RIGHT       ");
         lcd_gotoxy(13,1);
            x= (75-speed)*3;
            printf(LCD_PUTC, "%u",x);
            lcd_gotoxy(16,1);
            lcd_putc("% ");
            }
            else
            if(dir==50)
            {
            lcd_gotoxy(1,1);
         lcd_putc("REVERSE         ");
         lcd_gotoxy(13,1);
            x= speed+10;
            printf(LCD_PUTC, "%u",x);
            lcd_gotoxy(16,1);
            lcd_putc("% ");
            }
            else
            if(dir==60)
            {
            lcd_gotoxy(1,1);
         lcd_putc("FORWARD         ");
         lcd_gotoxy(13,1);
            x= speed;
            printf(LCD_PUTC, "%u",x);
            lcd_gotoxy(16,1);
            lcd_putc("% ");
           
}

Here is a part of the code for the recieving end of the cc1000. I still have to implement the rs232 for this side to display the recieved RF comands.
Code:
while(1){
/////////////////////////////////////////////////////////////////

set_adc_channel(0);
delay_us(20);
signal = read_adc();
if(signal>30){

output_low(pin_a1);
output_low(pin_a2);
output_low(pin_a3);
output_low(pin_a4);      
output_low(pin_a5);
output_low(pin_b4);
output_low(pin_b5);             
set_pwm1_duty(0);
setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_C
                       | CCP_PULSE_STEERING_B);
delay_ms(500);
output_high(pin_B3);
delay_ms(500);
output_low(pin_B3);
}
 else
   if(signal<31){
               
     if (CCRX_BUFFCOUNT >= 4) {   // As 4 bytes ontvang is
       temp = GETCC1000();
        if(temp == PREAMBLE){
          pay1 = GETCC1000();
          crc = GETCC1000();
            speed = GETCC1000();
            if(pay1!=crc){
            delay_ms(5);
            output_low(pin_b3);
            output_high(pin_b3);
            output_low(pin_a1);
            output_low(pin_a2);
            output_low(pin_a3);
            output_low(pin_a4);      
            output_low(pin_a5);
            output_low(pin_b4);
            output_low(pin_b5);
             
            set_pwm1_duty(0);
            setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_C
                                   | CCP_PULSE_STEERING_B);
            }
            else{
            output_high(pin_b3);
           
                 
            if (pay1==0xBB){
         output_low(pin_a1);
            output_low(pin_a2);
            output_low(pin_a3);
            output_low(pin_a4);      
            output_low(pin_a5);
            output_low(pin_b4);
            output_low(pin_b5);
             
            set_pwm1_duty(0);
            setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_C
                                   | CCP_PULSE_STEERING_B);
            output_high(pin_B3);
         
           }
//////////////////weapon///////////////////////////////////////////////////                               
               
               if(pay1 == 0x0B)
               {
               output_high(pin_A5);
               output_low(pin_b4);
               output_high(pin_b5);
                }
                else
                  if(pay1 == 0x0C){
                    output_low(pin_A5);
                    output_high(pin_b4);
                    output_high(pin_b5);
                  }

//////////////////////////////////right/////////////////////////////////////////////////////////
               if(pay1 == 0x1A){
               output_low(pin_a1);
               
               delay_ms(5);
               output_high(pin_a2);
               set_pwm1_duty(124);
               setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_C);
               output_high(pin_a3);
               output_high(pin_a4);
               }
               else
                    if(pay1 == 0x1B){
                    output_low(pin_a1);
                  output_low(pin_a2);
                  output_low(pin_a3);
                     output_low(pin_a4);
                   set_pwm1_duty(0);
                   setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_C
                                          | CCP_PULSE_STEERING_B);
                   }
                   else
                      if(pay1 == 0x1C){
                      output_low(pin_a3);
                      output_low(p1c);
                      output_high(pin_a2);
                      output_high(pin_a4);
                      set_pwm1_duty(124);
                      setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_B);
                      output_high(pin_a1);     
                      }
//////////////////////////////forward/////////////////////////////////////////
               if(pay1 == 0x3A){
               output_low(pin_a3);
               output_low(pin_a1);
               delay_ms(5);
               output_high(pin_a2);
               output_high(pin_a4);
               output_high(pin_b2);
               output_high(pin_b5);
               set_pwm1_duty(speed);
               setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_C);     
               }
               else
               if(pay1 == 0x3B){
                     output_low(pin_b2);
                    output_low(pin_b5);
                    delay_ms(5);
                    set_pwm1_duty(speed);
                     setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_C);
                     output_high(pin_a2);
                     output_high(pin_a4);
                   output_high(pin_a1);
                     output_high(pin_a3);     
                     }
               }
       
}//einde van crc                 
}//einde van if(ccrx_bufcount)
}//einde van seinsterkte toets

}//einde van hoof WHILE
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Nov 15, 2007 9:49 pm     Reply with quote

Your code looks quite twisted and for sure you have multiple and overlapped results in each loop.
It seems like you need to update the positions in 3 servos simultaneously according to
some environment variables. I propose you to think the problem in the opposite way.

First, make a main loop with an interrupt every 7ms. Then you will need to assign 3 tasks
to update parameters for each servo spaced by 21ms. You can get it using the same
timer, in this way you will "visit" the same servo every 21ms, hence you will have enough
time to collect the environment inputs data and update the corresponding parameters.


Humberto
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

PostPosted: Fri Nov 16, 2007 3:09 am     Reply with quote

Thanks.
Will you please explain your advice a bit more. I am reading the value of a analog for a forward-reverse action.
Code:
if(value1 > 90 && value1 <151){
output_low(pin_A4);
output_low(pin_A5);
set_adc_channel(1);
delay_us(20);
value = read_adc();

   if(value > 0 && value < 116  ) {
   output_low(pin_B5);
   output_high(pin_B3);
   PutCC1000(PREAMBLE);
   PutCC1000(0x3A);
    PutCC1000(0x3A);
    PutCC1000(140-value);
            putc('Y');
         delay_ms(20);
         putc(50);
         delay_ms(20);
         putc(140-value);
         delay_ms(20);
         putc('Z');
         delay_ms(20);
   }
   else
       if(value > 115 && value < 161  ) {
         
         output_low(pin_B5);
         output_low(pin_B3);
         }
         else
               if(value > 160) {
         output_low(pin_B3);
         output_high(pin_B5);
         PutCC1000(PREAMBLE);
         PutCC1000(0x3B);
            PutCC1000(0x3B);
            PutCC1000(value-131);
                    putc('Y');
                   delay_ms(20);
               putc(60);
               delay_ms(20);
               putc(value-131);
               delay_ms(20);
               putc('Z');
               delay_ms(20);
         }


As well as for left and right. However the forward reverse is only read if the left right analog is in the middle.

The third one i am reading is another analog that indicates if the lid of the car is moving up or down.

I am fairly new to pics and very new at using interupts so if you can please just give me some details as to what you propose.
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Fri Nov 16, 2007 10:14 am     Reply with quote

1) Set an internal timer to kick every 6.4ms. to handle the servos.
Code:

setup_timer_2(T2_DIV_BY_16,124,16); // (6.4ms @20Mhz)


2) Use a variable to handle the LCD display.
Code:

int update_display;


3) In the servo handler routine, make an incremental task handler (like the switch()
function I showed you previously)
Code:

#int_TIMER2
void  servos_handler_isr(void)
{
  update_display++;

  switch(task_handler)
        {
         case 1: update_servo_1();
                 task_handler++;
                 break;
         case 2: update_servo_2();
                 task_handler++;
                 break;
         case 3: update_servo_3();
                 task_handler=1;
                 break;
        }
}


4) In the main(), take out the 200ms delay and do all the evaluations (if(...) of the
involved variables (value, value1 and weapon) and set the data field of the payloads
accordingly.

5) In main() the display should be easily updated using the same timer.
Code:

    if(update_display== 60)  // this is TRUE every ~400ms
      {show_display();
       update_display=0;}


These are the steps I would do just in case, of course it would be incomplete but we
do not have enough info of your project. You will see that the program is always running,
with any waiting loops while all the timed events are triggered in background.

I just tried to show you how to do it in a structured and more controllable way,
writting code that will enable you to test it step by step.


Humberto
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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