IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PureBasic Discussion :

Modbus avec PureBasic


Sujet :

PureBasic

  1. #1
    Responsable Purebasic

    Avatar de comtois
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 301
    Billets dans le blog
    8
    Par défaut Modbus avec PureBasic
    Pour ceux qui seraient intéressés d'utiliser Modbus avec PureBasic @infratec (un utilisateur allemand) propose le code suivant :

    Fichier ModBus_RTU.pbi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    ;
    ; ModBus RTU
    ;
     
    #ModBus_RTU = #True
     
     
    Global ModBus_RTU_Echo.i
     
     
    XIncludeFile "ModBus_Helpers.pbi"
    XIncludeFile "ModBus_CRC.pbi"
     
     
     
     
    Procedure.i ModBus_RTU_ReadCoils(Port.i, Address.i, StartCoil.i, Quantity.i, Array BitField.a(1))
     
      Protected Result.i, *Buffer, i.i, Timeout.i, Size.i, Bytes.i, Mask.i, Byte.i, Ptr.i
     
     
      Result = -1
      *Buffer = AllocateMemory(128)
      If *Buffer
     
        PokeA(*Buffer, Address)
        PokeA(*Buffer + 1, #ModBus_FunctionCode_ReadCoils)
        PokeU(*Buffer + 2, ModBus_BigEndian16(StartCoil))
        PokeU(*Buffer + 4, ModBus_BigEndian16(Quantity))
        PokeU(*Buffer + 6, ModBus_CalcCRC(*Buffer, 1 + 1 + 2 + 2))
     
        WriteSerialPortData(Port, *Buffer, 1 + 1 + 2 + 2 + 2)
        If ModBus_RTU_Echo
          ReadSerialPortData(Port, *Buffer, 1 + 1 + 2 + 2 + 2)
        EndIf
     
        i = 0
        Timeout = 1000
        Repeat
          If AvailableSerialPortInput(Port)
            ReadSerialPortData(Port, *Buffer + i, 1)
            i + 1
            If i = 5 And PeekA(*Buffer + 1) = $80 | #ModBus_FunctionCode_ReadCoils
              Result = PeekA(*Buffer + 2)
              Break
            EndIf
     
            Bytes = PeekA(*Buffer + 2)
            Size = 1 + 1 + 1 + (Bytes / 8) + 2
            If Bytes & $07 : Size + 1 : EndIf
     
            If i = Size
              If ModBus_CheckCRC(*Buffer, Size)
                Quantity - 1
                ReDim BitField(Quantity)
                For i = 0 To Quantity
     
                  If i % 8 = 0
                    Mask = $01
                    Byte = PeekA(*Buffer + 3 + Ptr)
                    Ptr + 1
                  EndIf
     
                  BitField(i) = Byte & Mask
     
                  Mask << 1
                Next i
                Result = 0
              Else
                Result = -2
              EndIf
              Break
            EndIf
          Else
            Delay(1)
            Timeout - 1
          EndIf
        Until Timeout = 0
     
        If Timeout = 0
          Result = -10
        EndIf
     
        FreeMemory(*Buffer)
      EndIf
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_RTU_ReadDiscreteInputs(Port.i, Address.i, StartInput.i, Quantity.i, Array BitField.a(1))
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_RTU_ReadHoldingRegisters(Port.i, Address.i, StartRegister.i, Quantity.i, Array Words.u(1))
     
      Protected Result.i, *Buffer, i.i, Timeout.i, Size.i
     
     
      Result = -1
      *Buffer = AllocateMemory(128)
      If *Buffer
     
        PokeA(*Buffer, Address)
        PokeA(*Buffer + 1, #ModBus_FunctionCode_ReadHoldingRegisters)
        PokeU(*Buffer + 2, ModBus_BigEndian16(StartRegister))
        PokeU(*Buffer + 4, ModBus_BigEndian16(Quantity))
        PokeU(*Buffer + 6, ModBus_CalcCRC(*Buffer, 1 + 1 + 2 + 2))
     
        WriteSerialPortData(Port, *Buffer, 1 + 1 + 2 + 2 + 2)
        If ModBus_RTU_Echo
          ReadSerialPortData(Port, *Buffer, 1 + 1 + 2 + 2 + 2)
        EndIf
     
     
        i = 0
        Timeout = 1000
        Repeat
          If AvailableSerialPortInput(Port)
            ReadSerialPortData(Port, *Buffer + i, 1)
            Debug Hex(PeekA(*Buffer + i))
            i + 1
            If i = 5 And PeekA(*Buffer + 1) = $80 | #ModBus_FunctionCode_ReadHoldingRegisters
              Result = PeekA(*Buffer + 2)
              Break
            EndIf
            Size = 1 + 1 + 1 + PeekA(*Buffer + 2) + 2
            If i = Size
              If ModBus_CheckCRC(*Buffer, Size)
                Quantity - 1
                ReDim Words(Quantity)
                For i = 0 To Quantity
                  Words(i) = ModBus_BigEndian16(PeekU(*Buffer + 3 + 2 * i))
                Next i
                Result = 0
              Else
                Result = -2
              EndIf
              Break
            EndIf
          Else
            Delay(1)
            Timeout - 1
          EndIf
        Until Timeout = 0
     
        If Timeout = 0
          Result = -10
        EndIf
     
        FreeMemory(*Buffer)
      EndIf
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_RTU_ReadInputRegisters(Port.i, Address.i, StartRegister.i, Quantity.i, Array Words.u(1))
     
      Protected Result.i, *Buffer, i.i, Timeout.i, Size.i
     
     
      Result = -1
      *Buffer = AllocateMemory(128)
      If *Buffer
     
        PokeA(*Buffer, Address)
        PokeA(*Buffer + 1, #ModBus_FunctionCode_ReadInputRegisters)
        PokeU(*Buffer + 2, ModBus_BigEndian16(StartRegister))
        PokeU(*Buffer + 4, ModBus_BigEndian16(Quantity))
        PokeU(*Buffer + 6, ModBus_CalcCRC(*Buffer, 1 + 1 + 2 + 2))
     
        WriteSerialPortData(Port, *Buffer, 1 + 1 + 2 + 2 + 2)
        If ModBus_RTU_Echo
          ReadSerialPortData(Port, *Buffer, 1 + 1 + 2 + 2 + 2)
        EndIf
     
     
        i = 0
        Timeout = 1000
        Repeat
          If AvailableSerialPortInput(Port)
            ReadSerialPortData(Port, *Buffer + i, 1)
            Debug Hex(PeekA(*Buffer + i))
            i + 1
            If i = 5 And PeekA(*Buffer + 1) = $80 | #ModBus_FunctionCode_ReadHoldingRegisters
              Result = PeekA(*Buffer + 2)
              Break
            EndIf
            Size = 1 + 1 + 1 + PeekA(*Buffer + 2) + 2
            If i = Size
              If ModBus_CheckCRC(*Buffer, Size)
                Quantity - 1
                ReDim Words(Quantity)
                For i = 0 To Quantity
                  Words(i) = ModBus_BigEndian16(PeekU(*Buffer + 3 + 2 * i))
                Next i
                Result = 0
              Else
                Result = -2
              EndIf
              Break
            EndIf
          Else
            Delay(1)
            Timeout - 1
          EndIf
        Until Timeout = 0
     
        If Timeout = 0
          Result = -10
        EndIf
     
        FreeMemory(*Buffer)
      EndIf
     
      ProcedureReturn Result
     
    EndProcedure
     
    Procedure.i ModBus_RTU_WriteSingleCoil(Port.i, Address.i, Coil.i, Value.i)
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_RTU_WriteSingleRegister(Port.i, Address.i, Register.i, Value.i)
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
    Procedure.i ModBus_RTU_ReadExceptionStatus(Port.i, Address.i)
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
    Procedure.i ModBus_RTU_WriteMultipleCoils(Port.i, Address.i, StartCoil.i, Coils.i, Array Values.a(1))
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_RTU_WriteMultipleRegisters(Port.i, Address.i, StartRegister.i, Quantity.i, Array Values.u(1))
     
      Protected Result.i, *Buffer, i.i, Timeout.i
     
     
      Result = -1
      *Buffer = AllocateMemory(1 + 1 + 2 + 2 + 1 + 2 * Quantity + 2)
      If *Buffer
     
        PokeA(*Buffer, Address)
        PokeA(*Buffer + 1, #ModBus_FunctionCode_WriteMultipleRegisters)
        PokeU(*Buffer + 2, ModBus_BigEndian16(StartRegister))
        PokeU(*Buffer + 4, ModBus_BigEndian16(Quantity))
        PokeA(*Buffer + 6, 2 * Quantity)
        For i = 0 To Quantity - 1
          PokeU(*Buffer + 7 + i * 2, ModBus_BigEndian16(Values(i)))
        Next i
        PokeU(*Buffer + 7 + i * 2, ModBus_CalcCRC(*Buffer, 1 + 1 + 2 + 2 + 1 + 2 * Quantity))
     
        WriteSerialPortData(Port, *Buffer, 1 + 1 + 2 + 2 + 1 + 2 * Quantity + 2)
        If ModBus_RTU_Echo
          ReadSerialPortData(Port, *Buffer, 1 + 1 + 2 + 2 + 1 + 2 * Quantity + 2)
        EndIf
     
        i = 0
        Timeout = 1000
        Repeat
          If AvailableSerialPortInput(Port)
            ReadSerialPortData(Port, *Buffer + i, 1)
            i + 1
            If i = 5 And PeekA(*Buffer + 1) = $80 | #ModBus_FunctionCode_WriteMultipleRegisters
              Result = PeekA(*Buffer + 2)
              Break
            EndIf
            If i = 8
              If ModBus_CheckCRC(*Buffer, 8)
                Result = 0
              Else
                Result = -2
              EndIf
              Break
            EndIf
          Else
            Delay(1)
            Timeout - 1
          EndIf
        Until Timeout = 0
     
        If Timeout = 0
          Result = -10
        EndIf
     
        FreeMemory(*Buffer)
      EndIf
     
      ProcedureReturn Result
     
    EndProcedure

    Source de l'information
    Vous souhaitez participer à la rubrique PureBasic (tutoriels, FAQ, sources) ? Contactez-moi par MP.

  2. #2
    Responsable Purebasic

    Avatar de comtois
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 301
    Billets dans le blog
    8
    Par défaut
    Fichier ModBus_CRC.pbi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    ;
    ; ModBus CRC
    ;
     
    DataSection
      ModBus_CRCTable:
        Data.u $0000, $C0C1, $C181, $0140, $C301, $03C0, $0280, $C241
        Data.u $C601, $06C0, $0780, $C741, $0500, $C5C1, $C481, $0440     
        Data.u $CC01, $0CC0, $0D80, $CD41, $0F00, $CFC1, $CE81, $0E40     
        Data.u $0A00, $CAC1, $CB81, $0B40, $C901, $09C0, $0880, $C841     
        Data.u $D801, $18C0, $1980, $D941, $1B00, $DBC1, $DA81, $1A40     
        Data.u $1E00, $DEC1, $DF81, $1F40, $DD01, $1DC0, $1C80, $DC41     
        Data.u $1400, $D4C1, $D581, $1540, $D701, $17C0, $1680, $D641     
        Data.u $D201, $12C0, $1380, $D341, $1100, $D1C1, $D081, $1040     
        Data.u $F001, $30C0, $3180, $F141, $3300, $F3C1, $F281, $3240     
        Data.u $3600, $F6C1, $F781, $3740, $F501, $35C0, $3480, $F441     
        Data.u $3C00, $FCC1, $FD81, $3D40, $FF01, $3FC0, $3E80, $FE41    
        Data.u $FA01, $3AC0, $3B80, $FB41, $3900, $F9C1, $F881, $3840
        Data.u $2800, $E8C1, $E981, $2940, $EB01, $2BC0, $2A80, $EA41
        Data.u $EE01, $2EC0, $2F80, $EF41, $2D00, $EDC1, $EC81, $2C40     
        Data.u $E401, $24C0, $2580, $E541, $2700, $E7C1, $E681, $2640
        Data.u $2200, $E2C1, $E381, $2340, $E101, $21C0, $2080, $E041
        Data.u $A001, $60C0, $6180, $A141, $6300, $A3C1, $A281, $6240
        Data.u $6600, $A6C1, $A781, $6740, $A501, $65C0, $6480, $A441
        Data.u $6C00, $ACC1, $AD81, $6D40, $AF01, $6FC0, $6E80, $AE41
        Data.u $AA01, $6AC0, $6B80, $AB41, $6900, $A9C1, $A881, $6840
        Data.u $7800, $B8C1, $B981, $7940, $BB01, $7BC0, $7A80, $BA41
        Data.u $BE01, $7EC0, $7F80, $BF41, $7D00, $BDC1, $BC81, $7C40
        Data.u $B401, $74C0, $7580, $B541, $7700, $B7C1, $B681, $7640
        Data.u $7200, $B2C1, $B381, $7340, $B101, $71C0, $7080, $B041
        Data.u $5000, $90C1, $9181, $5140, $9301, $53C0, $5280, $9241
        Data.u $9601, $56C0, $5780, $9741, $5500, $95C1, $9481, $5440
        Data.u $9C01, $5CC0, $5D80, $9D41, $5F00, $9FC1, $9E81, $5E40
        Data.u $5A00, $9AC1, $9B81, $5B40, $9901, $59C0, $5880, $9841
        Data.u $8801, $48C0, $4980, $8941, $4B00, $8BC1, $8A81, $4A40
        Data.u $4E00, $8EC1, $8F81, $4F40, $8D01, $4DC0, $4C80, $8C41
        Data.u $4400, $84C1, $8581, $4540, $8701, $47C0, $4680, $8641
        Data.u $8201, $42C0, $4380, $8341, $4100, $81C1, $8081, $4040
    EndDataSection
     
     
    Procedure.u ModBus_CalcCRC(*Ptr, Len.i)
     
      Protected CRC_Value.u
      Protected i.i
     
     
      CRC_Value.u = $FFFF
     
      Len - 1
      For i = 0 To Len
        CRC_Value = (CRC_Value >> 8) ! PeekU(?ModBus_CRCTable + (PeekA(*Ptr + i) ! (CRC_Value & $FF)) << 1)
      Next i
     
      ProcedureReturn CRC_Value
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_CheckCRC(*Ptr, Len.i)
     
      Protected Result.i, CalcCRC.u
     
     
      Len - 2
      CalcCRC = ModBus_CalcCRC(*Ptr, Len)
      ;Debug Hex(CalcCRC)
      ;Debug Hex(PeekU(*Ptr + Len))
      If CalcCRC = PeekU(*Ptr + Len)
        Result = #True
      EndIf
     
      ProcedureReturn Result
     
    EndProcedure
    Vous souhaitez participer à la rubrique PureBasic (tutoriels, FAQ, sources) ? Contactez-moi par MP.

  3. #3
    Responsable Purebasic

    Avatar de comtois
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 301
    Billets dans le blog
    8
    Par défaut
    Fichier ModBus_Helpers.pbi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    ;
    ; ModBus helpers
    ;
     
     
    #ModBus_Coil_On = $FF00
    #ModBus_Coil_Off = $0000
     
    Enumeration
      #ModBus_FunctionCode_ReadCoils = $01
      #ModBus_FunctionCode_ReadDiscreteInputs
      #ModBus_FunctionCode_ReadHoldingRegisters
      #ModBus_FunctionCode_ReadInputRegisters
      #ModBus_FunctionCode_WriteSingleCoil
      #ModBus_FunctionCode_WriteSingleRegister
      #ModBus_FunctionCode_WriteMultipleCoils = $0F
      #ModBus_FunctionCode_WriteMultipleRegisters
    EndEnumeration
     
     
    Enumeration
      #ModBus_Exception_IllegalFunctionCode = $01
      #ModBus_Exception_IllegalDataAddress
      #ModBus_Exception_IllegalDataValue
      #ModBus_Exception_DeviceFailure
      #ModBus_Exception_Acknowledge
      #ModBus_Exception_DeviceBusy
      #ModBus_Exception_ParityError
      #ModBus_Exception_GatewayNotReachable = $0A
      #ModBus_Exception_GatewayNotResponding
    EndEnumeration
     
     
     
     
    Procedure.u ModBus_BigEndian16(Value.u)
     
      ProcedureReturn PeekA(@Value) << 8 | PeekA(@Value + 1)
     
    EndProcedure
    Vous souhaitez participer à la rubrique PureBasic (tutoriels, FAQ, sources) ? Contactez-moi par MP.

  4. #4
    Responsable Purebasic

    Avatar de comtois
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 301
    Billets dans le blog
    8
    Par défaut
    If you later add the other modbus types:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    ;
    ; ModBus utilities
    ;
     
     
    Enumeration
      #ModBus_Type_RTU
      #ModBus_Type_TCP
      #ModBus_Type_ASCII
      #ModBus_Type_RTU_Network
    EndEnumeration
     
     
    Prototype.i P_ModBus_ReadCoils(Connection.i, Address.i, StartCoil.i, Quantity.i, Array BitField.a(1))
    Prototype.i P_ModBus_ReadHoldingRegisters(Connection.i, Address.i, StartRegister.i, Quantity.i, Array Words.u(1))
    Prototype.i P_ModBus_ReadInputRegisters(Connection.i, Address.i, StartRegister.i, Quantity.i, Array Words.u(1))
    Prototype.i P_ModBus_WriteMultipleRegisters(Connection.i, Address.i, StartRegister.i, Quantity.i, Array Values.u(1))
    Prototype.i P_ModBus_WriteSingleCoil(Connection.i, Address.i, Coil.i, State.i)
     
    Global ModBus_ReadCoils.P_ModBus_ReadCoils
    Global ModBus_ReadHoldingRegisters.P_ModBus_ReadHoldingRegisters
    Global ModBus_ReadInputRegisters.P_ModBus_ReadInputRegisters
    Global ModBus_WriteMultipleRegisters.P_ModBus_WriteMultipleRegisters
    Global ModBus_WriteSingleCoil.P_ModBus_WriteSingleCoil
     
    Global ModBus_Type.i
     
     
    Procedure ModBus_SetType(Type.i)
     
      Select Type
        Case #ModBus_Type_RTU
    CompilerIf Defined(ModBus_RTU, #PB_Constant)
          ModBus_ReadCoils = @ModBus_RTU_ReadCoils()
          ModBus_ReadHoldingRegisters = @ModBus_RTU_ReadHoldingRegisters()
          ModBus_ReadInputRegisters = @ModBus_RTU_ReadInputRegisters()
          ModBus_WriteMultipleRegisters = @ModBus_RTU_WriteMultipleRegisters()
          ModBus_WriteSingleCoil = @ModBus_RTU_WriteSingleCoil()
          ModBus_Type = #ModBus_Type_RTU
    CompilerEndIf
        Case #Modbus_Type_TCP
    CompilerIf Defined(ModBus_TCP, #PB_Constant)
          ModBus_ReadCoils = @ModBus_TCP_ReadCoils()
          ModBus_ReadHoldingRegisters = @ModBus_TCP_ReadHoldingRegisters()
          ModBus_ReadInputRegisters = @ModBus_TCP_ReadInputRegisters()
          ModBus_WriteMultipleRegisters = @ModBus_TCP_WriteMultipleRegisters()
          ModBus_WriteSingleCoil = @ModBus_TCP_WriteSingleCoil()
          ModBus_Type = #ModBus_Type_TCP
        CompilerEndIf
      Case #ModBus_Type_RTU_Network
        CompilerIf Defined(ModBus_RTU_Network, #PB_Constant)
          ModBus_ReadCoils = @ModBus_RTU_Network_ReadCoils()
          ModBus_ReadHoldingRegisters = @ModBus_RTU_Network_ReadHoldingRegisters()
          ModBus_ReadInputRegisters = @ModBus_RTU_Network_ReadInputRegisters()
          ModBus_WriteMultipleRegisters = @ModBus_RTU_Network_WriteMultipleRegisters()
          ModBus_WriteSingleCoil = @ModBus_RTU_Network_WriteSingleCoil()
          ModBus_Type = #ModBus_Type_RTU_Network
          CompilerEndIf
      EndSelect
     
    EndProcedure
    Vous souhaitez participer à la rubrique PureBasic (tutoriels, FAQ, sources) ? Contactez-moi par MP.

  5. #5
    Responsable Purebasic

    Avatar de comtois
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 301
    Billets dans le blog
    8
    Par défaut
    La version Modbus TCP

    Fichier s ModBus_TCP.pbi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    ;
    ; ModBus TCP
    ;
     
    #ModBus_TCP = #True
     
    CompilerIf #PB_Compiler_IsMainFile
      EnableExplicit
    CompilerEndIf
     
     
    XIncludeFile "ModBus_Helpers.pbi"
     
     
    Procedure.i ModBus_TCP_ReadCoils(Connection.i, Address.i, StartCoil.i, Quantity.i, Array BitField.a(1))
     
      Protected Result.i, *Buffer, i.i, Timeout.i, Size.i, Bytes.i, Mask.i, Byte.i, Ptr.i, TransactionID.u
     
     
      Result = -1
      *Buffer = AllocateMemory(320)
      If *Buffer
     
        TransactionID.u = Random($FFFF)
     
        PokeU(*Buffer + 0, TransactionID)         ; Transaction ID
        PokeU(*Buffer + 2, 0)                     ; Protocol ID
        PokeU(*Buffer + 4, ModBus_BigEndian16(6)) ; Length
     
        PokeA(*Buffer + 6, Address)
        PokeA(*Buffer + 7, #ModBus_FunctionCode_ReadCoils)
        PokeU(*Buffer + 8, ModBus_BigEndian16(StartCoil))
        PokeU(*Buffer + 10, ModBus_BigEndian16(Quantity))
     
        If SendNetworkData(Connection, *Buffer, 12) = 12
     
          Timeout = 1000
          Repeat
            If NetworkClientEvent(Connection) = #PB_NetworkEvent_Data
              Size = ReceiveNetworkData(Connection, *Buffer, 320)
              If Size > 6
                If PeekU(*Buffer + 0) = TransactionID
                  If PeekA(*Buffer + 7) < $80
                    Quantity - 1
                    ReDim BitField(Quantity)
                    For i = 0 To Quantity
     
                      If i % 8 = 0
                        Mask = $01
                        Byte = PeekA(*Buffer + 9 + Ptr)
                        Ptr + 1
                      EndIf
     
                      BitField(i) = Byte & Mask
     
                      Mask << 1
                    Next i
                    Result = 0
                  Else
                    Result = PeekA(*Buffer + 8)
                  EndIf
                EndIf
              EndIf
              Break
            Else
              Delay(1)
              Timeout - 1
            EndIf
          Until Timeout = 0
     
          If Timeout = 0
            Result = #ModBus_Exception_GatewayNotResponding
          EndIf
     
        Else
          Result = #ModBus_Exception_GatewayNotReachable
        EndIf
     
        FreeMemory(*Buffer)
      EndIf
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_TCP_ReadDiscreteInputs(Connection.i, Address.i, StartInput.i, Quantity.i, Array BitField.a(1))
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_TCP_ReadHoldingRegisters(Connection.i, Address.i, StartRegister.i, Quantity.i, Array Words.u(1))
     
      Protected Result.i, *Buffer, i.i, Timeout.i, Size.i, TransactionID.u
     
     
      Result = -1
      *Buffer = AllocateMemory(320)
      If *Buffer
     
        TransactionID.u = Random($FFFF)
     
        PokeU(*Buffer + 0, TransactionID)         ; Transaction ID
        PokeU(*Buffer + 2, 0)                     ; Protocol ID
        PokeU(*Buffer + 4, ModBus_BigEndian16(6)) ; Length
     
        PokeA(*Buffer + 6, Address)
        PokeA(*Buffer + 7, #ModBus_FunctionCode_ReadHoldingRegisters)
        PokeU(*Buffer + 8, ModBus_BigEndian16(StartRegister))
        PokeU(*Buffer + 10, ModBus_BigEndian16(Quantity))
     
        If SendNetworkData(Connection, *Buffer, 12) = 12
     
          Timeout = 1000
          Repeat
            If NetworkClientEvent(Connection) = #PB_NetworkEvent_Data
              Size = ReceiveNetworkData(Connection, *Buffer, 320)
              If Size > 6
                If PeekU(*Buffer + 0) = TransactionID
                  If PeekA(*Buffer + 7) < $80
                    Quantity - 1
                    ReDim Words(Quantity)
                    For i = 0 To Quantity
                      Words(i) = ModBus_BigEndian16(PeekU(*Buffer + 9 + 2 * i))
                    Next i
                    Result = 0
                  Else
                    Result = PeekA(*Buffer + 8)
                  EndIf
                EndIf
              EndIf
              Break
            Else
              Delay(1)
              Timeout - 1
            EndIf
          Until Timeout = 0
     
          If Timeout = 0
            Result = #ModBus_Exception_GatewayNotResponding
          EndIf
     
        Else
          Result = #ModBus_Exception_GatewayNotReachable
        EndIf
     
        FreeMemory(*Buffer)
      EndIf
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_TCP_ReadInputRegisters(Connection.i, Address.i, StartRegister.i, Quantity.i, Array Words.u(1))
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_TCP_WriteSingleCoil(Connection.i, Address.i, Coil.i, Value.i)
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_TCP_WriteSingleRegister(Connection.i, Address.i, Register.i, Value.i)
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_TCP_ReadExceptionStatus(Connection.i, Address.i)
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_TCP_WriteMultipleCoils(Connection.i, Address.i, StartCoil.i, Coils.i, Array Values.a(1))
     
      Protected Result.i
     
     
      ProcedureReturn Result
     
    EndProcedure
     
     
     
     
    Procedure.i ModBus_TCP_WriteMultipleRegisters(Connection.i, Address.i, StartRegister.i, Quantity.i, Array Values.u(1))
     
      Protected Result.i, *Buffer, i.i, Timeout.i, TransactionID.u, Size.i
     
     
      Result = -1
      *Buffer = AllocateMemory(320)
      If *Buffer
     
        TransactionID.u = Random($FFFF)
     
        PokeU(*Buffer + 0, TransactionID)         ; Transaction ID
        PokeU(*Buffer + 2, 0)                     ; Protocol ID
        PokeU(*Buffer + 4, ModBus_BigEndian16(1 + 1 + 2 + 2  + 1 + 2 * Quantity)) ; Length
     
        PokeA(*Buffer + 6, Address)
        PokeA(*Buffer + 7, #ModBus_FunctionCode_WriteMultipleRegisters)
        PokeU(*Buffer + 8, ModBus_BigEndian16(StartRegister))
        PokeU(*Buffer + 10, ModBus_BigEndian16(Quantity))
        PokeA(*Buffer + 12, 2 * Quantity)
        For i = 0 To Quantity - 1
          PokeU(*Buffer + 13 + i * 2, ModBus_BigEndian16(Values(i)))
        Next i
     
        If SendNetworkData(Connection, *Buffer, 13 + 2 * Quantity) = 13 + 2 * Quantity
     
          Timeout = 1000
          Repeat
            If NetworkClientEvent(Connection) = #PB_NetworkEvent_Data
              Size = ReceiveNetworkData(Connection, *Buffer, 320)
              If Size > 6
                If PeekU(*Buffer + 0) = TransactionID
                  If PeekA(*Buffer + 7) < $80
                    Result = 0
                  Else
                    Result = PeekA(*Buffer + 8)
                  EndIf
                EndIf
              EndIf
              Break
            Else
              Delay(1)
              Timeout - 1
            EndIf
          Until Timeout = 0
     
          If Timeout = 0
            Result = #ModBus_Exception_GatewayNotResponding
          EndIf
     
        Else
          Result = #ModBus_Exception_GatewayNotReachable
        EndIf
     
        FreeMemory(*Buffer)
      EndIf
     
      ProcedureReturn Result
     
    EndProcedure
    Vous souhaitez participer à la rubrique PureBasic (tutoriels, FAQ, sources) ? Contactez-moi par MP.

Discussions similaires

  1. [Sondage] : Que programmez vous avec PureBasic ?
    Par comtois dans le forum PureBasic
    Réponses: 15
    Dernier message: 06/10/2015, 10h07
  2. Liaison modbus avec serie RS232
    Par vipere_70 dans le forum Automation
    Réponses: 2
    Dernier message: 22/10/2008, 22h27
  3. Communication Modbus avec un Diris en RS 485
    Par mat-tech dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 26/09/2008, 19h15
  4. ParallelFor avec PureBasic
    Par comtois dans le forum PureBasic
    Réponses: 1
    Dernier message: 05/02/2008, 14h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo