CANOpenMNode, manages a CANopen slave node

List

Questa pagina fa parte del Manuale Programmazione IEC 61131-3. Vai all indice.

Questo blocco funzione gestisce un modulo CAN su di una rete CANOpen gestita dal FB CANOpenMaster, occorre passare al FB l’indirizzo di allocazione del FB CANOpenMaster a cui è connesso il modulo. Il FB gestisce la ricezione e l’invio dei messaggi CANOpen da e verso il nodo.

Upgrade list

CANOpenMNode

Gestiva soltanto lettura/scrittura SDO, mentre il nuovo modulo (Object oriented) ha una serie di metodi per gestire il PDO mapping. Eliminata la definizione “CANOMMCTYPE” ora si utilizza la chiamata ai metodi relativi.

Information Circle

Blocco funzione

CODESYS: Non disponibile

LogicLab: eLLabCANOpenLib

Descrizione

SpyOn (BOOL) Se attivo permette di spiare il funzionamento della FB.
COMaster (@CANOpenMaster_v1) Indirizzo FB CANOpenMaster di gestione protocollo.
NodeID (BYTE) Definizione ID nodo da gestire.
PHBeatTime (UINT) Definizione tempo invio heartbeat (mS) (Vedi Meccanismo Heartbeat).
Done (BOOL) Attivo per un loop al termine esecuzione comando.
Fault (BOOL) Attivo per un loop se errore esecuzione. Può verificarsi su heartbeat o in caso di errore nei dati in ricezione.
HBeatOk (BOOL) Attivo se definito tempo di invio heartbeat e se il dispositivo lo invia.
Status (CO_NMT_STS) Stato del modulo (Definizione).
Abort (CO_ABORT) Struttura dati ricezione codice di abort dal modulo (Definizione).
Emcy (CO_EMERGENCY) Struttura dati ricezione codice di emergenza dal modulo (Definizione).
Errors (UDINT) Counter errori gestione modulo.

Immagine FB CANopenMNode_v1
Meccanismo Heartbeat

Sul nodo slave è possibile gestire anche contemporaneamente 2 diversi meccnismi di heartbeat:

Producer heartbeat

Generato dal nodo e controllato dalla FB CANOpenMNode. Impostando un tempo nel parametro PHBeatTime (Producer Heartbeat Time, in millisecondi) il nodo viene configurato per inviare ogni tempo definito un messaggio Heartbeat (Registro 1017h Producer Heartbeat Time). Il FB controlla la ricezione del messaggio ed attiva l’uscita HBeatOk. Se ogni tempo impostato +50mS non viene ricevuto il messaggio dal nodo si disattiva l’uscita.

Consumer heartbeat

Generato dalla FB CANOpenMaster e controllato dal nodo. Impostando un tempo nel parametro CANOpenMaster.PHBeatTime (Producer Heartbeat Time, in millisecondi), il nodo viene configurato per controllare la ricezione del messaggio dal nodo master (Registro 1016h Consumer Heartbeat Time). Se ogni tempo impostato +50mS non viene ricevuto il messaggio il nodo slave và in errore, il comportamento in caso di errore può essere configurato.

Metodi disponibili

Reset

Questo metodo esegue il reset del nodo can slave ponendolo in condizione di inizializzazione.

Il metodo ritorna (BOOL), FALSE se comando in corso, TRUE comando eseguito.

Immagine FB CANOpenMNode_v1-Reset
Start

Questo metodo forza in operational il nodo can slave.

Il metodo ritorna (BOOL), FALSE se comando in corso, TRUE comando eseguito.

Immagine metodo CANOpenMNode_v1.Start
SDORead

Questo metodo esegue la lettura di un oggetto SDO (Service Data Objects).

OIndex (UINT) Indice Object dictionary.
OSIndex (USINT) Sottoindice Object dictionary.
OType (VR_TYPE) Tipo variabile letta da Object dictionary.
OAddress (PVOID) Indirizzo variabile appoggio valore letto.

Il metodo ritorna (BOOL), FALSE se comando in corso, TRUE comando eseguito.

Immagine metodo CANOpenMNode_v1-SDORead
SDOWrite

Questo metodo esegue la scrittura di una variabile in un oggetto SDO (Service Data Objects).

OIndex (UINT) Indice Object dictionary.
OSIndex (USINT) Sottoindice Object dictionary.
OType (VR_TYPE) Tipo variabile da scrivere in Object dictionary.
OAddress (PVOID) Indirizzo variabile da scrivere.

Il metodo ritorna (BOOL), FALSE se comando in corso, TRUE comando eseguito.

Immagine metodo CANOpenMNode_v1-SDOWrite
SDOWValue

Questo metodo esegue la scrittura di un valore in un oggetto SDO (Service Data Objects).

OIndex (UINT) Indice Object dictionary.
OSIndex (USINT) Sottoindice Object dictionary.
OType (VR_TYPE) Tipo valore da scrivere in Object dictionary.
OValue (DWORD) Valore da scrivere.

Il metodo ritorna (BOOL), FALSE se comando in corso, TRUE comando eseguito.

Immagine metodo CANOpenMNode_v1-SDOWValue
PDOMap

Questo metodo esegue mappatura di un oggetto in un PDO (Process Data Object). Più oggetti possono essere mappati all’interno di un PDO, occorre fare riferimento alla dimensione di ogni oggetto per non superare 8 bytes.

PDO (STRING[6]) Definizione PDO (Esempio RPDO1, TPDO4, …).
OIndex (UINT) Indice oggetto.
OSIndex (USINT) Sottoindice oggetto.
OType (VR_TYPE) Tipo oggetto.

Il metodo ritorna (BOOL), FALSE se comando in corso, TRUE comando eseguito.

Immagine metodo CANOpenMNode_v1-PDOMap
PDOUMap

Questo metodo esegue la smappatura di un PDO (Process Data Object).

PDO (STRING[6]) Definizione PDO (Esempio RPDO1, TPDO4, …).

Il metodo ritorna (BOOL), FALSE se comando in corso, TRUE comando eseguito.

Immagine metodo CANOpenMNode_v1-PDOUMap
PDOCom

Questo metodo esegue le impostazioni della comunicazione di un PDO (Process Data Object).

PDO (STRING[6]) Definizione PDO (Esempio RPDO1, TPDO4, …).
COBID (WORD) COB assegnato al PDO.
TType (USINT) Tipo trasmissione.
ITime (UINT) Tempo di inhibit, impostabile sui TPDO, espresso in multipli di 100 μs. Ritardo minimo trasmissione TPDO per non sovraccaricare il bus su eventi in rapida successione. Impostabile solo se TType 254 o 255 (0 disabilita).

Il metodo ritorna (BOOL), FALSE se comando in corso, TRUE comando eseguito.

Immagine metodo CANOpenMNode_v1-PDOCom
TTypeDescrizione
0Synchronous (acyclic)
1~240Synchronous (cyclic every (1~240)-th sync)
241~253Not used
254Event-driven (manufacturer-specific)
255Event-driven (device profile and application profile specific)

Esempi

PDOCom('TPDO1', 16#180+NodeID, 255, 100); //Event-driven, 10mS inhibit time
PDOCom('TPDO1', 16#180+NodeID, 1, 0); //Synchronous every SYNC
PDOCom('RPDO1', 16#200+NodeID, 1, 0); //Synchronous every SYNC
PDOCom('RPDO1', 16#200+NodeID, 10, 0); //Synchronous every 10th SYNC

Dizionario oggetti

Il dizionario degli oggetti (Object Dictionary) è l’insieme degli oggetti utilizzati per configurare, inviare comandi e monitorare grandezze in CANOpen.

Elenco oggetti
  • 16#0000 not used
  • 16#0001-16#001F Static Data Types
  • 16#0020-16#003F Complex Data Types
  • 16#0040-16#005F Manufacturer Specific Complex Data Types
  • 16#0060-16#007F Device Profile Specific Static Data Types
  • 16#0080-16#009F Device Profile Specific Complex Data Types
  • 16#00A0-16#0FFF Reserved for further use
  • 16#1000-16#1FFF Communication Profile Area
  • 16#2000-16#5FFF Manufacturer Specific Profile Area
  • 16#6000-16#9FFF Standardised Device Profile Area
  • 16#A000-16#BFFF Standardised Interface Profile Area
  • 16#C000-16#FFFF Reserved for further use
Oggetti standardizzati

Ogni dispositivo CAN ha un proprio dizionario di oggetti ed occorre consultare la documentazione relativa per un elenco (File EDS). Esistono comunque oggetti che sono presenti in molti dispositivi eccone un elenco.

IndexSubTypeAccessDescription
16#10000UDINTRDevice type: Tipo dispositivo
16#100C0UINTR/WGuard time (mS): Moltiplicato per Live time factor fornisce la durata per il Lifeguarding t (0 disabilita).
16#100D0USINTR/WLive time factor
16#10170UINTR/WProducer heartbeat time (mS): Tempo di invio messaggio heartbeat (0 disabilita). Heartbeat disabilita il Nodeguarding.
16#10291USINTR/WError behaviour: Definisce lo stato del dispositivo in caso di errore. 0:Preoperational, 1:No change, 2:Stopped
16#1400~FFR/WReceive PDO communication parameter: Mappatura oggetti RPDO.
16#1600~FFR/WReceive PDO mapping parameter: Mappatura comunicazione RPDO.
16#1800~FFR/WTransmit PDO communication parameter: Mappatura comunicazione TPDO.
16#1A00~FFR/WTransmit PDO mapping parameter: Mappatura oggetti TPDO.

Spionaggio comunicazione

Se SpyOn attivo è possibile utilizzare utilizzare la console di spionaggio per verificare il funzionamento della FB. Per la definizione dei livelli di trigger e per il formato del record di spionaggio si rimanda alla CANOpenMaster.

Considerazioni

Esempi

Come utilizzare gli esempi.
Riportiamo il FB iRCop di gestione modulo comunicazione I/O Remoti CANOpen serie iR della Weintek. Nel FB sono gestiti 8 ingressi e 8 uscite ma può essere modificato per adattarlo alle proprie esigenze. Vedere programma ST_CANOpenMaster per il suo utilizzo.

LogicLab (Ptp184, iRCop)
FUNCTION_BLOCK iRCop
VAR
    i : UDINT; (* Auxiliary counter *)
    CaseNr : UINT; (* Case programma *)
    TPDOData : ARRAY[0..1, 0..7] OF BYTE; (* TPO data, Rx Tx *)
    MNode : CANOpenMNode_v1; (* CANOpen master node *)
END_VAR

VAR_INPUT
    SpyOn : BOOL; (* Spy active *)
    NodeID : BYTE; (* Node address *)
    COMaster : @CANOpenMaster_v1; (* CANOpen master *)
    PHBeatTime : UINT; (* Producer Heartbeat Time (mS) *)
    Output : BYTE; (* Outputs to module *)
END_VAR

VAR_OUTPUT
    HBeatOk : BOOL; (* Heartbeat Ok *)
    DType : DWORD; (* Device type *)
    Input : BYTE; (* Inputs from module *)
    Abort : CO_ABORT; (* Abort received *)
    Emcy : CO_EMERGENCY; (* EMCY service *)
    Errors : UDINT; (* Error counter *)
END_VAR

// *****************************************************************************
// FUNCTION BLOCK "iRCop"
// *****************************************************************************
// Manages the Weintek iRCop I/O module.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // MANAGE CAN OPEN NODE
    // -------------------------------------------------------------------------
    // Initialize the node parameters.

    MNode.SpyOn:=SpyOn; //Spy active
    MNode.NodeID:=NodeID; //Node address
    MNode.PHBeatTime:=PHBeatTime; //Producer Heartbeat Time (mS)

    // If master is defined manages the node.

    IF (COMaster = eNULL) THEN RETURN; END_IF;
    MNode(COMaster:=COMaster); //CANOpen master node
    HBeatOk:=MNode.HBeatOk; //Heartbeat Ok

    // =========================================================================
    // CHECK DIAGNOSTIC
    // =========================================================================
    // The abort and emergency status are copied out.

    IF (MNode.Abort.Recd) THEN Abort:=MNode.Abort; END_IF;
    IF (MNode.Emcy.Recd) THEN Emcy:=MNode.Emcy; END_IF;

    // =========================================================================
    // PREOPERATIONAL STATE
    // =========================================================================
    // Execute the module commands.

    CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // MODULE STARTUP
        // ---------------------------------------------------------------------
        // Reset the module.

        0: IF (MNode.Reset()) THEN CaseNr:=CaseNr+1; END_IF;

        // ---------------------------------------------------------------------
        // Reads the device type (it's just to show).

        1: IF (MNode.SDORead(16#1000, 0, DWORD_TYPE, ADR(DType))) THEN CaseNr:=CaseNr+1; END_IF;

        // Set the error behavior on heartbeat error.
        // Index 1029-01: Module goes on Pre-operational
        // Index 6206-01: Digital outputs (01h to 08h) output value are given in 6207
        // Index 6207-01: Digital outputs (01h to 08h) set to FALSE

        2: IF (MNode.SDOWValue(16#1029, 1, BYTE_TYPE, 2)) THEN CaseNr:=CaseNr+1; END_IF;
        3: IF (MNode.SDOWValue(16#6206, 1, BYTE_TYPE, 16#FF)) THEN CaseNr:=CaseNr+1; END_IF;
        4: IF (MNode.SDOWValue(16#6207, 1, BYTE_TYPE, 16#00)) THEN CaseNr:=100; END_IF;

        // --------------------------------------------------[Mappatura TPDO1]--
        // +----------+-[1 BYTE]-+-----+-----+----+-----+-----+-----+-----+
        // | 0x180+ID | Inputs   |                                        |
        // +----------+----------+-----+-----+----+-----+-----+-----+-----+
        // Map "Read input 001h to 008h" (Index 16#6000, SubIndex=1, 1 BYTE).
        // Set communication register, COB-ID=16#180+NodeID.

        100: IF (MNode.PDOMap('TPDO1', 16#6000, 1, BYTE_TYPE)) THEN CaseNr:=CaseNr+1; END_IF;
        101: IF (MNode.PDOCom('TPDO1', 16#180+NodeID, 16#FF, 100)) THEN CaseNr:=110; END_IF;

        // --------------------------------------------------[Mappatura RPDO1]--
        // +----------+-[1 BYTE]-+-----+-----+----+-----+-----+-----+-----+
        // | 0x200+ID | Inputs   |                                        |
        // +----------+----------+-----+-----+----+-----+-----+-----+-----+
        // Map "Write output 001h to 008h" (Index 16#6200, SubIndex=1, 1 BYTE).
        // Set communication register, COB-ID=16#200+NodeID.

        110: IF (MNode.PDOMap('RPDO1', 16#6200, 1, BYTE_TYPE)) THEN CaseNr:=CaseNr+1; END_IF;
        111: IF (MNode.PDOCom('RPDO1', 16#200+NodeID, 16#FF, 100)) THEN CaseNr:=200; END_IF;

        // ---------------------------------------------------------------------
        // Start module.

        200: IF (MNode.Start()) THEN CaseNr:=CaseNr+1; END_IF;
        201: IF (MNode.Status <> CO_NMT_STS#OPERATIONAL) THEN CaseNr:=0; END_IF;
    END_CASE;

    // =========================================================================
    // OPERATIONAL STATE
    // =========================================================================
    // If module is not operational the PDOs are not managed.

    IF (MNode.Status <> CO_NMT_STS#OPERATIONAL) THEN Input:=16#00; RETURN; END_IF;

    // -------------------------------------------------------------------------
    // LOGIC I/O MANAGEMENT
    // -------------------------------------------------------------------------
    // Return the logic inputs status from TPDO1, waited only 1 byte.

    IF (@COMaster.TPDORx(16#180+NodeID, ADR(TPDOData[0, 0])) <> 0) THEN
        Input:=TPDOData[0, 0]; //Inputs from module
    END_IF;

    // On output status change send it to the RPDO1.

    IF (SysIsCANRxTxAv(TRUE) AND (Output <> TPDOData[1, 0])) THEN
        TPDOData[1, 0]:=Output; //TPO data, Rx Tx
        i:[email protected](16#200+NodeID, ADR(TPDOData[1, 0]), 1);
    END_IF;

// [End of file]


Was this article helpful?