Convert to Python to Codesys

Draft

The PI-Plate has manufactures devices that can be used with the Raspiberry-PI. The objective of this project would not stop at just the relay plate, but also incorporate other Pi-Plate devices. The Device driver will be a child of the SPI master and have 7 slots for Pi-Plate devices.

Pi-Plates
Data Acquisition Plate with Generator Capabilities
Data Acquisition Plate
Tinker Plate, Mix of Data Acquisition and inputs
Relay Control
Temperature Measurement
Motion Control

https://pi-plates.com/pi-plates-catalog/

The relay plate has 7 relays on the plate. Looks like it is because of size and cost constraints. Stacking the plates will allow for 49 relays. Which is plenty for most projects and there is always the possibility of stringing together multiple Rasp-PIs via ethercat. Each relay will be mapped to a variable so true will be on and false will be off.

RELAY Control Functions
relayON(addr,relay) - turns on (closes) the specified relay
relayOFF(addr,relay) - turns off (opens) the specified relay
relayTOGGLE(addr,relay) - "toggles" state of specified relay. If relay is on, this command will turn it off. If relay is off, this command will turn it on. Use this command to blink a lamp off and on.
relayALL(addr,value) - used to control the state of all relays with a single command. "value" is a 7 bit number with each bit corresponding to a relay. Bit 0 is relay 1, bit 1 is relay 2, and so on. To turn all the relays on at once, use the number 127 for the value.
* relaySTATE(addr) - Returns a 7-bit number with the current state of each relay. Bit 0 is relay 1, bit 1 is relay 2, and so on. A "1" in a bit position means that the relay is on and zero means that it's off.

LED Control Functions
setLED(addr) - turn on the LED
clrLED(addr) - turn off the LED
* toggleLED(addr) - if LED is on, turn off. If LED is off, turn on.

System Level Functions
getID(addr) - return Pi-Plate descriptor string
getFWrev(addr) - return FW revision in byte format
getHWrev(addr) - return HW revision in byte format
getPMrev() - returns revision of python module
getADDR(addr) - return address of pi-plate. Used for polling available boards at power up.
RESET(addr) - set RELAYplate to power-on state. Turns all relays off. **

I am going to focus on
RelayAll
setLED
clrLED
getFWrev
getHWrev
RESET

  • Python Code
def getHWrev(addr):
    global RELAYbaseADDR
    VerifyADDR(addr)
    resp=ppCMDr(addr,0x02,0,0,1)
    rev = resp[0]
    whole=float(rev>>4)
    point = float(rev&0x0F)
    return whole+point/10.0  

def getFWrev(addr):
    global RELAYbaseADDR
    VerifyADDR(addr)
    resp=ppCMDr(addr,0x03,0,0,1)
    rev = resp[0]
    whole=float(rev>>4)
    point = float(rev&0x0F)
    return whole+point/10.0

 def relayALL(addr,relays):
    VerifyADDR(addr)
    assert ((relays>=0) and (relays<=127)),"Argument out of range. Must be between 0 and 127"
    ppCMDr(addr,0x13,relays,0,0)

 def ppCMDr(addr,cmd,param1,param2,bytes2return):
    global RELAYbaseADDR
    arg = list(range(4))
    resp = []
    arg[0]=addr+RELAYbaseADDR;
    arg[1]=cmd;
    arg[2]=param1;
    arg[3]=param2;
    GPIO.output(ppFRAME,True)
    null=spi.xfer(arg,300000,60)
    #null = spi.writebytes(arg)
    if bytes2return>0:
        time.sleep(.0001)
        for i in range(0,bytes2return): 
            dummy=spi.xfer([00],500000,20)
            resp.append(dummy[0])
    time.sleep(.001)
    GPIO.output(ppFRAME,False)
    time.sleep(.001)
    return resp   

    **Codesys Code:**

   FB_Relay_Plate

   //Globals
   Hardware_Version : BYTE;
   Firmware_Version : BYTE;
   Relay_Plate_Address : BYTE;  //0 to 7  Assigned by slot address?
   Relay_States : BYTE; //0 to 127, Bit 0 = Relay 0, Bit 7 = Relay 7
   Led_State : BOOL;  //True = On, False = Off
   Previous_State : BYTE;

    End

    VAR CONSTANT
    Relay_Base_Address : BYTE := 24;
    Frame_GPIO : BYTE := 25;
    PPINT : BYTE := 22;  
    END_VAR

   Intialize
       Method Set_Address
       Method Get_Hardware_Version : BYTE;
       Method Get_Firmware_Version : BYTE;


    Cyclic Calls

        METHOD Set_IO
            VAR
                    Previous_Relay_State : BOOL;
                    Previous_LED_State : BOOL;
                    Send_Data : BOOL;
                    CommandData : ARRAY [0..6] OF BYTE;
            END_VAR



            Write_Data(Data:=CommandData,Execute:=Send_Data, Data_Sent => DataSent);

          Case of iState

          Set_Relays: IF Previous_State <> Relay_States
                                            Send_Data := True;
                                            (*Format: ppCMDr(addr,0x13,relays,0,0)
                                                arg[0]=addr+RELAYbaseADDR;
                                                           arg[1]=cmd;
                                                           arg[2]=param1;
                                                           arg[3]=param2;
                                             null=spi.xfer(arg,300000,60)
                                             300000 = 0x93E0;
                                             60 = 0x3C;
                                            *)
                                            CommandData[0] := Relay_Base_Address + Relay_Plate_Address;
                                            CommandData[1] := 16#0x13;  //COMMAND FOR ALL RELAYS
                                            CommandData[2] := Relay_States;  //CURRENT RELAY STATE MAP
                                            CommandData[3] := 16#0x04;       //Don't know what the rest does
                                            CommandData[4] := 16#0x93;  
                                            CommandData[5] := 16#0xE0;
                                            CommandData[6] := 16#0x3C;

                                             If DataSent Then
                                                 Relays_Set := true;
                                                Send_Data := False;
                                                Previous_State := Relay_States;
                                             End_IF

                                        Else
                                            Relays_Set := true;
                                        End_IF

                                        If Relays_Set = True Then
                                            Send_Data := False;
                                            Previous_State := Relay_States;
                                            iState := Set_Leds;
                                        End_IF
           Set_Leds :

           Function Write_Data
           VARINPUT
               bExecute : BOOL;
               Data_Command : ARRAY [0..6] OF BYTE;
           END_VAR
            VAR
                        iStep : INT;
            VAR_END
            VAR OUTPUT
                Data_Sent : BOOL;
            VAR_END

               IF bExecute Then
                           //Set frame GPIO
                           //On_Output  //Not sure how to do this yet

                           //Send 1 byte at a time
                          senddata(Data:= Data_Command[iStep]);

                          //move to the next byte
                          iStep := iStep + 1;

                          //if last byte then reset and indicate last data sent
                          if iStep = 7 Then
                              iStep := 0;
                              Data_Sent := True

                              //Turn the output off
                              //Not sure how to do this yet.
                          End_IF
                 Else
                         //Reset Function if not executing
                         iStep := 0;
                         Data_Sent := False;
                  End_If;

          Method sendData : BOOL;
          VAR_INPUT
              DATA : BYTE;
          END_VAR
          VAR
            abyTxBuffer: ARRAY [0..2] OF BYTE;
            abyRxBuffer: ARRAY [0..2] OF BYTE;

        END_VAR

          abyTxBuffer[0] := DATA; //SPI_WRITE_CMD;
          abyTxBuffer[1] := byPort;
          abyTxBuffer[2] := byValue;


 Write_Data := transfer(pabyTxBuffer:=ADR(abyTxBuffer) , pabyRxBuffer:=ADR(abyRxBuffer) , udiLen:=3 , uiDelayus:=5 );

IF NOT Write_Data THEN
    _iState := 1000;
END_IF

Related

Home: Pi-Plate Python Code To SPI