-
1. Data: 2023-04-05 11:26:36
Temat: Multiplekser/sniffer/arbiter modbus
Od: heby <h...@p...onet.pl>
Cześć.
Sytuacja:
1) Jest urządzenie X
2) Jest podpięty do niego, przez RS486/modbus sterownik Y
3) Rejestry i komunikacja rozpracowane
4) chciałbym *nie* odpinać oryginalnego sterownika, ale czasami wysłać
własne polecenie, niejako "wtrącając" się do rozmowy.
Potrzebuję coś w rodzaju arbitera/multipleksera do modbus na rs485.
Wyobrażam sobie to tak, że arbier ma 2 porty dla rs485 i zapewnia prawie
normalną komunikację miedzy nimi (metodą store&forward). Sterowanikowi
wszystko jedno, czy dostanie ramkę odpowiedzi wprost z X czy będzie ona
wygenerowana identyczna przez moje urządzenie z bufora.
Raz na jakiś czas mogę zbuforować zapytanie Y i wysłać priorytetowo
moje, po czym wznowić komunikację z bufora jak gdby nic się nie stało. X
dostanie stwoją odpowiedź, tylko minimalnie później. Przypuszczalnie,
jeśli zmieszczę się w timeout w Y to nie powinno mieć problemu.
Ostatecznie mogę przyczaić się aż urządzenie zakończy komunikację i
natychmiast wysłać swoją ramkę. Można mieć rózne strategie.
Czyli problem softwareowy, store&forward i kolejka z priorytetem.
W zasadzie to jest łatwe do zrobienia na uC, ale zanim wyciągnę
lutownicę: widział ktoś może taki projekt albo gotowe urządzenie? Nie
chcę nic drogiego - w ramach hobby mogę sobie je zrobić sam, ale może
ktoś już takie popełnił. W sumie to uC z dwoma UARTami i z tysiąc lini kodu.
-
2. Data: 2023-04-05 20:26:54
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: Dawid Rutkowski <d...@w...pl>
A ja masz zamiar generować tą "wtrącaną" ramkę?
Czy zawsze taka sama, triggerowana guziczkiem?
A odpowiedź potrzebujesz?
W sumie nie wiem czy w modbus jest jakkolwiek zestandaryzowany multi-master...
-
3. Data: 2023-04-05 20:40:01
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: heby <h...@p...onet.pl>
On 05/04/2023 20:26, Dawid Rutkowski wrote:
> A ja masz zamiar generować tą "wtrącaną" ramkę?
To mało istotne. Po prostu coś wrzuci jakieś zapytanie w środek bałaganu.
> A odpowiedź potrzebujesz?
Tak.
> W sumie nie wiem czy w modbus jest jakkolwiek zestandaryzowany multi-master...
Nie ma, muszę go zrobić na kolanie.
-
4. Data: 2023-04-05 21:31:07
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: Piotrek <p...@p...na.berdyczow.info>
On 05.04.2023 20:40, heby wrote:
> On 05/04/2023 20:26, Dawid Rutkowski wrote:
>> W sumie nie wiem czy w modbus jest jakkolwiek zestandaryzowany
>> multi-master...
>
> Nie ma, muszę go zrobić na kolanie.
A rzeczywisie musisz? Nie możesz sobie zrobić "man in the middle" na
przykład używając tego:
https://github.com/cwalter-at/freemodbus
Przy czym mogę rekomendować wyłącznie slave - działa od ładnych kilku
lat bez przerwy. Z master się nie bawiłem.
Piotrek
-
5. Data: 2023-04-05 21:58:23
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: heby <h...@p...onet.pl>
On 05/04/2023 21:31, Piotrek wrote:
>>> W sumie nie wiem czy w modbus jest jakkolwiek zestandaryzowany
>>> multi-master...
>> Nie ma, muszę go zrobić na kolanie.
> A rzeczywisie musisz? Nie możesz sobie zrobić "man in the middle"
Dokładnie to chcę sobie zrobić. Z tą róznicą, że nie pasywny sniffer,
ale aktywny arbiter, co sprowadza się do trochę większej algroytmiki
buforowania. Ale to tylko kwestia programistyczna, do ogarnięcia.
Liczyłem na jakiś ... powiedzmy ... gotowiec z 3 dziurkami RS485,
obsługujący 2 masterów i 1 slave. Chyba nie jestem jedyny na świecie z
takim pomysłem ;)
> na
> przykład używając tego:
> https://github.com/cwalter-at/freemodbus
Tak, mogę zrobić sam, modbus jest prosty jak budowa cepa od strony
firmware. Tu chodzi o pytanie, czy całośc (hardware+firmware) nie
została już raz zrobiona przez kogoś, na przykład od IoT, strasznie
lubię dowiedywac się pod koniec projektu, że ktoś już go zrobił lepiej,
a ja straciłem czas na wynajdywanie kwadratowego koła.
-
6. Data: 2023-04-05 22:28:10
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: Piotrek <p...@p...na.berdyczow.info>
On 05.04.2023 21:58, heby wrote:
>> A rzeczywisie musisz? Nie możesz sobie zrobić "man in the middle"
>
> Dokładnie to chcę sobie zrobić. Z tą róznicą, że nie pasywny sniffer,
> ale aktywny arbiter, co sprowadza się do trochę większej algroytmiki
> buforowania. Ale to tylko kwestia programistyczna, do ogarnięcia.
Osadzone we FreeRTOS - zasadniczo samo się pisze ;-)
>
> Liczyłem na jakiś ... powiedzmy ... gotowiec z 3 dziurkami RS485,
> obsługujący 2 masterów i 1 slave. Chyba nie jestem jedyny na świecie z
> takim pomysłem ;)
GPT twierdzi, że nie ma ;-)
"[...]
Unfortunately, there are no known open-source projects that implement a
two-master, one-slave Modbus architecture. However, you can start with
existing Modbus libraries (e.g., libmodbus, FreeModbus) and modify them
according to the outlined approach to develop your custom solution."
ale przyciśnięty do muru
Are you sure there is no such open source project?
zaczął programować w Python. LOL
"I apologize if my previous response may have been unclear. While it is
challenging to be aware of every single open-source project available,
to the best of my knowledge (as of the knowledge cutoff in September
2021), there was no specific open-source project that implements a
two-master, one-slave Modbus architecture.
However, you may find open-source projects that implement Modbus
gateways or proxies, which you could adapt to achieve the desired
two-master, one-slave communication. One such project is modbus-tk, a
Python library that allows you to create Modbus masters and slaves, and
it includes a TCP to Serial gateway implementation.
Project Repository: https://github.com/ljean/modbus-tk
Here's a basic example of how you can use modbus-tk to create a Modbus
TCP to Serial gateway:
python
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp
from modbus_tk import modbus_rtu
def main():
# Configure Modbus RTU master
master_rtu = modbus_rtu.RtuMaster(
modbus_tk.utils.create_serial_handler(port="/dev/tty
S0")
)
master_rtu.set_timeout(5.0)
master_rtu.set_verbose(True)
# Configure Modbus TCP server
server_tcp = modbus_tcp.TcpServer(address="0.0.0.0", port=502)
server_tcp.start()
# Main loop to process Modbus TCP requests and forward them to
Modbus RTU
while True:
try:
request = server_tcp.get_request(blocking=True)
if request is not None:
response = master_rtu.execute(
request.slave_id,
request.function_code,
request.starting_address,
request.quantity_of_x,
request.output_value,
)
request.set_response(response)
except modbus_tk.modbus.ModbusError as exc:
print("Error processing request:", str(exc))
if __name__ == "__main__":
main()
This example creates a Modbus TCP server that forwards incoming requests
to a Modbus RTU master. You could extend this example to support two
Modbus TCP masters and manage the communication with the single Modbus
RTU slave.
Please note that this example uses Python, and you would need to adapt
the code to your specific requirements, such as handling communication
conflicts between the two masters."
P.
-
7. Data: 2023-04-05 22:44:23
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: heby <h...@p...onet.pl>
On 05/04/2023 22:28, Piotrek wrote:
> GPT twierdzi, że nie ma ;-)
GPT twierdzi, że to, jak jest najszybsza furmanka na świecie, zależy od
pojemności silnika. Nie dodał, czy jelit.
-
8. Data: 2023-04-05 23:02:43
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: Piotrek <p...@p...na.berdyczow.info>
On 05.04.2023 22:44, heby wrote:
> On 05/04/2023 22:28, Piotrek wrote:
>> GPT twierdzi, że nie ma ;-)
>
> GPT twierdzi, że to, jak jest najszybsza furmanka na świecie, zależy od
> pojemności silnika. Nie dodał, czy jelit.
>
A kto by tam się przykładał do roboty za darmo? ;-)
Ale wracając do naszych baranów ... będąc ciekawym czego można oczekiwać
od GPT, odświeżyłem sobie swój projekt sprzed lat.
Let's go back to the freemodbus library.
I need a client that waits for incoming write coil commands and performs
a specific action depending on the coil number.
Could you give me a code sample to implement such requirements.
"
To create a Modbus RTU Slave (client) using the FreeModbus library,
which waits for incoming Write Coil commands and takes specific actions
based on the coil number, you can follow the example below:
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "mb.h"
#include "mbport.h"
#define MB_USART_PORT_NUM (1) // Change this to the correct USART port
number
#define MB_SLAVE_ADDRESS (1) // Change this to the correct slave address
#define MB_COIL_START_ADDRESS (0) // Starting address of the coil
#define MB_COIL_COUNT (10) // Number of coils
static UCHAR ucCoilBuf[MB_COIL_COUNT / 8 + 1]; // Coil buffer
eMBErrorCode eMBRegCoilsCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT
usNCoils, eMBRegisterMode eMode) {
eMBErrorCode eStatus = MB_ENOERR;
int iNCoils = (int)usNCoils;
USHORT usCoilStart = usAddress - MB_COIL_START_ADDRESS;
if ((usCoilStart + usNCoils) <= MB_COIL_COUNT) {
if (eMode == MB_REG_WRITE) {
while (iNCoils > 0) {
USHORT usByteOffset = usCoilStart / 8;
UCHAR ucBitOffset = 1 << (usCoilStart % 8);
UCHAR ucByte = pucRegBuffer[usByteOffset];
if (ucByte & ucBitOffset) {
ucCoilBuf[usByteOffset] |= ucBitOffset;
} else {
ucCoilBuf[usByteOffset] &= ~ucBitOffset;
}
// Implement specific actions depending on the coil number
switch (usCoilStart) {
case 0:
// Perform action for coil 0
break;
case 1:
// Perform action for coil 1
break;
// Add more cases for other coils as needed
default:
break;
}
iNCoils--;
usCoilStart++;
}
} else {
eStatus = MB_ENOREG;
}
} else {
eStatus = MB_ENOREG;
}
return eStatus;
}
void ModbusSlaveTask(void *pvParameters) {
eMBErrorCode eStatus;
// Initialize Modbus stack
eStatus = eMBInit(MB_RTU, MB_SLAVE_ADDRESS, MB_USART_PORT_NUM,
9600, MB_PAR_NONE);
if (eStatus != MB_ENOERR) {
printf("Modbus initialization failed.\n");
vTaskDelete(NULL);
}
// Enable Modbus stack
eStatus = eMBEnable();
if (eStatus != MB_ENOERR) {
printf("Failed to enable Modbus stack.\n");
vTaskDelete(NULL);
}
while (1) {
// Poll the Modbus stack
eMBPoll();
// Add any necessary application logic here
}
}
int main(void) {
// Register the coil callback function
eMBRegisterCB(MB_FUNC_WRITE_SINGLE_COIL, eMBRegCoilsCB);
eMBRegisterCB(MB_FUNC_WRITE_MULTIPLE_COILS, eMBRegCoilsCB);
// Create Modbus Slave Task
xTaskCreate(ModbusSlaveTask, "ModbusSlaveTask",
configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY + 1, NULL);
// Start the FreeRTOS scheduler
vTaskStartScheduler();
for (;;) {
}
return 0;
}
"
Ciekawe, ciekawe ...
P.
-
9. Data: 2023-04-06 08:47:26
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: Dawid Rutkowski <d...@w...pl>
środa, 5 kwietnia 2023 o 20:43:13 UTC+2 heby napisał(a):
> On 05/04/2023 20:26, Dawid Rutkowski wrote:
> > A ja masz zamiar generować tą "wtrącaną" ramkę?
> To mało istotne. Po prostu coś wrzuci jakieś zapytanie w środek bałaganu.
O tyle istotne - szczególnie w kontekście ew. gotowca - że musi skądś i przez coś
brać to dodatkowe zapytanie i analogicznie dawać odpowiedź.
> > W sumie nie wiem czy w modbus jest jakkolwiek zestandaryzowany multi-master...
> Nie ma, muszę go zrobić na kolanie.
Hmm, już modbus zapomniałem nieco, ale czy tam da się odróżnić ramkę master->slave i
slave->master po jej budowie?
Czy jednak master spodziewa się widzieć tylko ramki slave->master?
Choć w sumie slave musi umieć rozróżnić te typy...
No ale chodzi o master, bo rozważamy klejony multi-master.
Jak umie rozróżnić to jeszcze pytanie, czy sprawdza zajętość magistrali czy wysyła na
pałę w interwałach.
Inaczej pozostaje tylko man-in-the middle i wnoszone opóźnienia, które mogą
uniemożliwić realizację.
-
10. Data: 2023-04-06 09:28:20
Temat: Re: Multiplekser/sniffer/arbiter modbus
Od: heby <h...@p...onet.pl>
On 06/04/2023 08:47, Dawid Rutkowski wrote:
>> On 05/04/2023 20:26, Dawid Rutkowski wrote:
>>> A ja masz zamiar generować tą "wtrącaną" ramkę?
>> To mało istotne. Po prostu coś wrzuci jakieś zapytanie w środek bałaganu.
> O tyle istotne - szczególnie w kontekście ew. gotowca - że musi skądś i przez coś
brać to dodatkowe zapytanie i analogicznie dawać odpowiedź.
To może być np. wbudowane w urządzenie TCP->serial, albo osobny port
RS485. Ten mój "master2" jes wirtualny, fizyczny, jakibądź.
>>> W sumie nie wiem czy w modbus jest jakkolwiek zestandaryzowany multi-master...
>> Nie ma, muszę go zrobić na kolanie.
> Hmm, już modbus zapomniałem nieco, ale czy tam da się odróżnić ramkę master->slave
i slave->master po jej budowie?
Da się, pamiętaj że to urządzenie "rozcina" przewód master<->slave.
Urządznie wie, po której stronie przyszła ramka więc wszystko jest jasne.
> Jak umie rozróżnić to jeszcze pytanie, czy sprawdza zajętość magistrali czy wysyła
na pałę w interwałach.
Pierwszy znak, który nadchodzi po stronie master1 natychmiast
przekierowuje master2 do bufora. Kiedy komunikacja na master1 zostanie
zakończona, master2 zostanie wysłany z bufora o ile coś w buforze jest.
I symetrycznie w drugą stronę.
Więc dziaął tu zasada "kto pierwszy, to do urządzenia, kto w trakcie, to
do bufora".
> Inaczej pozostaje tylko man-in-the middle i wnoszone opóźnienia, które mogą
uniemożliwić realizację.
Sprawdziłem, sterownik jest bardzo tolerancyjny na opóźnienie a
urządzenie odpowiada prawie natychmiast.