Discussion in "New Ideas regarding projects" started by    caze    Jun 29, 2008.
Sun Jun 29 2008, 01:02 am
#1
suppose in an industrial application we have to controll some events ,which are time dependent, using microcontroller.

the problem is like : there are 10 deveces . and these devices runs for 10 second (say) if it gets an input
signal.(note : all these 10 devices gets input signals randomly i.e. some times 2 devices may get input signal
,sometimes 4 or 5 or 8 or all 10 etc.)
now suppose if in first time slot (i.e. 10 second) 5 devices are running and before the end of first time slot
another 2 devices gets input signal .... and so on ...

how would u controll it using single microcontroller .


[ Edited Sat Jul 05 2008, 07:02 am ]
Sun Jun 29 2008, 07:32 am
#2

hi caze,

i don't see where you are having problem, can you be more clear


Arun
Sun Jun 29 2008, 08:57 am
#3
Would the devices go off after 10s by themselves or does the micro have to switch them off after the time slot elapses?
Sun Jun 29 2008, 11:27 am
#4
hi Caze

here comes the fundamental RTOS functionalities Semaphores mutex and mutual exclusion.
by using one or more than one or all of the above techniques we can
1. set priorities to the Tasks
2. make other tasks wait for the previous o complete, without missing input signals.
3. store the sequence of inputs in page tables (as in your computer) and then proccess accordingly may be by
a. FIFO or Priority basis or both.


that is the reason most of the industrial automation tenders nowadays necessarily mention RTOS as the main part of the product.

i believe using RTOS will solve the problem, still if ur uController doesnt support it.. u can make the necessary routines yourselves.
:bye
Sun Jun 29 2008, 05:58 pm
#5
hi @ sashijoseph,

devices has to be stoped by microcontroller itself.




Sun Jun 29 2008, 06:02 pm
#6
hi shyam,
great idea. but i guess writing routine for 8051 will be too lengthy and tedious work .

is it possible to
Sun Jun 29 2008, 09:07 pm
#7
yes it can be written

u will find some keil examples with RTX51.
a little effort and u can get the source of the kernel too

ammend it according to ur need and u'll get the solution..
here take a look this is a 51 code!

/******************************************************************************/
/*                                                                            */
/*   TRAFFIC.C:  Traffic Light Controller using the C-51 COMPILER             */
/*                                                                            */
/******************************************************************************/

char code menu[] = 
   "\n"
   "+***** TRAFFIC LIGHT CONTROLLER using C51 and RTX-51 tiny *****+\n"
   "| This program is a simple Traffic Light Controller.  Between  |\n"
   "| start time and end time the system controls a traffic light  |\n"
   "| with pedestrian self-service.  Outside of this time range    |\n"
   "| the yellow caution lamp is blinking.                         |\n"
   "+ command -+ syntax -----+ function ---------------------------+\n"
   "| Display  | D           | display times                       |\n"
   "| Time     | T hh:mm:ss  | set clock time                      |\n"
   "| Start    | S hh:mm:ss  | set start time                      |\n"
   "| End      | E hh:mm:ss  | set end time                        |\n"
   "+----------+-------------+-------------------------------------+\n";


#include <reg52.h>
                    /* special function registers 8052      */
#include <rtx51tny.h>
                 /* RTX-51 tiny functions & defines      */
#include <stdio.h>
                    /* standard I/O .h-file                 */
#include <ctype.h>
                    /* character functions                  */
#include <string.h>
                   /* string and memory functions          */


extern getline (char idata *, char);  /* external function:  input line       */
extern serial_init ();                /* external function:  init serial UART */

#define INIT      0                   /* task number of task:  init           */
#define COMMAND   1                   /* task number of task:  command        */
#define CLOCK     2                   /* task number of task:  clock          */
#define BLINKING  3                   /* task number of task:  blinking       */
#define LIGHTS    4                   /* task number of task:  signal         */
#define KEYREAD   5                   /* task number of task:  keyread        */
#define GET_ESC   6                   /* task number of task:  get_escape     */

struct time  {                        /* structure of the time record         */
  unsigned char hour;                 /* hour                                 */
  unsigned char min;                  /* minute                               */
  unsigned char sec;                  /* second                               */
};

struct time ctime = { 12,  0,  0 };   /* storage for clock time values        */
struct time start = {  7, 30,  0 };   /* storage for start time values        */
struct time end   = { 18, 30,  0 };   /* storage for end   time values        */

sbit  red    = P1^2;                  /* I/O Pin:  red    lamp output         */
sbit  yellow = P1^1;                  /* I/O Pin:  yellow lamp output         */
sbit  green  = P1^0;                  /* I/O Pin:  green  lamp output         */
sbit  stop   = P1^3;                  /* I/O Pin:  stop   lamp output         */
sbit  walk   = P1^4;                  /* I/O Pin:  walk   lamp output         */
sbit  key    = P1^5;                  /* I/O Pin:  self-service key input     */

char idata inline[16];                /* storage for command input line       */


/******************************************************************************/
/*        Task 0 'init': Initialize                                           */
/******************************************************************************/
void init (void) _task_ INIT  {       /* program execution starts here        */
  serial_init ();                     /* initialize the serial interface      */
  os_create_task (CLOCK);             /* start clock task                     */
  os_create_task (COMMAND);           /* start command task                   */
  os_create_task (LIGHTS);            /* start lights task                    */
  os_create_task (KEYREAD);           /* start keyread task                   */
  os_delete_task (INIT);              /* stop init task (no longer needed)    */
}


bit display_time = 0;                 /* flag:  signal cmd state display_time */

/******************************************************************************/
/*        Task 2 'clock'                                                      */
/******************************************************************************/
void clock (void)  _task_ CLOCK  {
  while (1)  {                        /* clock is an endless loop             */
    if (++ctime.sec == 60)  {         /* calculate the second                 */
      ctime.sec = 0;
      if (++ctime.min == 60)  {       /* calculate the minute                 */
        ctime.min = 0;
        if (++ctime.hour == 24)  {    /* calculate the hour                   */
          ctime.hour = 0;
        }
      }
    }
    if (display_time)  {              /* if command_status == display_time    */
      os_send_signal (COMMAND);       /* signal to task command: time changed */
    }
    os_wait (K_IVL, 100, 0);          /* wait interval:  1 second             */
  }
}


struct time rtime;                    /* temporary storage for entry time     */

/******************************************************************************/
/*        readtime: convert line input to time values & store in rtime        */
/******************************************************************************/
bit readtime (char idata *buffer)  {
  unsigned char args;                          /* number of arguments         */

  rtime.sec = 0;                               /* preset second               */
  args = sscanf (buffer, "%bd:%bd:%bd",        /* scan input line for         */
                 &rtime.hour,                  /* hour, minute and second     */
                 &rtime.min,
                 &rtime.sec);
  
  if (rtime.hour >
 23  ||  rtime.min >
 59  ||  /* check for valid inputs      */
      rtime.sec >
 59   ||  args < 2        ||  args == EOF)  {
    printf ("\n*** ERROR: INVALID TIME FORMAT\n");
    return (0);
  }
  return (1);
}



#define ESC  0x1B                     /* ESCAPE character code                */

bit   escape;                         /* flag: mark ESCAPE character entered  */

/******************************************************************************/
/*        Task 6 'get_escape': check if ESC (escape character) was entered    */
/******************************************************************************/
void get_escape (void) _task_ GET_ESC  {
  while (1)  {                                 /* endless loop                */
    if (_getkey () == ESC)  escape = 1;        /* set flag if ESC entered     */
    if (escape)  {                             /* if escape flag send signal  */
      os_send_signal (COMMAND);                /* to task 'command'           */
    }
  }
}


/******************************************************************************/
/*        Task 1 'command': command processor */
/******************************************************************************/
void command (void) _task_ COMMAND  {
  unsigned char i;

  printf (menu);                               /* display command menu        */
  while (1)  {                                 /* endless loop                */
    printf ("\nCommand: ");                    /* display prompt              */
    getline (&inline, sizeof (inline));        /* get command line input      */

    for (i = 0; inline[i] != 0; i++)  {        /* convert to uppercase        */
      inline[i] = toupper(inline[i]);
    }

    for (i = 0; inline[i] == ' '; i++);        /* skip blanks                 */

    switch (inline[i])  {                      /* proceed to command function */
      case 'D':                                /* Display Time Command        */
        printf ("Start Time: %02bd:%02bd:%02bd    "
                "End Time: %02bd:%02bd:%02bd\n",
                 start.hour, start.min, start.sec,
                 end.hour,   end.min,   end.sec);
        printf ("                        type ESC to abort\r");

        os_create_task (GET_ESC);              /* ESC check in display loop   */
        escape = 0;                            /* clear escape flag           */
        display_time = 1;                      /* set display time flag       */
        os_clear_signal (COMMAND);             /* clear pending signals       */

        while (!escape)  {                     /* while no ESC entered        */
          printf ("Clock Time: %02bd:%02bd:%02bd\r",      /* display time     */
                   ctime.hour, ctime.min, ctime.sec);
          os_wait (K_SIG, 0, 0);               /* wait for time change or ESC */
        }

        os_delete_task (GET_ESC);              /* ESC check not longer needed */
        display_time = 0;                      /* clear display time flag     */
        printf ("\n\n");
        break;

      case 'T':                                /* Set Time Command            */
        if (readtime (&inline[i+1]))  {        /* read time input and         */
          ctime.hour = rtime.hour;             /* store in 'ctime'            */
          ctime.min  = rtime.min;
          ctime.sec  = rtime.sec;
        }
        break;

      case 'E':                                /* Set End Time Command        */
        if (readtime (&inline[i+1]))  {        /* read time input and         */
          end.hour = rtime.hour;               /* store in 'end'              */
          end.min  = rtime.min;
          end.sec  = rtime.sec;
        }
        break;

      case 'S':                                /* Set Start Time Command */
        if (readtime (&inline[i+1]))  {        /* read time input and         */
          start.hour = rtime.hour;             /* store in 'start'            */
          start.min  = rtime.min;
          start.sec  = rtime.sec;
        }
        break;

      default:                                 /* Error Handling              */
        printf (menu);                         /* display command menu        */
        break;
    }   
  }
}


/******************************************************************************/
/*        signalon: check if clock time is between start and end              */
/******************************************************************************/
bit signalon (void)   {
  if (memcmp (&start, &end, sizeof (struct time)) < 0)  {
    if (memcmp (&start, &ctime, sizeof (struct time)) < 0  &&
        memcmp (&ctime, &end,   sizeof (struct time)) < 0)  return (1);
  }
                                                
  else  { 
    if (memcmp (&end,   &ctime, sizeof (start)) >
 0  &&
        memcmp (&ctime, &start, sizeof (start)) >
 0)  return (1);
  }
  return (0);                                  /* signal off, blinking on     */
}


/******************************************************************************/
/*        Task 3 'blinking': runs if current time is outside start & end time */
/******************************************************************************/
void blinking (void) _task_ BLINKING  {        /* blink yellow light          */
  red    = 0;                                  /* all lights off              */
  yellow = 0;
  green  = 0;
  stop   = 0;
  walk   = 0;

  while (1)  {                                 /* endless loop                */
    yellow = 1;                                /* yellow light on             */
    os_wait (K_TMO, 150, 0);                   /* wait for timeout: 150 ticks  */
    yellow = 0;                                /* yellow light off            */
    os_wait (K_TMO, 150, 0);                   /* wait for timeout: 150 ticks  */
    if (signalon ())  {                        /* if blinking time over       */
      os_create_task (LIGHTS);                 /* start lights                */
      os_delete_task (BLINKING);               /* and stop blinking           */
    }
  }
}


/******************************************************************************/
/*      Task 4 'lights': executes if current time is between start & end time */
/******************************************************************************/
void lights (void) _task_ LIGHTS  {            /* traffic light operation     */
  red    = 1;                                  /* red & stop lights on        */
  yellow = 0;
  green  = 0;
  stop   = 1;
  walk   = 0;
  while (1)  {                                 /* endless loop                */
    os_wait (K_TMO, 150, 0);                   /* wait for timeout: 150 ticks */
    if (!signalon ())  {                       /* if traffic signal time over */
      os_create_task (BLINKING);               /* start blinking              */
      os_delete_task (LIGHTS);                 /* stop lights                 */
    }
    yellow = 1;
    os_wait (K_TMO, 150, 0);                   /* wait for timeout: 150 ticks */
    red    = 0;                                /* green light for cars        */
    yellow = 0; 
    green  = 1;
    os_clear_signal (LIGHTS);
    os_wait (K_TMO, 200, 0);                   /* wait for timeout: 200 ticks */
    os_wait (K_TMO + K_SIG, 250, 0);           /* wait for timeout & signal   */
    yellow = 1;
    green  = 0;
    os_wait (K_TMO, 150, 0);                   /* wait for timeout: 150 ticks */
    red    = 1;                                /* red light for cars          */
    yellow = 0;
    os_wait (K_TMO, 150, 0);                   /* wait for timeout: 150 ticks */
    stop   = 0;                                /* green light for walkers     */    
    walk   = 1;
    os_wait (K_TMO, 250, 0);                   /* wait for timeout: 250 ticks */
    os_wait (K_TMO, 250, 0);                   /* wait for timeout: 250 ticks */
    stop   = 1;                                /* red light for walkers       */        
    walk   = 0;
  }
}


/******************************************************************************/
/*        Task 5 'keyread': process key stroke from pedestrian push button    */
/******************************************************************************/
void keyread (void) _task_ KEYREAD  {
  while (1)  {                                 /* endless loop                */
    if (key)  {                                /* if key pressed              */
      os_send_signal (LIGHTS);                 /* send signal to task lights  */
    }
    os_wait (K_TMO, 2, 0);                     /* wait for timeout: 2 ticks   */
  }
}
Mon Jun 30 2008, 11:39 am
#8
@Caze
Shyam's method is elegant and the correct way to go.

But you could also use the 8051's 2 timers and 8 external timers(2xLM558) to control all 10 devices.The micro would poll 10 input pins continuously and trigger the timers whenever it detects an input.
Would,by any chance, a device already triggered and yet to complete it's 10s,get another input signal?
Tue Jul 01 2008, 09:18 pm
#9
i feel its no more a challenge if we used external analog timers, in such case we don't need the micro at all because the input signals can trigger the timers which are hard wired (RC network) for 10 sec delay.

the Job can be done without using external timers and using only one internal timer of 8051. after a lot of thought process i have come up with the following approach:


1) wire 10 pins on micro as inputs

2) load timer0 with 50 milliSec values and start timer0

3) wire External interrupt(EX0) pin to all the 10 inputs with help of diodes in such a way that when any of the 10 inputs are received the EX0 pin along with the input pin/s is brought low( logic 0).

4) in the External Int. ISR check which pin/s are grounded and set a flag/s for that particular input pin/s and give output/s (start the device/s)

5) in the timer0 ISR declare 10 counters (use registers/variables) check which flag/s is high( already set high in the Ex int.ISR), if a match is found increment that particular counter/s and reti continue till you reach 200 decimal ( 50mSec X 200 times = 10secs) once the counters reach 200 then stop the device and clear the flag/s

6) even when some devices are running and some other new device/s is triggered the counter for that particular new device is also incremented along with the old running ones

7) all the checking and control is done in ISRs of External int.0 and timer int.0

8) time required for overhead instructions may cause slight delay and therefore normal 12 cycle 8051 clocked @ 12Mhz or 24 Mhz should be avoided for tasks like theses one should use the world's fastest 8051 " DS89C450" clocked at 24Mhz which is 10 times faster than normal 8051 and each instruction takes 40-45 nanosecs and task can be completed with near accuracy.

9) if both the Ex0 interrupt and 50mSec timer int. occur at the same time,by default first the EX0 is serviced followed by timer int.

10) the tick time of 50 msec can be reduced to say 20msec but to get 10 sec delay we would require to count 500 interrupts but the 8 bit counter can count max upto 255D

if interested i can write the code in asm and post it here.


Arun




 cazeiwannischay kumar like this.
Wed Jul 02 2008, 11:46 am
#10

3) wire External interrupt(EX0) pin to all the 10 inputs with help of diodes in such a way that when any of the 10 inputs are received the EX0 pin along with the input pin/s is brought low( logic 0).

Arun Kumar V


ORing the inputs will be better

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

Richardgar
Sat Apr 20 2024, 11:05 am
AntoniaRoons
Fri Apr 19 2024, 09:59 pm
carpinteyrowrl
Fri Apr 19 2024, 02:51 pm
DonaldJAX
Fri Apr 19 2024, 01:08 pm
Lewisuhakeply
Thu Apr 18 2024, 06:00 pm
Darrellciz
Thu Apr 18 2024, 11:07 am
Charlessber
Thu Apr 18 2024, 09:29 am
BartonSem
Thu Apr 18 2024, 04:56 am