③ Drive Configuration Subroutines

These subroutines do the actual work of configuring the Siemens drives. They are triggered by the engineer clicking the step buttons in the UI. They loop through every device in the Starter project and write parameters using SetParam() and SetSym() (see file ②).

📌 Key Siemens Objects Used:
PROJ.Devices — a collection of all devices (CU320 controllers) in the project.
adevice.TOs — the Technology Objects inside a device (individual drives).
aTO.ExternalTypeName — identifies the type: "SINAMICS_SERVO_SL" or "SINAMICS_VECTOR_SVC".
Device_to_CU(adevice) — helper function that returns the CU320 object for a given device.
Device_to_Infeed(adevice) — helper function that returns the infeed (ALM/SIC) object.

Ident_CheckDuplicatesOrUnassigned

Function Ident_CheckDuplicatesOrUnassigned
When called: When the engineer presses "Accept" in the Drive Identification screen.
What it does:
Before renaming drives, the script checks that:
  1. No two physical drives have been assigned the same function (duplicates)
  2. Every detected drive has been assigned a function (no unassigned drives)
Returns True if there is a problem (either condition), False if all is OK.
Function Ident_CheckDuplicatesOrUnassigned
    Dim DriveAllocated(20)          ' Tracks which function each physical drive has been assigned
    For index=1 To numdrives
        DriveAllocated(index)=0     ' Start with nothing assigned
    Next
    Duplicates=False
    Unassigned=False
    Projectdriveindex=0             ' Counter for physical drives found in the project

    For Each adevice In PROJ.Devices   ' Loop through every device (CU)
        For Each aTO In adevice.TOs    ' Loop through every Technology Object in that device
            If (aTO.ExternalTypeName="SINAMICS_SERVO_SL" Or ATO.ExternalTypeName="SINAMICS_VECTOR_SVC") Then
                ' Only count servo or vector TOs = these are the actual drive modules
                Projectdriveindex = Projectdriveindex+1

                ' Read what the engineer selected in the dropdown for this drive row
                AssignDrive = mainpage.document.GetElementById("Select_" & Projectdriveindex).Value
                ' AssignDrive = the functional drive index (1=Unwind, 2=Draw... 0 = not assigned)

                If AssignDrive=0 Then Unassigned=True   ' Dropdown left blank

                If DriveAllocated(AssignDrive)=0 Then
                    DriveAllocated(AssignDrive)=Projectdriveindex  ' First time this function seen — OK
                Else
                    Duplicates=True    ' Already assigned to another drive — DUPLICATE
                End If
            End If
        Next
    Next

    If Duplicates Then   MainPage.StatusText="Drive function selected more than once"
    If Unassigned Then   MainPage.StatusText="Drive function not selected"

    Ident_CheckDuplicatesOrUnassigned = Duplicates Or Unassigned  ' True = problem found
End Function

Ident_RenameControlUnits

Sub Ident_RenameControlUnits
What it does:
Renames each CU320 device and its CU Technology Object using the drive's PROFIBUS address (read from parameter p8931 index 3, or p2057 index 0 for older systems). Result: the device gets named "CU320_0xx" and the CU TO gets named "CU_0xx" where xx = the PROFIBUS node address.
Sub Ident_RenameControlUnits
    For Each aDevice In PROJ.Devices
        If (DiagCU320Identify = True) Then
            ' p8931[3] = The CU's assigned PROFIBUS address (new method)
            adevice.Name = "CU320_0" & Device_to_CU(aDevice).Parameters(8931,3)
            Device_to_CU(adevice).Name = "CU_0" & Device_to_CU(aDevice).Parameters(8931,3)
            ' Example result: device named "CU320_018", CU named "CU_018"
        Else
            ' p2057[0] = DIP switch address (legacy / older CU method)
            adevice.Name = "CU320_0" & Device_to_CU(aDevice).Parameters(2057,0)
            Device_to_CU(adevice).Name = "CU_0" & Device_to_CU(aDevice).Parameters(2057,0)
        End If
    Next
End Sub

ConfigureAllCUs — (Step 3: Config Infeed and CUs)

Sub ConfigureAllCUs
When called: Engineer presses "Config Infeed and CUs" button.
What it does: Loops through every device in the project and:
  1. Finds TM120 temperature modules → calls InitialTM120Parameters
  2. Finds each CU with or without an infeed → calls InitialInfeedParameters and InitialControlUnitParameters
  3. Sets comparison quality to WEAK/OFFLINE (so Starter doesn't complain about differences)
  4. Calls SetupComms to configure the PROFIBUS telegram assignments
Sub ConfigureAllCUs
    ' ── Phase 1: TM120 temperature modules ──────────────────────────────────────────
    For Each adevice In PROJ.Devices
        For Each aTO In adevice.TOs
            If (aTO.ExternalTypeName="SINAMICS_TM120") Then
                InitialTM120Parameters aTO   ' Configure the temperature sensing module
            End If
        Next
    Next

    ' ── Phase 2: CU320 + infeed configuration ──────────────────────────────────────
    For Each adevice In PROJ.Devices
        Set CU = Device_to_CU(aDevice)                    ' Get the CU320 for this device
        ThisDeviceHasInfeed = DeviceHasInfeed(aDevice)    ' Does this CU have an ALM/SIC infeed?
        Set Infeed = Device_to_infeed(aDevice)             ' Get the infeed object (may be Nothing if no infeed)

        If ThisDeviceHasInfeed Then
            InitialInfeedParameters Infeed, CU   ' Configure supply voltage, power factor, etc. on the infeed
        End If

        InitialControlUnitParameters CU, Infeed, ThisDeviceHasInfeed
        ' ↑ Configures the CU320: sets machine type, PLC type, safety mode, etc.

        adevice.SetCompareLevelForAll "OFFLINE", "WEAK"
        ' ↑ Tells Starter to use a weak comparison when checking parameters.
        '   This prevents false "parameter mismatch" warnings during configuration.
    Next

    ' ── Phase 3: Communications setup ─────────────────────────────────────────────
    If ConfigOption01_SetupComms Then
        SetupComms   ' See SetupComms documentation below
    End If
End Sub

ConfigureAllDrives — (Step 4: Config Drives)

Sub ConfigureAllDrives
When called: Engineer presses "Config Drives" button.
What it does:
For each drive in DriveList, validates that speed and torque values are numeric, then calls InitialDriveParameters to write the full set of parameters (speed calibration, torque limit, direction, encoder type, etc.) to that drive.
⚠️ Prerequisite: Steps 1 (Identify Drives) and 2 (Edit Machine Data) must be complete before running this step. The drive TOs must exist in the project with the correct names, and machine data must contain valid numeric speed and torque values.
Sub ConfigureAllDrives
    SpeedsValid=True

    ' ── Phase 1: Validate all speed/torque values before doing anything ────────────
    For DriveIndex=1 To numDrives
        If DriveIsInProject(DriveList(DriveIndex), 0) Then   ' Only check drives that exist in the project
            If Not (isNumeric(MachineData_Speed(DriveIndex)) And isNumeric(MachineData_Torque(DriveIndex))) Then
                SpeedsValid=False    ' Flag a problem if any speed or torque is not a number
            End If
        End If
    Next

    If SpeedsValid Then
        ' ── Phase 2: Configure each drive ────────────────────────────────────────────
        For DriveIndex=1 To numdrives
            For Each adevice In PROJ.Devices
                For Each aTO In adevice.TOs
                    If (aTO.ExternalTypeName="SINAMICS_SERVO_SL" Or ATO.ExternalTypeName="SINAMICS_VECTOR_SVC") Then
                        If drivelist(DriveIndex)=aTO.Name Then   ' Found the matching TO for this drive number
                            speed  = MachineData_Speed(DriveIndex)   ' Calculated motor speed at max web speed (RPM)
                            torque = MachineData_Torque(DriveIndex)  ' Motor rated/reference torque (Nm)
                            Set CU  = Device_to_CU(aDevice)
                            Set Infeed = Device_to_Infeed(aDevice)
                            ThisDeviceHasInfeed = DeviceHasInfeed(aDevice)

                            If MachineData_EnableConfig(DriveIndex)=1 Then
                                InitialDriveParameters aTO, CU, Infeed, ThisDeviceHasInfeed, DriveIndex, speed, torque
                                ' ↑ This is the main drive configuration function (defined elsewhere in Starter).
                                '   It sets p210 (voltage), p1082 (max speed), p2000 (reference speed),
                                '   p1460 (speed gain), p1462 (integral time), etc.
                            Else
                                PrintToLogFile("Initial parameters skipped: " & aTO.Name)
                                ' This drive is disabled in the machine data (Enable checkbox not ticked)
                            End If
                        End If
                    End If
                Next
            Next
        Next
    Else
        EchoToScreen("ConfigureAllDrives function - Error - speed or torque values not valid")
        ' Abort if any drive has invalid data — do not write half-configured parameters
    End If
End Sub

SetupComms — Communications Telegram Setup

Sub SetupComms
What it does:
Configures the PROFIBUS/PROFINET telegram structure on each CU320. This tells each CU which drive modules it should talk to, and in which slots. Uses Siemens parameter p978 (slot assignment) and sets up free telegram structure with p922, p2068, p2069.

Background: Each CU320 communicates with the PLC over PROFIBUS. The telegram has numbered "slots" — slot 1 = CU itself (free telegram), slot 2 = infeed, slots 3-10 = drive modules. DriveCommSlot(n) defines which slot each drive uses.
Sub SetupComms
    Counter=0   ' Counts how many devices have been processed

    For Each ThisDevice In PROJ.Devices
        Counter = Counter+1
        Set ThisCU = Device_to_CU(ThisDevice)

        ' ── Step 1: Clear all slots to "dummy" or "disabled" ──────────────────────────
        '   p978 = Slot assignment register. 255 = dummy slot, 0 = disabled
        NextUnassignedSlot = NumCommSlots+2  ' TM120 and other non-comms TOs go here
        For index=1 To 25
            index3 = index-1   ' p978 uses 0-based indexing
            If index3 <= NumCommSlots Then
                SetParam ThisCU, 978, index3, 255   ' Set slot as "dummy" (placeholder)
            Else
                SetParam ThisCU, 978, index3, 0     ' Disable slot (beyond NumCommSlots)
            End If
        Next

        ' ── Step 2: Assign slot 0 to the CU itself (free telegram 999) ───────────────
        '   CU always gets slot 0 with telegram type 999 (free/flexible telegram)
        SetParam ThisCU, 978, 0, ThisCU.DriveId    ' p978[0] = CU's own drive ID
        SetParam ThisCU, 922, 0, 999              ' p922[0] = 999 = Free telegram (custom structure)
        SetParam ThisCU, 2068, 1, 10             ' p2068[1] = 10 words in setpoint channel
        SetParam ThisCU, 2069, 1, 10             ' p2069[1] = 10 words in actual value channel

        For Each ThisTO In ThisDevice.TOs
            ' ── Step 3: Assign slot 1 to infeed (ALM / SIC) — uses telegram 370 ──────────
            '   Telegram 370 = standard Active Line Module telegram
            If (ThisTO.ExternalTypeName="SINAMICS_SIC" Or ThisTO.ExternalTypeName="SINAMICS_ALM") Then
                SetParam ThisCU, 978, 1, ThisTo.DriveId  ' p978[1] = infeed's drive ID
                SetParam ThisTo, 922, 0, 370             ' p922[0] = 370 = infeed telegram type
            End If

            ' ── Step 4: Assign drive modules to their defined comm slots ─────────────────
            '   Uses DriveCommSlot(n) from the drive list (file 01, Section 6)
            If (ThisTO.ExternalTypeName="SINAMICS_SERVO_SL" Or ThisTO.ExternalTypeName="SINAMICS_VECTOR_SVC") Then
                For index=1 To NumDrives
                    If DriveList(index)=ThisTo.Name And DriveCommSlot(index)>0 Then
                        SetParam ThisCU, 978, DriveCommSlot(index)-1, ThisTo.DriveId
                        ' ↑ Assign this drive's ID to its slot.
                        '   Subtract 1 because DriveCommSlot uses 1-based numbering but p978 is 0-based
                        SetParam ThisTo, 2068, 1, 10   ' 10-word setpoint channel for this drive
                        SetParam ThisTo, 2069, 1, 10   ' 10-word actual value channel for this drive
                    End If
                Next
            End If

            ' ── Step 5: TM120 temperature modules go at the end (no fixed slot) ──────────
            If (ThisTO.ExternalTypeName="SINAMICS_TM120") Then
                SetParam ThisCU, 978, NextUnassignedSlot-1, ThisTo.DriveId
                NextUnassignedSlot = NextUnassignedSlot+1   ' Move to next available slot
            End If
        Next  ' Next TO in this device
    Next  ' Next device

    TelegramIsConfigured=True   ' Mark comms as done — used by UpdateStatusDisplay to show "Complete" on step 3
End Sub

Continue to ④ HTML UI Builder.