SysI2CWrRd, writes/reads on I2C extension bus

List

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

Questa funzione gestisce la scrittura/lettura sul bus I2C di estensione. L’utilizzo di questa funzione permette di gestire qualsiasi componente I2C connesso al bus di estensione. Chiamando la funzione con WrBytes e RdBytes a zero, esegue un node check tornando TRUE se il nodo I2c esiste.

Attenzione, il bus I2C è utilizzato per l’accesso ai moduli di estensione per non rallentarne l’accesso si consiglia di eseguire comandi I2C non più lunghi di 4 bytes in scrittura e lettura. Nel caso serva gestire più bytes si consiglia di spezzare il comando in più comandi consecutivi.

Information Circle

Funzione

CODESYS: Non disponibile

LogicLab: eLLabXUnified12Lib

Descrizione

Address (BYTE) Indirizzo dispositivo I2C range da 16#00 a 16#7F.
WrBytes (USINT) Numero di bytes dati da scrivere. 0 se solo lettura.
WrBuffer (PVOID) Indirizzo buffer memoria che contiene i dati da scrivere, eNULL se solo lettura.
RdBytes (USINT) Numero di bytes dati da leggere. 0 se solo scrittura.
RdBuffer (PVOID) Indirizzo buffer memorizzazione dati letti, eNULL se solo scrittura.

La funziona ritorna un BOOL, FALSE: Errore esecuzione, TRUE: Funzione eseguita correttamente.

Immagine F SysI2CWrRd
Verifica dispositivo I2C

Per verificare se un dispositivo con un certo indirizzo I2C è connesso al bus di espansione del sistema è possibile utilizzare la funzione SysI2CWrRd passando l’indirizzo I2C da verificare con gli altri parametri non assegnati.

    IF (SysI2CWrRd(16#30, 0, eNULL, 0, eNULL)) THEN
        // Device with 16#30 I2C address is connected.
    ELSE
        // Device with 16#30 I2C address is not connected.
    END_IF;

Esempi

Come utilizzare gli esempi.

ST_SysI2CWrRd: Viene eseguita l’acquisizione del valore di temperatura e di umidità da un sensore SHT30-DIS della Sensirion come questo connesso al bus I2C di un sistema SlimLine. Non viene eseguito il controllo sul CRC dei valori acquisisti. In questo articolo si trova la stessa gestione realizzata con il FB di gestione bus I2C.

ST_ScanI2CDevices: Collegandosi in telnet alla porta indicata viene eseguito la scansione di tutti i possibili indirizzi I2C e ritornato l’elenco dei dispositivi connessi al bus I2C di espansione.

LogicLab (Ptp116, ST_SysI2CWrRd)
PROGRAM ST_SysI2CWrRd
VAR
    CaseNr : USINT; (* Program case *)
    TimeBf : UDINT; (* Time buffer (mS) *)
    Errors : UDINT; (* Error counter *)
    Temperature : REAL; (* Temperature value (°C) *)
    Humidity : REAL; (* Humidity value (%) *)
    I2CWrite : ARRAY[0..1] OF BYTE; (* I2C write buffer *)
    I2CRead : ARRAY[0..7] OF BYTE; (* I2C read buffer *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_SysI2CWrRd"
// *****************************************************************************
// Temperature and humidity acquisistion from a Sensirion SHT30-DIS.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // PROGRAM CASES
    // -------------------------------------------------------------------------
    // Program cases management.

    CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // Conversion command "Single Shot Mode high repeatability" clock
        // streching disabled.

        0:
        I2CWrite[0]:=16#24; //MSB
        I2CWrite[1]:=16#00; //LSB
        IF NOT(SysI2CWrRd(16#44, 2, ADR(I2CWrite), 0, eNULL)) THEN
            Errors:=Errors+1; //Error counter
            CaseNr:=0; //Program case
            RETURN;
        END_IF;

        // Save time to wait

        TimeBf:=SysTimeGetMs(); //Time buffer (mS)
        CaseNr:=CaseNr+1; //Program case

        // ---------------------------------------------------------------------
        // Wait conversion complete (Max time oh high repeatability 15 mS).

         1:
         IF ((SysTimeGetMs()-TimeBf) < T#15ms) THEN RETURN; END_IF;

        // Read the conversion results.

        IF NOT(SysI2CWrRd(16#44, 0, eNULL, 6, ADR(I2CRead))) THEN
            Errors:=Errors+1; //Error counter
            CaseNr:=0; //Program case
            RETURN;
        END_IF;

        // Convert the acquired values.

        Temperature:=-45.0+(175.0*(TO_REAL((I2CRead[0]*256)+I2CRead[1])/65535.0));
        Humidity:=100.0*(TO_REAL((I2CRead[3]*256)+I2CRead[4])/65535.0);
        CaseNr:=0; //Program case
    END_CASE;

// [End of file]
LogicLab (Ptp116, ST_ScanI2CDevices)
PROGRAM ST_ScanI2CDevices
VAR
    i : UDINT; (* Auxiliary variable *)
    Fp : eFILEP; (* File pointer array *)
    SOut : STRING[ 128 ]; (* String output *)
    TCPServer : SysTCPServer; (* TCP server *)
    CaseNr : USINT; (* Program case *)
    I2CAddress : BYTE; (* I2C address *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_ScanI2CDevices"
// *****************************************************************************
// Opens a TCP server and when a client connect to it the extension I2C is
// scanned.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // INITIALIZATION
    // -------------------------------------------------------------------------
    // TCPServer initialization.

    IF (SysFirstLoop) THEN
        TCPServer.FilesArr:=ADR(Fp); //Files array
        TCPServer.LocalAdd:=ADR('0.0.0.0'); //Local address
        TCPServer.LocalPort:=1120; //Local port 
        TCPServer.MaxConn:=1; //Accepted connections
        TCPServer.FlushTm:=50; //Flush time (mS)
        TCPServer.LifeTm:=15; //Life time (S)
        TCPServer.RxSize:=128; //Rx buffer size
        TCPServer.TxSize:=128; //Tx buffer size
    END_IF;

    // -------------------------------------------------------------------------
    // OBJECT EXECUTION
    // -------------------------------------------------------------------------
    // Manage the TCP server and check if a client has been connected.

    TCPServer(); //TCPServer management
    TCPServer.Enable:=TRUE; //TCPServer enable
    IF NOT(SysFIsOpen(Fp)) THEN CaseNr:=0; RETURN; END_IF;

    // -------------------------------------------------------------------------
    // PROGRAM CASES
    // -------------------------------------------------------------------------
    // Program cases management.

    CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // Init check.

        0:
        i:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('Scan I2C Bus devices%s'), STRING_TYPE, ADR('$r$n'));
        I2CAddress:=16#00; //I2C address
        CaseNr:=CaseNr+1; //Program case

        // ---------------------------------------------------------------------
        // Check if the I2C device is present.

        1:
        IF NOT(SysI2CWrRd(Address:=I2CAddress, WrBytes:=0, WrBuffer:=eNULL, RdBytes:=0, RdBuffer:=eNULL)) THEN
            i:=SysCVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%s '), STRING_TYPE, ADR('--'));
        ELSE
            i:=SysCVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%02X '), USINT_TYPE, ADR(I2CAddress));
        END_IF;

        // Increase the I2C address to check.
        
        I2CAddress:=I2CAddress+1; //I2C address

        // Every 16 addresses return the result.

        IF (MOD(I2CAddress, 16) = 0) THEN    
            i:=SysCVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%s'), STRING_TYPE, ADR('$r$n'));
            i:=Sysfwrite(ADR(SOut), TO_INT(LEN(SOut)), 1, Fp);
            i:=SysFOBfFlush(Fp); //Flush the socket data
            CaseNr:=CaseNr+1; //Program case
            RETURN;
        END_IF;

        // ---------------------------------------------------------------------
        // Waits the output buffer empty.

        2:
        IF (SysFGetOSpace(Fp) <> TO_INT(SysFGetOBfSize(Fp))) THEN RETURN; END_IF;
        i:=Sysmemset(ADR(SOut), 0, SIZEOF(SOut));

        // Check if all possible addresses has been tested.

        IF (I2CAddress < 16#80) THEN CaseNr:=CaseNr-1; RETURN; END_IF;
        i:=SysFOBfFlush(Fp); //Flush the socket data
        i:=Sysfclose(Fp); //Close socket
        CaseNr:=0; //Program case
    END_CASE;

// [End of file]
Was this article helpful?