Как правильно преобразовать значения, полученные через modbus?

Я получаю данные в своей консольной программе на C# с библиотекой Nmodbus4 с устройства через modbus rtu. Формат: 32 бит с плавающей запятой. Я запрашиваю устройство по регистрам 0x0D – 0x0F. Мой ответ 5132, 3595, 8458. И этот ответ должен соответствовать 2020 12 14 11:33:~35. т.е. формат данных: [год][месяц][день][час][минута][секунды]. Ниже моего кода:

      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();
 
        }
    }}

Формат даты в устройстве: дата и время в объединенном битовом поле двух регистров (начиная с младшего бита младшего значащего байта):

      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

Как правильно получить значение даты?

1 ответ

Ваша информация о битовом декодировании кажется неверной.

Если вы запишете три числа в виде отдельных байтов (20, 12, 14, 11, 33, 10), вы увидите, что ожидаемое значение можно извлечь непосредственно из этих байтов:

      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);
}

выходы: 2020-12-14 11:33:10

Другие вопросы по тегам