Logic

C

Thread Starter

Curt Wuollet

Hi all

I've more or less got the simple demo PLC hacked into shape and will attempt to wrestle it into the archive soon.

It consists of two executables, smio and smdisp. smdisp is the general purpose map displayer hacked into using a shared memory map amd a kludge
to allow forcing of outputs. The shared memory map I am using is not SysV shared mem it is ram excluded from the Linux mm and is reserved by telling the kernel you have 1 mb less than you actually have. mmap() is used to map a struct sized portion of this into user space. The pointer to struct returned by mmap() is used to access the map structure. Dereferencing this
pointer allows us to read and write to the structs in the reserved ram. All this is a lot simpler than it sounds.

The smio executable does the same shared mapping routine, does some things to setup and init the card and then goes into a read, solve, write loop. The two processes use "hit or miss" synchronization for now, if one is using the map, the other busywaits until it is done.

The solve part, the P in plc, is C code for now. We don't have a ladder compiler or a full suite of IEC1131 languages at our disposal (hint)
I'll post this working but horribly terse code tomorrow or Monday. The bad part is that it isn't real useful unless you have a dio48 or
dio48H card. The good part is that the lplc project actually has what is technically a plc available.

As far as the solving part is concerned, I have defined some macros so that we can do code like this:

if( I1 && I3 ) Q13; else !Q13;

That's the part I could use some ideas on. Ladder logic assumes the else clause. It would be nice if we can make that automatic. Or perhaps it is useful to leave an output on. In some places, I'm sure it would be. But, you guys are the control experts. I've attached the defines and the functions they use.

I'll make a tarball for anyone who's interested, I am having line problems again so It'll be probably be tomorrow noon CST till I get it in the archive. If it can wait for a couple of days I can provide some docs.

Also, I'd like to pause at this point long enough where this model is comfy for all. Then we will put Jiri's smm in the middle. This will remain so
that we have a tool to test and develop I/O. Jiri's map model is enough different that user side apps will have to be developed against that. I also need this model for some immediate applications. Doing the logic in C is fine for this as I am not a ladder maven anyway.

Regards

Curt W.

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Curt Wuollet wrote:
> The two processes use "hit or miss" synchronization for now, if one is
> using the map, the other busywaits until it is done.

Can you give a bit more detail?

I find it difficult to imagine how this can reliably work without a real semaphore...

> The solve part, the P in plc, is C code for now.

Yup - so's to one used with the SMM.

> As far as the solving part is concerned, I have defined some macros so
> that we can do code like this:

> if( I1 && I3 ) Q13; else !Q13;

In my interface, that'd be

if (plc_get(I1) && plc_get(I3)) plc_set(Q13,1); else plc_set(Q13,0);

> That's the part I could use some ideas on. Ladder logic assumes the else
> clause. It would be nice if we can make that automatic.

If you don't mind the syntax being backwards, it can be done like this:

plc_set( Q13, plc_get(I1) & plc_get(I3) );

If you define a bunch of simple macros, you can even do:

rung(I1 & I3, Q13);

> Or perhaps it is useful to leave an output on. In some places, I'm sure
> it would be.

Yes - those are the "SET" and "RST" commands in traditional ladder.

> Jiri's map model is enough different that user side apps will have to be
> developed against that.

I think it's actually fairly similar; if there's any reason at all to use this kind of map, the SMM will be easy enough to modify to use it instead.

Like your non-linux memory, shmem is a bunch of functions that, in the end, give you a pointer. You dereference it to access the memory.

The complications begin when you realize you can't have two processes accessing the memory at once - so you have to put in a semaphore. And
because I don't trust the end-user, I hide everything where the end-user can't get at it, and then have to provide all the access functions. Etc.


Jiri
--
Jiri Baum <[email protected]>
Windows is not popular. Windows is *widespread*. Linux is popular.

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
C

Curt Wuollet

Jiri Baum wrote:

> Curt Wuollet wrote:
> > The two processes use "hit or miss" synchronization for now, if one is
> > using the map, the other busywaits until it is done.
>
> Can you give a bit more detail?

I'll do better than that, I'll send you the code (late) tonight. Actually it works ok because the displayer is much slower than the IO loop and you never even notice the waits. The io part has a failsafe to unlock the map in case something dies and leaves it locked. This is advisory locking through the flags int in the struct. I do have one
problem though, the IO part is so fast that without a delay, the displayer never gets the lock. But when I use a usleep that should return in one microsec, more or less, it returns is like 20 _milli_ seconds and we lose the speed. I'll be working on this, but if anyone has a clue why this happens. please speak up. I left it in because we aren't too concerned with speed at this point. Without the delay, I was toggling
outputs at a scan time of 16 microseconds. I'm sure there were gaps for disk update, etc. but that's real fast. I'm also only locking long
enough to do a struct copy to a local struct *zapp = *mapp and a copy back.. this seems pretty fast also.

> I find it difficult to imagine how this can reliably work without a real
> semaphore...

It probably won't with more processes, but if this didn't work UNIX would fall apart.

> > The solve part, the P in plc, is C code for now.
>
> Yup - so's to one used with the SMM.
>
> > As far as the solving part is concerned, I have defined some macros so
> > that we can do code like this:
>
> > if( I1 && I3 ) Q13; else !Q13;

The pre processor really didn't like bangs in a macro name so I had to go to q1 and cq1 for set and clear.

> In my interface, that'd be
>
> if (plc_get(I1) && plc_get(I3)) plc_set(Q13,1); else plc_set(Q13,0);
>
> > That's the part I could use some ideas on. Ladder logic assumes the else
> > clause. It would be nice if we can make that automatic.
>
> If you don't mind the syntax being backwards, it can be done like this:
>
> plc_set( Q13, plc_get(I1) & plc_get(I3) );
>
> If you define a bunch of simple macros, you can even do:
>
> rung(I1 & I3, Q13);
>
> > Or perhaps it is useful to leave an output on. In some places, I'm sure
> > it would be.
>
> Yes - those are the "SET" and "RST" commands in traditional ladder.
>
> > Jiri's map model is enough different that user side apps will have to be
> > developed against that.
>
> I think it's actually fairly similar; if there's any reason at all to use
> this kind of map, the SMM will be easy enough to modify to use it instead.

We can talk about that, it does have the advantage that kernel code (RTLinux).

can access it directly. I'm not so sure about SysV shmem. Your code is about control and abstraction, it didn't look like anything would care much.

Regards and good night (morning) 2:30 AM CST here.

cww


_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Actually, I just realized why it would work - because the way the map is laid out, you don't actually need the locking at all. That's a fluke,
though, and shouldn't be relied upon.

> But when I use a usleep that should return in one microsec, more or less,
> it returns is like 20 _milli_ seconds and we lose the speed. I'll be
> working on this, but if anyone has a clue why this happens. please speak
> up.

That's because whenever you sleep, you give up the CPU and have to wait until you happen to be scheduled again.

This can be fixed by:
- using one of the soft-rt extensions to make the timeslices smaller, or,
- giving the process a higher static priority (if I'm reading the manpage right - sched_setscheduler(2)).


[on mutual exclusion for access to the shared memory]
> > I find it difficult to imagine how this can reliably work without a
> > real semaphore...

> It probably won't with more processes, but if this didn't work UNIX would
> fall apart.

Umm, no, Unix uses real semaphores.

> > > Jiri's map model is enough different that user side apps will have to
> > > be developed against that.

> > I think it's actually fairly similar; if there's any reason at all to
> > use this kind of map, the SMM will be easy enough to modify to use it
> > instead.

> We can talk about that, it does have the advantage that kernel code
> (RTLinux). can access it directly. I'm not so sure about SysV shmem.

I can't see why kernel code should have trouble accessing SysV shmem (especially if we lock it into real memory), but it doesn't matter; as I
wrote, the SMM will be easy enough to modify to use any kind of shared memory.

Don't forget that it also needs a semaphore.

> Your code is about control and abstraction, it didn't look like anything
> would care much.

I'm not sure what you meant here...


Jiri
--
Jiri Baum <[email protected]>
Windows is not popular. Windows is *widespread*. Linux is popular.

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
C

Curt Wuollet

Jiri Baum wrote:

<clip>....
> Actually, I just realized why it would work - because the way the map is
> laid out, you don't actually need the locking at all. That's a fluke,
> though, and shouldn't be relied upon.
>
> > But when I use a usleep that should return in one microsec, more or less,
> > it returns is like 20 _milli_ seconds and we lose the speed. I'll be
> > working on this, but if anyone has a clue why this happens. please speak
> > up.
>
> That's because whenever you sleep, you give up the CPU and have to wait
> until you happen to be scheduled again.
>
> This can be fixed by:
> - using one of the soft-rt extensions to make the timeslices
> smaller, or,
> - giving the process a higher static priority (if I'm reading the
> manpage right - sched_setscheduler(2))

Smaller timeslices might be the answer as we want the displayer to get slices too. I'm gonna play with non-sleeping delay like ins and outs. I really need a dso so I can see what scheduling does to us.

> [on mutual exclusion for access to the shared memory]
> > > I find it difficult to imagine how this can reliably work without a
> > > real semaphore...
>
> > It probably won't with more processes, but if this didn't work UNIX would
> > fall apart.
>
> Umm, no, Unix uses real semaphores.

That depends on where you look :^)

> > > > Jiri's map model is enough different that user side apps will have to
> > > > be developed against that.
>
> > > I think it's actually fairly similar; if there's any reason at all to
> > > use this kind of map, the SMM will be easy enough to modify to use it
> > > instead.
>
> > We can talk about that, it does have the advantage that kernel code
> > (RTLinux). can access it directly. I'm not so sure about SysV shmem.
>
> I can't see why kernel code should have trouble accessing SysV shmem
> (especially if we lock it into real memory), but it doesn't matter; as I
> wrote, the SMM will be easy enough to modify to use any kind of shared
> memory.
>
> Don't forget that it also needs a semaphore.
>
> > Your code is about control and abstraction, it didn't look like anything
> > would care much.
>
> I'm not sure what you meant here...

Once we have a chunk of sm and a pointer, it doesn't matter much where it came from.

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Curt Wuollet:
> Smaller timeslices might be the answer as we want the displayer to get
> slices too. I'm gonna play with non-sleeping delay like ins and outs. I
> really need a dso so I can see what scheduling does to us.

Non-sleeping delays won't give the other processes any time at all.

Curt Wuollet:
> > > Your code is about control and abstraction, it didn't look like
> > > anything would care much.

Jiri Baum:
> > I'm not sure what you meant here...

> Once we have a chunk of sm and a pointer, it doesn't matter much where
> it came from.

Right.

Yup, should be easy enough to plug any other kind of shared memory in there (and any other kind of semaphore).


Jiri
--
Jiri Baum <[email protected]>
Windows is not popular. Windows is *widespread*. Linux is popular.

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
B
At 08:11 PM 6/24/2000 -0500, you wrote:
>As far as the solving part is concerned, I have defined some macros so that
>we can do code like this:
>
>if( I1 && I3 ) Q13; else !Q13;
>
>That's the part I could use some ideas on. Ladder logic assumes the else
>clause. It would be nice if we can make that automatic. Or perhaps it is
>useful to leave an output on. In some places, I'm sure it would be. But, you
>guys are the control experts.

What I have done when emulate a PLC in C is turn off all output image points before the scan, then the logic will turn on the ones that are supposed to be on. This eliminates the else condition, but it makes latched outputs difficult. Most people do not like latched outputs anyhow.

Bill Sturm

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Curt Wuollet (I think):
> >if( I1 && I3 ) Q13; else !Q13;

> >That's the part I could use some ideas on. Ladder logic assumes the else
> >clause. It would be nice if we can make that automatic. Or perhaps it is
> >useful to leave an output on. In some places, I'm sure it would be. But, you
> >guys are the control experts.

Bill Sturm:
> What I have done when emulate a PLC in C is turn off all output image
> points before the
> scan, then the logic will turn on the ones that are supposed to be
> on. This eliminates
> the else condition, but it makes latched outputs difficult. Most people do
> not like
> latched outputs anyhow.

The way to have both is with a couple of #defines, like this:

/* normal rung - if X is true it turns Y on, otherwise turns Y off */
#define rung(X,Y) plc_set(Y,X)


/* latch (unlatch) rungs - if X is true, turns Y on (off) */
#define latch(X,Y) do {if (X) plc_set(Y,1);} while (0)
#define unlatch(X,Y) do {if (X) plc_set(Y,0);} while (0)

/* input points */
#define I1 plc_get(pt_I1)
#define I2 plc_get(pt_I2)
...

/* output points don't need #defines */
plc_pt_t Q1, Q2, Q3, ...;

...

rung(I1 & I2, Q13);
latch(I3, Q14);
unlatch(I4, Q14);


Notes: (1) While strictly speaking you should use & rather than &&, I think either will work in practice. Has anyone ever met a compiler for
which (1&&1)&1 is zero? Don't think so...
(2) Actually, the points will probably be better defined as I(1), Q(13) etc, by someone familiar with the pre-processor stringification
operators.
(3) You can only have one output on each rung. I can't see how to solve that easily.


Jiri
<[email protected]>

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Apparently I did this wrong last night, so I am trying again. I posted a reply on the Control.com site which doesn't make it back to this thread. So if someone moved the message and this is a repeat, I am sorry.

Here is my 2 cents on how I have solved some of the problems you are grappling with. You are welcome to use any of the concepts or ignore them
as you see fit.

As far as shared memory goes I recommend splitting it up into 3 separate parts with fixed read/write and read only access definitions. The first part is a message/command buffer that goes from applications to the PLC code. It is read/write from the application side, read only from the PLC side. A similar block that goes from the PLC to the application side, PLC gets read/write, the application gets read only. The use of the buffers is managed by a command/response protocol and both PLC and Application can send "requests" and respond to the same. It might be good to use a sequence number for each command so that responses can be paired back up.

The third section of shared memory should have the shadow copies of the I/O, internal memory, and ideally have the instructions for the ladder/flow chart logic. This section is read/write by the PLC and read only by the
application whenever the PLC is in "run" mode. When the PLC portion is stopped it could be written by anybody assuming that that doesn't cause too many problems with the shared memory manager, otherwise it is always read only by the application and it gets filled using the command/response buffers described above.

A few years ago I was stuck in the field for an extended time and needed something to do with my evenings so I decided to learn C++ by writing a
simulation of the process I was implementing. This is how I did the PLC ladder logic portion of the simulation. I can't reuse the original code
(and wouldn't want to) but the concepts are freely available (we actually ended up selling the program to the customer for use as a training aid).

I created memory block objects (files) similar to the A-B PLC3 and PLC5 processors. Attached to these files (objects) were in line functions to
read and write bits, bytes, and words which were implemented as in line functions. Essentially, the actual data was private inside the object,
with interface routines to access it. This probably cut the debugging time to a fraction of what it could have been. The objects were linked together on a list and consisted of an ID, file type (a PLC5 has a file of just bits), and a file size.

The memory operations consisted of calling the operation desired from the first file on the linked list, providing a file ID, a word offset, and, depending on the operation, a bit offset and a current rung logic state (true or false). The current state was used when I did a rung of ladder logic, at the beginning of the rung I set the state to true. For each successive operation, if the current state was false a bit read or compare operation would return false always. If the current state was true, it
returned the state of the operation. For bit write operations, the current state was just written into the bit and then it also returned the current state. The in line functions should also take care of managing the OS for doing an uninterrupted read/modify/write if required which I didn't need.

The ladder logic was compiled C++ but in reality it was implemented as calls to the memory objects, all chained together. My intent was to
eventually abstract this level and turn it into an interpreter. The ladder logic portion of the implementation consisted of 2 additional objects, the first was a start rung object which managed each rung. The second was a rung element which took care of calling each memory access, the last
element of a rung didn't link to another one. Everything was linked lists and for my implementation (no it wasn't the most efficient) I called the first rung of a program and the rung/ladder elements walked its way through the program doing function calls

A parallel rung object was defined but I never finished it. It essentially mimicked the start rung but took the current state of the rung and if any parallel branch returned true it was anded with the current state and that was passed to the remaining part of the rung.

The scarry part with all this is that it just worked. I think it took about 2 evenings to write the ladder logic portion after I had decided on the basic structure. The reason it went so fast was that once I had the base classes defined (essentially 3, start rung, rung element, memory access) I was done. It took longer once I started adding memory moves and compares and other stuff but it scaled very easily.

As far as performance, I think the in line functions may have saved the day since the code got passed all the way through the compiler. I never actually measured the performance of the ladder logic portion by itself. The code was part of a much larger simulation which simulated a factory automation project. The whole simulation took about 200msec on a 33Mhz 386 under DOS as long as there weren't too many debugging options turned on, writing to the display significantly impacted the performance. The whole simulation was implemented using linked lists of objects similar to the approach described above for the ladder logic and
included simulation of 2 serial Data Highway interfaces, 14 PLCs, and a host of processing simulations, including sorters. The micro VAX that hooked to it never suspected it wasn't talking to the factory floor. The code fit into about 400K and was written in Turbo C++.

If this is helpful great. If you have questions, I can get more specific.

Tom Bray


_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
R

Ralph G. McDonald

Bill Sturm wrote:
"This eliminates the else condition, but it makes latched outputs difficult. Most people do not like latched outputs anyhow. "

I find latched outputs very useful in setting states for programs for chemical pilot plants for one of my clients. They allow the program to be backed up if necessary by the operator. Used in this manner you can combine features of a "state" machine within a standard ladder logic program. They also work very well in alarm logic were multiple rungs in various subroutines may "Set" an alarm but it can only be "Reset" by a specific alarm reset routine after operator acknowledgement. It might be ok to eliminate them in an early test version of the LinuxPLC but I think they need to be included in the "finished" product.

Ralph McDonald


_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
C
Hi Tom

Do you write C? We can use both ideas and code. If you want to help us change the closed, proprietary, automation world by providing a free, community owned alternative, we are glad to have you. We also have many who lurk, providing guidance and advice. Right now we could use a ladder compiler that produces C output. Jiri has something cooking on this. We had tons of discussion on RLL before we were ready for it, but it's pretty quiet now.

In any case, Welcome to the list. and feel free to join in!

Regards

Curt W.


_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
C
Hi Ralph

Bill's idea for turning outputs off works ok even for latched outputs when done on a private map with the solver tracking which are latched. That way latched outs are simply turned on again before updating the main map. One of the attributes we will want to maintain on the outputs will be a latch bit. Thanks for your input. Your state machine simulation is interesting also.

Regards

cww


_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
B
If we use my original idea of clearing the output image table before each logic scan, then I thought
of a very simple way to accomplish latched outputs. Actually, I think an AB PLC uses the same method for its forced outputs.

We could have a latch table that is the same size and layout as the output image table. We then
set a bit in the latch table if we want the output to be persistent. Before we write the output image to the physical I/O, we OR the output image with the latch image. This way,
any bit we like can be set true until we reset it.

Does this help?

Bill Sturm


_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Bill Sturm:
> >"This eliminates the else condition, but it makes latched outputs
> >difficult. Most people do not like latched outputs anyhow. "
Ralph McDonald:
> >I find latched outputs very useful in setting states for programs for
> >chemical pilot plants for one of my clients.
... Bill Sturm:
> If we use my original idea of clearing the output image table before each
> logic scan, then I thought of a very simple way to accomplish latched
> outputs.

I'm still not sure I understand what the problem is with the "else clause".

A normal stepladder rung does *not* map to a C "if" statement. It maps most closely to an assignment statement, like this:

output = condition;

Now, we can't (easily) write it like that in C, so instead we say,

plc_set(output, condition);

An "if" statement corresponds most closely to a latch rung:

if (on_condition)
plc_set(output,1);

The corresponding unlatch rung would be:

if (off_condition)
plc_set(output,0);

Does that make sense or am I missing something obvious?

Jiri
--
Jiri Baum <[email protected]>
Windows is not popular. Windows is *widespread*. Linux is popular.

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
B
At 06:09 PM 7/3/2000 +1000, you wrote:
>I'm still not sure I understand what the problem is with the "else clause".
>
>A normal stepladder rung does *not* map to a C "if" statement. It maps most
>closely to an assignment statement, like this:
>
> output = condition;
>
>Now, we can't (easily) write it like that in C, so instead we say,
>
> plc_set(output, condition);

In most PLC's, if you do not explicitly turn on an output, then it will turn off automatically.
You must either have true logic for the output in the current scan, or you must use a set/reset type of instruction if you want an output to stay on. This is done partly for safety reasons, I think. It probably seems awkward to a computer programmer, but you get used to working and thinking this way. It is actually convenient that one rung will both turn on and off an output.

I have done the same when using "C Ladder" in my own programs. I chose the PLC scan model for some of my C programs. I found that using an else statement to turn off the outputs was a lot of extra typing and it did not accurately emulate the PLC.

I hope this clears things up,

Bill Sturm

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
> At 06:09 PM 7/3/2000 +1000, you wrote:
> >I'm still not sure I understand what the problem is with the "else clause".

> >A normal stepladder rung does *not* map to a C "if" statement. It maps
> >most closely to an assignment statement, like this:

> > output = condition;

> >Now, we can't (easily) write it like that in C, so instead we say,

> > plc_set(output, condition);

Bill Sturm:
> In most PLC's, if you do not explicitly turn on an output, then it will
> turn off automatically.

OK, I've never met this.

The way I've always seen it is that "a rung that is false will turn off its output".

> You must either have true logic for the output in the current scan, or
> you must use a set/reset type of instruction if you want an output to
> stay on.

OK.

Then again, normally, all rungs are evaluated every scan, so any outputs on them will be turned on or off as appropriate.

It only makes any difference if you have a jump or branch in a program, or if you change the program mid-execution.

> It is actually convenient that one rung will both turn on and off an
> output.

Well of course!

That's what the "plc_set(output, condition);" thing does, too - when the condition is true, it turns the output on, otherwise it turns it off.

I think once again the words got in the way of communicating...

> I have done the same when using "C Ladder" in my own programs. I chose
> the PLC scan model for some of my C programs. I found that using an else
> statement to turn off the outputs was a lot of extra typing and it did
> not accurately emulate the PLC.

Well, you shouldn't be using C "if" statements for ladder rungs. That's not what ladder rungs are. But I can see why you'd do it that way if, for some reason, you had to use them.


Jiri

footnote: technically, the second argument of plc_set is an integer, not a condition (so you should use the bitwise & and | rather than the logical && and ||), but that's not important now.
--
Jiri Baum <[email protected]>
Windows is not popular. Windows is *widespread*. Linux is popular.

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
> I used the if for the sole reason of having the else.

Hunh?

You used "if" to have the "else", but then you just used the else to turn off the same output that the "then" turned on.

But that's what the "plc_set(output, condition);" syntax does...

You'd probably want to define a simple macro, so you can instead say
rung(condition, output);


> It really won't matter much how they are implimented if you're gonna
> write in IL. or another symbiology that gets translated to function
> calls.

True. Still, it'd be a good thing to have in the tutorial for the people who want to write in C but don't really think in C very well (or haven't
thought through the implications of stepladder).


Jiri
--
Jiri Baum <[email protected]>
Windows is not popular. Windows is *widespread*. Linux is popular.

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Hello All,
This is my first posting to the list, I 've been lurking for about a week.

If anyone has experienced "Think n' Do" they would know outputs get latched automatically, which can leed to some confusion during
debugging. For instance if you have a descision block and the "Y" is pointing to a control block that energizes a coil, and you don't have
the "N" of the Descision pointing to a control block that de-energizes the coil, the coil will stay energized, even when the next scan doesn't
bring you through the "Y" output of the descision block.

Of course people will write telling me to de-energize the coil with the output "N" of the output "N" of the descision block (some might even
tell me to spell check my posts) but that's not the point... The point is, some vendors have implemented output latches explicitly.

There is the other side of the coin, where last I checked, Koyo (PLC Direct) didn't have a latched output function at all.

I liked the idea of four or more MMs for the application, where one is the Virtual table one was the I/O table, one was a force table and one
was the latch table. For inputs, you OR the I/O and the force table store the result in the Virtual table, scan the "ladder". For outputs
you XOR the virtual, force and latch tables then store the result in the I/O table. This of course would be a problem with the analog values.

What I would like to contribute to this project is a driver I wrote for the Computer Boards CIO-QUAD 4 board (4 encoder inputs). I bought the
board before that had support for it in their Universal Library. I haven't downloaded the code base to look how it might be implemtented. I am assuming we are accessing boards using iopl(2) instead of compiling the drivers into a kernel? What would the API look like for this board?

Blair

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Top