using <> in omron PLC - plc

I have a <>305 in my ladder logic like so
<> D19720 D3890
then after it i have a less then and a greater then like so
cf002 cf005
What it does is checks the encoders current value (d19720) with a stored value(d3890) To make sure they are the same value. Due to it being an encoder it would not take much for the value to be + or - 2 .
Is there any way i can keep the above code but say if its greater or less then current number +/- 4 ?
thus if the stored value is 500 , then the greater then would not come on untill 504 and the less then would not come on till 496

Sure. What I usually do when I need an output on over an encoder range is something like
| 12.34
|--[ >= ]---[ <= ]--------------------------O
| [ D100 ] [ D100 ]
| [ D201 ] [ D202 ]
This energizes 12.34 when D100 is between the range of values in D201 and D202. In this case you would have D100 as your encoder value, D201 would be 496 and D202 would be 504.
Above this rung you would need, of course, a rung (always on, presumably) which would take your setpoint value (500) in this case, and subtract 4, then store in D201; and add 4 and store in D202.

Related

Display result precision upto two decimal places in kdb without rounding off

x:1.375083
pk[x]
pk:{[x] string[[[0.01*floor 0.5+100*x]* 100]mod 100]}
"38"
In my function it is rounding off to 38, but i expect result to be 37.5 instead of 38
If I’m following, 1.375083 is a ratio that you want to report as a 37.5% increase; and that 2.375083 would be a 137.5% increase.
q)1.375083 2.375083-1
0.375083 1.375083
q).1*floor .5+1000*1.375083 2.375083-1
37.5 137.5
q)pk:string .1* floor .5+ 1000* -[;1] #
q)pk 1.375083 2.375083
"37.5"
"137.5"
Since pk is nothing but a sequence of unaries it can be defined as a composition, avoiding the (tiny) overhead of a lambda.
If you prefer a lambda, it is of course
{string .1*floor .5+1000*x-1}
I dont really understand what your asking for but you are rounding one dp less than you want in your result - please try and give a bit more detail for what you want your function to do and the conditions it should expect.
You should try and run through each stage of your function and print the output. This will help you understand where you are going wrong.
q)x
1.375083
q)1000*x
1375.083
q)floor 0.5+1000*x
1375
q)0.001*floor 0.5+1000*x
1.375
q)100*0.001*floor 0.5+1000*x
137.5
q)(100*0.001*floor 0.5+1000*x) mod 100
37.5
q)pk:{[x] string (100*0.001*floor 0.5+1000*x) mod 100}
q)pk x
"37.5"

Why does calling random() inside of a case statement produce unexpected results?

https://gist.github.com/anonymous/2463d5a8ee2849a6e1f5
Query 1 does not produce the expected results. However, queries 2 and 3 do. Why does moving the call to random() outside of the case statement matter?
Consider the first expression:
select (case when round(random()*999999) + 1 between 000001 and 400000 then 1
when round(random()*999999) + 1 between 400001 and 999998 then 2
when round(random()*999999) + 1 between 999999 and 999999 then 3
else 4
end)
from generate_series(1, 8000000)
Presumably, you are thinking that the value "4" should almost never be selected. But, the problem is that random() is being called separately for each when clause.
So, the chance the it fails each clause is independent:
About 60% of the time a random number will not match "1".
About 40% of the time a random number will not match "2".
About 99.9999% of the time a random number will not match "3" (I apologize if the number of nines is off, but the value is practically 1).
That means that about 24% of the time (60% * 40% * 99.9999%), the value "4" will appear. In actual fact, the first query returns "4" 23.98% of the time. To be honest, this is very close to the actual value, but given this size of data, but it is a bit further off than I would expect. However, it is close enough to explain what is happening.

Multiply a number by 2 in Brainfuck?

Given an arbitrarily long number, how can I output its double? I know how to multiply small numbers together as long as the result is <10, but what about larger integers like 32984335, and doubling something like that? I don't know the right way to handle something like this.
This is the algorithm you need to implement:
Start the current count with 0;
Multiply the current count by ten: this can be achieved by dupping 10 times, and then adding all dupes together;
Read a digit;
If it's null proceed to 8;
Convert it to an actual number: this can be achieved by subtracting 48;
Add it to the current count;
Proceed to 2;
Duplicate the current count;
Adding the dupes together;
Divide by ten using repeated subtraction; keep quotient and remainder;
Grab the remainder;
Make it a digit (add 48);
Print it;
Grab the quotient from 10;
If it's not zero, goto 10;
The end.
All these steps consists of basic brainfuck idioms, so it should be easy to implement.
Here's a start. It will multiply a byte of input, but I think you can build off it to make it work for any number. Basically, you take in a number, and store the number to multiply by (2) in the next pointer. You loop decrementing the first number, and then nest a loop decrementing the second number; in each iteration of the inner loop, you increment the pointer to the right of your second operand. This is your result.
, take input to ptr 0
[
- decrement first operand (input)
>++ number to multiply by (2) at ptr 1
[
>+ result in ptr 2
<- decrement second operand (2)
]
<
]
>> move to result
Here is my BF code: http://ideone.com/2Y9pk8
->>+>,+
[
-----------
[
-->++++++[-<------>]<
[->+<[->+<[->+<[->+<[>----<-<+>[->+<]]]]]]>
[-<++>]<+
>,+
[
-----------
[->+<]
]
>[-<+>]<
]
<[<]
>-[<++++++++[->++++++<]>.[-]]
>[<++++++++[->++++++<]>-.[-]>]
++++++++++.[-]
<+[-<+]
->>+>,+
]
It reads each number in each line until EOF, and multiply all numbers by two..
Here is the code for multiplying a number by 2.
,[>++<-]>.
Hope this helps.

Problem looking at data between 0 and -1

I'm trying to write a program that cleans data, using Matlab. This program takes in the max and min that the data can be, and throws out data that is less than the min or greater than the max. There looks like a small issue with the cleaning part. This case ONLY happens when the minimum range of the variable being checked is 0. If this is the case, for one reason or another, the program won't throw away data points that are between 0 and -1. I've been trying to fix this for some time now, and noticed that this is the only case where this happens, and if you try to run a SQL query selecting data that is < 0, it will leave out data between 0 and -1, so effectively the same error as what's happening to me. Wondering if anyone might recognize this and know what it could be.
I would write such a function as:
function data = cleanseData(data, limits)
limits = sort(limits);
data = data( limits(1) <= data & data <= limits(2) );
end
an example usage:
a = rand(100,1)*10;
b = cleanseData(a, [-2 5]);
c = cleanseData(a, [0 -1]);
-1 is less than 0, so 0 should be the max value. And if this is the case it will keep points between -1 and 0 by your definition of the cleaning operation:
and throws out data that is less than the min or greater than the max.
If you want to throw away (using the above definition)
data points that are between 0 and -1
then you need to set 0 as the min value and -1 as the max value --- which does not make sense.
Also, I think you mean
and throws out data that is less than the min AND greater than the max.
It may be that the floats are getting casted to ints before the comparison. I don't know matlab, but in python int(-0.5)==0, which could explain the extra data points getting in. You can test this by setting the min to -1, if you then also get values from -1 to -2 then you'll need to make sure casting isn't being done.
If I try to mimic your situation with SQL, and run the following query against a datatable that has 1.00, 0.00, -0.20, -0.80. -1.00, -1.20 and -2.00 in the column SomeVal, it correctly returns -0.20 and -0.80, which is as expected.
SELECT SomeVal
FROM SomeTable
WHERE (SomeVal < 0) AND (SomeVal > - 1)
The same is true for MatLab. Perhaps there's an error in your code. Dheck the above statement with your own SELECT statement to see if something's amiss.
I can imagine such a bug if you do something like
minimum = 0
if minimum and value < minimum

how to create unique integer number from 3 different integers numbers(1 Oracle Long, 1 Date Field, 1 Short)

the thing is that, the 1st number is already ORACLE LONG,
second one a Date (SQL DATE, no timestamp info extra), the last one being a Short value in the range 1000-100'000.
how can I create sort of hash value that will be unique for each combination optimally?
string concatenation and converting to long later:
I don't want this, for example.
Day Month
12 1 --> 121
1 12 --> 121
When you have a few numeric values and need to have a single "unique" (that is, statistically improbable duplicate) value out of them you can usually use a formula like:
h = (a*P1 + b)*P2 + c
where P1 and P2 are either well-chosen numbers (e.g. if you know 'a' is always in the 1-31 range, you can use P1=32) or, when you know nothing particular about the allowable ranges of a,b,c best approach is to have P1 and P2 as big prime numbers (they have the least chance to generate values that collide).
For an optimal solution the math is a bit more complex than that, but using prime numbers you can usually have a decent solution.
For example, Java implementation for .hashCode() for an array (or a String) is something like:
h = 0;
for (int i = 0; i < a.length; ++i)
h = h * 31 + a[i];
Even though personally, I would have chosen a prime bigger than 31 as values inside a String can easily collide, since a delta of 31 places can be quite common, e.g.:
"BB".hashCode() == "Aa".hashCode() == 2122
Your
12 1 --> 121
1 12 --> 121
problem is easily fixed by zero-padding your input numbers to the maximum width expected for each input field.
For example, if the first field can range from 0 to 10000 and the second field can range from 0 to 100, your example becomes:
00012 001 --> 00012001
00001 012 --> 00001012
In python, you can use this:
#pip install pairing
import pairing as pf
n = [12,6,20,19]
print(n)
key = pf.pair(pf.pair(n[0],n[1]),
pf.pair(n[2], n[3]))
print(key)
m = [pf.depair(pf.depair(key)[0]),
pf.depair(pf.depair(key)[1])]
print(m)
Output is:
[12, 6, 20, 19]
477575
[(12, 6), (20, 19)]