Menu

Home

Doug Lyons
Attachments

2024-Dec-09

Version 8.21.2.9 is the current version.

This project is a fork of mod_RSsim (www.sourceforge.net/projects/modrssim) which is also hosted on this site.
I had run into this program a couple of times in the past, but I did not have time to try and learn a new program then.
At the end of 2014 I had a project where I needed a good Modbus simulator.
I was reminded of this on the forum for www.advancedhmi.com and I decided to review it for use in this application..

There were many things that I liked about this program such as:

1) It is free.
2) It has source code available.
3) It is programmed in a language that I might be able to use to modify, fix, or improve it.
4) It supports the full range of ALL of the four Modbus data types by default.
5) It has a diagnostics screen that shows you the traffic for the Modbus commands and responses.
6) It supports both RS-232 and TCP/IP connections.
7) It has support for Rockwell/Allen-Bradley protocols in which I have an interest.
8) It supports scripting which is interesting for simulations.
9) It has a support site where people had listed problems and some solutions.
10) It has built-in help by pressing the "F1" key.
11) It provides for handling all of the Modbus device ID's from 0 to 255 at once.

I started testing and trying to get it to compile in VC6. After several days and deleting many lines I could compile it.
The deleted code did not affect the functionality, but mostly registration and website update testing.
I was able to test a fix that was posted on the support page and it worked for me, so I thought that this was good.
Eventually I moved the project to Visual Studio 2010 and was able to compile it without deletions.

Shortly though I ran into several annoyances. The Editor did not allow me to edit CHAR or HEX data.
Another thing is that when I set the data format (Fmt:), when I used the program again it did not remember my setting.
The "CSV Read" was not documented and when I tried to use it based on what I saw in the code there were problems.
After a bit of testing I was able to fix the issues mentioned above and continue with my testing.
Other problems occurred such as the inconsistency of 5-digit versus 6-digit Modbus addressing that you can see here..

Error Example

I was able to fix these errors as well and make other changes, fixes and improvements.
For instance I was writing a group of about 32 bits to the program, but only the first few bits were showing changes.
What I found is that the update count was based on bytes and not bits and needed to be multiplied by eight.
After I made this change, the bits updated on the screen as I expected.

Eventually I decided that I wanted to make my changes and improvements available to others.
I created this SourceForge project to do that and continue to make updates as I find the need.

This project has been cloned on Github by Pavel Kostromitinov and can be found here:
https://github.com/Cavaler/ModRSsim2/

Project Members:


Discussion

  • Chuck

    Chuck - 2022-12-02

    How are two register 32bit floats simulated? Do I have to manually figure out the bytes and put in two consecutive registers or is there a way to enter the single value and the simulator can populate both registers?

     
  • Doug Lyons

    Doug Lyons - 2024-01-25

    Yes. If you select the format (Fmt:) as "float 32" this will show the numbers as floating point values and you can enter them directly here. Because we cannot know whether the two consecutive words start on an even or odd address, all addresses are displayed as if they were the beginning value, so you will have to know to use and look at only the odd or even displayed values. This does not allow for any word or byte swaps, but only uses the standard IEEE-32 bit floating point format as used in the later Modicon PLC's.

     
  • Don Burdette

    Don Burdette - 2024-03-20

    How do you write scripts?

    I have a customer with a Modbus client with no user I/O and they want to set the real-time clock. They suggested Open ModSim, and I learned enough javascript to write a script that reads the PC clock and writes time into holding registers. But I can't get it to respond to my requests.

    I downloaded ModRSsim2 and it replies to the request, but I need to get the time values from the PC's RTC into the registers.

    Thanks in advance.

     
  • Doug Lyons

    Doug Lyons - 2024-03-20

    Don, Please see if you don't have "clock.vbs" in your sources download folder. It shows how you can use the "timer" variable that is part of Visual Basic Script to get the time.

    Since it is small I will include it here:

    dim x
    dim n
    dim hr
    dim min
    dim sec

    n = int(timer/100)
    x = timer - n*100
    h = timer

    SetRegisterValue 3, 0, n
    SetRegisterValue 3, 1, x

    if ((int(x/10)*10 - x) >= -1) then
    SetRegisterValue 3, 2, x
    ' Or your code here
    end if

    hr = int(timer/60/60)
    min = int((timer - hr * 3600)/60)
    sec = timer - hr * 3600 - min * 60

    SetRegisterValue 3, 10, hr
    SetRegisterValue 3, 11, min
    SetRegisterValue 3, 12, sec

    For information on how to enable scripts use the "F1" help key from the main screen and search for "script".
    This does not handle the date. If you need more help, please respond back to me here.

    You might also want to review stack overflow on this topic here:
    https://stackoverflow.com/questions/7011357/how-do-i-get-the-date-time-vbs
    Thanks, Doug Lyons

     

    Last edit: Doug Lyons 2024-03-20
    • Don Burdette

      Don Burdette - 2024-03-21

      Hi Doug,

      Thanks for the fast response. I was going to post a message this morning that I had figured it out, but you beat me to it.

      I found the help page, and that told me I needed a VB script and some of the syntax I needed. Then googling 'vb script date' gave me the functions I needed. I ended up with this:

      dim d
      d = Now()
      SetRegisterValue 3, 1, DatePart("s", d)
      SetRegisterValue 3, 2, DatePart("n", d)
      SetRegisterValue 3, 3, DatePart("h", d)
      SetRegisterValue 3, 4, DatePart("w", d)
      SetRegisterValue 3, 5, DatePart("d", d)
      SetRegisterValue 3, 6, DatePart("m", d)
      SetRegisterValue 3, 7, DatePart("yyyy", d)

      This is exactly what I need. It's a great tool, and way easier to use than the other one I tried. Thanks for supporting it.

      Don

      From: wiki@modrssim2.p.re.sourceforge.net wiki@modrssim2.p.re.sourceforge.net On Behalf Of Doug Lyons
      Sent: Wednesday, March 20, 2024 5:31 PM
      To: [modrssim2:wiki] Home@wiki.modrssim2.p.re.sourceforge.net
      Subject: [modrssim2:wiki] Discussion for Home page

      You don't often get email from douglyons@users.sourceforge.netdouglyons@users.sourceforge.net. Learn why this is importanthttps://aka.ms/LearnAboutSenderIdentification

      Don, Please see if you don't have "clock.vbs" in your sources download folder. It shows how you can use the "timer" variable that is part of Visual Basic Script to get the time.

      Since it is small I will include it here:

      dim x
      dim n
      dim hr
      dim min
      dim sec

      n = int(timer/100)
      x = timer - n*100
      h = timer

      SetRegisterValue 3, 0, n
      SetRegisterValue 3, 1, x

      if ((int(x/10)*10 - x) >= -1) then
      SetRegisterValue 3, 2, x
      ' Or your code here
      end if

      hr = int(timer/60/60)
      min = int((timer - hr * 3600)/60)
      sec = timer - hr * 3600 - min * 60

      SetRegisterValue 3, 10, hr
      SetRegisterValue 3, 11, min
      SetRegisterValue 3, 12, sec

      For information on how to enable scripts use the "F1" help key from the main screen and search for "script".
      This does not handle the date. If you need more help, please respond back to me here.
      Thanks, Doug Lyons


      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/modrssim2/wiki/Home/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       
  • Don Burdette

    Don Burdette - 2024-03-25

    Hi Doug,

    My customer is saying they want the time in UTC. I've seen some posts showing how to read the registry time offset, but I can't get them to work.

    Here's what one says to do:
    Dim var_offset
    Dim WshShell
    set WshShell = WScript.CreateObject("WScript.Shell")
    var_offset = WshShell.RegRead("HKLM\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias")
    d = DateAdd("n", var_offset, Now())

    But as soon as I add the 'set' line it stops working. I guess you aren't running wscript interpreter? Any suggestions on how to do this?

    TIA

     
  • Don Burdette

    Don Burdette - 2024-03-25

    Oops! I should have read your post more carefully. The stack overflow link shows how to do it. Thanks!

     
  • Don Burdette

    Don Burdette - 2024-03-25

    Or maybe not. When I try to run this it doesn't update. If I comment out the for loop it updates, but it doesn't have the UTC offset. I'm also not sure I see how to get the bias for the local time zone.

    dim d
    dim offset
    offset = 0

    Dim wmi : Set wmi = GetObject("winmgmts:root\cimv2")
    Set timeZones = wmi.ExecQuery("SELECT Bias, Caption FROM Win32_TimeZone")
    For Each tz In timeZones
    tz.Bias = -300
    tz.Caption = (UTC-05:00) Eastern Time (US & Canada)
    Next
    d = DateAdd("n", offset, Now())

    'd = Now()
    SetRegisterValue 3, 1, DatePart("s", d)
    SetRegisterValue 3, 2, DatePart("n", d)
    SetRegisterValue 3, 3, DatePart("h", d)
    SetRegisterValue 3, 4, DatePart("w", d)
    SetRegisterValue 3, 5, DatePart("d", d)
    SetRegisterValue 3, 6, DatePart("m", d)
    SetRegisterValue 3, 7, DatePart("yyyy", d)

     
  • Doug Lyons

    Doug Lyons - 2024-03-26

    Don,

    It seems to me you should be able to just look up this key's value in the machine manually:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\Bias.

    Then just take this value (300 for Eastern Time) and plug it into the script as shown below.

    dim d

    d = DateAdd("n", 300, Now())

    SetRegisterValue 3, 1, DatePart("s", d)
    SetRegisterValue 3, 2, DatePart("n", d)
    SetRegisterValue 3, 3, DatePart("h", d)
    SetRegisterValue 3, 4, DatePart("w", d)
    SetRegisterValue 3, 5, DatePart("d", d)
    SetRegisterValue 3, 6, DatePart("m", d)
    SetRegisterValue 3, 7, DatePart("yyyy", d)

    Because "Now()" will be automatically updated for Daylight Time by default, this should work.
    Note that you do not want the "ActiveTimeBias" because this changes for Standard Time and Daylight Time, so you would be double compensating if you used this dynamic value.
    You should not need to even read the registry, just use the offset based on their Time Zone.

    Doug Lyons

     
  • Don Burdette

    Don Burdette - 2024-03-26

    My task is to set the machine's clock to UTC using a PC connected by modbus. Hundreds of these will be deployed across the country and beyond. Requiring manual intervention by the end user is not an option.

    So, not at all knowing what I'm doing, I've been slogging around the swamp for a while, and I think I stumbled on the answer. I ended up here:
    https://learn.microsoft.com/en-us/windows/win32/wmisdk/swbemdatetime

    Based on that, I came up with this, which appears to work:

    Set dateTime = CreateObject("WbemScripting.SWbemDateTime") 'create a date/time object
    dateTime.SetVarDate(Now()) 'put the current time into the object
    d = dateTime.GetVarDate (false) 'the false value retreives UTC time

    SetRegisterValue 3, 1, DatePart("s", d) 'load seconds into modbus holding register at address 1
    SetRegisterValue 3, 2, DatePart("n", d) 'minutes
    SetRegisterValue 3, 3, DatePart("h", d) 'hours
    SetRegisterValue 3, 4, DatePart("w", d) 'day of the week
    SetRegisterValue 3, 5, DatePart("d", d) 'date (day of month)
    SetRegisterValue 3, 6, DatePart("m", d) 'month
    SetRegisterValue 3, 7, DatePart("yyyy", d) 'full year

     
  • Kali

    Kali - 2024-09-11

    Hi. Is it possible to run 2 instances of ModRSsim2 with to different IP?. I need to simulate 2 diferent IP both with the same ID.

     
  • Doug Lyons

    Doug Lyons - 2024-10-01

    Hello, Kali. The ModRSSim2 server takes its IP address from the computer that it is running on.
    Therefore, it is possible by doing something similar to the following.
    Install a Virtual Machine server such as Virtual Box or VMWare. Now install an operating system in two seperate instances. You can find a free version of ReactOS that is capable of running this at
    https://sourceforge.net/projects/reactos/files/ReactOS/0.4.15-ReleaseCandidates/.
    Set these two machines to have dedicated IP addresses that correspond to the two IP address that you want to simulate. Install ModRSSim2 in each of these machines. Good Luck. Doug Lyons

     

    Last edit: Doug Lyons 2024-10-01
  • AMILCAR DUARTE

    AMILCAR DUARTE - 2024-10-26

    Hello Mr. Doug,

    I am new to ModRSim2, and I have been trying to update IEEE32 floats using the scripts, with no luck so far.

    Using the SetRegisterValue and GetRegisterValue I can only manipulate one register at a time, and the float32 gets truncated.

    All the VBS solutions I have found for converting IEEE32 to two words or to four bytes, and vice-versa, seem to use VB functions that are not accepted by the script compiler.

    Do you have any workaround for handling float32 in ModRSim2 ?

    Thanks in advance

     
  • Doug Lyons

    Doug Lyons - 2024-11-04

    Mr. Duarte,

    If you look at the 2nd row of selections near the top of the display, there is one that shows "Fmt:".
    You can use the pull-down selection and set this to "float 32". This will allow you some options.
    Because a 32-bit float takes two 16-bit registers, they can begin on either an even or odd address.
    Since the system does not know which is intended, the display attempts to show both values.
    So you have to decide whether to read/write to the even or odd address.
    I see that you reference "SetRegisterValue" and "GetRegisterValue".
    These functions do not support setting floating point registers at this time.
    But since the source code is provided, it would be possible to extend it fairly easily to do this.
    You could use REG_TYPE of 5 (which is not used) to indicate a 32-bit float number.
    Now the programming would have to be extended to handle the details, but it could be done.
    Otherwise, you would have to enter the 32-bit float as two Set/Get Register Values.
    I hope that this helps. Good Luck. Doug Lyons

     
  • AMILCAR DUARTE

    AMILCAR DUARTE - 2024-11-06

    Mr. Doug,

    Thank you very much for the feedback.

    I have explored a little bit more of the software and, following up on your sugestion, I was able to implement the Set/Get float32 in VBS.

     
  • Doug Lyons

    Doug Lyons - 2024-11-12

    Mr. Duarte,
    Would you be willing to share your VBS code here so that it might benefit others? Thanks.
    Doug Lyons

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.