suggestions for enhancements to webcontrol (not 32)

Another suggestion would be "edge detection" mneumonic. I see frequently here discussions and inordinate complexity to detect the start or end of an event. You already have the non-blocking timers on inputs, outputs and vars, so you must be saving some state information. Perhaps some small variation to the existing code could be used for Rising or Falling edge (or simply detecting a change of state and using the logic to work out which way it is??)

tsteq IP1[E] 0 test input1 is first detected going from high to low (falling edge)
tsteq IP3[E] 1 test input 3 is first detected going from low to high (rising edge)

Thanks for your suggestion, Ross. There are total four certain I/O pins can detect edge change, but that require to have interrupt to handle them. Which means when state changing, it will interrupt then software to determine if input is accepted. That will be a slower process. Current hardware does not have them in the input. Also, we need to make sure those interrupts are not used by anything else. We will take a note of this and plan to do that in the future.

What is the purpose of this edge detection? I am sure what you wanted is something interesting. If we know the purpose, we can better assist you.
 
Thanks for your suggestion, Ross. There are total four certain I/O pins can detect edge change, but that require to have interrupt to handle them.
I wasn't suggesting going down to that hardware level :)

What is the purpose of this edge detection? I am sure what you wanted is something interesting. If we know the purpose, we can better assist you.
I've seen it here on the forum time and again, and encountered it dozens of times with other people I've sent boards to.
I've had it myself - and there's an active thread running...

Wanting to detect when a button is pressed, or when an event happens - humidity gets too high, or too low, and sending an email. But ONLY sending an email ONCE - not every scan while the condition exists.

Yes, there are techniques to work around it - and we all have to use them - but wow, wouldn't it be nice to be able to do (for example)

tsteq ip1[E] 1 # Has input 1 just gone high?
gosub something # go do input 1 active code
.... and get on with the rest of your life

No needing to code additional tests, or use more registers as flags to note that you've done it already etc!
 
TTL input and outputs already have the non-blocking delay.
It is interesting that you described that, so humidity has direction and value, email has send state. I need to understand better before I can present to our programming engineers.

The example you described is already functioning in the firmware:
tsteq ip1[E] 1 # Has input 1 just gone high?
gosub something # go do input 1 active code
.... and get on with the rest of your life
 
The example you described is already functioning in the firmware:
tsteq ip1[E] 1 # Has input 1 just gone high?
gosub something # go do input 1 active code
.... and get on with the rest of your life

No, the non-blocking delay will CONTINUE to return TRUE as long as the condition remains.
That's why people have to jump through hoops to detect that they have already acted on this event and NOT do it again.
What I'm proposing is a "has just changed" detection.
If we've just changed (WAS 1 and is NOW 0) - and the level NOW is 0, then it's been a falling-edge.
If we've just changed (WAS 0 and is NOW 1) - and the level NOW is 1, then it's been a rising-edge.

So it's not quite the same as your non-blocking delay, but it could very likely use much of the same code and storage as your non-blocking timers to detect the FIRST TIME an input changes state.
 
I am not sure I understand how do you propose to present this in PLC logic, how to configure it in web GUI. Then we will think about if that is possible to do.
 
I am not sure I understand how do you propose to present this in PLC logic

I proposed using a non-numeric argument for the non-blocking timer.
This:
start
tsteq ip1[1000] 1
email em1
set op1 ip1
end

output 1 will follow input 1. An email will be sent one second after input 1 goes high, but will CONTINUE TO SEND EMAIL WHILE INPUT 1 IS HIGH.
Currently, in order to prevent this the programmer must set a flag after the email is sent, and then check that flag again each time to see if the mail has already been sent - and clear the flag when the condition clears. Not so bad for one event, but TEDIOUS for lots.

My suggestion is that the "non-blocking delay code" be extended so the programmer can query if the variable or IO has changed state SINCE LAST CHECKED. This is not the same as a hardware edge-detector. It is in SOFTWARE - so when you come to the test, it can see if the CURRENT state is the same as (or different to) the LAST state. Ie, "EDGE"

start
tsteq ip1[E] 1
email em1
set op1 ip1
end

In this construct, the 'E' (only a suggestion) would mean "Edge" or "Change of state". The test would be the logical "and" of "Has this input changed state" AND "is this input now 1". If the two are true, then the result is true. So when input 1 (in this example) goes high, an email is instantly sent - but (and this is where it is different) - it will NOT CONTINUE TO SEND. The input would need to go low again, and then go high again before it would re-trigger.

This would make for far more efficient and logical coding.


, how to configure it in web GUI. Then we will think about if that is possible to do.
There is nothing to put in the GUI.
 
This is kind of confusing to me. E is a hex code for decimal 14. What if I want to know the ip state both high and low and perform different tasks, just state change does not tell me if the door is open or close. I think a lot of times the email sending depend on different situations to allow send again, nost just simple the state change again on input. For example, when a critical situation happened, I would like to send out one email every miniute once until the pronblem fixed.
 
This is kind of confusing to me. E is a hex code for decimal 14.
Sure, use "EDGE" or something then. It doesn't matter what colour it is, it's the function that matters!

What if I want to know the ip state both high and low and perform different tasks, just state change does not tell me if the door is open or close.
Yes, but the second part of the test - 0 or 1 - is. If you detect a change-of-state, you know you may have to do something.
If the state is NOW logic 0, and it's just changed, then it must be (by definition!) a falling edge.

So you could test [EDGE] 1 and do something because the button has just been pressed
and do something completely different when you see [EDGE] 0 because that is the release.

I'm not going to try to teach people to program, I'm offering a suggestion for a new primitive that would greatly assist people who can.
 
Ross,

When you say edge change, supposedly we create another variable to remeber that input state changed.
However, how long do you think this edge change stays, for example, half hour late, checking the input state still edge changed?
Also, how do you distinguish the edge state changing after the first time the edge state change? For example, I pushed button twice before your code checked.

Thanks for taking the time to discuss, with customers' help we will make it a better product. .
 
When you say edge change, supposedly we create another variable to remeber that input state changed.
However, how long do you think this edge change stays, for example, half hour late, checking the input state still edge changed?

How are you doing the non-blocking timer now? I (presume) you are storing the time of the last (identified) transition, so you can then see if it's been (in its current state) for whatever period the user specifies. If that's the case, you already have most of the information right there.
If I were doing the job, I would maintain one more bit field per I/O or var, and that would be the state on last "check". So whenever the PLC code reads the status of the input, you update the bitfield. All you need do is a simple XOR of the bitfield and the I/O BEFORE updating it, and you have an indication if it has changed or not.

Also, how do you distinguish the edge state changing after the first time the edge state change? For example, I pushed button twice before your code checked.

I wouldn't bother. If the user code is too slow to get around the loop, then there are far greater problems :)
If its something likely to happen that quickly, you have given us a counter (hooray!).
 
The problem is that when we check the bit for the "edge changed", we will always see "1', after the first edge change. Because from then on, no matter input from zero to one or one to zero, the state chagne is always true. Are you saying clear that bit each time that bit is accessed?
 
The problem is that when we check the bit for the "edge changed", we will always see "1', after the first edge change. Because from then on, no matter input from zero to one or one to zero, the state chagne is always true. Are you saying clear that bit each time that bit is accessed?

No, I'm suggesting XORing the current input state to the SAVED STATE, and using that XOR result as the "changed state" indicator. Then, saving the current state of the input for the next time you come back to check. This has to be in the part of the PLC code that checks the input, not the background scheduler that reads the inputs (if indeed there is one)
 
I/O state is on scheduler being checked all the time does not matter PLC call it or not, because there users only use this board for I/O purpose.
 
I/O state is on scheduler being checked all the time does not matter PLC call it or not

Yes, I accept that. But the PLC core code reads your (seperately buffered) I/O right? That is, as you are actually executing the users program it must "do stuff". For example, if I were to code tstle ip1[1000] 1 there is some code that has to do *SOMETHING* to determine if input 1 has been high for at least the last 1000 milliseconds.

It's HERE that the code would instead, check the *CURRENT* I/O state and compare it to a flag that stores the what the I/O state was LAST TIME IT CHECKED. It does not require any interaction with the actual, physical input. No change to the scheduler. Just see what the current view of the input is. And comparing that to a copy of the state - only available to this part of code.

And..... then once it's made this comparison, it copies the current view of the input (again, from your buffered/scheduler updated information) to the local copy.

It's probably easier to do it in flowchart - I'm too busy at the moment, but will try to make some time shortly to do one.
 
Another thought struck me this morning. I had been considering replacing my old generator controller with a webcontrol board. It has two major limitations in this application though.
1. I really want a display. Even just a 4x20 LCD char display. I'd rather not have to resort to LED indicators.
2. I really need to record total run time - nonvolatile.

The user variables, stored in FLASH or EEPROM or whatever - through the GUI would be fine if they were under PLC control. I know, if someone were to write code that constantly wrote that memory it would be terminal in short order.... but there it would be highly useful if used properly.

Let me give you an example. My current controller, build with an atmel 90S8535 also has a very limited write cycle on its memory. Yet I have been running my controller now for 7 years, 24 hrs a day, 7 days a week. It's up around 9,000 hours run time. I achieve a happy medium by only updating the engine-hours non-volatile storage every time the generator stops - so it's had around 3500 start/stops. I'd like to see the option to write to this memory under program control - even if you put a great big red disclaimer and warning around its use - sure, it COULD kill the board, but if used properly it would be well worth having!

Finally - would it be excessively difficult to enable read/writing of RAM variables via the cgi interface?
 
Back
Top