Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

(very) basic program flow control question

Status
Not open for further replies.

Mark_R

Member
Hi,

I'm an accomplished ladder logic programmer trying to transition to embedded micro controllers. I'm struggling with the basic concept of program flow control. I have avoided C/Basic/Etc. like the plague, but the project at hand is forcing me in that direction.

In ladder logic, the ladder scans continuously, updating rungs as it goes. If there is a timer running, or some other task / condition pending on a rung, program execution moves on. The rung gets re-visited on the next scan and so on. The point is, multiple things can be happening simultaneously.

In C, BASIC whatever, I'm missing the big picture here.

An example of somthing we have built with a PLC;
Let's say I have a machine that controls a widget filler and has a serial modem for reporting status.
The widget filling is ongoing, one widget after another, I can visualize this code well enough.
Now, lets say I need to send information out of the modem, I branch to a loop to open the serial port and initialize the modem, now I need to wait for the modem to open a port and reply ready, so I loop until success or error comes in on the receive buffer. Let's say this takes 20 seconds, What about the widgets? has production stopped? Are they overflowing?

It seems to me that only one thing can happen at once and if one has to wait for an event then everything else has to stop. This can't be the case.

I don't get it, and I can't seem to find the answer. :confused:

Anyone?

Thanks.
 
Last edited:
Hi,

I'm an accomplished ladder logic programmer trying to transition to embedded micro controllers. I'm struggling with the basic concept of program flow control. I have avoided C/Basic/Etc. like the plague, but the project at hand is forcing me in that direction.

In ladder logic, the ladder scans continuously, updating rungs as it goes. If there is a timer running, or some other task / condition pending on a rung, program execution moves on. The rung gets re-visited on the next scan and so on. The point is, multiple things can be happening simultaneously.

In C, BASIC whatever, I'm missing the big picture here.

An example of somthing we have built with a PLC;
Let's say I have a machine that controls a widget filler and has a serial modem for reporting status.
The widget filling is ongoing, one widget after another, I can visualize this code well enough.
Now, lets say I need to send information out of the modem, I branch to a loop to open the serial port and initialize the modem, now I need to wait for the modem to open a port and replay ready, so I loop until success or error comes in on the receive buffer. Let's say this takes 20 seconds, What about the widgets? has production stopped? Are they overflowing?

It seems to me that only one thing can happen at once and if one has to wait for an event then everything else has to stop. This can't be the case.

I don't get it, and I can't seem to find the answer. :confused:

Anyone?

Basically two options, one is to use interrupts, the other to use looping and polling.

Either would be fine for your application, mechanical processes like widget filling are extremely slow, and micro-controllers run extremely fast.

Opening your serial port might take a few micro-seconds, and sending each byte can take less than that (if using the hardware UART - as you just feed it the byte, and it's send automatically).

It's a question of understanding how long you've got to do things, and not sitting in a permanent loop waiting for something to happen.

For example - you've got a loop waiting for a switch to be pressed - if the switch is never pressed the loop will never complete. In this situation the other processes could be interrupt driven, or just polled every so many times through the loop - crude 'code' like this:

Code:
While Switch not Pressed
    X=X+1;
    If X = 10 then Begin
        Gosub Check for something else;
        X=0;
    End;
Wend
 
So typically the main program loop is quite short?
I guess I'm still thinking like a ladder programmer where you typically cycle through most of your program but only act on the active parts.
 
Mark,

Please show me a "typical" ladder logic diagram like the kind you would want to run on a PIC? Inputs, Time(on), Time(off), LED output, Serial output, Control Relays, etc.

Please humor me. I'm very interested. I used to work with AB and Modicon PLCs many many years ago.

Regards, Mike
 
Mike,

Here is a typical project for us, granted, this is far more complicated than something I would be trying to implement in a uC, but It's something to look at.

To understand whats going on;
This is molding / heat seal machine, The plates have mold cavities which the sheet plastic is pulled into via vacuum, the nozzle meters out a 2-part mix (+/- 1%), the size and ratio varies based on the "recipe" selected.
The two hand buttons clamp the press to seal and bake the part and a count down timer begins. After the timer counts down, the mold opens.
All the while the four mold plates are maintaining heat +/- 1.5 degree via PID loops. (no external temperature controllers, PIDs are part of the PLC) There are other secondary functions such as temperature deviation alarms, temp probe averaging, probe fail indication, auto heat start via real time clock/timer, finished parts counters, prototype mode, storage of 20 recipes, etc.

I have to leave the office today but I'll try to whip up a ladder equivalent of what I'm trying to implement in the embedded controller.
 

Attachments

  • Ladder View.pdf
    144.2 KB · Views: 304
  • DSC_0246.JPG
    DSC_0246.JPG
    544.2 KB · Views: 238
Last edited:
I use a cooperative multitasking type system when I write code for most of my projects. Here is a post I made in another thread which details how to implement the co-op multitasking system.

Basically, what you'd need to do here to utilize a modem is add something like the following:

modem.c
Code:
void Service_Modem( Uint8 cmd, Uint8 *data, Uint8 length )
{
static Uint8 modem_state = MODEM_IDLE;
static Uint8 out_data[100];
static Uint8 in_data[100];
static Uint8 out_len = 0;
static Uint8 in_len = 0;
static Uint8 i;
Uint8* response;

   switch (modem_state)
   {
      case MODEM_IDLE:
         switch (cmd)
         {
            case CMD_OPEN_MODEM:
               modem_state = OPEN_MODEM;
               i = 0;
               sprintf(out_data, "whatever command you send to the modem to open it\r\n");
               out_len = strlen(out_data);
               break;
            
            case CMD_CLOSE_MODEM:
               modem_state = CLOSE_MODEM;
               break;

            case CMD_SEND_DATA:
               memcpy( out_data, data, length );
               out_len = length;
               modem_state = SEND_DATA;
               break;
         }
         break;

      case OPEN_MODEM:
         Open_Modem( OPEN_MODEM );
         modem_state = WAIT_FOR_OPEN_MODEM_RESPONSE;
         break;
         
      case WAIT_FOR_OPEN_MODEM_RESPONSE:
         result = Open_Modem( TICK );
         if (result == TRUE )
            modem_state = MODEM_IDLE;
         break;

     case SEND_DATA:
         if ((i != out_len) && (uart_tx_buffer_is_empty))
         {
            tx_modem_uart( out_data[i] );
            i++;
         }
         else if (i == out_len)
         {
            modem_state = MODEM_IDLE;
            in_len = 0;   // we just sent data, clear the rx buffer
         }
         break;
   }
}

Uint8 Open_Modem( Uint8 cmd )
{
static Uint8 out_data[100];
static Uint8 in_data[100];
static Uint8 in_len;
static Uint8 out_len;
static Uint8 i;
static Uint8 state;
static Uint8 modem_is_open = FALSE;

   switch (state)
   {
      case IDLE:
         switch (cmd)
         {
            case CMD_OPEN_MODEM:
               if (modem_is_open == FALSE)
                  state = OPEN_MODEM;
               break;
 
            case CMD_TICK:
               break;
         }
         break;

      case OPEN_MODEM:
         if ((i != out_len) && (uart_tx_buffer_is_empty))
         {
            tx_modem_uart( out_data[i] );
            i++;
         }
         else if (i == out_len)
         {
            in_len = 0;
            modem_state = WAIT_FOR_OPEN_RESPONSE;
         }
         break;

      case WAIT_FOR_OPEN_RESPONSE:
         if (uart_rx_buffer_has_data)
         {
            in_data[in_len] = uart_rx_data;
            in_len++;
            state = IDLE;
         }
         
         if (strcmp(in_data, "OK\r\n", 4) == 0)
            modem_is_open = TRUE;
         break;
   }
   
   return modem_is_open;
}

I have to go to work now otherwise I'd try to flesh it out some more. But as you can see, it uses state machines to remember what is going on in the modem code. It doesn't spin in a loop waiting for the modem to response with OK, it comes and checks on it later.
 
Mark,

C or any procedural language can work in much the same way as ladder programming.

A main loop checks each task in turn and activates it only if the task is ready to run. It could be waiting on a timer or blocked waiting for IO. In either of these cases it is skipped.

A while back I wrote a detailed tutorial illustrating ) but it can easily be used with any working PIC.

coop-jpg.34850

3v0
 

Attachments

  • coop.jpg
    coop.jpg
    95.6 KB · Views: 397
Last edited:
Mark,

Thank you for the program example. Seems the features and capabilities of these PLCs has evolved quite a bit from my experience with them some 35 years ago as an Electrical Field Service Engineer for a material handling company. I look forward to studying it and will try to offer some program flow suggestions as I become more familiar with it.

Regards, Mike
 
Mark,

Thank you for the program example. Seems the features and capabilities of these PLCs has evolved quite a bit from my experience with them some 35 years ago as an Electrical Field Service Engineer for a material handling company. I look forward to studying it and will try to offer some program flow suggestions as I become more familiar with it.

Regards, Mike

If you really want to wade through 200 rungs of logic, you should know;
X are (real world) inputs
Y are outputs
GX are inputs from the HMI (touchscreen buttons)
C are "coils" (internal software bits)
T are timers (resolution in tenths of a second)
TA are timer accumulators (the memory location of the associated timers current value)
V are word length memory locations
B is one bit-of-word
if you see "K" that is a constant value.

Don't forget, this is not the logic I'm trying to implement in a uC, just a (far more complicated) example.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top