Sign in to follow this  
Followers 0
justwhy2003

Cumulative flow

14 posts in this topic

Hi If im using a Mitsubishi FX3u with FX2n-8AD analogue input card to measure the reading from a flow meter on a 4-20mA (prob 0-4000 res) loop and displaying it on Citect SCADA, what are the options for recording and displaying cumulative flow? It it ok just to sample the flow at say 5 second intervals and add this value to a battery backed up register in the PLC or will this increase dramatically very quickly and fill the register. Or should i look to the SCADA to provide this feature? If i could id preffer to do it in the PLC as id trust the PLC memory more than the SCADA. Although i also have to configure the SCADA to produce weekly reports which may help me out in this area. Any thoughts?

Share this post


Link to post
Share on other sites
Hello, I've done exactly what you're trying to do with Citect in the past, the only difference being that I did it with Opto 22 instead of a PLC. It's the same thing though, I just took a sample of the flow rate every second, divided it by 60 (because it was in Gallons per minute) and added that to a total in a seperate register. As long as you use a double integer you should be fine. That way if you lose connection to Citect for any reason your flow total shouldn't be off. Edited by Duffanator

Share this post


Link to post
Share on other sites
thanks, sounds like the answer im looking for. what is a double integer tho? just a double register? my flow range is about 0-10 m^3/hr and the AD resolution is 8000. ill then divide my 0-8000 word by 3600 to get the instaneous flow and add it to my cumulative flow register...? Edited by justwhy2003

Share this post


Link to post
Share on other sites
Yeah, double register. 32 bit register, whatever you want to call it. Here's how I would do it: Multiply your AD signal by 100, so: say you get 5000 as your signal, multiply by 100 to get 500000. Then divide by 800 to get your 0-10 flow rate: 500000 / 800 = 625. That is 6.25m^3/Hr Then multiply 625 by 100 to get 62500. Then divide 62500 by 3600 to get the instaneous flow. 62500 / 3600 = 17.36 The PLC will round this to 17 and this will actually be .17m^3 Add this number to your total every second and you will have a running total accurate to a hundreth of a m^3 This number will still be a whole number in the PLC, so in Citect you'll have to do a IntToReal() command to change it to a real number and then divide it by 100 to move the decimal place. Edited by Duffanator

Share this post


Link to post
Share on other sites
Duffenator has it. Your flow meter gives you rate, and you should be accumulating amount of material. If you want a longer sample period, just multiply your instantaneous flow by the number of seconds in your sample period. One correction to his post, however, is that the FX3U will not round 17.36 to 17. It will truncate. This is an important distinction, because if your result was 17.68, then the FX3U would still return 17 as your value. You have to decide if that makes a difference in your application. I have coded rounding into integer math in the past to compensate. Now, to answer your original question about overruns, that is something you will have to calculate yourself. On average, how much will be added to the register at each interval? What is your measurement period? Can you reset the register after each measurement period? On the FX3U, you have three options for math: 16-bit integer, 32-bit integer (AKA double), or float. 16-bit only goes up to 32,767, and would likely give you overruns. 32-bit goes up to just over 2,147,483,648, and if that's adequate, then that will be simplest. If you need more headroom, or decimal precision, use float. Duffenator's example does give you some decimal precision, at the expense of headroom. It's a trick I use a lot, as it's often simpler that doing float. Assuming you go with 32-bit integer, also known as double integers, or double words, or just doubles, here's how they are handled in the FX3U. All data registers, for example D100, are 16-bit words. To get a 32-bit word, you have to "double" by pairing two data registers together. This is done simply by using the "double" version of the instruction. For instance, use DADD instead of ADD and DMUL instead of MUL. Then the instruction uses two registers instead of one for each of the operands. If you put D100 in a double instruction, then it will use D100 and D101. So be careful not to use D101 for anything else.

Share this post


Link to post
Share on other sites
Thanks, that works. However can i just go through the math to help clear things up if this arrises in a different application. 1st: multiply by 100, i presume this is to put the value into 32 bit register mode using the DMUL command and also to improve the resolution. 2nd: divide by 800, is this to put the units from m^3/hr to 1/100ths of m^3/hour, again to improve resolution? 3rd: multiply by 100 to put back into m^3/hr 4th: divide by 3600, to give a value of 1/100ths of m^3/second Is this correct? Ive also since realised that the flow meter im using (siemens Magflow 5000) has a pulsed output per volume through the flow meter that i can used to increment a register in the PLC. I think ill use that but id like to make sure i understand the above method as i can think of other applications ive encountered in the past.. Also Duffanator, is the reason i need to change to a real number because the value is split between 2 registers? do i just make a tag in Citect for the lower of the 2 registers im using (eg D100 if im using D100.D101) and then apply the IntToReal() command in the numeric object graphic? Thanks again for your help Edited by justwhy2003

Share this post


Link to post
Share on other sites
I guess what my question is now is how do I transfer and display on Citect a value relating to a 32 bit word from the PLC....

Share this post


Link to post
Share on other sites
The first multiply by 100 is so you can get the extra two decimal places of information, because as JRoss said the PLC will truncate (I was listening!) any number after a decimal point if you're not doing floating point calculations. Divide by 800 is to get your 0.00 to 10.00m^3/Hr flow rate value from the 0-8000 AD signal. The next multiply by 100 is so you don't lose the two decimal places when you do the next division to find instantaneous flow value. When you divide that by 3600 you're finding how much flow you had in that one second sample time. So, you're taking your m^3/hr value and dividing by 60 to find m^3/Minute and then by 60 again to find m^3/second. Since you're going to sample every second then this value you just add together every second and that should be a good way of getting a flow total for the day. You have to change it to a real number in Citect is because you need to display the number to the hundreth place and you can't do that with an integer value. It's pretty easy to get the value out of the PLC with Citect. Create your variable tag in Citect and make the Data Type "Long" then put the D register value in the address field. So, say you did all the math on it and your final flow total value you put in D100, since it's going to be a double it will take up D100 and D101. With the Long variable type in Citect you put D100 in the address field and it will automaticly take D100 and D101 because that will make up 1 32 bit register. You will probably have to write a small Cicode file to do the IntToReal() conversion. You will have to tagread into variables in the Cicode and then do the conversion, divide by 100 (to move the decimal place) and then tagwrite to a seperate variable tag. (I'm sure there are plenty of ways to do it but that's the way I usually do it.) I hope that helped you understand a little better, I'm not usually good at explaining stuff :-P I'll include a screen shot of a function I created in Citect to convert variables to real, hopefully it will explain it a little better.

Share this post


Link to post
Share on other sites
Thanks, i got it working. I didnt however use Cicode. As i said before, im now using a pulse from the flow meter to increment a double register and I represented this as a double word of whole m^3 values for my cumulative flow. For the instantaneous flow I made a tag for my D register as a "intiger" word, 0-8000 raw data and 0-3 engineering data. I then made a number object using that tag and set the format as xx.xx. This gave me my decimal place. Im using citect version 7.1, not sure if that makes a difference. To be honest ive never used Cicode. Im not sure how. i see in your tunmbnail that you have a function ChangeToReal(). is everything below that point, part of the function or is each section i.e. iVacuumLevel _ TagRead("SLMT_Vacuum_Level",0"); a different function. Are the function(s) running all the time or only when the a certain condition is met? How does the function relate to the graphics? do you make a tag containing the function or add it to the graphic in the same way as a tag? Sorry if im asking too many questions but i think i could use cicode to my advantage if i learn how to use it.

Share this post


Link to post
Share on other sites
No, everything after the ChangeToReal() is part of that function. (The function ends with an END statement) So, everytime that function is called it will do all those conversions. Here is the complete function: FUNCTION ChangeToReal() INT IStaticCheckMContact INT iStaticCheckActive INT iVacuumLevel INT iFormTemp INT iSealTemp INT iPlugTemp INT iFormOn INT iSealOn INT iPlugOn REAL rFormTempConverted REAL rSealTempConverted REAL rPlugTempConverted REAL rVacuumLevelConverted REAL rFormOnConverted REAL rSealOnConverted REAL rPlugOnConverted WHILE TRUE DO iVacuumLevel = TagRead("SLMT_Vacuum_Level",0); rVacuumLevelConverted = IntToReal(iVacuumLevel); rVacuumLevelConverted = rVacuumLevelConverted / 10; TagWrite("SLMT_Vacuum_Level_Real",rVacuumLevelConverted,0); iFormTemp = TagRead("SLMT_Form_Temp_Raw",0); rFormTempConverted = IntToReal(iFormTemp); rFormTempConverted = rFormTempConverted / 10; TagWrite("SLMT_Form_Temp",rFormTempConverted,0); iSealTemp = TagRead("SLMT_Seal_Temp_Raw",0); rSealTempConverted = IntToReal(iSealTemp); rSealTempConverted = rSealTempConverted / 10; TagWrite("SLMT_Seal_Temp",rSealTempConverted,0); iPlugTemp = TagRead("SLMT_Plug_Temp_Raw",0); rPlugTempConverted = IntToReal(iPlugTemp); rPlugTempConverted = rPlugTempConverted / 10; TagWrite("SLMT_Plug_Temp",rPlugTempConverted,0); iFormOn = TagRead("SLMT_Form_ON",0); rFormOnConverted = IntToReal(iFormOn); rFormOnConverted = rFormOnConverted / 10; TagWrite("SLMT_Form_ON_Fix",rFormOnConverted,0); iSealOn = TagRead("SLMT_Seal_ON",0); rSealOnConverted = IntToReal(iSealOn); rSealOnConverted = rSealOnConverted / 10; TagWrite("SLMT_Seal_ON_Fix",rSealOnConverted,0); iPlugOn = TagRead("SLMT_Plug_ON",0); rPlugOnConverted = IntToReal(iPlugOn); rPlugOnConverted = rPlugOnConverted / 10; TagWrite("SLMT_Plug_ON_Fix",rPlugOnConverted,0); // This is for trending the static test screen enabled bit. iStaticCheckMContact = TagRead("SLMT_Static_Enabled",0); IF iStaticCheckMContact = 1 THEN iStaticCheckActive = 1; ELSE iStaticCheckActive = 0; END // end of If Then Statement TagWrite("SLMT_Static_Enabled_Int",iStaticCheckActive,0); SleepMS(250); END // End While Do Statement END // End of Function I have this function running forever in a While Do loop that starts when Citect starts up, the SleepMS(250) at the end means that it will pause for 250 ms and then loop back up to the top. This is to free up processor time for other functions. You can create functions like this and run them only at certain times if you'd like, it all depends on what you want to do, it's very flexible. As far as the tagging, I have one variable tag to get the information out of the PLC, then I make another variable tag that is local to the computer (it's called a disktag) and put the converted value in there. Then whenever I want to display that data I will use the disktag variable because it is being constantly updated to a real value.

Share this post


Link to post
Share on other sites
Thanks Duffanator Thats alot of information. Ive only got around to playing with it today. Ive copied some of your Cicode for 1 tag from my PLC as below: FUNCTION ChangeToReal() INT iVacuumLevel REAL rVacuumLevelConverted WHILE TRUE DO iVacuumLevel = TagRead("SLMT_Vacuum_Level",0); rVacuumLevelConverted = IntToReal(iVacuumLevel); rVacuumLevelConverted = rVacuumLevelConverted / 10; TagWrite("SLMT_Vacuum_Level_Real",rVacuumLevelConverted,0); SleepMS(250); END // End While Do Statement END // End of Function I called the tag that ive taken from the PLC SLMT_Vacuum_Level Do i now need to make a seperate IO device to connect to the PC disk rather than the external source and make a tag called SLMT_Vacuum_Level_Real in my variable tags, like all my other variables to date? What is the address of this new tag? thanks again justin Edited by justwhy2003

Share this post


Link to post
Share on other sites
Yeah, you pretty much have it. You just need to make a new I/O device for disktags. See the attached thumbnail. You can then assign your variable tag to the disktags and give it an address of R0 (R for Real), you could give it any address if you'd like but I use R for real, I for int, d for double so on and so forth.

Share this post


Link to post
Share on other sites
Hi Ive set up my device logger in Citect (7.1)to log events that occur during run time such as when a button is pressed by selecting the log device in the General Access options. Can i now do the same for inputs i.e. to log when a device has sent a run or trip signal? how is this done. Also im using the xp template for my windows etc. How do i display the occurances in the display bars at the bottom of the xp template? will this be a function of the device? justin

Share this post


Link to post
Share on other sites
You should be able to do that. You will probably have to make a digital variable tag and point to whatever address in the PLC that you want to look at. I usually take all the inputs or outputs from one card and group them into a D register so I can pull out all 16 points with only one variable tag. Then you can split it back up in Citect with some coding. I don't really do much with logging in Citect so I can't be of much help and I've never used the XP templete so I can't really help with that either. Sorry!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0