Tia Portal Rs485 communication with plc

And another note. Lets say i weighed and it counted 10kg 450 grams. Can i save it in a memory type of thing? Create a history section and show each counted times and see what the count value is?

This blue coloured line is off topic, if you guys say i need to open a new post for this question then i will oblige. Sorry about this in advance and thank you again for all your help guys

Kind of off topic but same type of question goes with the speed values? Lets say i configured a speed value for my motor. But this speed works really well in certain situations. A few days later i need to change my motor speed. And i find a new speed value that comes in handy in certain situations aswell. But i need go back to my first speed value and i forgot what it was. You see? i want to be able to save, load, update and delete my motor speed values so that i can save new values and call them whenever i need them or update them if i need to change it a little or delete them if i dont need them anymore. Is there a way i can do that?
 
Pseudocode which you can convert to FBD-code.


(* weight with 5kg steps *)


if weight_now > (weight_stored + 5) or weight_now < (weight_stored - 5) then

weight_stored:=weight_now;

end_if;



(* zeroing weight if less than 5kg , otherwise 5kg is allways showed as mimimum weight *)

if weight_now < 5 then
weight_stored := 0
end_if;









For storing data you can look recipes. If you have HMI there is probably setting for recipes.


Recipes can be done also on PLC, but it is more coding.


It is time to new thread.
 
Last edited:
;) This won't work


if weight_now > (weight_stored + 5) or weight_now < (weight_stored - 5) then

weight_stored:=weight_now;

end_if;


Dependinf of weight first measured first digit will be between 0..9 not 0 or 5.




So back to coding, you need first last digit (grams 0..9) so divide by 10 and then multiple by 10 like you have allready done.


Then subtract from original weight your manipulated value.


1456/ 10 -> 145 -> * 10 -> 1450 (weight_temp)



1456 - 1450 = 6 (weight_0_9_grams)



Then make couple compares.


if weight_0_9_grams >=0 or weight_0_9_grams <= 3 then

gram_add:= 0:
end_if;


if weight_0_9_grams >3 or weight_0_9_grams < 8 then

gram_add:= 5:
end_if;


if weight_0_9_grams >8 or weight_0_9_grams < 10 then

gram_add:= 10: // 10! we need to round next +10 g

end_if;




weight_now:= weight_temp + gram_add



(which should be 1450 + 5 = 1455 when weight measured was 1456)
 
Still it would be better if we could find a way to make the grams increase 5(610-615-620-625-630...) at a time instead of 10(610-620-630...).

Change Network 4 to this:
CONV(Int to Real) #yigit #adam DIV(Real) #adam 5.0 #salak ROUND(Real to Real) #salak #salak DIV(Real) #salak 200.0 #salak
Update: fixed typo

But better to not use the Int=>Real=>Int conversions at all, as the number starts out as an Int, so replace all current networks with this:
ADD #yigit 2 #salak_dint_kg
< #ygit 0 SUB #salak_dint_kg 4 #salak_dint_kg
MOD #salak_dint_kg 1000 #salak_dint_g SUB #
salak_dint_kg #salak_dint_g #salak_dint_kg DIV #salak_dint_kg 1000 #salak_dint_kg
< #salak_dint_kg 0 > #salak_dint_g 0 ADD #salak_dint_kg 1 #
salak_dint_kg SUB 1000 #salak_dint_g #salak_dint_g
MOD #salak_dint_g 5 #silly SUB #salak_dint_g #silly #salak_dint_g

 
Last edited:
But better to not use the Int=>Real=>Int conversions at all, as the number starts out as an Int, so replace all current networks with this:
...
Whoops, that will only work with total integer gram values (#yigit) greater than -3. There are two ways to implement MOD, and apparently Siemens chose to implement it wrong mathematically; it is not documented, so perhaps it was a naive choice, but the implementation can be determined empirically.

See the image in the attached .ZIP for working code: the function that converts from integer total grams to integer kg, and to integer sub-kg g to the nearest 5g, is on the right; the Main OB1 on the left calls that function with several values to test the function.

I put the image in a .ZIP because it is wide and so would mess up the display of the thread.
 
Last edited:
i see, that worked well but my teacher said that it was pointless because no weighers count like 5-10-15-20, they all go normally so i just wasted your time guys. I apologize. At least now i know how to do that tho. Thats a bonus. :D
 
Now regarding the modbus calibration we talked about earlier, i talked with the supplier and they told me that in order to tare the weight value 122 ('z') can be written to Modbus address 0. And for calibration By writing 108 ('l') to Modbus 0 address weight in current modbus addresses 1 and 2 is calibrated.

Now from my understanding we write our modbuss adresses like 40000, 40008.... because when i write the 40008 like it says in the manual, it works. But now on to the strange point. How can i write 0 and 122 at the same time? Thats when it hit me. What if i wrote 40000 to the data address and 122 to the Reading arrays that we have(Reading_val[0],Reading_val[1],Reading_val[2],Reading_val[3],Reading_val[4].... I tried putting 122 to all of them. None of them worked out. And i thought maybe i needed to write that 122 like 40122. Nope didnt work either. After that i thought hey maybe i need to write 40008 to the data address because if it could not read the values how can it tare right? So thats what i did. Put 40008 to the Data_Addr and then put that 122 to the Reading_Val[0].... All of them, i tried all of them. And none of them worked. I am stumped you guys. whats the solution to this problem. How give a special command to the address 0.

And you know what? this isnt the craziest part. There are some special commands that uses Address 0, 1 ,2 at the same time. For example if i wanted to calibrate to 100.000 i need to put 108 to 0 address and put 34464 to the 1 address and 1 to 2 address. I dont get this at all. How am i suppose to do that. I can only use 1 address and see. Please help you guys

Screenshot (701).png
 
Now i talked with the suppliers yet again and they say that i need to use 122 command as a byte. They say that one of the Receive_Val's Should be a byte. If its a int, it wouldnt comply to the 122 command. The question i have is that how can i make one of them a byte?

Screenshot (717).png
 
I believe Modbus is capable of sending multiple 16-bit words in a single write command, so if you wrote three 16-bit words, in a single Modbus operation, from an array on the PLC with values [108, 34464, 1], to Adr0 as a starting address, then

  • 108 would be written to weighscale register 0 (Adr0),
  • 34464 would be written to weighscale register 1 (Adr1)
  • 1 would be written to weighscale register 2 (Adr2)
Here are the tricky parts:

  • I would assume these are Holding Registers, not Input Registers
    • Because you cannot write to Input Registers.
  • To write multiple Holding Registers in a single Modbus operation, I think requires using Function Code 16
  • The first Holding Register, which I assume is Adr0, is at Modbus entity 40001, not at 40000.
    • Adr1 will be at 40002, and Adr2 will be at 40003, but writing the array of three 16-bit words at one time, with 40001 as the starting address, should put the subsequent values from the PLC array into those subsequent Holding Registers.
    • There is no entity 40000
    • The entity convention, e.g. 40001 comprises two parts:
Based on my reading, that is what I think should happen, but I am only guessing: I have no actual experience with all of this.
 
Now regarding the modbus calibration we talked about earlier, i talked with the supplier and they told me that in order to tare the weight value 122 ('z') can be written to Modbus address 0. And for calibration By writing 108 ('l') to Modbus 0 address weight in current modbus addresses 1 and 2 is calibrated.

Now from my understanding we write our modbuss adresses like 40000, 40008.... because when i write the 40008 like it says in the manual, it works. But now on to the strange point. How can i write 0 and 122 at the same time? Thats when it hit me. What if i wrote 40000 to the data address and 122 to the Reading arrays that we have(Reading_val[0],Reading_val[1],Reading_val[2],Reading_val[3],Reading_val[4].... I tried putting 122 to all of them. None of them worked out. And i thought maybe i needed to write that 122 like 40122. Nope didnt work either. After that i thought hey maybe i need to write 40008 to the data address because if it could not read the values how can it tare right? So thats what i did. Put 40008 to the Data_Addr and then put that 122 to the Reading_Val[0].... All of them, i tried all of them. And none of them worked. I am stumped you guys. whats the solution to this problem. How give a special command to the address 0.

And you know what? this isnt the craziest part. There are some special commands that uses Address 0, 1 ,2 at the same time. For example if i wanted to calibrate to 100.000 i need to put 108 to 0 address and put 34464 to the 1 address and 1 to 2 address. I dont get this at all. How am i suppose to do that. I can only use 1 address and see. Please help you guys




This


attachment.php





is command values to modbus registers 0,1,2 (40001-40003)


For zero calibration you only need write value 122 to register 40001. (on Siemens modbus block. Lenght 1 int, value 122 to slave register 40001)


If you want to value calibration to know value, then you write 3 values with same write (Modbus FC16 code)


40001 needs value 108 which tells to unit that commands is now weight calibration.

then 40002 is weight value and 40003 = 1 is for start for that calibration.


On siemens you have data array of int (lenght at least 3 ints)
Then locate values 108, xx, yy (where xxx and yy is weight low and high values)


On Siemens modbus block write start is 40001, lenght 3 and locate array of 3 ints for data to write.
 
Last edited:
on calibration value is gived by dividing decimal value to low and high bytes.


if we look this calculator

https://www.rapidtables.com/convert/number/decimal-to-hex.html


and put 100000 (max. value for calibration) there we get 17 bits long binary format


1 10000110 10100000


and if we look first 16 bits, it is "10000110 10100000".


10000110 10100000 (LSB) is on decimal value 34464.


00000000 00000001 binary is on decimal value 1





On Siemens for this same conversion you need first DINT variable. (weight for calibration on DINT format)

Then AND this dint with binary data value 2#0000 0000 0000 0000 1111 1111 1111 1111 and locate this new value to another dint variable (It is your LSB byte value)


for original DINT make another ANDing with value 2#1111 1111 1111 1111 0000 0000 0000 0000 and locate value to third DINT variable.


If you now look these three DINT-variables on animation table, you should see on first 100000 (dec) and on other DINTs values 1 and 34464 (dec)


Then convert these LSB and MSB dints to integers and locate on array of int. (2,3 place)


For writeng 122 and 108 on byte format to DINT you need also conversion.


First you need byte variable (data format is maybe hex) then make conversion from byte to int.



If values 108 and 122 are hex, then you need on decimal side values 264 and 290. this value needs locate to 1st place to array of int.
 
Last edited:

Similar Topics

Im trying to create a level indicator for water Tank i have used the ADD function while the pump is on and level increasing everything works...
Replies
17
Views
165
My PLC (S7-1200 with CPU-1212C) has now been delivered to customer site. They've asked me to do some updates to the software. I can do that on my...
Replies
21
Views
334
Does anyone know why the connection interface is greyed out and says why I can only use Teleservice instead of the other options like PN/IE? I am...
Replies
0
Views
44
Hi guys I after a bit of advice on Tia portal graphics, I would like to add a conveyor belt graphic to a hmi and the conveyor in the basic...
Replies
3
Views
130
Hi I used to be able to launch PLCsim without any problem. Now it tells me " STEP 7 Professional Licence is required to simulate this PLC"...
Replies
15
Views
453
Back
Top Bottom