реклама на сайте
подробности

 
 
5 страниц V  < 1 2 3 4 > »   
Reply to this topicStart new topic
> FreeModbus
MrYuran
сообщение Mar 3 2011, 08:28
Сообщение #16


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 3 2011, 10:44) *
Так где я не прав?

Покажите ещё СВ-функцию чтения регистров
Далее, ReadOutputRegisters - это какая функция? (код функции)
Вообще-то, при чтении Input регистров как бы нужна функция ReadInput, но точно можно определить по коду.
Ну или пакет запроса приведите.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 3 2011, 08:28
Сообщение #17


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



В разных реализациях по разному отсчитываются адреса. Holding начинаются с 40000 по терминологии modbus, а в вызове функции может быть отсчёт и от 0, и от 1. Попробуйте вот этой утилитой потестить:
http://www.chipkin.com/cas-modbus-scanner
В ней, например, для чтения holding register 9 нужно задать такие настройки (см аттач).
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 3 2011, 08:47
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Со стороны мастера (ПК)
Код
//Modbus Functions
const BYTE CModbus::READ_OUTPUT_REGISTERS      = 3;


из примера freemodbus:
Код
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;

    if( ( usAddress >= REG_INPUT_START )
        && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegInputStart );
        while( usNRegs > 0 )
        {
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}


пакет запроса:
Код
01 03 03 E8 00 01 04 7A

ответ:
Код
01 83 04 40
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 3 2011, 09:14
Сообщение #19


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Сдаётся мне, вы холдинги хотите прочитать вместо инпутов.
Проверьте тогда ещё константы
REG_HOLDING_START и REG_HOLDING_NREGS

Для чтения Input регистров функция 04


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 3 2011, 09:59
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



со стороны мастера изменил запрос на
Код
01 04 03 E8 00 01 B1 BA


ответ уже без ошибки:
Код
01 04 02 00 00 B9 30


но это не то, что я ожидаю получить. Я должен получить инкрементированное значение usRegInputBuf[0]++;
Что еще не так?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 3 2011, 10:10
Сообщение #21


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 3 2011, 12:59) *
но это не то, что я ожидаю получить. Я должен получить инкрементированное значение usRegInputBuf[0]++;
Что еще не так?

А вот тут уже возможно играет смещение на 1.
Попробуйте ещё соседний регистр поменять.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 3 2011, 10:17
Сообщение #22


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



Если я ничего не путаю, в ответе должно быть два байта ячейки usRegInputBuf[0]. Если вы её никак не инициализируете, то будет возвращаться неопределённое значение. Скорее всего именно нули.
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 3 2011, 10:27
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(Dimoza @ Mar 3 2011, 14:17) *
в ответе должно быть два байта ячейки usRegInputBuf[0]. Если вы её никак не инициализируете, то будет возвращаться неопределённое значение. Скорее всего именно нули.

Глобальная переменная инициализируется нулем. Дальше в цикле она инкрементируется:
Код
usRegInputBuf[0]++;

Т.е. я должен увидеть на приеме 0,1,2,3...

Цитата(MrYuran @ Mar 3 2011, 14:10) *
А вот тут уже возможно играет смещение на 1.
Попробуйте ещё соседний регистр поменять.

а вот так:
Код
usRegInputBuf[1]++;

уже отвечает то, что нужно!

А где необходимо добавить это смещение на 1 ?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 4 2011, 09:05
Сообщение #24


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 3 2011, 13:27) *
А где необходимо добавить это смещение на 1 ?

Ну, чтобы не лезть в глубины, можно в CB-функции подправить вычисление iRegIndex
Хотя, идеологически более правильно залезть внутрь и разобраться, почему так.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 4 2011, 22:35
Сообщение #25


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Вот ответ автора freemodbus на проблему смещения адреса:
Код
MODBUS protocol address (Base0) is Address 1 in the FreeMODBUS stack. The term PLC address is no longer correct.
The MODBUS PDU addresses registers at 0. The MODBUS application protocol start address at 1.
For MODBUS POLL testing simply add 1 to the register you set when you use Base 0 and you should get the address which FreeMODBUS uses.


т.е. нужно добавить 1 в определении
#define REG_HOLDING_START 1001

PS. А вопрос был такой:
Код
I’m using Modbus Poll to debug he FreeModbus programs. If REG_HOLDING_START is set to be 1000, the valid address of Modbus Poll looks like this:
PLC Addresses (Base1) = 31000
Protocol Addresses (Base0) = 00999
But if REG_HOLDING_START is set to be 0, the first address of Protocol Addresses cannot be found because the address cannot be -1.
Do you recommend not to use REG_HOLDING_START = 0 in this case?
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 4 2011, 23:00
Сообщение #26


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



Насколько я уяснил это для себя, "по-простому", в modbus нумерация регистров и койлов начинается с 1. Так для пользователя оборудования будет проще: сложно обычному человеку понять, что такое нулевой датчик. А вот 1, 2, 3 и так далее - уже проще. НО! В передаваемом пакете modbus этому самому 1-му датчику будет соответствовать адрес 0.
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 5 2011, 10:26
Сообщение #27


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Как правильно передать код ошибки MB_EX_SLAVE_BUSY = 0х06 , в случае, если SLAVE занят вычислениями, т.е. результат еще не готов?
Функцию опроса ModBus я поместил в другую функцию, которую периодически вызываю по таймеру:
Код
void MBPoll()
{
  (void)eMBPoll();
}

Я вижу выход такой:
в функции eMBErrorCode eMBRegHoldingCB(...) по глобальному флагу Busy,
Код
if(Busy) eStatus = MB_ETIMEDOUT;
else
...
, возвращаемое значение из этой функции преобразуется в исключение MB_EX_SLAVE_BUSY;
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 5 2011, 11:29
Сообщение #28


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 5 2011, 13:26) *
Я вижу выход такой:

Ну да, как-то так.
Я, кстати, смещение на 1 тоже задал в дефайне, не долго думая sm.gif
(заглянул по случаю, освежил память)


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 7 2011, 11:47
Сообщение #29


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Еще для полного счастья нужно использовать функции для записи\чтения битов ForceSingleCoil (0x05), ReadSingleCoil(0x01).
Приведите, пожалуйста, пример с использованием этих функций. Флаги, битовое поле в области ввода-вывода ниже 0x1f.
Код
// Flags
typedef union
{
    unsigned char Complete;   // Access all 8 bits
    
    struct
    {
        bool IsTestCompleted   : 1;    
        bool IsDataReady      : 1;      
        bool IsRelayOn          : 1;  
        bool IsReset          : 1;  
        bool IsOverheat          : 1;  
        bool IsKeyPressed      : 1;
        bool IsOpenoff              : 1;  
        bool IsShortcut          : 1;  
    };
} FLAGS;
__no_init volatile FLAGS Flags@0x28; // Флаги, битовое поле в области ввода-вывода ниже 0x1f (ACSR Register)
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 7 2011, 16:14
Сообщение #30


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 7 2011, 14:47) *
Еще для полного счастья нужно использовать функции для записи\чтения битов ForceSingleCoil (0x05), ReadSingleCoil(0x01).

Не пробовал, т.к. особого смысла не вижу.
Не проще ли все флаги оптом передать в регистре статуса, например?


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post

5 страниц V  < 1 2 3 4 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 09:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.01505 секунд с 7
ELECTRONIX ©2004-2016