Jump to content

Phil Salkie

Bloggers
  • Content Count

    59
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by Phil Salkie

  1. If you can live with a slower data transfer rate, you can increase the distance. Assuming you only need to collect results once or twice a minute, you could set a rate of 1200 baud, and run your RS-232 signal a few thousand feet without any problems. Alternately, you could put a $60 RS-232 <-> RS422 converter at the PC end, switch the DIP switches to RS-422, and run your data half a mile at 9600 baud.
  2. If you're just trying to decide if any of your 100 thermocouples has failed, consider either using a loop, or searching the table of MB bits for a "1" value using the "VECTOR FIND" function block - you'll either get a "-1" result showing that all thermocouples are OK (no "1" values found) or the index value of the first failed thermocouple. Much, much better than making a huge string of normally open contacts.
  3. It wouldn't make much sense right now, as VisiLogic only supports having a single program open at any one time. If a future version were to support multiple programs being open at once (like almost any other modern application) then having a connection open for each program would be sensible and potentially very useful (think debugging networked PLC applications without having a laptop for each PLC.) Well, the PLCs can have unique names, and must have unique IP addresses. That can be a way of sorting out which PLC is which, but I don't really see the benefit of having multiple simultaneous connections to the Download Manager, unless I'm missing something obvious...
  4. If you're using compensating cable (that is, extension wire which has the same alloys as the wires of the thermocouple) you shouldn't be creating measurement error with the wires themselves. Are you using thermocouple terminal blocks? If you land the thermocouple on a standard terminal block, then land the wire on the other side of that terminal block, you are essentially adding in any temperature difference across that block. We keep compensating terminal blocks in stock for our customers who are involved in temperature sensing applications. As for linearization, you can more precisely calibrate your thermocouple input by sending the input signal through a linearization function block. That block gives you a linear transform between two ranges of values - for example, if an analog input gives you a value between 0 and 1000, you can use the linearization block to convert that to a span of 0 to 250 pounds. (I would usually make that 0 to 2500, then show my display with one decimal point to preserve measurement accuracy.) In the case of temperature, you can set a low and high calibration point, place the thermocouple in a low temperature, store the value it is producing and enter the value it should produce. Then do the same for a high temperature - that will correct the end-points of your measurement range, and (all things being equal) you should have a much more accurate temperature reading within your working range.
  5. Thank you both - there are quite a few very useful functions in the Unitronics, the key is figuring out what they're useful for... It's nice having this forum to share some ideas.
  6. Considerably less than using a timer, which adds an average of 1/2 scan time each time the timer turns on. The SB3 method will add up to 1 timer period at the beginning of the timing, and 1/2 scan time to the overall amount, but since the time base is constant and not dependent on the scan of the program, it should work as well as using the RTC to UTC method, and almost as well as counting 2.5ms interrupts.
  7. That's true of _any_ integer mathematics anywhere. For example, in the real number (infinite precision floating point) world, ((X / 10) * 10) = X, no question about that. However, in integer-only math, if X is 4, then (4 / 10) = 0, remainder 4. and 0 * 10 = 0, so your result is obviously not what you expected. If you reverse the order of operations, making intermediate results larger instead of smaller, then you would rephrase the formula as ((X * 10) / 10), X * 4 = 40, 40 / 10 = 4. This works until you overflow the internal 32-bit integers. That's true of MI or ML - you always run the risk of an internal overflow with no warning - it's just easier to do if the sources are 32-bit integers. The internal calculations of the function block are not done in any of the 25 MF registers that are available to the PLC program, so your data is safe - similarly, the intermediate results of the 32 bit integer calculations are not done in any of the PLC's ML or DW registers. If you are using all the MF registers for other things, all you have to do is use some floating point constant in your formula - such as multiplying the result by 1.0000001 (since the formula parser doesn't recognize 1.0 as a floating point number.) in order to force the entire calculation into floating point - the sources and result can all be integers, but the calculation will take place in floating point.
  8. I just put up a Blog entry which touches on this exact issue - have a look at it here. What you seem to be running into is the fact that when you try to accumulate time values, you have a small amount of error due to the scan time of the PLC. It's possible to get around this by using timed interrupt routines and counting up time in 2.5 millisecond increments - but for longer values, it's easier to use the RTC->UTC conversion function to get a value for "Now" in seconds, save that value as your "Start" time, then calculate elapsed time with ("Now" - "Start").
  9. I just programmed a timed filtration system, and was very pleased at how simple the code is to handle a simple on/off timer with selectable day-of-the week: Pretty neat, huh? I coupled that with a simple screen letting the user set start and stop times and select the days to run: and the lion's share of the job was done. But there's much more to Unitronics timekeeping than just simple timers. In the forums, there's been some discussion of the difference between RTC and UTC, the use of UTC to do things such as determine long periods of elapsed time, or to store and retrieve date/time values in log files. Let's try to clear up the confusion, shall we? First, let's look at the different ways that times can be stored in a Unitronics PLC. For starters, there's RTC (Real Time Clock) - that's a collection of five MI registers, in a specific order: Base + 0: Seconds Base + 1: Hours and Minutes Base + 2: Days and Months Base + 3: Year Base + 4: Day Of Week If you point a function block which uses an RTC value at the special register SI30, you'll get the PLC's built-in Real Time Clock value which should be set for the current date and time of day. You can also point these function blocks at any other group of registers, so that you can manipulate time values which are not the current time, but may instead be values which the user has entered, or values stored in a table, or values which the program has saved for some reason. Now, the main reason to use an RTC value is that it is very familiar - there's not much question in our minds about what the "hours" field means, or what "month" it is. There are several problems with this representation, though - while an RTC date is easy for a human to read, it can be a lot of work for a computer to do calculations solely on RTC values. For example, if we want to find out the difference between two RTC dates, we might find that the month has changed and that the later date has a lower day value than the earlier date, and we wind up having to compare and subtract both days and months - but months have different numbers of days depending on the month _and_ the year (that annoying leap year thing!) Here's where the UTC value comes in. UTC is a standardized time format which counts the number of seconds elapsed since an "Epoch" value. The Vision series uses an Epoch of Midnight, January 1, 1900 as its starting point, and counts seconds in a 32 bit register moving forward from then. So, for example, 1 AM, January 1, 1900 would have a UTC value of 3600 - 60 minutes of 60 seconds each from the epoch. There are function blocks to convert from RTC register blocks to UTC values, and back again - thus, if you wanted to compare two RTC dates, you would simply convert both values to UTC and subtract the results. That would give you a difference between the dates in seconds, which you could convert to hours, days, or whatever just by dividing by the correct constant (3600 seconds in an hour, 86400 seconds in a day, etc.) It is important to realize that any given time/date value maps one-to-one with a UTC value - thus, 4:14:35 30 March 2004 equals 3,289,608,875 and 3,481,706,253 converts to 12:37:33 1 May 2010. This lets us readily do mathematics and comparisons in the otherwise complicated realm of date handling. When would we want to actually do this? How about product packaging - I want to tell an ink-jet printer to print an expiration date which is 28 days from today. Doing this on other PLCs can be a nightmare, requiring a stored table of the days per month plus a special rung to add a day on leap years. On the Unitronics, however, we merely convert the system RTC to a UTC value, add 24192 (28 * 24 * 60 * 60) and convert back from UTC to an RTC at a different location. That RTC value then gets formatted and sent to the printer, and we're done - no worrying about rolling over the month or how many days there are in April. Or maybe we want to time a long value - something long enough that trying to count seconds or minutes with an MI register starts producing inaccurate results due to the fact that the program takes time to scan, and every time you add a pulse, you will be off by a few milliseconds. So all you do is convert RTC to UTC in a "Now" DW register, save that value to a "Start Time" DW register at the beginning of your timing interval, and calculate your elapsed time by subtracting "Start Time" from "Now" - the result will be a doubleword integer value of elapsed seconds, accurate to durations of years. (Note that if the user changes the Real Time Clock setting while you're timing, the time result will be wrong.) There's more to all of this - things like timer values and date strings in ASCII, but I'll cover some of that in my next post...
  10. If I may rephrase the question: "Are the internal calculations of a FORMULA block performed in 16 bit integers, 32 bit integers, or floating point?" The answer would appear to be "That depends" (I've tested this on the V570, your results may vary). If no floating point constants or variables are used, the internal calculations seem to be done with 32 bit integers. If a floating point constant or variable is used, then all internal calculations are done in floating point. A=MI0 B=MI1 Result in MI2 The formula: (A * / 10000 (divide by ten thousand) works properly throughout the 16 bit integer ranges of the MI sources, so long as the result will fit into a 16 bit integer. A=ML0 B=ML1 Result in ML2 This formula: (A * / 10000000 (that's a divide by ten million) will give incorrect results for A=1,000,000 and B=1000 because the intermediate result (10,000,000,000) is larger than a 32 bit integer. However, this formula: (A * / 10000000.000001 (still effectively dividing by ten million, but forcing the calculations to floating point) will give correct results with A=2,000,000,000 and B=10,000,000 (the end result being 2,000,000,000 and the intermediate being 2 * 10^16) Oddly enough, the FORMULA block's parser interprets 10000000.0 as an integer, not a floating point, so I had to put that extra .000001 on the ten million in order to force a floating point calculation. And, as always, check the ranges of your variables before doing a calculation - there doesn't seem to be any SB to tell your program that an integer calculation has gone out of range, so if you were to have a FORMULA block working in the integer range, and an intermediate calculation overflowed the internal 32-bit registers, your program would have no way to know, and it would basically be operating on a random result - that would be, at best, BAD.
  11. I connect to a V570 via a 24-port switch all the time, for what that's worth. Could there be a cabling issue, or a bad port on the switch? Is it a 10 base T hub and your computer has its port locked to 100? If it's an unmanaged switch, it should just forward any traffic it sees regardless of the IP address ranges involved, so I'd really suspect a hardware/cabling issue.
  12. Using 8.6.2 - If I export a file with the extension ".xls", then I get a properly formatted file containing no operand descriptions at all - this used to work, and now doesn't. If I export a file with the extension ".xlsx" I get the same message as you got - "The Excel file you have selected cannot support the exported values" - I've never actually seen VisiLogic make a proper .xlsx file. I believe this has all been broken for a while, I have just been re-using old export files, modifying them, and then importing to my new projects, so I forgot to report it. It used to be that it was necessary to have Microsoft Excel installed on the machine in order to export or import .xls files, I assume this is still the case.
  13. Were you reading the output in the same network that you changed it in? Remember that the Unitronics follows an international PLC standard which states that no bit statuses change during the processing of a single network. Therefore this: ------------------------ MB0 MB1 -|P|-----( )- MB0 MB1 MB2 -| |--| |---( )- ------------------------ will never turn on MB2 because the read of MB1 gives the status that MB1 had on entering the network, whereas this: ------------------------ MB0 MB1 -|P|-----( )- ------------------------ MB0 MB1 MB2 -| |--| |---( )- ------------------------ will do what everyone in the world (except the standards committee) would expect the first network to do, turn on MB2 for one scan on the rising edge of MB0. As a general rule, don't combine rungs in networks. If you feel it's necessary or advisable, then look at the STL Quick View to make sure the actual compiled logic does what you thought it was going to do.
  14. If you were to look over my shoulder while I'm working at my desktop or laptop PC, you'd probably notice pretty quickly that my computers don't look quite like most. Firstly, my keyboard doesn't have its letters in the usual "QWERTY" layout - I use the Dvorak layout, optimized for faster typing with minimum finger movement. I credit that (along with the refusal to use a trackpad) with curing my carpal tunnel syndrome - it took a month or so to switch over, but I've never regretted it. There's lots of information (and stickers to put on your keys) available online - you can start here. The next thing you might realize is that my machines aren't running Windows - they've all got Kubuntu Linux installed. This gives me a fast, stable, multi-user development platform with multiple virtual desktops (my machines all have six screens' worth of display space, and I can switch between the screens by dragging the mouse or clicking on a "pager" - I don't have to minimize or hide windows to change between applications, they just stay open on different virtual screens.) I have a huge selection of free software available for me to do my work with - multiple different office suites, CAD programs, PC Board design systems, language compilers, and so on. I don't have to worry about computer viruses, trojans, malicious websites - none of those things have any real effect on a Linux system. My systems get rebooted once or twice a year - the time and money I save Howman by not buying virus software, not scanning and cleaning, not looking high and low for software drivers, and not rebooting is significant. The annoyance I save myself is priceless. There are, however, some software packages which are only available on Windows systems - and VisiLogic is one of them. So how do I manage to do my Unitronics development while running on Linux? I run Win XP under Oracle's amazing VirtualBox system. VirtalBox is capable of running on Linux, Intel Mac, or Windows, and can install and boot a native Win XP, Linux, Unix session from a virtual hard drive - just a special file on your workstation's hard drive. This has a number of benefits over running XP as your main operating system: *** Since it's not your main method of accessing the internet, you're not browsing or running Flash or accessing PDFs under Windows, and Windows doesn't need to directly access USB thumb drives. That all means that Windows is much less likely to get a virus or trojan - and if it does: *** Your virtal hard drives can be copied and backed-up like any other file - that means that if you need to install some program which may cause problems, you can just make a copy of your virtual drive and do the install - if there's trouble, just restore that backup and you're right back where you started. (That's also a great way to recover from a virus - just restore the backup hard-drive file, and you're good to go.) *** Your XP session is on one virtual screen, but you have as many other screens as you need - so while I have VisiLogic open on one screen, I can have another screen with spreadsheets, another with CAD files, and so on - just drag the mouse to switch between them. You can even have Linux windows overlaying the Windows window, so you can read from your documentation while typing into the Windows session underneath. *** If XP crashes (which it will, sooner or later), it doesn't affect the rest of the system. *** Your virtual hard drive is portable between computers - if you change motherboards or move to another computer, just copy the virtual hard drive file, and you have your XP session all set up. (Make sure you have the proper Microsoft license files if you want to run the same hard drive on more than one machine!) There are two versions of VirtualBox available - one is the Open Source version, VirtualBox OSE, and the other is the commercial version. The major difference is that the commercial version has better screen handling and handles USB ports - that lets you use a USB to Serial converter to talk to your Unitronics. The commercial version has a free trial, but it's well worth the $50 US price tag. So, if you're a Linux or Mac user, give VirtualBox a try. If you're a Windows user and want to try out Linux, I recommend Ubuntu Linux - if you need some help getting started, drop me a line, I'll be happy to assist.
  15. Is this compare function in a subroutine? I've often built a subroutine, but forgotten to call it from the main sequence program, so it monitors and appears correct, but it is never actually _run_.
  16. You'll be using the Protocol:Scan FB to read the incoming data stream, capturing the characters you are interested in to MI registers so that your ladder program can check their ranges and decide which message to send out. Hard to be more helpful without knowing more about the incoming data...
  17. In your "HW Configuration" page, you define the hardware you'll be using with your PLC. In those tabs, you'll see entries for the analogue inputs and outputs - assign MI registers for each input and output you'll be using. Your raw loadcell input will now show up in, for instance, MI 400. Now, scale that to match the output range you'll require for your analogue output - the "Linearization" FB will likely be quite helpful there - and place the value in the register you've selected for the analogue output, for example MI 410.
  18. I suspect what you've been doing is holding your finger on the screen while applying power to the unit - that is the "hidden" method of stopping the boot process to allow reload after, for example, an incomplete operating system upgrade. To get into info mode, power up the unit, then once the unit is sitting at a display screen (such as the "out of the box" Unitronics animation) touch the screen for four seconds, being careful not to move your finger around. Then you'll see the two boxes allowing you to select between "Enter Info Mode" and "Calibrate Touchscreen".
  19. I suspect you're seeing the result of putting a timer current value (which is a 32 bit number) into a 16 bit MI, and winding up trimming off the upper 16 bits of the data. This will only be a problem if the timer preset is large enough that it exceeds the size of 15 bits - the positive portion of a signed integer. (That's about five and a half minutes.)
  20. Using three variables is exactly how I do it - if you use a fixed width font, it can look pretty good.
  21. If the internal scan time value is not what you are looking for, you can use a timer of 10 or 100 seconds duration and count the number of scans in that time period. You can then divide by some multiple of ten to get various resolutions of timing (basically, moving the decimal point on the result to get scan time in milliseconds, 10 X microseconds, etc.)
  22. Starting up V570 ethernet connection from an "new out of the box" condition takes several steps: Go into the "Info Mode", enter the password (1111), go to "Version", then "Software", and write down the PLC Name that's at the bottom of the screen. Then hit "Escape" twice, select "Ethernet", then "IP Parameters", and enter your desired IP address and Netmask, then press "Apply". Hit "Escape", select "Socket Parameters", and set Socket 0's Port to 20256 and the TCP_UDP to "TCP Slave", then press "Apply". Now go to Visilogic and open your project. Go to "Connection", then "Communication & OS", set "Connection Type" to "TCP/IP Call", check the button for "Favorites", and click the folder icon on that line to open a list of PLC Names, IP Addresses, and ports. Put in the PLC name you wrote down, at the IP address you chose, and port 20256. After that information is entered, press the "Get OPLC Information" button - you should see the information about your PLC show up in those boxes. In order to get around having to do this for each new PLC, I have taken to naming all PLCs for a given customer by the same name, since we haven't yet had multiple V570 PLCs on an ethernet network in the plant - we just use it for programming, monitoring, debugging, and Modbus connection to Building Management systems. I put the PLC name, the SD Card password, and the TCP/IP initialization information in the first rung of the program - you can download an example framework program from the link at the bottom of this blog entry. I then can use the VisiLogic function "Project/Create Project Files" to create a clone file, with project and OS - selecting the latest OS available - and save that file with a name like "ETHERNET" (it has to be 8 characters). I use the SD Card Tools to format an SD Card to Unitronics layout, then put the ETHERNET.c57 file which I created in the /system directory of the SD card. I can then insert that SD card into the V570 PLC, go into INFO mode, select "SD", then "Clone", and "Upload to PLC". That loads the program in, which sets the ethernet IP address and port and sets up the PLC name to the proper one for that customer. Having the SD card with a minimal framework application lets me quickly initialize a new PLC and get it immediately ready to program and monitor over Ethernet.
  23. It'd be fiddly, but could you use the "Draw Line" function block in ladder logic to draw in an upper and lower process boundary line whenever the screen is displayed?
  24. When Programmable Logic Controllers were first introduced, their programs were geared toward the replacement of simple relay circuits. Logic statement 0 was processed first, then logic statement 1, and so on until an END instruction was reached. Then the PLC's supervisory software, or "Operating System", would do some housekeeping - update timers and counters, send outputs to the physical devices, read inputs from the physical devices, and run the user's stored program again. Logic statement five was never skipped, statement ten was never executed twice in a row. The addition of branch control instructions changed all that. Now all but the least expensive "Smart Relay" controllers have the ability for the program to decide that rather than go forward to the next instruction, the system should instead branch backward - to make a loop. Obviously, if that loop were to go on forever, the controller would never get to execute its housekeeping after the program's "END" instruction - so we have to be careful to limit how many loops we make. This power to make a loop, combined with the ability for the controller to do something slightly different each time through the loop, gives us the power to replace hundreds, even thousands of PLC instructions with a very small amount of PLC code - and to improve the program's reliability while we're at it. Let's take as an example the password scanning logic I wrote about last week. In that example program, I had eight nearly-identical rungs of logic - one to check the password for level one, one to check the password for level two, and so on. I could have, instead, written a small loop of program which counted from one to eight, checking the password that corresponded to that loop counter, and after the eighth time through, stopped looping and continued on to the rest of the program. The benefits to writing loops include using less program memory space, taking less of your time to enter than copying, pasting, and changing all those rungs, and decreasing the number of typos - if you process fifteen things in a loop, either they all work or they all don't. If you write them out longhand, then you may make a typo on number 12 and not notice it for years. The downside to writing loops is that the code is never obvious - PLCs tend not to have very clear methods of handling the kind of indirect addressing that loops use, and no two controller brands have the same indexing method. Also, it takes some setup and thought to get a loop working right - it is often easier to just cut and paste repeated rungs if there are only going to be two or three of them. (In this case, eight was right about at my limit - had it been twelve, I would have made it a loop right away.) So now that we know some of the rewards and pitfalls, let's recode those password checking rungs into a loop structure: First, we'll need to initialize a count variable for the loop. We'll start with MI 280 at zero, counting up and stopping when we reach eight. We then place a LABEL instruction, which is where the loop will jump back up to (PassLoop). Next, we take the value of MI 280 and use it as an _index_ into the list of passwords, pulling out the password for the current level and storing it in MI 281. We'll then have a single rung which checks passwords, just like the eight rungs we had before - the difference is that our new single rung will be processed eight times in a single scan. Finally, we increment the loop counter and go back to the top of the loop if the counter is less than 8. And that's it! We've cut the number of rungs in half, and once it's running, we're sure that if one password level works, they all do. So, next time you find yourself starting to copy and paste rungs, decide if you're feeling loopy instead! This is a downloadable link to a V570 application file containing the framework code with looped password checking - it has been released into the public domain, feel free to use it as a starting-point for making your own V570 projects. To learn more about Howman Controls, visit our web page at www.howman.com
  25. At power-up, take the current RTC registers, move the whole set of them to a batch of work registers with a vector copy. Change the time of day registers in the work area (hour, minutes, seconds) to the time of day you're trying to check on, and convert the work area to a UTC value. Take the DOW register from the work area, which is today's day of week, and use that to see how many days you need to back up the calculated UTC value to get to the desired day of week - subtract 86,400 times the number of days from that UTC value. That's now the UTC value for the time of day you're looking for, on the day of the week you're looking for. Now compare that UTC to the saved power-down UTC - if the saved value is less than the calculated "magic date/time", the PLC was powered off at that time.
×
×
  • Create New...