Skip to content

Instantly share code, notes, and snippets.

@nikvoronin
Last active January 3, 2021 21:55
Show Gist options
  • Save nikvoronin/fb5ab0805abeb40ba1b63a462c51e202 to your computer and use it in GitHub Desktop.
Save nikvoronin/fb5ab0805abeb40ba1b63a462c51e202 to your computer and use it in GitHub Desktop.
Changes online value of the Scaling Factor Numerator through the CurrentConfig.xml in TwinCAT 3.1
using System;
using System.Linq;
using System.Xml.Linq;
namespace Tc3_CurrentConfig
{
public class CurrentConfig
{
const string CURRENTCONFIG_PATH = @"C:\TwinCAT\3.1\Boot\CurrentConfig.xml";
/// <summary>
/// Writes Scaling Factor Numerator
/// </summary>
/// <param name="newValue">New value of Scaling Factor Numerator</param>
/// <param name="axisNo">NC axis number. Count begins from 1. 1 is a first axis.</param>
/// <returns>Current value of Scaling Factor Numerator</returns>
public static double WriteScalingFactorNumerator(double newValue, int axisNo)
{
if (axisNo < 1 || axisNo > 255)
throw new ArgumentOutOfRangeException( "axisNo", axisNo,
"1 >= axisNo <= 255. Count begins from 1. 1 is a first axis.");
const int HEX_START_INDEX = 96;
const int HEX_VALUE_LENGTH = 16; // double = 8 bytes length
string hexAxisNo = axisNo.ToString("X2");
/// Loading ///////////////////////////////////////////////////////
XDocument doc = XDocument.Load(CURRENTCONFIG_PATH);
var xEncAxis1 = doc.Descendants()
.Single(e =>
e.Name.LocalName == "InitCmd"
&& e.Elements().Where(
ee => (ee.Name.LocalName == "port" && ee.Value == "500" )
|| (ee.Name.LocalName == "iGrp" && ee.Value == "5124")
|| (ee.Name.LocalName == "iOffs" && ee.Value == "0" )
|| (ee.Name.LocalName == "data" && ee.Value.StartsWith(hexAxisNo)) )
.Count() == 4 );
var xData = xEncAxis1.Elements().Single(e => e.Name.LocalName == "data");
string data = xData.Value;
/// Current Value /////////////////////////////////////////////////
string hexValue = data.Substring(HEX_START_INDEX, HEX_VALUE_LENGTH);
double currentDoubleValue = BitConverter.ToDouble(HexToByteArray(hexValue));
/// Write New Value ///////////////////////////////////////////////
hexValue = BitConverter.ToString(BitConverter.GetBytes(newValue))
.Replace("-","") // BitConverter returns like this AA-BB-CC-...
.ToLower(); // Tc3 writes hex in lower case
xData.Value = data.Substring(0, HEX_START_INDEX) + hexValue + data.Substring(HEX_START_INDEX + HEX_VALUE_LENGTH);
doc.Save(CURRENTCONFIG_PATH);
return currentDoubleValue;
}
// inefficient but fun, see: https://stackoverflow.com/a/321404
public static byte[] HexToByteArray(string hexValue)
{
return Enumerable.Range(0, hexValue.Length / 2)
.Select(x => Convert.ToByte(hexValue.Substring(x * 2, 2), 16))
.ToArray();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment