Обязательно.mixalych писал(а):Автор в обучающих видео задает адрес и скорость порта надо ли это делать в версии 2.5.1?
1. Значения двух датчиков кладёшь в соседние регистры, считываешь как int32(long int), в скада одно получаешь делением на 65536, другое остаток от деления на 65536. Можно похожим образом передать и три значения, зависит от размерности исходников.JonyBest писал(а):Пользуюсь связкой Демо-версией Simple-Scada 2 и OPC-сервер Modbus Universal MasterOPCВсе устраивает, но в последнее время возник дефицит бесплатных тегов Modbus........
За второе отдельное спасибо! А по первому можно пример на два и три значения, не догоняю как...Sancho писал(а):Значения двух датчиков кладёшь в соседние регистры, считываешь как int32(long int), в скада одно получаешь делением на 65536, другое остаток от деления на 65536. Можно похожим образом передать и три значения, зависит от размерности исходников.2. Овен ОРС
Сокращая переменные в одном месте, Вы увеличиваете их в другом, раздуваете программу счётчиком и т.д.KSP писал(а):но для сокращения числа переменных пользуюсь вот таким нехитрым приспособлением
Если разобрались с ОРС, то не забивайте себе мозг.JonyBest писал(а):За второе отдельное спасибо! А по первому можно пример на два и три значения, не догоняю как...
Код: Выделить всё
bool _modbusSlaveDataTable_1[1];
int _modbusSlaveAddresTable_1[1] = {0};
byte _modbusSlaveBufferSize = 0;
byte _modbusSlaveLastRec = 0;
long _modbusSlaveTime;
byte _modbusSlaveBuffer[64];
const unsigned char _modbusSlave_fctsupported[] = {2};
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
pinMode(10, INPUT);
digitalWrite(10, HIGH);
pinMode(11, OUTPUT);
}
void loop()
{_modbusSlavePoll();
//Плата:1
digitalWrite(11, !( (digitalRead (10))));
_modbusSlaveDataTable_1[0] = !( (digitalRead (10)));
}
bool _isTimer(unsigned long startTime, unsigned long period )
{
unsigned long currentTime;
currentTime = millis();
if (currentTime>= startTime) {return (currentTime>=(startTime + period));} else {return (currentTime >=(4294967295-startTime+period));}
}
int modbusCalcCRC(byte length, byte bufferArray[])
{
unsigned int temp, temp2, flag;
temp = 0xFFFF;
for (unsigned char i = 0; i < length; i++) {
temp = temp ^ bufferArray[i];
for (unsigned char j = 1; j <= 8; j++) {
flag = temp & 0x0001;
temp >>= 1;
if (flag) temp ^= 0xA001;
}
}
temp2 = temp >> 8;
temp = (temp << 8) | temp2;
temp &= 0xFFFF;
return temp;
}
byte _modbusSlavePoll()
{
byte avalibleBytes = Serial.available();
if (avalibleBytes == 0) return 0;
if (avalibleBytes != _modbusSlaveLastRec) {
_modbusSlaveLastRec = avalibleBytes;
_modbusSlaveTime = millis();
return 0;
}
if (!(_isTimer(_modbusSlaveTime, 5))) return 0;
_modbusSlaveLastRec = 0;
byte state = _modbusGetSlaveRxBuffer();
if (state < 7) {
return state;
}
if ((_modbusSlaveBuffer[0] != 1) && (_modbusSlaveBuffer[0] != 0)) return 0;
byte exception = _modbusValidateRequest();
if (exception > 0) {
if (exception != 255) { _modbusSlaveBuildException( exception );
_modbusSlaveSendTxBuffer();
}
return exception;
}
switch ( _modbusSlaveBuffer[1] ) {
case 2 :
return process_modbus_FC1(1);
break;
default:
break;
}
return 25;
}
byte _modbusValidateRequest() {
int msgCRC =
((_modbusSlaveBuffer[_modbusSlaveBufferSize - 2] << 8)
| _modbusSlaveBuffer[_modbusSlaveBufferSize - 1]);
if ( modbusCalcCRC( _modbusSlaveBufferSize - 2, _modbusSlaveBuffer ) != msgCRC ) { return 255;}
boolean isSupported = false;
for (uint8_t i = 0; i < sizeof( _modbusSlave_fctsupported ); i++) {
if (_modbusSlave_fctsupported[i] == _modbusSlaveBuffer[1]) {
isSupported = 1;
break;
}
}
if (!isSupported) { return 1;}
int intRegs = 0;
byte byteRegs;
switch ( _modbusSlaveBuffer[1] ) {
case 2 :
if(!(checkModbusRange(word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3]) , word( _modbusSlaveBuffer[4], _modbusSlaveBuffer[5]),1))){return 2;}
break;
}
return 0; // OK, no exception code thrown
}
bool checkModbusAddres(int addr, byte table)
{
return (!(( modbusSlaveIndexForAddres(addr,table)) == -1));
}
int modbusSlaveIndexForAddres(int addr, byte table)
{
int tableSize = 0;
switch (table) {
case 1:
tableSize = 1;
break;
}
for (byte i = 0; i < tableSize; i++) {if((modbusSlaveAddresFromIndex(i,table)) == addr){return i;}}
return -1;
}
int modbusSlaveAddresFromIndex(byte index, byte table)
{
switch (table) {
case 1:
return _modbusSlaveAddresTable_1[index];
break;
}
return -1;
}
bool checkModbusRange(int startAddr, int addrNumber, byte table)
{
for (int i=0; i < addrNumber; i++) {if(!(checkModbusAddres((startAddr+i),table))){return false;}}
return true;
}
void _modbusSlaveBuildException( byte exception ) {
byte func = _modbusSlaveBuffer[1];
_modbusSlaveBuffer[0] = 1;
_modbusSlaveBuffer[1] = func + 0x80;
_modbusSlaveBuffer[ 2 ] = exception;
_modbusSlaveBufferSize = 3;}
void _modbusSlaveSendTxBuffer()
{
if(_modbusSlaveBuffer[0] == 0) {return;}
byte i = 0;
int crc = modbusCalcCRC( _modbusSlaveBufferSize,_modbusSlaveBuffer );
_modbusSlaveBuffer[ _modbusSlaveBufferSize ] = crc >> 8;
_modbusSlaveBufferSize++;
_modbusSlaveBuffer[ _modbusSlaveBufferSize ] = crc & 0x00ff;
_modbusSlaveBufferSize++;
UCSR0A=UCSR0A |(1 << TXC0);
digitalWrite(13, HIGH );
delay (5);
Serial.write( _modbusSlaveBuffer, _modbusSlaveBufferSize );
while (!(UCSR0A & (1 << TXC0)));
delay (5);
digitalWrite(13, LOW );
Serial.flush();
_modbusSlaveBufferSize = 0;
}
byte _modbusGetSlaveRxBuffer()
{
boolean bBuffOverflow = false;
digitalWrite(13, LOW );
_modbusSlaveBufferSize = 0;
while (Serial.available() ) {
_modbusSlaveBuffer[ _modbusSlaveBufferSize ] = Serial.read();
_modbusSlaveBufferSize ++;
if (_modbusSlaveBufferSize >= 64) bBuffOverflow = true;
}
if (bBuffOverflow) {return -3; }
return _modbusSlaveBufferSize;
}
byte process_modbus_FC1(byte table)
{
byte bytesNo, bitsNo;
int currentCoil, coil;
bool value;
byte index;
int startCoil = word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[ 3] );
int coilNo = word( _modbusSlaveBuffer[4], _modbusSlaveBuffer[5] );
bytesNo = byte(coilNo / 8);
if (coilNo % 8 != 0) bytesNo ++;
_modbusSlaveBuffer[2] = bytesNo;
_modbusSlaveBufferSize = 3;
bitsNo = 0;
for (currentCoil = 0; currentCoil < coilNo; currentCoil++) {
coil = startCoil + currentCoil;
index = modbusSlaveIndexForAddres(coil, table);
if (table == 1) {value = _modbusSlaveDataTable_1[index]; }
bitWrite(
_modbusSlaveBuffer[ _modbusSlaveBufferSize ],
bitsNo,
value);
bitsNo ++;
if (bitsNo > 7) {
bitsNo = 0;
_modbusSlaveBufferSize++;
}
}
if (coilNo % 8 != 0) _modbusSlaveBufferSize ++;
_modbusSlaveSendTxBuffer();
return _modbusSlaveBufferSize + 2;
}