ModBus i C#

0

Witam
Ma dla kolegi napisać program, który tylko będzie odczytywał z urządzenia 3 rejestr. Komunikacja jest po RS-485 i przy użyciu ModBusa RTU. Obsługę portu już mam, lecz modbusa nie znam wcale. W urządzeniu mam odczytać dane z np.: nr rej. 32 adr. rej. 31, a funkcja 0x04. Może ktoś z Was już pisał coś podobnego i mógłby mnie naprowadzić lub podać co wysłać do portu (jak zbudować ramkę) oraz jak odebrać dane.

Za wszelkie porady z góry dziękuję.

0

Pisałem modbusa, protokół prosty ale jak się chce go skodzić w całości to trzeba się trochę naklepać. Anyway, ramka dla funkcji czwarte tutaj: http://www.simplymodbus.ca/FC04.htm. Na tej samej stronie masz opisane pozostałe funkcje oraz toola który pokazuje tyle informacji ile się da (przyzwoicie podgląda się nim ramki i zawartości rejestrów), trochę stary ale do uruchomienia. Kompleksowo modbusa opisanego masz tutaj: http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf

0

Po przeczytaniu paru artykułów i pobraniu classy modbus.cs (https://code.google.com/p/nmodbus/ - za link dziękuję) do mojego programu udało się pobrać jakieś dane, lecz ponowny odczyt wymaga odłączenie konwertera rs-485 od USB inaczej wyrzuca błąd.

                        ModbusMasterSerial mm = new ModbusMasterSerial(ModbusSerialType.RTU,"COM17" , 19200, 8, Parity.None, StopBits.One, Handshake.None);
                        mm.Connect();
                        MessageBox.Show("Rej 11: "+mm.ReadInputRegisters(1, 10, 1).First().ToString("D5"));
                        Thread.Sleep(2000);
                        mm.Disconnect();

Czy w ogóle dobrze podchodzę do tematu (mam jedno urządzenie, czy one jest master czy slave)? Odczytuję z 10 rejestru dane, czy może coś innego? Ja zrobić, aby dało się ponownie odczytać rejestr?
Może trzeba to zrobić inaczej? Proszę o pomoc - do tej pory nie miałem styczności z modbus'em. Widzę, że będę musiał się sporo nauczyć, lecz czas mnie nagli i dlatego proszę o pomoc.

0
syli napisał(a):

Czy w ogóle dobrze podchodzę do tematu (mam jedno urządzenie, czy one jest master czy slave)?

Urządzenie to slave a klient to master.

0

Czyli mam użyć

ModbusSlaveSerial mm = new ModbusSlaveSerial(dane, ModbusSerialType.RTU,"COM17" , 19200, 8, Parity.None, StopBits.One, Handshake.None);

Tylko co podać za "dane". Chce odczytać np. tylko rejestr 31 z urządzenia id=1. Jak i co wysłać do urządzenia i jak odczytać odpowiedź?
Bardzo proszę o pomoc.

0

Podaj do jakiego urządzenia się łączysz.

0

Dziękuję za wszelką pomoc. Już poradziłem sobie.
Dla zainteresowanych podaje kod:

                short[] values = new short[Convert.ToInt32(1)]; //nie wiem co dokładnie ma być tutaj, ale działa.
                ushort pollStart = Convert.ToUInt16(  rejestr początkowy );
                ushort pollLength = Convert.ToUInt16( ilosc rejestrow );
                if (mb.Open(Port, Predkosc komunikacji, 8, Parity.None, StopBits.One))
                {
                    mb.SendFc4(  adres urządzenia  , pollStart, pollLength, ref values);

oraz po dopisaniu funkcji 4 (SendFc4) do programu z http://www.codeproject.com/Articles/20929/Simple-Modbus-Protocol-in-C-NET

public bool SendFc4(byte address, ushort start, ushort registers, ref short[] values)
        {
            //Ensure port is open:
            if (sp.IsOpen)
            {
                //Clear in/out buffers:
                sp.DiscardOutBuffer();
                sp.DiscardInBuffer();
                //Function 3 request is always 8 bytes:
                byte[] message = new byte[8];
                //Function 3 response buffer:
                byte[] response = new byte[5 + 2 * registers];
                //Build outgoing modbus message:
                BuildMessage(address, (byte)4, start, registers, ref message);
                //Send modbus message to Serial Port:
                try
                {
                    sp.Write(message, 0, message.Length);
                    GetResponse(ref response);
                }
                catch (Exception err)
                {
                    modbusStatus = "Error in read event: " + err.Message;
                    return false;
                }
                //Evaluate message:
                if (CheckResponse(response))
                {
                    //Return requested register values:
                    for (int i = 0; i < (response.Length - 5) / 2; i++)
                    {
                        values[i] = response[2 * i + 3];
                        values[i] <<= 8;
                        values[i] += response[2 * i + 4];
                    }
                    modbusStatus = "Read successful";
                    return true;
                }
                else
                {
                    modbusStatus = "CRC error";
                    return false;
                }
            }
            else
            {
                modbusStatus = "Serial port not open";
                return false;
            }

        }

Wszystko działa.
Pozdrawiam

0
  1. Programming Modbus TCP/IP with .Net (C#/VB.Net):

  2. Programming Modbus RTU with .Net (C#/VB.Net):

1 użytkowników online, w tym zalogowanych: 0, gości: 1