-
-
Save RozeDoyanawa/0939f08db3fea6dc496a785403476364 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* Status update timer setup *) | |
(* #wTmrStatusRefreshValue:= INT_TO_WORD(StatusRefreshInterval); *) | |
bEnableStatusUpdate:= NOT bStatusUpdateTimerFlag AND NOT bQueStatusUpdate AND NOT bQueInputUpdate AND NOT bQueStatusUpdate; | |
tmrStatusUpdate(EN:= EN, TON:= bEnableStatusUpdate, TimerValue:= INT_TO_WORD(StatusRefreshInterval), Out=>bStatusUpdateTimerFlag); | |
(* Retry timer setup *) | |
tmrRetry(EN:= EN, TON:= bTmrRetryEnable, TimerValue:= INT_TO_WORD(25), Out=> bTmrRetryFlag); | |
IF bStatusUpdateTimerFlag AND NOT Busy THEN (* If status update timer has triggered *) | |
bQueStatusUpdate:= TRUE; (* Schedule Status Word Update *) | |
END_IF; | |
IF bTmrRetryFlag THEN (* If retry timer has triggered *) | |
bTmrRetryEnable:= FALSE; (* Disable retry timer *) | |
(*bQueSetSpeed:= TRUE;*) (* Schedule setting of speed | Disabled*) | |
bQueSetControlWord:= TRUE; (* Schedule setting of control word *) | |
END_IF; | |
(* Main State Machine *) | |
CASE iState OF | |
(* Idle State *) | |
0: IF bQueStatusUpdate THEN | |
iState:= 1; (* Send Status Word Request *) | |
ELSIF bQueInputUpdate THEN | |
iState:= 3; (* Send Input Request *) | |
ELSIF wSpeed <> Speed OR bQueSetSpeed THEN | |
bQueSetSpeed:= FALSE; (* Clear Explicit Speed Update Request *) | |
iState:= 5; (* Send Speed Update *) | |
ELSIF bStarted <> Start OR bReversing <> Reversing OR bQueSetControlWord THEN (* If Start or reversing state is different from last transmission or if ControlWord transmission has explicitly been requested *) | |
bQueSetControlWord:= FALSE; (* Clear Explicit update request flag *) | |
iState:= 6; (* Send ControlWord Update *) | |
IF Start THEN (* Make sure to send speed an extra time when start was requested *) | |
wSpeed:= 0; (* Clear buffered speed to force re-send *) | |
END_IF; | |
END_IF; | |
(* Send Status Word Request *) | |
1: IF NOT bBusInUse AND NOT Busy AND NOT bModbus_Executing_P1 THEN | |
bBusInUse:= TRUE; (* Set Bus in use so no other block tries to claim it *) | |
Done:= FALSE; (* Clear previously set done flag *) | |
Busy:= TRUE; (* Set internal busy so we know we claimed the bus *) | |
w50Modbus_CommandData_P1[0]:= INT_TO_WORD(SlaveID); (* Load Slave ID *) | |
w50Modbus_CommandData_P1[1]:= 16#0003; (* Function code, 0x3=Read Holding Register *) | |
w50Modbus_CommandData_P1[2]:= 16#0004; (* Number of bytes to send NOT words. Excluding addr, size and function*) | |
w50Modbus_CommandData_P1[3]:= 16#C417; (* Holding register address 0xC417 is 50199 is Register(50200) is Status Control Word (SCW)*) | |
w50Modbus_CommandData_P1[4]:= INT_TO_WORD(1); (* Number of words to read *) | |
iState:= 2; (* Wait Status Word (SCW) Response *) | |
bModbus_Executing_P1:= TRUE; (* Initiate transfer *) | |
END_IF; | |
(* Wait Status Word Response *) | |
2:IF Busy AND NOT bModbus_Executing_P1 THEN | |
bQueStatusUpdate:= FALSE; | |
IF InputReading THEN (* If we are interested in input port states *) | |
iState:= 3; (* Send Input Request *) | |
ELSE | |
iState:= 0; (* Idle State *) | |
END_IF; | |
IF NOT bModbus_Error_P1 THEN (* Only if no bus error *) | |
IF w50Modbus_RecievedData_P1[2] = 0 THEN (* Only if response function is 0 *) | |
IF SHR (w50Modbus_RecievedData_P1[4] AND 16#00F0, 8) = 2 THEN (* If we received requested number of bytes *) | |
wReceived:= SHL(w50Modbus_RecievedData_P1[4] AND 16#00FF, 8) OR SHR(w50Modbus_RecievedData_P1[5] AND 16#FF00, 8); | |
DeviceStatus:= wReceived; (* Output received ControlWord *) | |
(* Mask out status bits *) | |
UnitReady:= (SHR(wReceived, 0) AND 16#1) = 1; | |
ControlReady:= (SHR(wReceived, 1) AND 16#1) = 1; | |
CoastingEnabled:= (SHR(wReceived, 2) AND 16#1) = 1; | |
Error_Trip:= (SHR(wReceived, 3) AND 16#1) = 1; | |
Error_NoTrip:= (SHR(wReceived, 4) AND 16#1) = 1; | |
TripLocked:= (SHR(wReceived, 6) AND 16#1) = 1; | |
Warning:= (SHR(wReceived, 7) AND 16#1) = 1; | |
SpeedOK:= (SHR(wReceived, 8) AND 16#1) = 1; | |
BusInControl:= (SHR(wReceived, 9) AND 16#1) = 1; | |
FrequencyLimitOK:= (SHR(wReceived, 10) AND 16#1) = 1; | |
Running:= (SHR(wReceived, 11) AND 16#1) = 1; | |
ResistorBreakFault:= (SHR(wReceived, 12) AND 16#1) = 1; | |
VoltageFault:=(SHR(wReceived, 13) AND 16#1) = 1; | |
TorqueFault:= (SHR(wReceived, 14) AND 16#1) = 1; | |
ThermalWarning:= (SHR(wReceived, 15) AND 16#1) = 1; | |
IF Running <> Start THEN (* If Local Start State differs from Frequency converter *) | |
bTmrRetryEnable:= TRUE; (* Retry setting state *) | |
END_IF; | |
END_IF; | |
END_IF; | |
Busy:= FALSE; (* Release Busy Flag *) | |
Done:= TRUE; (* Tell we are done *) | |
bBusInUse:= FALSE; (* Release Bus *) | |
END_IF; | |
END_IF; | |
(* Send Input Request *) | |
3: IF NOT bBusInUse AND NOT Busy AND NOT bModbus_Executing_P1 THEN | |
bBusInUse:= TRUE; (* Set Bus in use so no other block tries to claim it *) | |
Done:= FALSE; (* Clear previously set done flag *) | |
Busy:= TRUE; (* Set internal busy so we know we claimed the bus *) | |
w50Modbus_CommandData_P1[0]:= INT_TO_WORD(SlaveID); (* Load Slave ID *) | |
w50Modbus_CommandData_P1[1]:= 16#0003; (* Function code, 0x3=Read Holding Register *) | |
w50Modbus_CommandData_P1[2]:= 16#0004; (* Number of bytes to send NOT words. Excluding addr, size and function*) | |
w50Modbus_CommandData_P1[3]:= 16#40D7; (* Holding register address 0x40D7 is 16599 is Register(16600) is Config Param (16-60)*) | |
w50Modbus_CommandData_P1[4]:= INT_TO_WORD(1); (* Number of words to read *) | |
iState:= 4; (* Wait Input Request Response *) | |
bModbus_Executing_P1:= TRUE; (* Initiate transfer *) | |
END_IF; | |
(* Wait Input Request Response *) | |
4:IF Busy AND NOT bModbus_Executing_P1 THEN | |
bQueInputUpdate:= FALSE; | |
iState:= 0; (* Idle State *) | |
IF NOT bModbus_Error_P1 THEN (* Only if no bus error *) | |
IF w50Modbus_RecievedData_P1[2] = 0 THEN (* Only if response function is 0 *) | |
IF SHR (w50Modbus_RecievedData_P1[4] AND 16#00F0, 8) = 2 THEN (* If we received requested number of bytes *) | |
wReceived:= SHL(w50Modbus_RecievedData_P1[4] AND 16#00FF, 8) OR SHR(w50Modbus_RecievedData_P1[5] AND 16#FF00, 8); | |
(* Mask out input states *) | |
Input18:= (wReceived AND 16#F000) > 0; | |
Input19:= (wReceived AND 16#0F00) > 0; | |
Input27:= (wReceived AND 16#00F0) > 0; | |
Input33:= (wReceived AND 16#000F) > 0; | |
END_IF; | |
END_IF; | |
Busy:= FALSE; (* Release Busy Flag *) | |
Done:= TRUE; (* Tell we are done *) | |
bBusInUse:= FALSE; (* Release Bus *) | |
END_IF; | |
END_IF; | |
(* Send Speed Update *) | |
5: IF NOT bBusInUse AND NOT Busy AND NOT bModbus_Executing_P1 THEN | |
bBusInUse:= TRUE;(* Set Bus in use so no other block tries to claim it *) | |
Done:= FALSE; (* Clear previously set done flag *) | |
Busy:= TRUE; (* Set internal busy so we know we claimed the bus *) | |
wSpeed:= Speed; | |
w50Modbus_CommandData_P1[0]:= INT_TO_WORD(SlaveID); (* Load Slave ID *) | |
w50Modbus_CommandData_P1[1]:= 16#0010; (* Function code, 0x10=Write Holding Register *) | |
w50Modbus_CommandData_P1[2]:= 16#0007; (* Number of bytes to send NOT words. Excluding addr, size and function*) | |
w50Modbus_CommandData_P1[3]:= 16#C359; (* Holding register address 0xC359 is 50009 is Register(50010) is Bus Reference Value*) | |
w50Modbus_CommandData_P1[4]:= 16#0001; (* Number of words to write *) | |
w50Modbus_CommandData_P1[5]:= 16#0200 OR SHR(wSpeed,8); (* Byte Count + speed high-byte*) | |
w50Modbus_CommandData_P1[6]:= SHL(wSpeed AND 16#FF, 8); (* Speed low-byte *) | |
iState:= 100; (* State to Wait transfer complete / error*) | |
bModbus_Executing_P1:= TRUE; (* Initiate transfer *) | |
END_IF; | |
(* Send ControlWord Update *) | |
6: IF NOT bBusInUse AND NOT Busy AND NOT bModbus_Executing_P1 THEN (* Wait for bus to be free *) | |
bBusInUse:= TRUE;(* Set Bus in use so no other block tries to claim it *) | |
Done:= FALSE; (* Clear previously set done flag *) | |
Busy:= TRUE; (* Set internal busy so we know we claimed the bus *) | |
wTemp:= 0; (* Use a temporary variable to store the CTW *) | |
IF Start THEN (* If Start requested *) | |
wTemp:= wTemp OR SHR(16#1, 6); (* Set bit 6 of CTW *) | |
END_IF; | |
IF Reversing THEN (* If Reversing requested *) | |
wTemp:= wTemp OR SHR(16#1, 15); (* Set bit 15 of CTW *) | |
END_IF; | |
bReversing:= Reversing; (* Store written reversing state *) | |
bStarted:= Start; (* Store written start state *) | |
w50Modbus_CommandData_P1[0]:= INT_TO_WORD(SlaveID); (* Load Slave ID *) | |
w50Modbus_CommandData_P1[1]:= 16#0010; (* Function code, 3=Read Holding Register *) | |
w50Modbus_CommandData_P1[2]:= 16#0007; (* Number of bytes to send NOT words. Excluding addr, size and function*) | |
w50Modbus_CommandData_P1[3]:= 16#C34F; (* Holding register address 0xC34F is 49999 is Register(50000) is Control Word (CTW)*) | |
w50Modbus_CommandData_P1[4]:= 16#1; (* Number of words to write *) | |
w50Modbus_CommandData_P1[5]:= 16#0200 OR SHR(wTemp,8); (* Byte Count + CTW high-byte*) | |
w50Modbus_CommandData_P1[6]:= SHL(wTemp AND 16#FF, 8); (* CTW low-byte *) | |
iState:= 100; (* State to Wait bus Ready *) | |
bModbus_Executing_P1:= TRUE; (* Initiate transfer *) | |
END_IF; | |
(* Wait Transfer complete / error *) | |
100: IF Busy AND NOT bModbus_Executing_P1 THEN | |
iState:= 0; (* State to Idle State *) | |
Busy:= FALSE; (* Release Busy Flag *) | |
Done:= TRUE; (* Tell we are done *) | |
bBusInUse:= FALSE; (* Release Bus *) | |
END_IF; | |
END_CASE; | |
(* Bus error checking *) | |
IF Busy AND NOT bModbus_Executing_P1 AND bModbus_Error_P1 AND NOT ErrorClear AND NOT Error THEN (* If We own the bus and Executing stopped and there is a bus error *) | |
Error:= TRUE; (* Flag error *) | |
Busy:= FALSE; (* Clear Busy *) | |
bBusInUse:= FALSE; (* Release Bus *) | |
ELSIF Error AND ErrorClear THEN (* If there is an error and clearing it is requested *) | |
iState:= 0; (* Idle State *) | |
Error:= FALSE; (* Clear error flag *) | |
END_IF; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment