0

I am getting data in my console program on C# with library Nmodbus4 from a device via modbus rtu. Format: 32 bit floating point.I am request the device by registers 0x0D – 0x0F. My response is 5132, 3595, 8458 .And this answer should match 2020 12 14 11:33:~35. i.e data format are [year][month][day][hour][minute][seconds]. Below my code:

using Modbus.Device;
using Modbus.Utility;
using System;
using System.Collections;
using System.Globalization;
using System.IO.Ports;

namespace Elemer19
{ 
    class Program
    {
        static void Main(string[] args)
        {  
            string[] pathFolder = ReadDirectory.readDir();
            Console.WriteLine("OPENING COM PORT - {0}", pathFolder[0]);

            byte slaveID = 4;
            ushort startAddress = 0x0D;
            ushort numOfPoints = 3;

            SerialPort _serialPort = new SerialPort(pathFolder[0],
                             9600,
                             Parity.None,
                             8,
                             StopBits.One);  
            try
            { 
                _serialPort.Open();

                ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(
                    _serialPort);
                master.Transport.ReadTimeout = 300;
 
                ushort[] date = master.ReadHoldingRegisters(slaveID, startAddress, numOfPoints); 
                    
                foreach (int item in date)
                {
                    Console.Write("\r\n{0}", item);  //5132, 3595, 8458
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(DateTime.Now.ToString() + ":Connect process " + ex.StackTrace +
               "==>" + ex.Message);
            }
 
            Console.ReadLine();
 
        }
    }}

Date format in the device: date and time in the combined bit field of the two registers (starting with the least significant bit of the least significant byte):

seconds - (bits 0 ... 5 - values ​​0 ... 59)
minutes - (bits 6 ... 11 - values ​​0 ... 59)
hours - (bits 12 ... 16, values ​​0 ... 23)
number - (bits 17 ... 21, values ​​0 ... 30) - days 1 ... 31
month - (bits 22 ... 25, values ​​0 ... 11) - months January ... December
year - (bits 26 ... 31, values ​​0 ... 63) - years 2000 ... 2063

How to get the date value correctly?

Catsbreak
  • 23
  • 6
  • *My response is 513235958458* - you should get three 16-bit numbers, not one number which also is out of range for ushort. Could you please post the real data you get? – Klaus Gütter Dec 14 '20 at 10:40
  • @KlausGütter Yes, I wrote together by mistake. My answer is 5132, 3595, 8458. In my context, it turns out 5132 [year] [month] 3595 [day] [hour], 8458 [minute] [second]. I don't understand how to convert to a readable date. – Catsbreak Dec 14 '20 at 10:48
  • @KlausGütter Done. Thanks for pointing out the error. – Catsbreak Dec 14 '20 at 10:53

1 Answers1

2

Your bit-decoding information seems to be wrong.

If you write the three numbers as individual bytes (20, 12, 14, 11, 33, 10), you will see that your expected value can be directly extracted from these bytes:

DateTime ConvertToDateTime(ushort[] data)
{
    var year = (int)(data[0] >> 8);
    var month = (int)(data[0] & 0xFF);
    var day = (int)(data[1] >> 8);
    var hour = (int)(data[1] & 0xFF);
    var minute = (int)(data[2] >> 8);
    var second = (int)(data[2] & 0xFF);
    
    return new DateTime(2000 + year, month, day, hour, minute, second);
}

yields: 2020-12-14 11:33:10

Klaus Gütter
  • 11,151
  • 6
  • 31
  • 36