Attribute VB_Name = "modConfig"
' This module is included to handle all of the initial
' settings for both paleomag and biomag magnetometers.

' DLL declarations
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long

'Sample changer settings

' Holes are found at every slot divisible by HoleSlotNum
' SlotMax is smallest slot number
' SlotMax is largest slot number

Public SlotMin As Integer, SlotMax As Integer, HoleSlotNum As Integer

' Size of movement between slots for the DC Servo motors.  On Lowenstam, one rev is
' 4000 steps, small gear is 22 teeth, large is 50 teeth, and 9 slots
' per big wheel.  Note that this is a negative number, because going from
' zero to a positive number will DECREASE the slot number under the changer.
' Therefore, on Lowenstam, OneStep = 4000 * 50 / (22 * 9) = -1010.1010101

Public OneStep As Double

'Program settings
Public Prog_UsageFile  As String
Public Prog_DefaultBackup As String
Public Prog_DefaultPath As String
Public Prog_LogoFile As String

Public Prog_TextEditor As String

Public Prog_HelpURLRoot As String

Public DumpRawDataStats As Boolean
Public LogMessages As Boolean

' Calibration variables read from file
Public ZCal      As Double
Public XCal      As Double
Public YCal      As Double
Public IRMPos    As Long
Public IRMHiPos  As Long
Public SCoilPos  As Long
Public ZeroPos    As Long      ' Zero position in motor steps
Public MeasPos    As Long      ' Measuring Position in motor steps
Public AFPos      As Long      ' AF Position in motor steps
Public SampleBottom As Long    ' distance from load to base of sample;
Public SampleTop As Long       '  used to measure height of sample
Public SampleHeight As Long
Public SampleHoleAlignmentOffset As Double
Public LiftSpeedSlow As Long
Public LiftSpeedNormal As Long
Public LiftSpeedFast As Long
Public CmdHomeToTop As Integer
Public CmdSamplePickup As Integer
Public MotorIDTurning As Integer
Public MotorIDChanger As Integer
Public MotorIDUpDown As Integer
Public SCurveFactor As Integer
Public TurningMotorFullRotation As Long
Public TurningMotor1rps As Long
Public UpDownMotor1cm As Double
Public TrayOffsetAngle As Double
Public UpDownTorqueFactor As Integer
Public PickupTorqueThrottle As Double


Public ChangerSpeed As Long
Public TurnerSpeed As Long

Public RangeFact  As Double      ' Range factor
Public RemeasureCSDThreshold As Double

'  now the Af demag calibration values
Public AFDelay          As Integer
Public AFRampRate       As Integer
Public AfAxialCoord     As String
Public AfTransCoord     As String

'  Axial Coil Calibration Variables
Public AfAxialYpoint    As Double
Public AfAxialXpoint    As Double
Public AfAxialLowSlope   As Double
Public AfAxialHighSlope As Double
Public AfAxialMax       As Double
Public AfAxialMin       As Double
'  Transverse Coil Calibration Variables
Public AfTransYpoint    As Double
Public AfTransXpoint    As Double
Public AfTransLowSlope  As Double
Public AfTransHighSlope As Double
Public AfTransMax       As Double
Public AfTransMin       As Double
'  Now the IRM Pulse coil variables
Public IRMHFAxis          As String
Public IRMLFAxis          As String
Public IRMLFBackfieldAxis   As String

Public PulseVoltMax       As Double

Public PulseLFX(20) As Double
Public PulseLFY(20) As Double

Public PulseHFX(20) As Double
Public PulseHFY(20) As Double

Public PulseLFMax         As Double
Public PulseLFMin         As Double

Public PulseHFMax         As Double
Public PulseHFMin         As Double


' now susceptibility variables
Public SusceptibilityMomentFactorCGS As Double
Public SusceptibilityScaleFactor As Double

' MCC volt conversion converts a charging volt
' to a MCC output voltage (default: 10 V MCC -> 450 V)
Public PulseMCCVoltConversion As Double
Public PulseReturnMCCVoltConversion As Double

' Now the ARM calibration variables
Public ARMMax            As Double
Public ARMVoltGauss     As Double
Public ARMVoltMax       As Double
Public ARMTimeMax       As Double

Public DoVacuumReset    As Boolean
'  Now assign the COMM Ports to the proper lines!
Public COMPortSquids    As Integer
Public COMPortAf        As Integer
Public COMPortUpDown    As Integer
Public COMPortTurning   As Integer
Public COMPortChanger   As Integer
Public COMPortVacuum    As Integer
Public COMPortSusceptibility As Integer
Public SusceptibilitySettings As String

Public MailSMTPHost As String
Public MailFrom    As String
Public MailFromName    As String
Public MailCCList    As String
Public MailStatusMonitor As String

Public AFAxialX(25) As Double
Public AFAxialY(25) As Double

Public AFTransX(25) As Double
Public AFTransY(25) As Double

Public EnableIRM As Boolean
Public EnableIRMHi As Boolean
Public EnableARM As Boolean
Public EnableAF As Boolean
Public EnableSusceptibility As Boolean
Public EnableIRMBackfield As Boolean
Public EnableIRMReturn As Boolean


Public Sub Config_ReadINISettings()
    
    ' This procedure reads settings from a file and adjusts
    ' variables in memory accordingly. (c:\paleomag\paleomag.ini)
    
    Dim i As Integer
    
    Prog_UsageFile = Config_GetFromINI("Program", "UsageFile", "C:\Paleomag\PALEOUSE.DAT", Prog_INIFile)
    Prog_DefaultBackup = Config_GetFromINI("Program", "DefaultBackupDrive", "E", Prog_INIFile)
    Prog_DefaultPath = Config_GetFromINI("Program", "DefaultPath", "C:\USER", Prog_INIFile)
    Prog_HelpURLRoot = Config_GetFromINI("Program", "HelpURLRoot", "file:///C:/Paleomag/Paleomag%202007/Help/", Prog_INIFile)
    Prog_LogoFile = Config_GetFromINI("Program", "LogoFile", "", Prog_INIFile)
    Prog_TextEditor = Config_GetFromINI("Program", "TextEditor", "notepad.exe", Prog_INIFile)
    
    DEBUG_MODE = ("True" = Config_GetFromINI("Program", "DebugMode", "False", Prog_INIFile))
    NOCOMM_MODE = ("True" = Config_GetFromINI("Program", "NoCommMode", "False", Prog_INIFile))
    DumpRawDataStats = ("True" = Config_GetFromINI("Program", "DumpRawDataStats", "False", Prog_INIFile))
    LogMessages = ("True" = Config_GetFromINI("Program", "LogMessages", "False", Prog_INIFile))
    
    SlotMin = Int(val(Config_GetFromINI("SampleChanger", "SlotMin", "1", Prog_INIFile)))
    SlotMax = Int(val(Config_GetFromINI("SampleChanger", "SlotMax", "200", Prog_INIFile)))
    HoleSlotNum = Int(val(Config_GetFromINI("SampleChanger", "HoleSlotNum", "10", Prog_INIFile)))
    OneStep = val(Config_GetFromINI("SampleChanger", "OneStep", "-1010.1010101", Prog_INIFile))
    
    ZeroPos = val(Config_GetFromINI("SteppingMotor", "ZeroPos", "-25886", Prog_INIFile))
    MeasPos = val(Config_GetFromINI("SteppingMotor", "MeasPos", "-30607", Prog_INIFile))
    AFPos = val(Config_GetFromINI("SteppingMotor", "AFPos", "-8405", Prog_INIFile))
    IRMPos = val(Config_GetFromINI("SteppingMotor", "IRMPos", "-8405", Prog_INIFile))
    IRMHiPos = val(Config_GetFromINI("SteppingMotor", "IRMHiPos", "-8405", Prog_INIFile))
    SCoilPos = val(Config_GetFromINI("SteppingMotor", "SCoilPos", "-4202", Prog_INIFile))
    SampleBottom = val(Config_GetFromINI("SteppingMotor", "SampleBottom", "-2385", Prog_INIFile))
    SampleTop = val(Config_GetFromINI("SteppingMotor", "SampleTop", "-1979", Prog_INIFile))
    SampleHeight = SampleTop - SampleBottom
    SampleHoleAlignmentOffset = val(Config_GetFromINI("SteppingMotor", "SampleHoleAlignmentOffset", "-0.02", Prog_INIFile))
    LiftSpeedSlow = val(Config_GetFromINI("SteppingMotor", "LiftSpeedSlow", "4000000", Prog_INIFile))
    LiftSpeedNormal = val(Config_GetFromINI("SteppingMotor", "LiftSpeedNormal", "25000000", Prog_INIFile))
    LiftSpeedFast = val(Config_GetFromINI("SteppingMotor", "LiftSpeedFast", "50000000", Prog_INIFile))
    ChangerSpeed = val(Config_GetFromINI("SteppingMotor", "ChangerSpeed", "40000000", Prog_INIFile))
    TurnerSpeed = val(Config_GetFromINI("SteppingMotor", "TurnerSpeed", "2000000", Prog_INIFile))
    SCurveFactor = val(Config_GetFromINI("SteppingMotor", "SCurveFactor", "32767", Prog_INIFile))
    TurningMotorFullRotation = val(Config_GetFromINI("SteppingMotor", "TurningMotorFullRotation", "2000", Prog_INIFile))
    TurningMotor1rps = val(Config_GetFromINI("SteppingMotor", "TurningMotor1rps", "16000000", Prog_INIFile))
    UpDownMotor1cm = val(Config_GetFromINI("SteppingMotor", "UpDownMotor1cm", "10", Prog_INIFile))
    UpDownTorqueFactor = Int(val(Config_GetFromINI("SteppingMotor", "UpDownTorqueFactor", "40", Prog_INIFile)))
    PickupTorqueThrottle = val(Config_GetFromINI("SteppingMotor", "PickupTorqueThrottle", "0.4", Prog_INIFile))
    TrayOffsetAngle = val(Config_GetFromINI("SteppingMotor", "TrayOffsetAngle", "0", Prog_INIFile))
    
    CmdHomeToTop = val(Config_GetFromINI("MotorPrograms", "CmdHomeToTop", "206", Prog_INIFile))
    CmdSamplePickup = val(Config_GetFromINI("MotorPrograms", "CmdSamplePickup", "241", Prog_INIFile))
    MotorIDTurning = val(Config_GetFromINI("MotorPrograms", "MotorIDTurning", "16", Prog_INIFile))
    MotorIDChanger = val(Config_GetFromINI("MotorPrograms", "MotorIDChanger", "16", Prog_INIFile))
    MotorIDUpDown = val(Config_GetFromINI("MotorPrograms", "MotorIDUpDown", "16", Prog_INIFile))
    
    ' Now Magnetometer Calibration Constants
    ZCal = val(Config_GetFromINI("MagnetometerCalibration", "ZCal", "-2.516", Prog_INIFile))
    XCal = val(Config_GetFromINI("MagnetometerCalibration", "XCal", "-3.410", Prog_INIFile))
    YCal = val(Config_GetFromINI("MagnetometerCalibration", "YCal", "-3.470", Prog_INIFile))
    RangeFact = val(Config_GetFromINI("MagnetometerCalibration", "RangeFact", "0.00001", Prog_INIFile))
    
    RemeasureCSDThreshold = val(Config_GetFromINI("Magnetometery", "RemeasureCSDThreshold", "15", Prog_INIFile))
    
    
    ' now the susceptibility factor
    SusceptibilityMomentFactorCGS = val(Config_GetFromINI("SusceptibilityCalibration", "SusceptibilityMomentFactorCGS", "10", Prog_INIFile))
    SusceptibilityScaleFactor = val(Config_GetFromINI("SusceptibilityCalibration", "SusceptibilityScaleFactor", "1", Prog_INIFile))
    
    ' Now assign AF axes
    
    AFDelay = val(Config_GetFromINI("AF", "AFDelay", "1", Prog_INIFile))
    AFRampRate = val(Config_GetFromINI("AF", "AFRampRate", "3", Prog_INIFile))
    
    AfAxialCoord = Config_GetFromINI("AFAxial", "AFAxialCoord", "X", Prog_INIFile)
    AfTransCoord = Config_GetFromINI("AFTrans", "AFTransCoord", "Y", Prog_INIFile)
    
    ' Now the Af Axial coil calibration numbers
    AfAxialYpoint = val(Config_GetFromINI("AFAxial", "AFAxialYPoint", "132.95", Prog_INIFile))
    AfAxialXpoint = val(Config_GetFromINI("AFAxial", "AFAxialXPoint", "300.0", Prog_INIFile))
    AfAxialLowSlope = val(Config_GetFromINI("AFAxial", "AFAxialLowSlope", "0.550", Prog_INIFile))
    AfAxialHighSlope = val(Config_GetFromINI("AFAxial", "AFAxialHighSlope", "0.544", Prog_INIFile))
    AfAxialMax = val(Config_GetFromINI("AFAxial", "AFAxialMax", "1650", Prog_INIFile))
    AfAxialMin = val(Config_GetFromINI("AFAxial", "AFAxialMin", "10", Prog_INIFile))
    
    '  Now the Af Transverse coil calibration numbers
    AfTransYpoint = val(Config_GetFromINI("AFTrans", "AFTransYPoint", "203", Prog_INIFile))
    AfTransXpoint = val(Config_GetFromINI("AFTrans", "AFTransXPoint", "350", Prog_INIFile))
    AfTransLowSlope = val(Config_GetFromINI("AFTrans", "AFTransLowSlope", "0.6000", Prog_INIFile))
    AfTransHighSlope = val(Config_GetFromINI("AFTrans", "AFTransHighSlope", "0.5905", Prog_INIFile))
    AfTransMax = val(Config_GetFromINI("AFTrans", "AFTransMax", "700", Prog_INIFile))
    AfTransMin = val(Config_GetFromINI("AFTrans", "AFTransMin", "10", Prog_INIFile))
 
    '  Now the IRM Pulse coil calibration numbers (CIT Lowenstam only)
    
    IRMHFAxis = Config_GetFromINI("IRMPulse", "IRMHFAxis", "Z", Prog_INIFile)
    IRMLFAxis = Config_GetFromINI("IRMPulse", "IRMLFAxis", "X", Prog_INIFile)
    IRMLFBackfieldAxis = Config_GetFromINI("IRMPulse", "IRMLFBackfieldAxis", "Y", Prog_INIFile)
    
    
    PulseHFMax = val(Config_GetFromINI("IRMPulseHF", "PulseHFMax", "13080", Prog_INIFile))
    PulseHFMin = val(Config_GetFromINI("IRMPulseHF", "PulseHFMin", "50", Prog_INIFile))
    
    PulseLFMax = val(Config_GetFromINI("IRMPulse", "PulseLFMax", "13080", Prog_INIFile))
    PulseLFMin = val(Config_GetFromINI("IRMPulse", "PulseLFMin", "50", Prog_INIFile))
    PulseMCCVoltConversion = val(Config_GetFromINI("IRMPulse", "PulseMCCVoltConverstion", "0.022222", Prog_INIFile))
    
    PulseVoltMax = val(Config_GetFromINI("IRMPulse", "PulseVoltMax", "10", Prog_INIFile))
    PulseReturnMCCVoltConversion = val(Config_GetFromINI("IRMPulse", "PulseReturnMCCVoltConverstion", "0.022222", Prog_INIFile))
    
    ' Now the ARM calibration values as well
    ARMMax = val(Config_GetFromINI("ARM", "ARMMax", "20", Prog_INIFile))
    ARMVoltGauss = val(Config_GetFromINI("ARM", "ARMVoltGauss", "0.1033", Prog_INIFile))
    ARMVoltMax = val(Config_GetFromINI("ARM", "ARMVoltMax", "2.0", Prog_INIFile))
    ARMTimeMax = val(Config_GetFromINI("ARM", "ARMTimeMax", "600", Prog_INIFile))
    
    ' Now the vacuum options
    DoVacuumReset = (Config_GetFromINI("Vacuum", "DoVacuumReset", "False", Prog_INIFile) = "True")
    
    '  Now assign the COMM Ports to the proper lines!
    COMPortSquids = Config_GetFromINI("COMPorts", "COMPortSquids", "10", Prog_INIFile)
    COMPortAf = Config_GetFromINI("COMPorts", "COMPortAf", "9", Prog_INIFile)
    COMPortUpDown = Config_GetFromINI("COMPorts", "COMPortUpDown", "4", Prog_INIFile)
    COMPortTurning = Config_GetFromINI("COMPorts", "COMPortTurning", "5", Prog_INIFile)
    COMPortChanger = Config_GetFromINI("COMPorts", "COMPortChanger", "6", Prog_INIFile)
    COMPortVacuum = Config_GetFromINI("COMPorts", "COMPortVacuum", "3", Prog_INIFile)
    COMPortSusceptibility = Config_GetFromINI("COMPorts", "COMPortSusceptibility", "8", Prog_INIFile)
    SusceptibilitySettings = Config_GetFromINI("COMPorts", "SusceptibilitySettings", "9600,N,8,2", Prog_INIFile)
    
    ' Now settings for mailer application
    MailSMTPHost = Config_GetFromINI("Email", "MailSMTPHost", vbNullString, Prog_INIFile)
    MailFrom = Config_GetFromINI("Email", "MailFrom", "paleomag@localhost", Prog_INIFile)
    MailFromName = Config_GetFromINI("Email", "MailFromName", "2G Magnetometer Sample Changer", Prog_INIFile)
    MailCCList = Config_GetFromINI("Email", "MailCCList", vbNullString, Prog_INIFile)
    MailStatusMonitor = Config_GetFromINI("Email", "MailStatusMonitor", vbNullString, Prog_INIFile)
    
    ' AF line points
    AFTransX(0) = 0
    AFTransY(0) = 0
    AFAxialX(0) = 0
    AFAxialY(0) = 0
    
    For i = 1 To 25
        AFTransX(i) = val(Config_GetFromINI("AFTrans", "AFTransX" & Format$(i, "0"), "0", Prog_INIFile))
        AFTransY(i) = val(Config_GetFromINI("AFTrans", "AFTransY" & Format$(i, "0"), "0", Prog_INIFile))
        AFAxialX(i) = val(Config_GetFromINI("AFaxial", "AFAxialX" & Format$(i, "0"), "0", Prog_INIFile))
        AFAxialY(i) = val(Config_GetFromINI("AFaxial", "AFAxialY" & Format$(i, "0"), "0", Prog_INIFile))
    Next i
    
    ' IRM Pulse line points
    
    PulseHFX(0) = 0
    PulseHFY(0) = 0
    PulseLFX(0) = 0
    PulseLFY(0) = 0
    
    For i = 1 To 20
        PulseHFX(i) = val(Config_GetFromINI("IRMPulseHF", "PulseHFX" & Format$(i, "0"), "0", Prog_INIFile))
        PulseHFY(i) = val(Config_GetFromINI("IRMPulseHF", "PulseHFY" & Format$(i, "0"), "0", Prog_INIFile))
        PulseLFX(i) = val(Config_GetFromINI("IRMPulse", "PulseLFX" & Format$(i, "0"), "0", Prog_INIFile))
        PulseLFY(i) = val(Config_GetFromINI("IRMPulse", "PulseLFY" & Format$(i, "0"), "0", Prog_INIFile))
    Next i
    
    ' now for the rockmag enable/disable modules
    EnableIRM = (Config_GetFromINI("Modules", "EnableIRM", "True", Prog_INIFile) = "True")
    EnableIRMHi = (Config_GetFromINI("Modules", "EnableIRMHi", "False", Prog_INIFile) = "True")
    EnableIRMBackfield = (Config_GetFromINI("Modules", "EnableIRMBackfield", "False", Prog_INIFile) = "True")
    EnableIRMReturn = (Config_GetFromINI("Modules", "EnableIRMReturn", "False", Prog_INIFile) = "True")
    EnableARM = (Config_GetFromINI("Modules", "EnableARM", "True", Prog_INIFile) = "True")
    EnableAF = (Config_GetFromINI("Modules", "EnableAF", "True", Prog_INIFile) = "True")
    EnableSusceptibility = (Config_GetFromINI("Modules", "EnableSusceptibility", "True", Prog_INIFile) = "True")
    
End Sub

Public Sub Config_writeSettingstoINI()
    Dim i As Integer

    FileCopy Prog_INIFile, Prog_INIFile + ".bak"

    Config_SaveSetting "SampleChanger", "SlotMin", Str$(SlotMin)
    Config_SaveSetting "SampleChanger", "SlotMax", Str$(SlotMax)
    Config_SaveSetting "SampleChanger", "OneStep", Str$(OneStep)
    Config_SaveSetting "SampleChanger", "HoleSlotNum", Str$(HoleSlotNum)


    Config_SaveSetting "SteppingMotor", "ZeroPos", Str$(ZeroPos)
    Config_SaveSetting "SteppingMotor", "MeasPos", Str$(MeasPos)
    Config_SaveSetting "SteppingMotor", "IRMPos", Str$(IRMPos)
    Config_SaveSetting "SteppingMotor", "IRMHiPos", Str$(IRMHiPos)
    Config_SaveSetting "SteppingMotor", "AFPos", Str$(AFPos)
    Config_SaveSetting "SteppingMotor", "SCoilPos", Str$(SCoilPos)
    Config_SaveSetting "SteppingMotor", "SampleBottom", Str$(SampleBottom)
    Config_SaveSetting "SteppingMotor", "SampleTop", Str$(SampleTop)
    Config_SaveSetting "SteppingMotor", "SampleHoleAlignmentOffset", Str$(SampleHoleAlignmentOffset)
    Config_SaveSetting "SteppingMotor", "LiftSpeedSlow", Str$(LiftSpeedSlow)
    Config_SaveSetting "SteppingMotor", "LiftSpeedNormal", Str$(LiftSpeedNormal)
    Config_SaveSetting "SteppingMotor", "LiftSpeedFast", Str$(LiftSpeedFast)
    Config_SaveSetting "SteppingMotor", "TurnerSpeed", Str$(TurnerSpeed)
    Config_SaveSetting "SteppingMotor", "ChangerSpeed", Str$(ChangerSpeed)
    Config_SaveSetting "SteppingMotor", "SCurveFactor", Str$(SCurveFactor)
    Config_SaveSetting "SteppingMotor", "TurningMotorFullRotation", Str$(TurningMotorFullRotation)
    Config_SaveSetting "SteppingMotor", "TurningMotor1rps", Str$(TurningMotor1rps)
    Config_SaveSetting "SteppingMotor", "UpDownMotor1cm", Str$(UpDownMotor1cm)
    Config_SaveSetting "SteppingMotor", "UpDownTorqueFactor", Str$(UpDownTorqueFactor)
    Config_SaveSetting "SteppingMotor", "PickupTorqueThrottle", Str$(PickupTorqueThrottle)
    Config_SaveSetting "SteppingMotor", "TrayOffsetAngle", Str$(TrayOffsetAngle)

    Config_SaveSetting "MagnetometerCalibration", "ZCal", Str$(ZCal)
    Config_SaveSetting "MagnetometerCalibration", "XCal", Str$(XCal)
    Config_SaveSetting "MagnetometerCalibration", "YCal", Str$(YCal)
    Config_SaveSetting "MagnetometerCalibration", "RangeFact", Str$(RangeFact)
    
    Config_SaveSetting "Magnetometry", "RemeasureCSDThreshold", Str$(RemeasureCSDThreshold)
    
    Config_SaveSetting "SusceptibilityCalibration", "SusceptibilityMomentFactorCGS", Str$(SusceptibilityMomentFactorCGS)
    Config_SaveSetting "SusceptibilityCalibration", "SusceptibilityScaleFactor", Str$(SusceptibilityScaleFactor)
    
    Config_SaveSetting "AFDelay", "AFDelay", Str$(AFDelay)
    Config_SaveSetting "AFRampRate", "AFRampRate", Str$(AFRampRate)
    
    Config_SaveSetting "AFAxial", "AFAxialCoord", AfAxialCoord
    Config_SaveSetting "AFAxial", "AFAxialYPoint", Str$(AfAxialYpoint)
    Config_SaveSetting "AFAxial", "AfAxialXpoint", Str$(AfAxialXpoint)
    Config_SaveSetting "AFAxial", "AfAxialHighSlope", Str$(AfAxialHighSlope)
    Config_SaveSetting "AFAxial", "AfAxialLowSlope", Str$(AfAxialLowSlope)
    Config_SaveSetting "AFAxial", "AfAxialMax", Str$(AfAxialMax)
    Config_SaveSetting "AFAxial", "AfAxialMin", Str$(AfAxialMin)
    
    Config_SaveSetting "AFTrans", "AFTransCoord", AfTransCoord
    Config_SaveSetting "AFTrans", "AFTransYPoint", Str$(AfTransYpoint)
    Config_SaveSetting "AFTrans", "AfTransXpoint", Str$(AfTransXpoint)
    Config_SaveSetting "AFTrans", "AfTransHighSlope", Str$(AfTransHighSlope)
    Config_SaveSetting "AFTrans", "AfTransLowSlope", Str$(AfTransLowSlope)
    Config_SaveSetting "AFTrans", "AfTransMax", Str$(AfTransMax)
    Config_SaveSetting "AFTrans", "AfTransMin", Str$(AfTransMin)

    Config_SaveSetting "IRMPulse", "IRMHFAxis", IRMHFAxis
    Config_SaveSetting "IRMPulse", "IRMLFAxis", IRMLFAxis
    Config_SaveSetting "IRMPulse", "IRMLFBackfieldAxis", IRMLFBackfieldAxis
    
    
    Config_SaveSetting "IRMPulseHF", "PulseHFMax", Str$(PulseHFMax)
    Config_SaveSetting "IRMPulseHF", "PulseHFMin", Str$(PulseHFMin)
    
    Config_SaveSetting "IRMPulse", "PulseLFMax", Str$(PulseLFMax)
    Config_SaveSetting "IRMPulse", "PulseLFMin", Str$(PulseLFMin)
    Config_SaveSetting "IRMPulse", "PulseMCCVoltConverstion", Str$(PulseMCCVoltConversion)

    Config_SaveSetting "IRMPulse", "PulseVoltMax", Str$(PulseVoltMax)
    Config_SaveSetting "IRMPulse", "PulseReturnMCCVoltConverstion", Str$(PulseReturnMCCVoltConversion)


    Config_SaveSetting "ARM", "ARMMax", Str$(ARMMax)
    Config_SaveSetting "ARM", "ARMVoltGauss", Str$(ARMVoltGauss)
    Config_SaveSetting "ARM", "ARMVoltMax", Str$(ARMVoltMax)
    Config_SaveSetting "ARM", "ARMTimeMax", Str$(ARMTimeMax)
    
    Config_SaveSetting "Vacuum", "DoVacuumReset", Str$(DoVacuumReset)
    
    Config_SaveSetting "COMPorts", "COMPortSquids", Str$(COMPortSquids)
    Config_SaveSetting "COMPorts", "COMPortAf", Str$(COMPortAf)
    Config_SaveSetting "COMPorts", "COMPortUpDown", Str$(COMPortUpDown)
    Config_SaveSetting "COMPorts", "COMPortTurning", Str$(COMPortTurning)
    Config_SaveSetting "COMPorts", "COMPortChanger", Str$(COMPortChanger)
    Config_SaveSetting "COMPorts", "COMPortVacuum", Str$(COMPortVacuum)
    Config_SaveSetting "COMPorts", "COMPortSusceptibility", Str$(COMPortSusceptibility)
    Config_SaveSetting "COMPorts", "SusceptibilitySettings", SusceptibilitySettings

    
    Config_SaveSetting "MotorPrograms", "CmdHomeToTop", Str$(CmdHomeToTop)
    Config_SaveSetting "MotorPrograms", "CmdSamplePickup", Str$(CmdSamplePickup)
    Config_SaveSetting "MotorPrograms", "MotorIDTurning", Str$(MotorIDTurning)
    Config_SaveSetting "MotorPrograms", "MotorIDChanger", Str$(MotorIDChanger)
    Config_SaveSetting "MotorPrograms", "MotorIDUpDown", Str$(MotorIDUpDown)
    
    Config_SaveSetting "Program", "UsageFile", Prog_UsageFile
    Config_SaveSetting "Program", "DefaultPath", Prog_DefaultPath
    Config_SaveSetting "Program", "HelpURLRoot", Prog_HelpURLRoot
    Config_SaveSetting "Program", "NoCommMode", Str$(NOCOMM_MODE)
    Config_SaveSetting "Program", "DebugMode", Str$(DEBUG_MODE)
    Config_SaveSetting "Program", "DumpRawDataStats", Str$(DumpRawDataStats)
    Config_SaveSetting "Program", "LogMessages", Str$(LogMessages)
    Config_SaveSetting "Program", "LogoFile", Prog_LogoFile
    Config_SaveSetting "Program", "TextEditor", Prog_TextEditor
    
    Config_SaveSetting "Email", "MailSMTPHost", MailSMTPHost
    Config_SaveSetting "Email", "MailFrom", MailFrom
    Config_SaveSetting "Email", "MailFromName", MailFromName
    Config_SaveSetting "Email", "MailCCList", MailCCList
    Config_SaveSetting "Email", "MailStatusMonitor", MailStatusMonitor
    
    Config_SaveSetting "Program", "DefaultBackupDrive", Prog_DefaultBackup
    
    For i = 1 To 25
        If AFAxialX(i) > 0 Then Config_SaveSetting "AFAxial", "AFAxialX" & Format$(i, "0"), Str$(AFAxialX(i))
        If AFAxialY(i) > 0 Then Config_SaveSetting "AFAxial", "AFAxialY" & Format$(i, "0"), Str$(AFAxialY(i))
        If AFTransX(i) > 0 Then Config_SaveSetting "AFTrans", "AFTransX" & Format$(i, "0"), Str$(AFTransX(i))
        If AFTransY(i) > 0 Then Config_SaveSetting "AFTrans", "AFTransY" & Format$(i, "0"), Str$(AFTransY(i))
    Next i
    
    For i = 1 To 20
        If PulseLFX(i) > 0 Then Config_SaveSetting "IRMPulse", "PulseLFX" & Format$(i, "0"), Str$(PulseLFX(i))
        If PulseLFY(i) > 0 Then Config_SaveSetting "IRMPulse", "PulseLFY" & Format$(i, "0"), Str$(PulseLFY(i))
        If PulseHFX(i) > 0 Then Config_SaveSetting "IRMPulseHF", "PulseHFX" & Format$(i, "0"), Str$(PulseHFX(i))
        If PulseHFY(i) > 0 Then Config_SaveSetting "IRMPulseHF", "PulseHFY" & Format$(i, "0"), Str$(PulseHFY(i))
    Next i
    
    Config_SaveSetting "Modules", "EnableIRM", Str$(EnableIRM)
    Config_SaveSetting "Modules", "EnableIRMHi", Str$(EnableIRMHi)
    Config_SaveSetting "Modules", "EnableIRMBackfield", Str$(EnableIRMBackfield)
    Config_SaveSetting "Modules", "EnableIRMReturn", Str$(EnableIRMReturn)
    Config_SaveSetting "Modules", "EnableARM", Str$(EnableARM)
    Config_SaveSetting "Modules", "EnableAF", Str$(EnableAF)
    Config_SaveSetting "Modules", "EnableSusceptibility", Str$(EnableSusceptibility)
    
    
End Sub


Private Function Config_ReadLine(filenum As Integer) As String
    ' This function reads a line from the file with id
    ' #filenum, and returns a string from the file.  It
    ' ignores lines that start with "'".
    Dim lchar As String
    
    Line Input #filenum, Config_ReadLine
    lchar = Left$(Config_ReadLine, 1)
    If lchar = Chr$(39) Then
        Config_ReadLine = Config_ReadLine(filenum)
    End If
End Function

Public Function Config_GetSetting(sSection As String, sKey As String, sDefault As String) As String
    Config_GetSetting = Config_GetFromINI(sSection, sKey, sDefault, Prog_INIFile)
End Function

Public Sub Config_SaveSetting(sSection As String, sKey As String, sDefault As String)
    Dim dummy As Boolean
    dummy = Config_AddToINI(sSection, sKey, sDefault, Prog_INIFile)
End Sub


'// VB Web Code Example
'// www.vbweb.co.uk


'// Functions
Public Function Config_GetFromINI(sSection As String, sKey As String, sDefault As String, sIniFile As String)
    Dim sBuffer As String, lRet As Long
    ' Fill String with 255 spaces
    sBuffer = String$(255, 0)
    ' Call DLL
    lRet = GetPrivateProfileString(sSection, sKey, vbNullString, sBuffer, Len(sBuffer), sIniFile)
    If lRet = 0 Then
        ' DLL failed, save default
        If LenB(sDefault) <> 0 Then Config_AddToINI sSection, sKey, sDefault, sIniFile
        Config_GetFromINI = sDefault
    Else
        ' DLL successful
        ' return string
        Config_GetFromINI = Left(sBuffer, InStr(sBuffer, Chr(0)) - 1)
    End If
End Function

'// Returns True if successful. If section does not
'// exist it creates it.
Public Function Config_AddToINI(sSection As String, sKey As String, sValue As String, sIniFile As String) As Boolean
    Dim lRet As Long
    ' Call DLL
    lRet = WritePrivateProfileString(sSection, sKey, sValue, sIniFile)
    Config_AddToINI = (lRet)
End Function
