Dealing with MODBUS

0 37
Avatar for wabinab
6 months ago

OK, particularly, one was dealing with this sensor thingy that comes with quite a bad documentation, so it was painful dealing with it. The first thing, after you get it powered up and connected on MODBUS/TCPIP (assuming you don't use the older RS232 or RS485), it's to find the damn IP address. Basically, when checking the documentation, it tells me it has an IP address of 192.168.0.X, where X is what you have to find yourself. So, let's get to the steps.

First, when connected via ethernet, most probably the device has IP but the computer can't detect it, so you need to change the ethernet's IP address first. On windows, this means going to "Network and Sharing Center" (type npca.cpl in command prompt), and check the Ethernet. You're gonna go to "Properties" (right click and click properties from the dropdown, or double click and click properties on the modal), wait for the page to load, then click on the "Internet Protocol Version 4 (TCP/IPv4)" twice, it'll open up a modal where you can choose "Use the following IP address".

Now, when we don't know the IP address, what we're gonna do is just simply put in an IP address, so for example, I just randomly choose 150 or whatsoever (whatever IP that's not being used at the current moment) so that's 192.168.0.150. Then, set subnet mask 255.255.255.0. Leave Default Gateway Empty. Then, click "Ok" all the way out. If you now type ipconfig on cmd, you should see the new IP.

Next, download an IP scanner, such as Angry IP Scanner (or another one on your choice). First, remember to include the port to scan, which is 502, by clicking on "Tools" --> "Preferences" --> "Ports" and add it on "Port Selection" textbox (text area). Then, choose to scan IP range from 192.168.0.0 to 192.168.0.254. Upon finish scanning, find the one that has port 502 open. Mine, I got 192.168.0.18, and remember this may be different from what you set earlier since you picked a random guy to fix ethernet no 192.168.0.x issue (otherwise it'll give you a random ip like 169.254.y.z which we don't want).

Now that you get the IP, you can start the client to see if it can get data or not. For example, some people use the Modbus Poll (Modbus Master Simulator) and ensure you scan the holding registry (40000-40999); at least that's in my case, I'm checking for data stored inside the registry to get started. But if you use something else like Modbus Monitor XPF, it uses the address of 6-digit rather than 5-digit, so 400,000-400,999 instead of 40,000-40,999. So, it's the same, but different convention.

Now, what you need to remember, is change the SlaveId scan to 255 (It's called UnitId in Modbus Monitor XPF). By default, UnitId is 1, which isn't the broadcasting ID. Broadcasting ID means whatever the actual UnitId is, it can be read from 255 (provided you only connect one single device). Then, checking the documentation, they probably write down the default UnitId for you. In my case, it's 254. So, I could either read the device data from 255 (broadcasting), or 254 (device-specific).

Next, is to change its parameters. For example, if you want your device to connect to the router rather than directly to your computer, you would change the gateway, the ip address, and possibly the subnet mask. Also, you may decide to change the device id, etc. But you have to be careful, because if you make a mistake and click save (on one's device, that's changing the "port" address to save internet configuration), there's no way to connect back; unless your device has a built-in factory-reset button, which isn't in one's case. For example, one can't connect one's device because one accidentally save port from 502 to 1, and until I checked port 1, one didn't manage to connect and couldn't find the problem.

Then, you could proceed on. Here are some problems one encountered while playing with the sensor (not necessarily fits the title of ModBus but yeah one's gonna put in anyways even if it's out of topic).

Calibration

Sensors come with default factory calibration data, and it's crucial to understand how calibration works. By right, one don't understand how it works in the beginning. For example, one thought that the calibration has two poles: min and max. So by setting min to "true" when I give it an input signal of 0V, it calibrates to that, then setting max to "true" when I give it an input signal of N Volts (via a sensor output or a battery, depending how you play with it), then it'll calibrates to that value. But it seems not. Therefore, it seems like one couldn't calibrate it to factory data after one calibrate it oneselves.

Later, one pull all the values from holding registries, and one saw that they're calibrated to min = 0, max = 4095, so that means that the range is now reset to factory calibration (ignore the fact that there may be accuracy/precision loss in calibration, which one encounters, without knowing the reason; perhaps because one give it an input larger than it can take that causes it to lose some calibration accuracy/precision???). If we instead set it to min = 0, max = 3000, then the actual factory calibration is still there, but your display (especially if you use percentage) will range from 0-3000 instead. Though, other default types like 0-10V if you don't set to min = 0, max = 4095, would be inaccurate (unless your device has some loss of precision/accuracy that you may say that, min = 0, max = 4092, to recalibrate for the inaccuracies). In this case:

  • After testing with a meter that you believed/proved is more accurate and precise, the actual value of the battery is 7.52V, but your device shows 7.59V. Therefore, raising the "min" would help. Here, we set min = 118, max = 4095. Now, it can recalibrate to approximately correct values.

  • After testing with a meter that you believed/proved is more accurate and precise, the actual value of the battery is 7.52V, but your device shows 7.45V. Therefore, reducing the "max" would help. Here, we set min = 0, max = 3977. Now, it recalibrates with approximately correct values. (max values are guessed, untested)

  • As for how the values are selected? In the first case, you change to "raw" with batteries pluck in, see the values is 3111, then 7.52/10*4096 = 3080.192 \approx 3080. Therefore, you're gonna raise the min slowly by slowly until it displays the desired. Unfortunately, it isn't as easy as 3111-3080 = 31 then you can say min = 31; which doesn't work. As for other methods, one isn't sure.

Data Types

Ok, most modbus has a u16 data type, which ranges from 0 - 65535 inclusive. However, that's not always the case. For example, even though that's the only possible store, they could store an u32 data type by taking up two registries; or they could just store u8 that is parse-able with just normal u16 type; and sometimes, if they need negative, they could use i16 data types. That's what happens in one's case.

For most except the sensor readings and an address, it uses the u16 data type (or parse-able u8 to u16). Then, there's the address which one don't know how to parse, but it seems like it's either 4 registries of u32, or two pair of registries of u32, perhaps as a decimal value, one before the dot, and one after the dot. Both probable. For the sensor data, on the other hand, it's i16, because a 10k Thermistor has a standard range of -50°C to 150°C (although one isn't sure why one's sensor supports only -50°C to 110°C for 10V standard, weird). Anyways, the focus is on "negative", which means we need to use a signed integer (i16) instead of an unsigned one (u16). Therefore, it needs to be parsed differently.

Sensor Limitations

If the sensor receiver machine says it can afford 0-10V (well, not mentioned explicitly but from its choices), then don't insert something that's well passed 10V. For example, one tried 12V, and then the current starts leaking into other ports as well. So, that's unprotected.

Addressing/Registry Standards

Yes, the documentation might mentioned what addresses/registers are available, save what information, read-only or read/write. But, there are quite a lot of ways to interpret. First, is it input register or holding register, which input register starts with 30x and holding register starts with 40x. Then, is it 5 digit or 6-digit: which actually depends on the library or program you used. Say, one program, one could access the register address 0 with 400001 and another with 40000. Now, see another difference? Some addressing starts with zero so you need to add 1 to all listed address, while others follow the computer convention and starts at 0. One used to accidentally write into the wrong register; nothing too bad happen, sometimes they have write protection; but it's possible to get things really bad like write the wrong ip or port then you don't know which one you write, and you cannot reset, so you need to try connect and can't connect, etc.

Conclusion

All in all, MODBUS isn't easy to deal with. The internet does have a list that says this is what and that is what, but one haven't found a good explanation site that could tell you what each of each means, hence this blog. Generally, you could experiment around and see what works. There are ways to try it out!

Remember to Like and Subscribe!

1
$ 0.00
Sponsors of wabinab
empty
empty
empty
Avatar for wabinab
6 months ago

Comments