diff --git a/.markdownlint.yml b/.markdownlint.yml index 62620c9..a152550 100644 --- a/.markdownlint.yml +++ b/.markdownlint.yml @@ -11,4 +11,5 @@ first-line-h1: false no-emphasis-as-header: false MD024: allow_different_nesting: true - siblings_only: true \ No newline at end of file + siblings_only: true +MD036: false \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS index 609d69f..14abed2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,4 @@ # These owners will be the default owners for everything in the repo. # Unless a later match takes precedence, the listed user will be # requested for review when someone opens a pull request. -# * @michijudge @sjuergen +# * @sjuergen diff --git a/README.md b/README.md index 27015ec..f6286a0 100644 --- a/README.md +++ b/README.md @@ -32,32 +32,66 @@ Simatic.Ax.axftcmlib ## Classes -### Class PneumaticCylinder +## ControlModuleAbstract + +This is a base class for all control modules + +```mermaid +--- +title: ControlModuleAbstract +--- +classDiagram + ExecuteCommand <|-- ControlModuleAbstract + class ControlModuleAbstract{ + +WORD GetErrorStatus() + } + class ExecuteCommand{ + +BOOL Busy() + +BOOL Done() + +BOOL Error() + +WORD ErrorID() + } +``` -PneumaticCylinder (*Note: Needs an active compressor to function with the model) +### Class ActuatorTimeBased + +```mermaid +--- +title: ActuatorTimeBased +--- +classDiagram + ControlModuleAbstract <|-- ActuatorTimeBased + class ControlModuleAbstract{ + +WORD GetErrorStatus() + } + class ActuatorTimeBased{ + +QControl : IBinOutput; + +OnDuration : TIME; + +itfCommand Start() + } +``` |Method|Description| |-|-| -|PneumaticCylinderPush()|Cylinder pushes| -|PneumaticCylinderRetract()|Cylinder retracts| -|Start()| Activates StateMachine and executes it once| +|Start()|Actuator will be activated for the time `OnDuration`|
Example for the class Cylinder ... ```iec-st VAR_GLOBAL - SortingLineValveEjector : BOOL; //Actual PLC-variable - CylinderOutputWriter : BinOutput; //Used to write on the PLC-variable - CylinderClassInstance : PneumaticCylinder := (CoilPushing := CylinderOutputWriter); //Class instance initialized with the needed OutputWriter - EnableCylinder : BOOL; + Actuator : ActuatorTimeBased := (QControl := Q_Actuator) ; + Q_Actuator : BinOutput; + DQ : BOOL; END_VAR PROGRAM - CylinderClassInstance.RunCyclic(); //Class Setup-> needs to be called in every cycle - IF (EnableCylinder) THEN - CylinderClassInstance.Start(); // start pushing the cylinder for a configured time + cmd := Actuator.Start(); + IF NOT(cmd.Busy()) THEN + IF (cmd.Done()) THEN + ; // your code + END_IF; END_IF; - CylinderOutputWriter.WriteCyclic(Q => SortingLineValveEjector); //Writing on the Actual PLC-variable ->needs to be called in every cycle + DQ := Q_Actuator.Q(); // True if actuator is active END_PROGRAM ``` diff --git a/apax-lock.json b/apax-lock.json index 149d196..af0821e 100644 --- a/apax-lock.json +++ b/apax-lock.json @@ -12,7 +12,8 @@ "@simatic-ax/io": "6.0.0", "@ax/system-timer": "7.0.17", "@simatic-ax/commands": "1.0.0", - "@simatic-ax/statemachine": "^6.0.1" + "@simatic-ax/statemachine": "^6.0.1", + "@simatic-ax/types": "^1.0.0" }, "devDependencies": { "@ax/sdk": "2405.0.0", @@ -50,16 +51,15 @@ }, "@ax/axunitst": { "name": "@ax/axunitst", - "version": "5.1.23", - "integrity": "sha512-SAfV92MvnhERKpyZ3rH3gh91ymcrhvU3CRaezbuyVFt2HhZblR/4heF+wQ4mC+dj0Z1U4NHrCiyN1R0N7VuNkg==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst/-/axunitst-5.1.23.tgz", + "version": "5.2.6", + "integrity": "sha512-j2gfKb3tperrm4aRuFWlh0dvvqBya055+FiIo0PJyIT7bRlNLTgu0OSRulObAUn9rJBZL8OkOmGjz2Wsz9gipA==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst/-/axunitst-5.2.6.tgz", "dependencies": { - "@ax/axunitst-library": "5.1.23", - "@ax/axunitst-test-director": "5.1.23", - "@ax/axunitst-docs": "5.1.23", + "@ax/axunitst-library": "5.2.6", + "@ax/axunitst-test-director": "5.2.6", + "@ax/axunitst-docs": "5.2.6", "@ax/build-native": "16.0.3" - }, - "deprecated": "" + } }, "@simatic-ax/snippetscollection": { "name": "@simatic-ax/snippetscollection", @@ -117,6 +117,13 @@ "@ax/system-timer": "7.0.17" } }, + "@simatic-ax/types": { + "name": "@simatic-ax/types", + "version": "1.0.0", + "integrity": "sha512-E8yKADC1HQAIpEAGNDmr4LQkijtlkUHcOwDNDCiUpG2Eyck3eib2dGsQoBdyDk8fQjBsMm1imYeq81Xw3S7Xaw==", + "resolved": "https://npm.pkg.github.com/download/@simatic-ax/types/1.0.0/8d5234b7b6cab437eb92be9fc3f0ae6715514701", + "dependencies": {} + }, "@ax/apax-build": { "name": "@ax/apax-build", "version": "1.0.0", @@ -293,30 +300,29 @@ }, "@ax/axunitst-library": { "name": "@ax/axunitst-library", - "version": "5.1.23", - "integrity": "sha512-0D0FFFqVLHgHDDSde8xZJx84Zvx4YnoGmxcq+H0x1D9hEwJIsOVQFSVsmR4MfomNNaE5840kQ5rMh9gR0FRR5Q==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-library/-/axunitst-library-5.1.23.tgz", + "version": "5.2.6", + "integrity": "sha512-j411mz5F1NKscxVXRLD6bDPYfDDPOsmQbneQqXHZVWfyzymoyYDn8biWjWKgmliGdHzgMsg1SxDYb7qcGz99dA==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-library/-/axunitst-library-5.2.6.tgz", "dependencies": { "@ax/system-strings": "^7.0.17" } }, "@ax/axunitst-test-director": { "name": "@ax/axunitst-test-director", - "version": "5.1.23", - "integrity": "sha512-ezbqpJdHyU7ig8cfiAtvb90CkAEhQVbmki1XPnCaS4XStixao0sTa06qcfLzzYZC2EVa1CxzRIfgXtyHgu+nMQ==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-test-director/-/axunitst-test-director-5.1.23.tgz", + "version": "5.2.6", + "integrity": "sha512-sVo6jaiyedRul6MOJnjBKAzKwBF/g6y6kFq5l0mQzQtr4ek5d0Wj/E0XcrVIRSfq9/jvCaLFfkNt/ae+5gda9w==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-test-director/-/axunitst-test-director-5.2.6.tgz", "dependencies": { - "@ax/axunitst-test-director-linux-x64": "5.1.23", - "@ax/axunitst-test-director-win-x64": "5.1.23" + "@ax/axunitst-test-director-linux-x64": "5.2.6", + "@ax/axunitst-test-director-win-x64": "5.2.6" } }, "@ax/axunitst-docs": { "name": "@ax/axunitst-docs", - "version": "5.1.23", - "integrity": "sha512-nUjL4G8k0d+JKVSy+/alN947dZOgITDagj4uKSAnFib+BfyqDJsuX4afzv8hizUMpGTlepDODhVYJ75DMvu/Ug==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-docs/-/axunitst-docs-5.1.23.tgz", - "dependencies": {}, - "deprecated": "" + "version": "5.2.6", + "integrity": "sha512-G6VNc9uiytIeuu1vG8YzsgYlLG/7BMsjv4CR/SIVFsqRhFMNQO2xTLte2DoZiD2DfhTjYwuExo1hRhCBuLfssQ==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-docs/-/axunitst-docs-5.2.6.tgz", + "dependencies": {} }, "@ax/build-native": { "name": "@ax/build-native", @@ -328,68 +334,6 @@ "@ax/build-native-linux": "16.0.3" } }, - "@ax/system-strings": { - "name": "@ax/system-strings", - "version": "7.0.17", - "integrity": "sha512-xrT2GzVqeTXVF5Nq7wXKwYTb9FqIV3F5DWWGGEUwZvrm5t2unyFqsBDXoFBWDicPuhUFaH0FUwp1NqvMSN95pQ==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/system-strings/-/system-strings-7.0.17.tgz", - "dependencies": { - "@ax/system-math": "7.0.17", - "@ax/system-datetime": "7.0.17" - } - }, - "@ax/axunitst-test-director-linux-x64": { - "name": "@ax/axunitst-test-director-linux-x64", - "version": "5.1.23", - "integrity": "sha512-vHEj+8zr5nsfg6tSC5dVLqYVgTtusYW9O0Rkx02ttiPdJa3seRcNgqMDmgdFp1QAb/YcsmhOTohWbvi8cPQcHg==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-test-director-linux-x64/-/axunitst-test-director-linux-x64-5.1.23.tgz", - "os": [ - "linux" - ], - "cpu": [ - "x64" - ], - "dependencies": {} - }, - "@ax/axunitst-test-director-win-x64": { - "name": "@ax/axunitst-test-director-win-x64", - "version": "5.1.23", - "integrity": "sha512-J/QImr7Fa9Gk+y+df9gp3md0f57HqsEOTdU/19yrOCvQ077PNjs4zl4E2uzWFlVbYo0Cer3JrL/8ARIXuKedpA==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-test-director-win-x64/-/axunitst-test-director-win-x64-5.1.23.tgz", - "os": [ - "win32" - ], - "cpu": [ - "x64" - ], - "dependencies": {} - }, - "@ax/build-native-winx64": { - "name": "@ax/build-native-winx64", - "version": "16.0.3", - "integrity": "sha512-M1qk2yNNsGzz6NXKB0miyfOO4bpYkVcfnGhkHirXcJSLFnWDSx7hnRi0yhLp6jny99RkXEcRn9Cwx8lqynmUDg==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/build-native-winx64/-/build-native-winx64-16.0.3.tgz", - "os": [ - "win32" - ], - "cpu": [ - "x64" - ], - "dependencies": {} - }, - "@ax/build-native-linux": { - "name": "@ax/build-native-linux", - "version": "16.0.3", - "integrity": "sha512-CfqbzR+wPnocP0+pDpb3cYBxdefkS6WvHbGaDNGAoCkK3Y8WnNfWbxXr37e5XIi7iPMZ8BONWaRFIN5h4RMeOA==", - "resolved": "https://registry.simatic-ax.siemens.io/@ax/build-native-linux/-/build-native-linux-16.0.3.tgz", - "os": [ - "linux" - ], - "cpu": [ - "x64" - ], - "dependencies": {} - }, "@ax/simatic-package-tool": { "name": "@ax/simatic-package-tool", "version": "1.0.3", @@ -754,6 +698,68 @@ "dependencies": {}, "deprecated": "" }, + "@ax/system-strings": { + "name": "@ax/system-strings", + "version": "7.0.17", + "integrity": "sha512-xrT2GzVqeTXVF5Nq7wXKwYTb9FqIV3F5DWWGGEUwZvrm5t2unyFqsBDXoFBWDicPuhUFaH0FUwp1NqvMSN95pQ==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/system-strings/-/system-strings-7.0.17.tgz", + "dependencies": { + "@ax/system-math": "7.0.17", + "@ax/system-datetime": "7.0.17" + } + }, + "@ax/axunitst-test-director-linux-x64": { + "name": "@ax/axunitst-test-director-linux-x64", + "version": "5.2.6", + "integrity": "sha512-FQo2kcqxf6JoPWVZJbO43E1V2yJWrawWajHR+NKdMaAwXWsraH5AFmYKMmbQqiodCW6jBdQ/5dBOivGa0hmuSw==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-test-director-linux-x64/-/axunitst-test-director-linux-x64-5.2.6.tgz", + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "dependencies": {} + }, + "@ax/axunitst-test-director-win-x64": { + "name": "@ax/axunitst-test-director-win-x64", + "version": "5.2.6", + "integrity": "sha512-9gnw1YUW0Jfdpreha7g1GmgFYjhwufPHcSiDKzI/wpozzJYCqc25W9rmkKK0ROcY2X9hMb56kQE0h4O/+ufOWQ==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/axunitst-test-director-win-x64/-/axunitst-test-director-win-x64-5.2.6.tgz", + "os": [ + "win32" + ], + "cpu": [ + "x64" + ], + "dependencies": {} + }, + "@ax/build-native-winx64": { + "name": "@ax/build-native-winx64", + "version": "16.0.3", + "integrity": "sha512-M1qk2yNNsGzz6NXKB0miyfOO4bpYkVcfnGhkHirXcJSLFnWDSx7hnRi0yhLp6jny99RkXEcRn9Cwx8lqynmUDg==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/build-native-winx64/-/build-native-winx64-16.0.3.tgz", + "os": [ + "win32" + ], + "cpu": [ + "x64" + ], + "dependencies": {} + }, + "@ax/build-native-linux": { + "name": "@ax/build-native-linux", + "version": "16.0.3", + "integrity": "sha512-CfqbzR+wPnocP0+pDpb3cYBxdefkS6WvHbGaDNGAoCkK3Y8WnNfWbxXr37e5XIi7iPMZ8BONWaRFIN5h4RMeOA==", + "resolved": "https://registry.simatic-ax.siemens.io/@ax/build-native-linux/-/build-native-linux-16.0.3.tgz", + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "dependencies": {} + }, "@ax/system-math": { "name": "@ax/system-math", "version": "7.0.17", diff --git a/apax.yml b/apax.yml index ef96370..1607a8c 100644 --- a/apax.yml +++ b/apax.yml @@ -40,4 +40,6 @@ dependencies: "@ax/system-timer": 7.0.17 "@simatic-ax/commands": 1.0.0 "@simatic-ax/statemachine": ^6.0.1 + "@simatic-ax/types": ^1.0.0 + # "@ax/simatic-1500-technology-objects": ^0.1.52 installStrategy: overridable diff --git a/src/Actuator/ActuatorTimeBased.st b/src/Actuator/ActuatorTimeBased.st index dd10c35..3a88b99 100644 --- a/src/Actuator/ActuatorTimeBased.st +++ b/src/Actuator/ActuatorTimeBased.st @@ -4,10 +4,10 @@ USING Simatic.Ax.Io.Output; NAMESPACE Simatic.Ax.axftcmlib CLASS ActuatorTimeBased - EXTENDS ControlModuleAbstract + EXTENDS ExecuteControlModuleAbstract IMPLEMENTS IActuator VAR PUBLIC - ControlPush : IBinOutput; + QControl : IBinOutput; OnDuration : TIME; END_VAR VAR @@ -20,27 +20,27 @@ NAMESPACE Simatic.Ax.axftcmlib END_METHOD METHOD PROTECTED OVERRIDE _executeCustom - IF (ControlPush = NULL) THEN + IF (QControl = NULL) THEN THIS.SetError(WORD#16#8101); RETURN; ELSE THIS.SetError(FALSE); END_IF; - _tonOnDuration(signal := ControlPush.IsOn(), Duration := OnDuration); + _tonOnDuration(signal := QControl.IsOn(), Duration := OnDuration); CASE _state OF ActuatorState#Retracted: // IF () - ControlPush.SetOff(); + QControl.SetOff(); ActuatorState#Activating: - ControlPush.SetOn(); + QControl.SetOn(); _state := ActuatorState#Activated; ActuatorState#Activated: IF (_tonOnDuration.output) THEN _state := ActuatorState#Retracting; - ControlPush.SetOff(); + QControl.SetOff(); END_IF; ActuatorState#Retracting: - ControlPush.SetOff(); + QControl.SetOff(); _state := ActuatorState#Retracted; THIS.SetDone(); END_CASE; @@ -48,16 +48,8 @@ NAMESPACE Simatic.Ax.axftcmlib METHOD PUBLIC Start : itfCommand THIS.InitState(); - THIS.Enable(); - Start := THIS; - END_METHOD - - METHOD PUBLIC Enable _state := ActuatorState#Activating; - END_METHOD - - METHOD PUBLIC Disable - _state := ActuatorState#Retracted; + Start := THIS; END_METHOD METHOD PUBLIC GetState : ActuatorState diff --git a/src/Actuator/IActuator.st b/src/Actuator/IActuator.st index f567814..0ea28cd 100644 --- a/src/Actuator/IActuator.st +++ b/src/Actuator/IActuator.st @@ -1,8 +1,6 @@ +USING Simatic.Ax.Commands; NAMESPACE Simatic.Ax.axftcmlib INTERFACE IActuator - METHOD Enable END_METHOD - METHOD Disable END_METHOD - METHOD GetState : ActuatorState - END_METHOD + METHOD Start : itfCommand END_METHOD END_INTERFACE END_NAMESPACE \ No newline at end of file diff --git a/src/Axis/Legacy/Axis.st b/src/Axis/Legacy/Axis.st deleted file mode 100644 index 5db9762..0000000 --- a/src/Axis/Legacy/Axis.st +++ /dev/null @@ -1,290 +0,0 @@ -USING Simatic.Ax.IO.Input; -USING System.Timer; -USING Simatic.Ax.SimpleControlModules; - -NAMESPACE Simatic.Ax.axftcmlib.Motion - TYPE INTERNAL - StatesHoming : (Idle, MoveOutOfSensor, FindReferenceSensor, Done) := Idle; - END_TYPE - - TYPE INTERNAL - StateMoveAbsolute : (Idle, Moving, Stopping, Done) := Idle; - END_TYPE - - TYPE INTERNAL - MotionMode : (Stopped, Homing, MoveAbsolute, MoveRelative, MoveVelocity); - END_TYPE - - TYPE - PlcOpenState : (Ready, Busy, Done, Error) := Ready; - END_TYPE - - ///Class contains all functions necessary for realisng a motion axis - ///The motor is used for "powering" the axis - ///The encoder is needed to monitor the current position - CLASS Axis2 - IMPLEMENTS IAxis - VAR PUBLIC - Motor : IMotor; - Encoder : IEncoder; - ReferenceSwitch : IBinSignal; - END_VAR - VAR PROTECTED - _stateHoming : StatesHoming; - _stateMoveAbsolute : StateMoveAbsolute; - _motionMode : MotionMode; - _velocity : LREAL; - _direction : Direction; - _position : LINT; - _distance : LINT; - _plcOpenState : PlcOpenState; - _done : BOOL; - _isHomed : BOOL; - _statusRefSwitch : BOOL; - END_VAR - - ///Outputs the current status of the axis and executes the protected methods(must be called in every cicle) - METHOD PUBLIC RunCyclic - _statusRefSwitch := ReferenceSwitch.Q(); - CASE _motionMode OF - MotionMode#Stopped: - _plcOpenState := PlcOpenState#Ready; - ; - MotionMode#Homing: - _plcOpenState := PlcOpenState#Busy; - _done := THIS._homing(velocity := _velocity, direction := _direction); - IF _done THEN - _plcOpenState := PlcOpenState#Done; - _isHomed := TRUE; - _motionMode := MotionMode#Stopped; - END_IF; - MotionMode#MoveAbsolute: - IF (NOT (_isHomed)) THEN - _plcOpenState := PlcOpenState#Error; - RETURN; - END_IF; - _plcOpenState := PlcOpenState#Busy; - _done := THIS._moveAbsolute(velocity := _velocity, posititon := _position); - IF _done THEN - _plcOpenState := PlcOpenState#Done; - _motionMode := MotionMode#Stopped; - END_IF; - ; - MotionMode#MoveRelative: - IF (NOT (_isHomed)) THEN - _plcOpenState := PlcOpenState#Error; - RETURN; - END_IF; - _plcOpenState := PlcOpenState#Busy; - _done := THIS._moveRelative(velocity := _velocity, distance := _distance); - IF _done THEN - _plcOpenState := PlcOpenState#Done; - _motionMode := MotionMode#Stopped; - END_IF; - ; - MotionMode#MoveVelocity: - _plcOpenState := PlcOpenState#Busy; - Motor.Move(_velocity, _direction); - - END_CASE; - END_METHOD - - ///Moves axis with a velocity - /// Has to be stopped manually with Halt() - METHOD PUBLIC MoveVelocity - VAR_INPUT - velocity : LREAL; - direction : Direction; - END_VAR - _velocity := velocity; - _direction := direction; - _motionMode := MotionMode#MoveVelocity; - END_METHOD - - ///Moves axis to a new position based on the current position - METHOD PUBLIC MoveRelative : BOOL - VAR_INPUT - velocity : LREAL; - distance : LINT; - END_VAR - _velocity := velocity; - _distance := distance; - _motionMode := MotionMode#MoveRelative; - END_METHOD - - ///Moves axis to a new position based on the default position - ///homing the axis beforehand is needed to execute this function - METHOD PUBLIC MoveAbsolute : BOOL - VAR_INPUT - velocity : LREAL; - position : LINT; - END_VAR - _velocity := velocity; - _position := position; - _motionMode := MotionMode#MoveAbsolute; - END_METHOD - - ///Moves axis to the default "homing" position (needed for moveAbsolute()) - METHOD PUBLIC Homing : BOOL - VAR_INPUT - velocity : LREAL; - direction : Direction; - END_VAR - _velocity := velocity; - _direction := direction; - _motionMode := MotionMode#Homing; - END_METHOD - - ///Homes axis without moving it into default position - ///Sets position to given value - METHOD PUBLIC Homing : BOOL - VAR_INPUT - Position : LINT; - END_VAR - Encoder.SetValue(value := Position); - _stateHoming := StatesHoming#Done; - _plcOpenState := PlcOpenState#Done; - _isHomed := TRUE; - END_METHOD - - ///Stops movement of the axis - ///needs to be called manually for MoveVelocity() - METHOD PUBLIC Halt - Motor.Halt(); - _motionMode := MotionMode#Stopped; - _plcOpenState := PlcOpenState#Done; - END_METHOD - ///Checks whether the axis is homed or not - METHOD PUBLIC IsHomed : BOOL - IsHomed := _isHomed; - END_METHOD - - - //Protected methods are executed by RunCyclic() - - ///Moves axis with a velocity - /// Has to be stopped manually with Halt() - METHOD PROTECTED _moveVelocity - VAR_INPUT - velocity : LREAL; - direction : Direction; - END_VAR - Motor.Move(velocity, direction); - END_METHOD - - ///Moves axis to a new position based on the current position - METHOD PROTECTED _moveRelative : BOOL - VAR_INPUT - velocity : LREAL; - distance : LINT; - END_VAR - _moveRelative := THIS._moveAbsolute(velocity := velocity, posititon := Encoder.GetValue() + distance); - END_METHOD - - ///Moves axis to a new position based on the default position - ///homing the axis beforehand is needed to execute this function - METHOD PROTECTED _moveAbsolute : BOOL - VAR_INPUT - velocity : LREAL; - posititon : LINT; - END_VAR - VAR_TEMP - dir : Direction; - END_VAR - CASE _stateMoveAbsolute OF - StateMoveAbsolute#Idle: - IF (posititon = Encoder.GetValue()) THEN - _stateMoveAbsolute := StateMoveAbsolute#Done; - _moveAbsolute := TRUE; - Motor.Halt(); - ELSE - _stateMoveAbsolute := StateMoveAbsolute#Moving; - Motor.Move(velocity, dir); - END_IF; - StateMoveAbsolute#Moving: - dir := THIS.DecideDirection(enc := Encoder, setPoint := posititon); - Motor.Move(velocity, dir); - IF (Encoder.GetValue() = posititon) THEN - _stateMoveAbsolute := StateMoveAbsolute#Done; - Motor.Halt(); - END_IF; - StateMoveAbsolute#Done: - _moveAbsolute := TRUE; - _stateMoveAbsolute := StateMoveAbsolute#Idle; - ; - END_CASE; - END_METHOD - - ///Homes axis without moving it into default position - ///Sets position to given value - METHOD PROTECTED _homing : BOOL - VAR_INPUT - velocity : LREAL; - direction : Direction; - END_VAR - // Reference switch already reached - // Move out from the Reference switch in opposit direction - CASE _stateHoming OF - StatesHoming#Idle: - _isHomed := FALSE; - IF (ReferenceSwitch.Q()) THEN - _stateHoming := StatesHoming#MoveOutOfSensor; - ELSE - _stateHoming := StatesHoming#FindReferenceSensor; - END_IF; - StatesHoming#MoveOutOfSensor: - Motor.Move(direction := THIS._oppositDirection(direction := direction)); - IF (ReferenceSwitch.QFal()) THEN - Motor.Halt(); - _stateHoming := StatesHoming#FindReferenceSensor; - END_IF; - StatesHoming#FindReferenceSensor: - Motor.Move(direction := direction); - IF (ReferenceSwitch.QRis()) THEN - Motor.Halt(); - Encoder.SetValue(value := 0); - _stateHoming := StatesHoming#Done; - END_IF; - StatesHoming#Done: - _homing := TRUE; - _stateHoming := StatesHoming#Idle; - END_CASE; - ; - END_METHOD - - ///inverts the current direction - METHOD PROTECTED _oppositDirection : Direction - VAR_INPUT - direction : Direction; - END_VAR - IF (direction = Direction#PositiveDirection) THEN - _oppositDirection := Direction#NegativeDirection; - ELSE - _oppositDirection := Direction#PositiveDirection; - END_IF; - END_METHOD - - ///decides the needed direction to reach setpoint - METHOD PROTECTED DecideDirection : Direction - VAR_INPUT - enc : IEncoder; - setpoint : LINT; - END_VAR - IF (setpoint >= enc.GetValue()) THEN - DecideDirection := Direction#PositiveDirection; - ELSE - DecideDirection := Direction#NegativeDirection; - END_IF; - END_METHOD - - ///Outputs current status of the PLC - METHOD PUBLIC GetPlcOpenState : PlcOpenState - GetPlcOpenState := _plcOpenState; - END_METHOD - ///Returns whether the axis is busy with a movement command - METHOD PUBLIC IsRunning : BOOL - IsRunning := _plcOpenState = PlcOpenstate#Busy; - END_METHOD - END_CLASS - -END_NAMESPACE \ No newline at end of file diff --git a/src/Axis/Legacy/IAxis.st b/src/Axis/Legacy/IAxis.st deleted file mode 100644 index 33edde0..0000000 --- a/src/Axis/Legacy/IAxis.st +++ /dev/null @@ -1,51 +0,0 @@ -NAMESPACE Simatic.Ax.axftcmlib.Motion - - ///Interface for implementing an axis - ///Contains basic functions needed for realising an axis - INTERFACE IAxis - ///Moves axis wit given velcity in a given direction - METHOD MoveVelocity - VAR_INPUT - velocity : LREAL; - direction : Direction; - END_VAR - END_METHOD - ///Moves axis to destination based on current position - METHOD MoveRelative : BOOL - VAR_INPUT - velocity : LREAL; - distance : LINT; - END_VAR - END_METHOD - ///Moves axis to a new position based on the default position - METHOD MoveAbsolute : BOOL - VAR_INPUT - velocity : LREAL; - position : LINT; - END_VAR - END_METHOD - ///Stops axis - METHOD Halt - END_METHOD - ///Moves axis into the default position - METHOD Homing : BOOL - VAR_INPUT - velocity : LREAL; - direction : Direction; - END_VAR - END_METHOD - ///Resets current position to deafult value without actual movement - METHOD Homing : BOOL - VAR_INPUT - Position : LINT; - END_VAR - END_METHOD - ///Returns whether the defaultposition is set - METHOD IsHomed : BOOL - END_METHOD - ///Returns whether the axis is busy with a movement command - METHOD IsRunning : BOOL - END_METHOD - END_INTERFACE - -END_NAMESPACE diff --git a/src/Compressor/Compressor.st b/src/Compressor/Compressor.st new file mode 100644 index 0000000..cad0383 --- /dev/null +++ b/src/Compressor/Compressor.st @@ -0,0 +1,51 @@ +USING Simatic.Ax.IO.Input; +USING Simatic.Ax.IO.Output; +USING Simatic.Ax.Commands; + +NAMESPACE Simatic.Ax.axftcmlib + + ///Implementation of the Compressor interface + /// needs an IBinOutout that is used to write on the PLC-Variables + CLASS Compressor + EXTENDS EnablingControlModuleAbstract + IMPLEMENTS IEnablingCm + VAR PUBLIC + QControl : IBinOutput; + END_VAR + ///turns the compressor on + + METHOD PUBLIC Enable : itfCommand + IF QControl = NULL THEN + Enable := THIS; + RETURN; + END_IF; + QControl.SetOn(); + THIS.InitState(); + Enable := THIS; + END_METHOD + ///turns the compressor off + + METHOD PUBLIC Disable : itfCommand + Disable := THIS; + IF THIS._Error THEN + RETURN; + END_IF; + QControl.SetOff(); + THIS.SetDone(); + END_METHOD + + METHOD PROTECTED OVERRIDE _executeCustom + IF THIS._Error THEN + RETURN; + END_IF; + QControl.SetOn(); + END_METHOD + + METHOD PROTECTED OVERRIDE _initmethod + IF (QControl = NULL) THEN + THIS.SetError(WORD#16#8001); + END_IF; + END_METHOD + END_CLASS + +END_NAMESPACE diff --git a/src/Compressor/PneumaticCompressor.st b/src/Compressor/PneumaticCompressor.st deleted file mode 100644 index a48647b..0000000 --- a/src/Compressor/PneumaticCompressor.st +++ /dev/null @@ -1,24 +0,0 @@ -USING Simatic.Ax.IO.Input; -USING Simatic.Ax.IO.Output; - -NAMESPACE Simatic.Ax.axftcmlib - ///Implementation of the Compressor interface - /// needs an IBinOutout that is used to write on the PLC-Variables - CLASS PneumaticCompressor IMPLEMENTS IPneumaticCompressor - - VAR PUBLIC - ActiveCompressor : IBinOutput; - END_VAR - - ///turns the compressor on - METHOD PUBLIC PneumaticCompressorOn - ActiveCompressor.SetOn() ; - END_METHOD - - ///turns the compressor off - METHOD PUBLIC PneumaticCompressorOff - ActiveCompressor.SetOff(); - END_METHOD - END_CLASS - -END_NAMESPACE \ No newline at end of file diff --git a/src/ControlModuleAbstract.st b/src/ControlModuleAbstract.st index d9a714b..69d08ed 100644 --- a/src/ControlModuleAbstract.st +++ b/src/ControlModuleAbstract.st @@ -3,7 +3,7 @@ USING Simatic.Ax.Commands; NAMESPACE Simatic.Ax.axftcmlib ///Provides basic functionality for programming on a plc /// has acces to the protected Methods and "Contructors" of the classes - CLASS ABSTRACT ControlModuleAbstract EXTENDS ExecuteCommand + CLASS ABSTRACT ExecuteControlModuleAbstract EXTENDS ExecuteCommand VAR PUBLIC END_VAR diff --git a/src/EnablingControlModuleAbstract.st b/src/EnablingControlModuleAbstract.st new file mode 100644 index 0000000..0d5328c --- /dev/null +++ b/src/EnablingControlModuleAbstract.st @@ -0,0 +1,42 @@ +USING Simatic.Ax.Commands; + +NAMESPACE Simatic.Ax.axftcmlib + ///Provides basic functionality for programming on a plc + /// has acces to the protected Methods and "Contructors" of the classes + CLASS ABSTRACT EnablingControlModuleAbstract EXTENDS Command + VAR PUBLIC + + END_VAR + VAR PROTECTED + _init : BOOL; + _hasError : BOOL; + _errorState : WORD; + _exec : BOOL; + END_VAR + + METHOD PROTECTED OVERRIDE Execute + IF (NOT _init) THEN + THIS._initmethod(); + _init := TRUE; + END_IF; + THIS._executeCustom(); + ; + END_METHOD + + + METHOD PROTECTED ABSTRACT _executeCustom + + END_METHOD + + METHOD PROTECTED ABSTRACT _initmethod + + END_METHOD + + + METHOD PUBLIC GetErrorStatus : WORD + GetErrorStatus := _errorState; + END_METHOD + + END_CLASS + +END_NAMESPACE \ No newline at end of file diff --git a/src/Encoder/TmCount.st b/src/Encoder/TmCount.st new file mode 100644 index 0000000..b028df1 --- /dev/null +++ b/src/Encoder/TmCount.st @@ -0,0 +1,84 @@ +// USING Simatic.Ax.SimpleControlModules; +// USING Siemens.Simatic.S71500.TechnologyObjects; + +// NAMESPACE Simatic.Ax.axftcmlib +// CLASS TmCountEncoder implements IEncoder +// VAR PUBLIC +// HWID : WORD; +// ChannelNo : INT; +// END_VAR +// VAR PRIVATE +// hsc: HighSpeedCounter; +// hwConfig : HSC_Configuration; +// ParmIn : PRAM_IN; +// PramOut : PRAM_OUT; +// _relativeCount : LINT; +// _actualValue : LINT; +// _actualValueOld : LINT := 0; +// END_VAR + + +// METHOD PUBLIC Evaluate +// hwConfig.HWID := HWID; +// hwConfig.ChannelNo := ChannelNo; +// ParmIn.SwGate := TRUE; +// hsc.Process(hwConfig,ParmIn,PramOut); +// _actualValue := PramOut.CapturedValue; +// IF _actualValueOld <> 0 THEN +// // Berechnung der relativen Ă„nderung +// _relativeCount := (_actualValue - _actualValueOld); +// ELSE +// // Initiale Bedingung, wenn PreviousValue 0 ist, um Division durch 0 zu vermeiden +// _relativeCount := 0; +// END_IF; +// _actualValueOld := _actualValue; +// END_METHOD + +// METHOD PUBLIC Reset +// ParmIn.SetCountValue := TRUE; +// hwConfig.Values.StartValue := 0; +// hsc.Process(hwConfig,ParmIn,PramOut); +// ParmIn.SetCountValue := FALSE; +// END_METHOD + +// METHOD PUBLIC SetValue +// VAR_INPUT +// value : LINT; +// END_VAR +// ParmIn.SetCountValue := TRUE; +// hwConfig.Values.StartValue := TO_DINT(value); +// hsc.Process(hwConfig,ParmIn,PramOut); +// ParmIn.SetCountValue := FALSE; +// _actualValue := value; +// _actualValueOld := value; +// ; +// END_METHOD + +// METHOD PUBLIC GetValue : LINT +// GetValue := _actualValue; +// ; +// END_METHOD + +// METHOD PUBLIC SetDirection +// VAR_INPUT +// mode : CountMode; +// END_VAR + +// ; +// END_METHOD + +// METHOD PUBLIC RelativeCount : LINT +// RelativeCount := _relativeCount; +// END_METHOD + +// METHOD PUBLIC ResetRelative +// _relativeCount := 0; +// _actualValueOld := _actualValue; +// END_METHOD + +// METHOD PUBLIC GetModulo : LINT +// ; +// END_METHOD +// END_CLASS + +// END_NAMESPACE diff --git a/src/Compressor/IPneumaticCompressor.st b/src/IEnablingCm.st similarity index 72% rename from src/Compressor/IPneumaticCompressor.st rename to src/IEnablingCm.st index 2d0280c..6d3d059 100644 --- a/src/Compressor/IPneumaticCompressor.st +++ b/src/IEnablingCm.st @@ -1,14 +1,16 @@ ///Interface for a class compressor ///contains the basic functions neede for the Fischertechnik models /// Is used to power a pneumatic cylinder +USING Simatic.Ax.Commands; + NAMESPACE Simatic.Ax.axftcmlib -INTERFACE IPneumaticCompressor +INTERFACE IEnablingCm ///turns the compressor on - METHOD PneumaticCompressorOn + METHOD Enable : itfCommand END_METHOD ///turns the compressor off - METHOD PneumaticCompressorOff + METHOD Disable : itfCommand END_METHOD END_INTERFACE diff --git a/test/Compressor_test.st b/test/Compressor_test.st index e44cac2..480700c 100644 --- a/test/Compressor_test.st +++ b/test/Compressor_test.st @@ -1,33 +1,47 @@ -//USING Simatic.Ax.Cylinder; USING AxUnit.Assert; USING Simatic.Ax.IO.Input; USING Simatic.Ax.axftcmlib; USING Simatic.Ax.IO.Output; +USING Simatic.Ax.Commands; NAMESPACE Simatic.Ax.axftcmlib + {TestFixture} CLASS MyCompressorTest VAR PROTECTED - _testCompressor : PneumaticCompressor; - _testSubject : BinOutput; + _testCompressor : Compressor; + _testCompressorStateless : Compressor; + _Q : BinOutput; + cmd : itfCommand; END_VAR - METHOD PUBLIC SetUp - _testCompressor.ActiveCompressor := _testSubject; + + {TestSetup} + METHOD PUBLIC TestSetup + _testCompressor := _testCompressorStateless; + _testCompressor.QControl := _Q; END_METHOD {Test} METHOD PUBLIC TestTurnCompressorOn_Expect_state_is_On - THIS.SetUp(); - _testCompressor.PneumaticCompressorOn(); - AxUnit.Assert.Equal(expected := TRUE, actual :=_testSubject.IsOn()); // _testCompressor.ActiveCompressor.IsOn()); + cmd := _testCompressor.Enable(); + AxUnit.Assert.Equal(expected := TRUE, actual := cmd.Busy()); + AxUnit.Assert.Equal(expected := TRUE, actual := _Q.IsOn()); END_METHOD {Test} - METHOD PUBLIC TestTurnCompressorOff_Expect_state_is_Off - THIS.SetUp(); - _testCompressor.PneumaticCompressorOff(); - AxUnit.Assert.Equal(expected := FALSE, actual := _testSubject.IsOn()); - END_METHOD + METHOD PUBLIC Missing_the_control_Q_leads_To_error + _testCompressor.QControl := NULL; + cmd := _testCompressor.Enable(); + AxUnit.Assert.Equal(expected := TRUE, actual := cmd.Error()); + AxUnit.Assert.Equal(expected := FALSE, actual := _Q.IsOn()); + END_METHOD + {Test} + METHOD PUBLIC TestTurnCompressorOff_Expect_state_is_Off + cmd := _testCompressor.Disable(); + AxUnit.Assert.Equal(expected := TRUE, actual := cmd.Done()); + AxUnit.Assert.Equal(expected := FALSE, actual := _Q.IsOn()); + END_METHOD END_CLASS -END_NAMESPACE \ No newline at end of file + +END_NAMESPACE