Как правильно преобразовать значения, полученные через 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

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

Мой ответ 513235958458 - вы должны получить три 16-битных числа, а не одно число, которое также находится за пределами допустимого диапазона для ushort. Не могли бы вы опубликовать реальные данные, которые вы получили?

Klaus Gütter 14.12.2020 11:40

@KlausGütter Да, я написал вместе по ошибке. Мой ответ 5132, 3595, 8458. В моем контексте получается 5132 [год] [месяц] 3595 [день] [час], 8458 [минута] [секунда]. Я не понимаю, как преобразовать в удобочитаемую дату.

Catsbreak 14.12.2020 11:48

@Клаус Гюттер Готово. Спасибо, что указали на ошибку.

Catsbreak 14.12.2020 11:53
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
684
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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

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