/// <summary> /// Constructs a new SmcSettings object that has the default settings for a particular product. /// </summary> /// <param name="productId">The product ID of the device. /// Pass this argument as 0 if the product ID is unknown at this time. /// </param> public SmcSettings(UInt16 productId) { this.productId = productId; rc1 = SmcChannelSettings.defaultRCSettings(); rc2 = SmcChannelSettings.defaultRCSettings(); analog1 = SmcChannelSettings.defaultAnalogSettings(); analog2 = SmcChannelSettings.defaultAnalogSettings(); forwardLimits = new SmcMotorLimits(); reverseLimits = new SmcMotorLimits(); if (productId == 0xA5 || productId == 0xA9) { // For the versions with 40V MOSFETs: highVinShutoffMv = 35000; } else { // For the versions with 30V MOSFETs: highVinShutoffMv = 25000; } switch (productId) { case 0xA3: currentLimit = 921; break; case 0xA5: currentLimit = 1096; break; default: case 0xA7: currentLimit = 776; break; case 0xA9: currentLimit = 1153; break; } }
/// <summary> /// Compares this object to another and sees if they have the same values. /// </summary> public override bool Equals(object x) { SmcChannelSettings s = x as SmcChannelSettings; if (s == null) { return(false); } return(this.convertToStruct().Equals(s.convertToStruct())); }
/// <summary> /// Returns the default settings for the given channel. /// </summary> /// <param name="channel"></param> /// <returns></returns> public static SmcChannelSettings defaults(SmcChannel channel) { if (channel.type() == SmcChannelType.Analog) { return(SmcChannelSettings.defaultAnalogSettings()); } else { return(SmcChannelSettings.defaultRCSettings()); } }
/// <summary> /// Returns the default settings for Analog channels. /// </summary> public static SmcChannelSettings defaultAnalogSettings() { var cs = new SmcChannelSettings(); cs.errorMin = 0; cs.errorMax = 4095; cs.inputMin = 40; cs.inputMax = 4055; cs.inputNeutralMin = 2015; cs.inputNeutralMax = 2080; return(cs); }
/// <summary> /// Returns the default settings for RC channels. /// </summary> public static SmcChannelSettings defaultRCSettings() { var cs = new SmcChannelSettings(); cs.errorMin = 500 * 4; cs.errorMax = 2500 * 4; cs.inputMin = 1000 * 4; cs.inputMax = 2000 * 4; cs.inputNeutralMin = 1475 * 4; cs.inputNeutralMax = 1525 * 4; return(cs); }
internal SmcSettings(UInt16 productId, SmcSettingsStruct s) { this.productId = productId; // [Add-new-settings-here] this.neverSleep = (s.b1 & SmcBoolSettings1.NeverSleep) != 0; this.uartResponseDelay = (s.b1 & SmcBoolSettings1.UartResponseDelay) != 0; this.useFixedBaudRate = (s.b1 & SmcBoolSettings1.UseFixedBaudRate) != 0; this.disableSafeStart = (s.b1 & SmcBoolSettings1.DisableSafeStart) != 0; this.enableI2C = (s.b1 & SmcBoolSettings1.EnableI2C) != 0; this.ignoreErrLineHigh = (s.b1 & SmcBoolSettings1.IgnoreErrLineHigh) != 0; this.tempLimitGradual = (s.b1 & SmcBoolSettings1.TempLimitGradual) != 0; this.ignorePotDisconnect = (s.b1 & SmcBoolSettings1.IgnorePotDisconnect) != 0; this.motorInvert = (s.b1 & SmcBoolSettings1.MotorInvert) != 0; this.coastWhenOff = (s.b1 & SmcBoolSettings1.CoastWhenOff) != 0; this.crcForCommands = (s.b1 & SmcBoolSettings1.CrcForCommands) != 0; this.crcForResponses = (s.b1 & SmcBoolSettings1.CrcForResponses) != 0; this.fixedBaudRateBps = Smc.convertBaudRegisterToBps(s.fixedBaudRateRegister); this.speedUpdatePeriod = s.speedUpdatePeriod; this.commandTimeout = s.commandTimeout; this.serialDeviceNumber = s.serialDeviceNumber; this.overTempCompleteShutoffThreshold = s.overTempCompleteShutoffThreshold; this.overTempNormalOperationThreshold = s.overTempNormalOperationThreshold; this.inputMode = s.inputMode; this.pwmPeriodFactor = s.pwmPeriodFactor; this.mixingMode = s.mixingMode; this.minPulsePeriod = s.minPulsePeriod; this.maxPulsePeriod = s.maxPulsePeriod; this.rcTimeout = s.rcTimeout; this.consecGoodPulses = s.consecGoodPulses; this.vinScaleCalibration = s.vinScaleCalibration; this.lowVinShutoffTimeout = s.lowVinShutoffTimeout; this.lowVinShutoffMv = s.lowVinShutoffMv; this.lowVinStartupMv = s.lowVinStartupMv; this.highVinShutoffMv = s.highVinShutoffMv; this.serialMode = s.serialMode; this.rc1 = new SmcChannelSettings(s.rc1); this.rc2 = new SmcChannelSettings(s.rc2); this.analog1 = new SmcChannelSettings(s.analog1); this.analog2 = new SmcChannelSettings(s.analog2); this.forwardLimits = new SmcMotorLimits(s.forwardLimits); this.reverseLimits = new SmcMotorLimits(s.reverseLimits); this.currentLimit = s.currentLimit; this.currentOffsetCalibration = s.currentOffsetCalibration; this.currentScaleCalibration = s.currentScaleCalibration; }
private static void writeChannelSettings(StreamWriter sw, string name, bool analog, SmcChannelSettings cs) { writeAlternateUse(sw, name + "_alternate_use", cs.alternateUse); if (analog) { writePinMode(sw, name + "_pin_mode", cs.pinMode); } writeBool(sw, name + "_invert", cs.invert); writeU32(sw, name + "_scaling_degree", cs.scalingDegree); writeU32(sw, name + "_error_min", cs.errorMin); writeU32(sw, name + "_input_min", cs.inputMin); writeU32(sw, name + "_input_neutral_min", cs.inputNeutralMin); writeU32(sw, name + "_input_neutral_max", cs.inputNeutralMax); writeU32(sw, name + "_input_max", cs.inputMax); writeU32(sw, name + "_error_max", cs.errorMax); }
/// <summary> /// Changes the settings for a specified channel. /// </summary> /// <param name="settings">The settings of the device. This object will be modified.</param> /// <param name="channel">Specifies the channel to change.</param> /// <param name="channelSettings">The new settings for the channel.</param> public static void setChannelSettings(this SmcSettings settings, SmcChannel channel, SmcChannelSettings channelSettings) { switch (channel) { case SmcChannel.Analog1: settings.analog1 = channelSettings; break; case SmcChannel.Analog2: settings.analog2 = channelSettings; break; case SmcChannel.Rc1: settings.rc1 = channelSettings; break; case SmcChannel.Rc2: settings.rc2 = channelSettings; break; default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
/// <summary> /// Fixes certain things about a setttings object so that it doesn't make the device /// do something invalid. /// For each thing that gets fixed, a warning is added to the warnings list that is passed in. /// </summary> /// <param name="newSettings">The settings to fix.</param> /// <param name="warnings">A list of warnings. This function will add items to the list.</param> /// <param name="productId">The product ID of the device these settings will be used for.</param> /// <param name="firmwareVersion">The firmware version of the device these settings will be used for. /// If unknown, this argument should be 0.</param> public static void fixSettings(SmcSettings newSettings, List <string> warnings, UInt16 productId, UInt16 firmwareVersion) { if (productId == 0) { throw new Exception("Internal error: an invalid product ID was passed to fixSettings."); } if (newSettings.productId != productId) { throw new Exception( "These settings are for a different device. " + "The settings are for the " + Smc.productIdToShortModelString(newSettings.productId) + ", " + "not the " + Smc.productIdToShortModelString(productId) + "."); } // TODO: change the messages here to use present tense and future tense (like the Tic and Jrk). if (newSettings.overTempCompleteShutoffThreshold < newSettings.overTempNormalOperationThreshold) { warnings.Add( "The over-temperature complete shutoff threshold was " + "lower than the over-temperature normal operation threshold. " + "Both settings will be set to " + Smc.temperatureToString(newSettings.overTempCompleteShutoffThreshold) + " so the motor will shut off at that temperature."); newSettings.overTempNormalOperationThreshold = newSettings.overTempCompleteShutoffThreshold; } if (newSettings.lowVinStartupMv < newSettings.lowVinShutoffMv) { if (newSettings.lowVinShutoffMv + 500 > UInt16.MaxValue) { newSettings.lowVinStartupMv = UInt16.MaxValue; } else { newSettings.lowVinStartupMv = (UInt16)(newSettings.lowVinShutoffMv + 500); } warnings.Add("The Low VIN Startup voltage was lower than the Low VIN Shutoff voltage (" + newSettings.lowVinShutoffMv / (decimal)1000 + " V). " + "The Low VIN Startup voltage will be changed to " + newSettings.lowVinStartupMv / (decimal)1000 + " V."); } if (newSettings.highVinShutoffMv < newSettings.lowVinStartupMv) { newSettings.highVinShutoffMv = (new SmcSettings(productId).highVinShutoffMv); warnings.Add("The High VIN Shutoff voltage was lower than the Low VIN Startup voltage (" + newSettings.lowVinStartupMv / (decimal)1000 + " V). " + "The High VIN Shutoff voltage will be changed to " + newSettings.highVinShutoffMv / (decimal)1000 + " V."); } if (newSettings.vinScaleCalibration > 1500) { newSettings.vinScaleCalibration = 1500; warnings.Add("The VIN scale calibration was too high. It will be changed to 1500."); } if (newSettings.currentScaleCalibration > 20000) { newSettings.currentScaleCalibration = 20000; warnings.Add("The current scale calibration was too high. It will be changed to 20000."); } // Prevent the channel scaling values from being out of order (it's okay if they are equal) foreach (SmcChannel channel in Smc.channels) { SmcChannelSettings cs = newSettings.getChannelSettings(channel); if (cs.errorMin > cs.inputMin || cs.inputMin > cs.inputNeutralMin || cs.inputNeutralMin > cs.inputNeutralMax || cs.inputNeutralMax > cs.inputMax || cs.inputMax > cs.errorMax) { warnings.Add("The scaling values for " + channel.name() + " are out of order. They will be reset to their default settings."); SmcChannelSettings defaults = SmcChannelSettings.defaults(channel); cs.errorMin = defaults.errorMin; cs.inputMin = defaults.inputMin; cs.inputNeutralMin = defaults.inputNeutralMin; cs.inputNeutralMax = defaults.inputNeutralMax; cs.inputMax = defaults.inputMax; cs.errorMax = defaults.errorMax; } } fixMotorLimits(newSettings.forwardLimits, "forward", warnings); fixMotorLimits(newSettings.reverseLimits, "reverse", warnings); }