Библиотека Сетевые переменные и управление/чтение портов различных МК в сети

MaksVV
Offline
Зарегистрирован: 06.08.2015

Допустим МК соединены по какой нибудь сети  - RS485, Serial или CAN (а возможно ли это в STM32?). Хочется чтобы между ними были единые перемменные, ну или правельнее сказать, навереное, переменные которые синхронизируются между собой. Возможна ли примерно такая библиотека? или это утопия.  Также хотелось бы по простому рулить портами различных контроллеров в сети.  

например как то так для сети RS485

#include <RS485.h>

mainRS485 MK_01;     // адрес данного МК в сети

rs485 int RTCHour;     // объявление сетевых переменных
rs485 int RTCMinute;
rs485 int RTCSecond;

   

void setup() {
Serial.begin (9600);

RS485.begin (MK_01, MK_02, MK_03, MK_04,); //инициализация контроллеров в сети

}

void loop() {

RS485.read();   // синхронизация с другими контроллерами сети

if (RTCMinute == 0 && digitalRead (MK_03.port_10, LOW)) {   //если сетевая переменная RTCMinute = 0 и порт 10 в контроллере MK_03 в LOW
    digitalWrite (MK_03.port_13, HIGH);   // включить встроенный светодиод на контроллере МК_03
}
}

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

Спустя год все таки дошли руки победить мою хотелку. А все потому что есть такая программа FLProg. В ней реализовано программирование ардуино графически, жутко непонятная вещь для меня. Но там есть создание сети Модбас (на RS485). В первых вариантах программы у меня ничего не получалось, т.к. регистры данных модабаса все были в одной области памяти (нельзя было например создать в сети переменную boolean, только int). но вот вышло обновление FLProg до версии 2.4. Посмотрел, увидел изменения в организации модбаса (тут уже разделения по регистрам и автор проги перестал использовать стандартную корявую библиотеку модбас для ардуино, а создал свою), попробовал - получилось. 

В итоге FLProg использую только для создания скетча сети модбаса и прикручиваю всё это к моим скетчам. Не легко это, т.к. FLProg  создает скетчи при компиляции хоть и такие же - в ардуино IDE, но, ппц трудно читаемые. 

Короче всё что за loop )) тупо копипастю, переменные до setup тоже. Ну а в loopе не трудно догадаться что и куда приравнять. 

В итоге Сделал мастер и слейв, см. ниже скетчи.  На мастере тактовая кнопка, встроенный светодиод 13, часы реального времени далласа. На слейве тактовая кнопка, встроенный светодиод 13, LCD экран. 

Первое. Состояние светодиода засинхронизировано - горит на обоих МК или выключен на обоих МК. Т.е. включили на одном кнопкой (светики включились на обоих МК), выключить можем на другом (при этом естевенно выключаться тоже оба). За это отвечает bool переменная модбаса. Тут инфа ходит туда сюда, мастер - слейв, слейв - мастер.

Второе. Время (часы и минуты) передаются от мастера к слеву. На слейве часы выводятся на экран. За это отвечают int переменные модбаса. Тут инфа ходит только от мастера к слейву. (но можно также сделать тутда сюда, или только от слейва к мастеру). 

мастер

#include <RTC.h>
RTC  time;
int  Minuta;  // gtv1
int  Chas;    // gtv2
int  Day;     // gtv3
int  Weekday; // gtv4
int  Month;  //  gtv5


// для сети Modbus 
bool _modbusMasterDataTable_0_reg_1[1];
int _modbusMasterAddressTable_0_reg_1[1] = {0};
int _modbusMasterDataTable_4_reg_1[2];
int _modbusMasterAddressTable_4_reg_1[2] = {0, 1};
byte _modbusMasterBufferSize = 0;
byte _modbusMasterState = 1;
long _modbusMasterSendTime;
byte _modbusMasterLastRec = 0;
long _modbusMasterStartT35;
byte _modbusMasterBuffer[64];
byte _modbusMasterCurrentReg = 0;
byte _modbusMasterCurrentVariable = 0;
struct _modbusMasterTelegramm {
  byte slaveId;        
  byte function;        
  int startAddres;   
  int numbeRegs;   
  int valueIndex;
};
_modbusMasterTelegramm _modbusTelegramm;
long _startTimeMasterRegs[1];
long _updateTimeMasterRegsArray[] = {1000};
byte _readWriteMasterVars[] = {1,3,3};
const unsigned char _modbusMaster_fctsupported[] = {1, 5, 3, 6, 16};
bool svet = 0; //свет контроллера
bool buttonON = 0;
#define button 6

unsigned long Time, timer=0;
bool timerenabled=false;
#define TIMEREXPIRED (Time-timer)>3000 


bool lastbutton = 1;
bool currentbutton = 0;

bool debounce (bool last){
bool current = digitalRead (button);
if (last != current) {delay (20); current = digitalRead (button);}
return current; }

void setup()
{
  
Serial.begin(9600);
time.begin(RTC_DS3231);    
pinMode(10, OUTPUT);
digitalWrite(10, LOW);
pinMode (button, INPUT); digitalWrite(button, HIGH);
pinMode (13, OUTPUT); digitalWrite(13, LOW);

for(int i=0; i<1; i++) {_startTimeMasterRegs[i] =  millis();}
}
void loop()
{bool _tempVariable_bool;
int _tempVariable_int;

Time = millis();
digitalWrite (13, svet);
if (digitalRead (button)==1) buttonON = 0;
if (!buttonON){ if(digitalRead (button) == 0) {buttonON = 1; svet = !svet ;  
_tempVariable_bool = svet;
if (! (_tempVariable_bool == _modbusMasterDataTable_0_reg_1[0])) {_readWriteMasterVars[0] = 5;};
_modbusMasterDataTable_0_reg_1[0] = _tempVariable_bool; timer=Time;  timerenabled=true;}}

currentbutton = debounce (lastbutton);

_tempVariable_int = Minuta;
if (! (_tempVariable_int == _modbusMasterDataTable_4_reg_1[0])) {_readWriteMasterVars[1] = 6;};
_modbusMasterDataTable_4_reg_1[0] = _tempVariable_int;
_tempVariable_int = Chas;
if (! (_tempVariable_int == _modbusMasterDataTable_4_reg_1[1])) {_readWriteMasterVars[2] = 6;};
_modbusMasterDataTable_4_reg_1[1] = _tempVariable_int;



if (timerenabled){    if (TIMEREXPIRED) timerenabled=false; 
  }

//Плата:1
if (timerenabled==0) { if (digitalRead (button) == 1) svet = (_modbusMasterDataTable_0_reg_1[0]);
}

switch ( _modbusMasterState ) {
    case 1:
      _nextModbusMasterQuery();
      break;
    case 2:
      pollModbusMaster();
      break;
  }
time.gettime();
Minuta = time.minutes;
Chas = time.Hours;
Day = time.day;
Weekday = time.weekday;
Month = time.month; 
}

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;
}
void _nextModbusMasterQuery()
{
_selectNewModbusMasterCurrentReg(_modbusMasterCurrentReg, _modbusMasterCurrentVariable);
if (_modbusMasterCurrentReg == 0)  return;
_createMasterTelegramm();
_modbusMasterSendQuery();
}
void _selectNewModbusMasterCurrentReg(byte oldReg, byte oldVar)
{
bool isNeeded = 1;
if (oldReg == 0) {_selectNewModbusMasterCurrentReg(1, 0); return;}
if (!(_isTimer  ((_startTimeMasterRegs[oldReg - 1]),(_updateTimeMasterRegsArray[oldReg -1])))) {isNeeded = 0;}
if( ! isNeeded ) {if(oldReg < 1) {_selectNewModbusMasterCurrentReg(oldReg+1, 0); return;} else {_modbusMasterCurrentReg = 0; _modbusMasterCurrentVariable = 0; return;}}
if (oldVar == 0) {_modbusMasterCurrentReg = oldReg; _modbusMasterCurrentVariable = 1; return;}
byte temp;
switch (oldReg) {
case 1:
temp = 3;
 break;
 }
if (oldVar < temp) {_modbusMasterCurrentReg = oldReg; _modbusMasterCurrentVariable = oldVar +1; return;}
_startTimeMasterRegs[oldReg -1] = millis();
if(oldReg < 1) { _selectNewModbusMasterCurrentReg(oldReg+1, 0); return;} 
_modbusMasterCurrentReg = 0; _modbusMasterCurrentVariable = 0; return;
}
void _createMasterTelegramm()
{
switch (_modbusMasterCurrentReg) {
case 1:
_modbusTelegramm.slaveId = 1;
switch (_modbusMasterCurrentVariable) {
case 1:
_modbusTelegramm.function = _readWriteMasterVars[0];
_modbusTelegramm.startAddres = 0;
_modbusTelegramm.numbeRegs = 1;
_modbusTelegramm.valueIndex = 0;
_readWriteMasterVars[0] = 1;
break;
case 2:
_modbusTelegramm.function = _readWriteMasterVars[1];
_modbusTelegramm.startAddres = 0;
_modbusTelegramm.numbeRegs = 1;
_modbusTelegramm.valueIndex = 0;
_readWriteMasterVars[1] = 3;
break;
case 3:
_modbusTelegramm.function = _readWriteMasterVars[2];
_modbusTelegramm.startAddres = 1;
_modbusTelegramm.numbeRegs = 1;
_modbusTelegramm.valueIndex = 1;
_readWriteMasterVars[2] = 3;
break;
}
break;
}
}
void _modbusMasterSendQuery()
{
bool boolTemp;
int intTemp;
byte currentIndex = _modbusTelegramm.valueIndex;
  _modbusMasterBuffer[0]  = _modbusTelegramm.slaveId;
  _modbusMasterBuffer[1] = _modbusTelegramm.function;
  _modbusMasterBuffer[2] = highByte(_modbusTelegramm.startAddres );
  _modbusMasterBuffer[3] = lowByte( _modbusTelegramm.startAddres );
  switch ( _modbusTelegramm.function ) {
case 1:
case 3:
 _modbusMasterBuffer[4] = highByte(_modbusTelegramm.numbeRegs );
      _modbusMasterBuffer[5] = lowByte( _modbusTelegramm.numbeRegs );
      _modbusMasterBufferSize = 6;
      break;
case 5:
 switch ( _modbusMasterCurrentReg ) {
case 1 :
boolTemp = _modbusMasterDataTable_0_reg_1[currentIndex];
break;
}
      if (boolTemp) {
        _modbusMasterBuffer[4] = 0xff;
      } else {
        _modbusMasterBuffer[4] = 0;
      };
      _modbusMasterBuffer[5] = 0;
      _modbusMasterBufferSize = 6;
      break;
case 6:
 switch ( _modbusMasterCurrentReg ) {
case 1 :
intTemp = _modbusMasterDataTable_4_reg_1[currentIndex];
break;
}
      _modbusMasterBuffer[4]      = highByte(intTemp);
      _modbusMasterBuffer[5]      = lowByte(intTemp);
      _modbusMasterBufferSize = 6;
      break;
}
  _modbusMasterSendTxBuffer();
  _modbusMasterState = 2;
}
void _modbusMasterSendTxBuffer()
{
 byte i = 0;
int crc = modbusCalcCRC( _modbusMasterBufferSize, _modbusMasterBuffer );
  _modbusMasterBuffer[ _modbusMasterBufferSize ] = crc >> 8;
_modbusMasterBufferSize++;
 _modbusMasterBuffer[ _modbusMasterBufferSize ] = crc & 0x00ff;
 _modbusMasterBufferSize++;
UCSR0A=UCSR0A |(1 << TXC0);
digitalWrite(10, 1 );
delay(5);
Serial.write( _modbusMasterBuffer, _modbusMasterBufferSize );
 while (!(UCSR0A & (1 << TXC0)));
digitalWrite(10, 0 );
Serial.flush();
  _modbusMasterBufferSize = 0;
  _modbusMasterSendTime = millis();
}
void pollModbusMaster()
{
if (_modbusTelegramm.slaveId == 0) {   _modbusMasterState = 1;   return;}
  if (_isTimer(_modbusMasterSendTime, 1000)) {
    _modbusMasterState = 1;
    return;
  }
  byte avalibleBytes = Serial.available();
  if (avalibleBytes == 0) return;
  if (avalibleBytes != _modbusMasterLastRec) {
    _modbusMasterLastRec = avalibleBytes;
    _modbusMasterStartT35 = millis();
    return;
  }
  if (!(_isTimer(_modbusMasterStartT35, 5 ))) return;
  _modbusMasterLastRec = 0;
  byte readingBytes = _modbusMasterGetRxBuffer();
  if (readingBytes < 5) {
    _modbusMasterState = 1;
    return ;
  }
byte exeption = validateAnswer();
  if (exeption != 0) {
 _modbusMasterState = 1;
    return;
  }
 switch ( _modbusMasterBuffer[1] ) {
case 1:
get_FC1(0);
break;
 case 3:
 get_FC3(4);
break;
}
  _modbusMasterState = 1;
  return;
}
byte _modbusMasterGetRxBuffer()
{
boolean bBuffOverflow = false;digitalWrite(10, LOW );
 _modbusMasterBufferSize = 0;
  while (Serial.available() ) {
    _modbusMasterBuffer[ _modbusMasterBufferSize ] = Serial.read();
    _modbusMasterBufferSize ++;
    if (_modbusMasterBufferSize >= 64) bBuffOverflow = true;
  }
  if (bBuffOverflow) {return -3;}
  return _modbusMasterBufferSize;
}
byte validateAnswer()
{
uint16_t u16MsgCRC =    ((_modbusMasterBuffer[_modbusMasterBufferSize - 2] << 8) | _modbusMasterBuffer[_modbusMasterBufferSize - 1]);
  if ( modbusCalcCRC( _modbusMasterBufferSize - 2,_modbusMasterBuffer ) != u16MsgCRC ) { return 255; }
  if ((_modbusMasterBuffer[1] & 0x80) != 0) {return _modbusMasterBuffer[2] ;}
  boolean isSupported = false;
  for (byte i = 0; i < sizeof( _modbusMaster_fctsupported ); i++) {
    if (_modbusMaster_fctsupported[i] == _modbusMasterBuffer[1]) {
      isSupported = 1;

      break;
    }
  }
  if (!isSupported) {return 1;}
  return 0;
}
void get_FC1(byte table)
{
 byte currentByte = 3;
  byte currentBit = 0;
bool value;
  byte i;
  int currentIndex = _modbusTelegramm.valueIndex;
  for (i = 0; i < _modbusTelegramm.numbeRegs; i++) {
 value= bitRead(_modbusMasterBuffer[currentByte], currentBit);
switch ( _modbusMasterCurrentReg ) {
case 1 :
if(table == 0) {_modbusMasterDataTable_0_reg_1[currentIndex] =value;}
break;
}
currentIndex ++;
    currentBit ++;
    if (currentBit > 7) {
      currentBit = 0;
      currentByte ++;
    }
  }
  _modbusMasterState = 1;
}
void get_FC3(byte table)
{
int currentIndex = _modbusTelegramm.valueIndex;
  byte currentByte = 3;
int value;
  for (int i = 0; i < _modbusTelegramm.numbeRegs; i++) {
   value = word( _modbusMasterBuffer[ currentByte],   _modbusMasterBuffer[ currentByte + 1 ]);
switch ( _modbusMasterCurrentReg ) {
case 1 :
if(table == 3) {} else {_modbusMasterDataTable_4_reg_1[currentIndex + i] =value;}
break;
}
    currentByte += 2;
  } 
}

 

слейв 

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);

int  Minuta;  // gtv1
int  Chas;    // gtv2
int  Day;     // gtv3
int  Weekday; // gtv4
int  Month;  //  gtv5


bool _modbusSlaveDataTable_0[1];
int _modbusSlaveAddresTable_0[1] = {0};
int _modbusSlaveDataTable_4[2];
int _modbusSlaveAddresTable_4[2] = {0, 1};
byte _modbusSlaveBufferSize = 0;
byte _modbusSlaveLastRec = 0;
long _modbusSlaveTime;
byte _modbusSlaveBuffer[64];
const unsigned char _modbusSlave_fctsupported[] = {1, 5, 15, 3, 6, 16};
bool svet = 0; //Свет в контроллере

bool buttonON = 0;
#define button 6

unsigned long time, timer=0;
bool timerenabled=false;
#define TIMEREXPIRED (time-timer)>3000 


bool lastbutton = 1;
bool currentbutton = 0;

bool debounce (bool last){
bool current = digitalRead (button);
if (last != current) {delay (20); current = digitalRead (button);}
return current; }


void setup()
{
Serial.begin(9600);
pinMode(10, OUTPUT);
digitalWrite(10, LOW);

lcd.begin();
lcd.backlight();

lcd.clear ();
pinMode (button, INPUT); digitalWrite(button, HIGH);
pinMode (13, OUTPUT); digitalWrite(13, LOW);
}
void loop()
{_modbusSlavePoll();



time = millis();
digitalWrite (13, svet);
if (digitalRead (button)==1) buttonON = 0;
if (!buttonON){ if(digitalRead (button) == 0) {buttonON = 1; svet = !svet ;  


_modbusSlaveDataTable_0[0] = svet; timer=time;  timerenabled=true;}}

currentbutton = debounce (lastbutton);

  Minuta  = (_modbusSlaveDataTable_4[0]);  
  Chas    = (_modbusSlaveDataTable_4[1]);    
  

if (timerenabled){    if (TIMEREXPIRED) timerenabled=false; 
  }


if (timerenabled==0) { if (digitalRead (button) == 1) svet = (_modbusSlaveDataTable_0[0]);
}



lcd.setCursor (0,0); 
if (Chas<10) {lcd.print ("0");}
lcd.print (Chas); lcd.print (" : "); 
if (Minuta<10) {lcd.print ("0");}
lcd.print (Minuta); lcd.print ("         ");
if (svet) {lcd.setCursor (0,1);
lcd.print ("CBET VKLUCHEN!!!");}
else {lcd.setCursor (0,1);
lcd.print ("                ");}
 
}

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 1 :
   return process_modbus_FC1(0);
      break;
case 5:
      return process_modbus_FC5();
      break;
 case 15:
      return process_modbus_FC15();
      break;
 case 3 :
      return process_modbus_FC3(4);
      break;
  case 6 :
      return process_modbus_FC6();
      break;
 case 16 :
      return process_modbus_FC16();
      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 1:
 if(!(checkModbusRange( word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3]) , word( _modbusSlaveBuffer[4], _modbusSlaveBuffer[5]) ,0))){return 2;}
 break;
case 5:
if(!(checkModbusAddres( word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3]),0))){return 2;}     
        break;
case 15 :
 if(!(checkModbusRange(word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3]) , word( _modbusSlaveBuffer[4], _modbusSlaveBuffer[5]) ,0))){return 2;}
 break;
case 6 :
if(!(checkModbusAddres(( word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3]) ),4))){return 2;}     
        break;
case 3 :
case 16 :
 if(!(checkModbusRange((word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3])), (word( _modbusSlaveBuffer[4], _modbusSlaveBuffer[5])),4))){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 0:
tableSize = 1;
break;
case 4:
tableSize = 2;
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 0:
return _modbusSlaveAddresTable_0[index];
break;
case 4:
return _modbusSlaveAddresTable_4[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(10, HIGH );
  delay (5);
Serial.write( _modbusSlaveBuffer, _modbusSlaveBufferSize );
 while (!(UCSR0A & (1 << TXC0)));
  delay (5);
digitalWrite(10, LOW );
Serial.flush();
  _modbusSlaveBufferSize = 0;
}
byte _modbusGetSlaveRxBuffer()
{
  boolean bBuffOverflow = false;
digitalWrite(10, 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 == 0) {value = _modbusSlaveDataTable_0[index]; } 
 bitWrite(
      _modbusSlaveBuffer[ _modbusSlaveBufferSize ],
      bitsNo,
      value);
    bitsNo ++;
    if (bitsNo > 7) {
      bitsNo = 0;
      _modbusSlaveBufferSize++;
    }
  }
  if (coilNo % 8 != 0) _modbusSlaveBufferSize ++;
  _modbusSlaveSendTxBuffer();
  return _modbusSlaveBufferSize + 2;
}
byte process_modbus_FC3(byte table)
{
  int startAddr = word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3] );
  int byteRegsno = word( _modbusSlaveBuffer[4], _modbusSlaveBuffer[5] );
  int i;
  int value;
byte index;
  _modbusSlaveBuffer[ 2 ]  = byteRegsno * 2;
  _modbusSlaveBufferSize = 3;
  for (i = startAddr; i < startAddr + byteRegsno; i++) {
index = modbusSlaveIndexForAddres(i, table);
if (table == 4) {value = _modbusSlaveDataTable_4[index]; } 
  _modbusSlaveBuffer[ _modbusSlaveBufferSize ] = highByte(value);
    _modbusSlaveBufferSize++;
    _modbusSlaveBuffer[ _modbusSlaveBufferSize ] = lowByte(value);
    _modbusSlaveBufferSize++;
  }
   _modbusSlaveSendTxBuffer();
  return _modbusSlaveBufferSize + 2;
}
byte process_modbus_FC5()
{
 byte index;
 int coil = word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3] );
index = modbusSlaveIndexForAddres(coil, 0);
_modbusSlaveDataTable_0[index] = (_modbusSlaveBuffer[4] == 0xff );
  _modbusSlaveBufferSize = 6;
  _modbusSlaveSendTxBuffer();
  return  _modbusSlaveBufferSize + 2;
}
byte process_modbus_FC15( ) 
{
byte  frameByte, bitsNo;
  byte currentCoil, coil;
 byte index;
int startCoil = word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3] );
int coilNo = word( _modbusSlaveBuffer[4], _modbusSlaveBuffer[5] );
bitsNo = 0;
frameByte = 7;
for (currentCoil = 0; currentCoil < coilNo; currentCoil++) {
coil = startCoil + currentCoil;
index = modbusSlaveIndexForAddres(coil, 0);
_modbusSlaveDataTable_0[index] = bitRead( _modbusSlaveBuffer[ frameByte ], bitsNo );
bitsNo ++;
    if (bitsNo > 7) {
      bitsNo = 0;
      frameByte++;
    }
  }
  _modbusSlaveBufferSize = 6;
  _modbusSlaveSendTxBuffer();
  return _modbusSlaveBufferSize + 2;
}
byte process_modbus_FC6()
{
 int addres = word( _modbusSlaveBuffer[2], _modbusSlaveBuffer[3] );
 int index;
index = modbusSlaveIndexForAddres(addres, 4);
_modbusSlaveDataTable_4[index] =word( _modbusSlaveBuffer[4], _modbusSlaveBuffer[5] );
  _modbusSlaveBufferSize = 6;
  _modbusSlaveSendTxBuffer();
  return _modbusSlaveBufferSize + 2;
}
byte process_modbus_FC16(  ) 
{
byte func = _modbusSlaveBuffer[1];
  int startAddr = _modbusSlaveBuffer[2] << 8 | _modbusSlaveBuffer[3];
  int byteRegsno = _modbusSlaveBuffer[4] << 8 | _modbusSlaveBuffer[5];
  int i;
 int index;
  _modbusSlaveBuffer[4]   = 0;
  _modbusSlaveBuffer[5]   = byteRegsno;
  _modbusSlaveBufferSize = 6;
  for (i = 0; i < byteRegsno; i++) {
index = modbusSlaveIndexForAddres((startAddr+i), 4);
_modbusSlaveDataTable_4[index] =word( _modbusSlaveBuffer[ 7 + i * 2 ],  _modbusSlaveBuffer[8 + i * 2 ]);
  }
  _modbusSlaveSendTxBuffer();
  return _modbusSlaveBufferSize +2;
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

MaksVV. А то на то и выходит. Или хрень на FLProg или хрень на С++. Последняя это потому хрень, что С++ большинство банально плавают и даже (о ужас) тонут.