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:
- Matlab -> Przesłanie do mod_RSim wartości z wyjścia obiektu
- 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
- Java -> Na podstawie uchybu sterowania obliczenie sygnału sterowania i przesłanie go do mod_RSim
- 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();
}
}
}
- mod_RSim.png (89 KB) - ściągnięć: 50