Cześć, wykonuje projekt korzystając z Javy a dokładniej z bilioteki JlibModbus i Matlaba. W Javie mam napisany regulator PID oraz tworzę tam obiekt ModbusMaster i łączę się z symulatorem Modbus, którym jest program mod_RSim pełniący w zasadzie funkcję bazy danych. W Matlabie mam obiekt o pewnej transmitancji i również łączę się z symulatorem poprzez port 502. Wszystko dzieje się póki co na jednym urządzeniu czyli adres IP jest ten sam. Problem mam z symulowaniem czasu. Nie wiem w jaki sposób zamknąć to wszystko w pętlę, żeby cała symulacja działa się cyklicznie w czasie rzeczywistym, lub aby np. jednej sekundzie symulacji odpowiadała jedna minuta czasu rzeczywistego. Cały ten proces można opisać tak:

  1. Matlab -> Przesłanie do mod_RSim wartości z wyjścia obiektu
  2. Java -> Pobranie przez program wartości wyjścia obiektu z mod_RSim i obliczenie na podstawie tej wartości i wartości zadanej uchybu sterowania
  3. Java -> Na podstawie uchybu sterowania obliczenie sygnału sterowania i przesłanie go do mod_RSim
  4. Matlab -> Pobranie wartości sygnału sterowania i podanie go na obiekt o określonej transmitancji.
    Niestety w Simulinku nie można utworzyć żadnego obiektu wspierającego komunikację Modbus TCP, przynajmniej ja o tym nie wiem. Istnieje możliwość połączenia skryptu Matlaba z Simulinkiem, ale również nie wiem jak zamknąć to wszystko w pętlę, żeby działo się to w czasie rzeczywistym

Przykładowy kod Matlaba wykorzystywanych funkcji:

t = tcpip('192.168.0.15',502);
fopen(t);
set(t,'Timeout',.5);
transaction_ID=uint8([0 0]);
protocol_ID=uint8([0 0]);
mod_function=uint8([3]); %odczyt n rejestrow
mod_message=uint8([0 0 0 3]); 
len=length([mod_function mod_message]);
data_length=uint8([0 len+1]); %ilosc bajtow function+message+unitID
unit_ID = uint8([1]);
mess=[transaction_ID protocol_ID data_length unit_ID mod_function mod_message]
fwrite(t,mess)
A = fread(t);
wartosc_zerowy_rejestr = A(10)*256+A(11)
%wartosc zapisana jest na dwoch bajtach, dlatego pierwszy bajt mnozymy razy
%256, jesli chcemy pobrac kolejna liczbe to bierzemy indeksy o 2 wieksze
fclose(t);

Kod Javy

public class MasterTCP {
    static public void main(String[] args) {
        try {
            ModbusMaster m = ModbusMasterFactory.createModbusMasterTCP(new TcpParameters("192.168.0.15", 502, true));
            Modbus.setAutoIncrementTransactionId(true);

            int slaveId = 2;
            int offset = 0;
            int quantity = 10;

            try {
                if (!m.isConnected()) {
                    m.connect();
                }

                int value = 122;
                m.writeSingleRegister(slaveId, 0, value);

            } catch (ModbusProtocolException e) {
                e.printStackTrace();
            } catch (ModbusNumberException e) {
                e.printStackTrace();
            } catch (ModbusIOException e) {
                e.printStackTrace();
            } finally {
                try {
                    m.disconnect();
                } catch (ModbusIOException e) {
                    e.printStackTrace();
                }
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}