C#_SDK Quick start

C#_SDK quick start

Applicable Model

WT901C-485

HWT901B-485

SINDT-485

HWT605-485

HWT905-485

Routine download

Go to the link below to download the sample

https://github.com/WITMOTION/WitStandardModbus_WT901C485

Noun introduction

Modbus protocol: Modbus is a serial communication protocol published by Modicon Corporation (now Schneider Electric) in 1979 for the use of programmable logic controller (PLC) communication. Modbus has become the industry standard (De facto) for communication protocols in the industrial field, and is now a common connection method between industrial electronic devices.

Routine introduction

This routine introduces how to use C# to develop the upper computer to connect to the Modbus protocol sensor, receive sensor data and communicate with the sensor;

Before viewing this routine, please read the relevant sensor manual to understand the protocol used by the sensor and the basic functions of the sensor

Routine directory

The routine project directory is as follows

Dll:The dependent files of the project, please import these dlls into your project before running the project.

Form1:There is only one Form window in the routine, all logic codes are in the Form window file, and there are no other files

Turn on the device

The WT901C485 object represents the WT901C485 device in the program, and you can communicate with the device through it; when opening the device, you need to specify the serial port number and baud rate of the sensor, and then call the WT901C485.Open() method

/// <summary>
/// oprn device
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void openButton_Click(object sender, EventArgs e)
{
      // Get the serial port number and baud rate of the connection
      string portName;
      int baudrate;
      byte modbusId;
      try
      {
            portName = (string)portComboBox.SelectedItem;
            baudrate = (int)baudComboBox.SelectedItem;
            modbusId = byte.Parse(ModbustextBox.Text.Replace("0x",""),             System.Globalization.NumberStyles.HexNumber);
      }
      catch (Exception ex)
      {
            MessageBox.Show(ex.Message);
            return;
      }
      // Do not open repeatedly
      if (WT901C485.IsOpen())
      {
            return;
      }
      // open device
      try
      {
            WT901C485.SetPortName(portName);
            WT901C485.SetBaudrate(baudrate);
            WT901C485.SetModbusId(modbusId);
            WT901C485.Open();
            // Implement logging data events
            WT901C485.OnRecord += WT901C485_OnRecord;
      }
      catch (Exception ex)
      {
            MessageBox.Show(ex.Message);
            return;
      }
}

Turn off the device


Just call the WT901C485.Close() method to close the device
/// <summary>
/// turn off the device
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void closeButton_Click(object sender, EventArgs e)
{
try
{
// Turn off the device if it is already on
if (WT901C485.IsOpen())
{
WT901C485.OnRecord -= WT901C485_OnRecord;
WT901C485.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}

Receive sensor data

Get data

The WT901C485 object will automatically calculate the sensor data and save it on itself. The data of the sensor can be obtained through the WT901C485.GetDeviceDavta() method. WT901C485.GetDeviceData() needs to pass in a key to get sensor data. Please check the key that needs to be used in the routine, the key is stored in the WitSensorKey class

/// <summary>
/// Get device data
/// </summary>
private string GetDeviceData(WT901C485 WT901C485)
{
      StringBuilder builder = new StringBuilder();
      builder.Append(WT901C485.GetDeviceName()).Append("\n");

// acceleration
builder.Append("AccX").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AccX)).Append("g \t");
 builder.Append("AccY").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AccY)).Append("g \t");
 builder.Append("AccZ").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AccZ)).Append("g \n");

// angular velocity
builder.Append("GyroX").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AsX)).Append("°/s \t");
 builder.Append("GyroY").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AsY)).Append("°/s \t");
 builder.Append("GyroZ").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AsZ)).Append("°/s \n");

// angle
builder.Append("AngleX").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AngleX)).Append("° \t");
 builder.Append("AngleY").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AngleY)).Append("° \t");
 builder.Append("AngleZ").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.AngleZ)).Append("° \n");

// magnetic field
builder.Append("MagX").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.HX)).Append("uT \t");
 builder.Append("MagY").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.HY)).Append("uT \t");
 builder.Append("MagZ").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.HZ)).Append("uT \n");

// latitude and longitude
builder.Append("Lon").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.Lon)).Append("′ \t");
 builder.Append("Lat").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.Lat)).Append("′ \n");

// The port number
builder.Append("D0").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.D0)).Append ("\t");
 builder.Append("D1").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.D1)).Append("\t");
 builder.Append("D2").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.D2)).Append("\t");
 builder.Append("D3").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.D3)).Append("\n");

//Quaternion
builder.Append("Q0").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.Q0)).Append("\t");
 builder.Append("Q1").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.Q1)).Append("\t");
 builder.Append("Q2").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.Q2)).Append("\t");
 builder.Append("Q3").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.Q3)).Append("\n");

//barometric pressure
builder.Append("P").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.Q1)).Append("Pa \t");
 builder.Append("H").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.Q2)).Append("m \t");

// temperature
builder.Append("T").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.T)).Append("℃ \n");

// GPS
builder.Append("GPSHeight").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.GPSHeight)).Append(" m \t");
 builder.Append("GPSYaw").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.GPSYaw)).Append("° \t");
 builder.Append("GPSV").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.GPSV)).Append("km/h \n");

// positioning accuracy
builder.Append("PDOP").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.PDOP)).Append("\t");
 builder.Append("VDOP").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.VDOP)).Append("\t");
 builder.Append("HDOP").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.HDOP)).Append("\n");

// version number
builder.Append("VersionNumber").Append(":").Append(WT901C485.GetDeviceData(WitSensorKey.VersionNumber)).Append("\n");
      return builder.ToString();
}

Record data

The data of the sensor can be obtained through the WT901C485 object, but usually the host computer needs to record the data of the sensor. WT901C485 has an OnRecord event that will notify you when the data should be recorded, and the OnRecord event can be realized when the device is turned on; and then through the cooperation of WT901C485.GetDeviceData( ) method to record the data

// Some code
/// <summary>
/// turn on the device
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void openButton_Click(object sender, EventArgs e)
{
// Get the serial port number and baud rate of the connection
string portName;
int baudrate;
byte modbusId;
try
{
portName = (string)portComboBox.SelectedItem;
baudrate = (int)baudComboBox.SelectedItem;
modbusId = byte.Parse(ModbustextBox.Text.Replace("0x",""), System.Globalization.NumberStyles.HexNumber);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
// Do not open repeatedly
if (WT901C485.IsOpen())
{
return;
}
// turn on the device
try
{
WT901C485.SetPortName(portName);
WT901C485.SetBaudrate(baudrate);
WT901C485.SetModbusId(modbusId);
WT901C485.Open();
// Implement logging data events
WT901C485.OnRecord += WT901C485_OnRecord;
Thread.Sleep(1000);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
/// <summary>
/// This is called when the sensor data is refreshed, you can log the data here
/// </summary>
/// <param name="WT901C485"></param>
private void WT901C485_OnRecord(WT901C485 WT901C485)
{
string text = GetDeviceData(WT901C485);
Debug.WriteLine(text);
}

Set sensor

The sensor can be operated by the method of WT901C485

WT901C485.UnlockReg() Send unlock register command

WT901C485.AppliedCalibration() Send Applied Calibration command

WT901C485.StartFieldCalibration() Send start field calibration command

WT901C485.EndFieldCalibration() Send end field calibration command

WT901C485.SendProtocolData() Send other commands

Set address

Set the address of the sensor by calling the WT901C485.SetModbusId() method

// /// <summary>
/// Set the device address to 50
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SetAddrBtn_Click(object sender, EventArgs e)
{
if (WT901C485.IsOpen() == false)
{
return;
}
try
{
// Unlock registers and send commands
WT901C485.UnlockReg();
byte modbusId = byte.Parse(ModbustextBox.Text.Replace("0x", ""), System.Globalization.NumberStyles.HexNumber);
WT901C485.SetModbusId(modbusId);
// The following two lines are equivalent to the above, it is recommended to use the above

//WT901C485.SendProtocolData(Modbus16Utils.GetWrite(T901C485.GetModbusId(), 0x69, 0xB588));
//WT901C485.SendProtocolData(new byte[] { 50, 06, 00, 69, B5, 88, 22, A1 });
//WT901C485.SendProtocolData(Modbus16Utils.GetWrite(T901C485.GetModbusId(), 0x1A, 0x0050));
//WT901C485.SendProtocolData(new byte[] { 50, 06, 00, 1A, 00, 50, A1, B0 });
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

Accelerometer Calibration

Applied calibration of the sensor by calling the WT901C485.AppliedCalibration() method

/// <summary>
/// Accelerometer Calibration
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void appliedCalibrationButton_Click(object sender, EventArgs e)
{
      if (WT901C485.IsOpen() == false)
      {
            return;
      }
      try
      {
            // Unlock registers and send commands
            WT901C485.UnlockReg();
            WT901C485.AppliedCalibration();
            // The following two lines are equivalent to the above, it is recommended to use the above
            //WT901C485.SendProtocolData(Modbus16Utils.GetWrite(T901C485.GetModbusId(), 0x69,             0xB588));
            //WT901C485.SendProtocolData(new byte[] { 50, 06, 00, 69, B5, 88, 22, A1 });
            //WT901C485.SendProtocolData(Modbus16Utils.GetWrite(T901C485.GetModbusId(), 0x01,       0x0001));
            //WT901C485.SendProtocolData(new byte[] { 50, 06, 00, 01, 00, 01, 32, 4B });
      }
      catch (Exception ex)
      {
            MessageBox.Show(ex.Message);
      }
}

Magnetic Field Calibration

Perform magnetic field calibration on the sensor by calling the WT901C485.StartFieldCalibration() method and WT901C485.EndFieldCalibration() method

/// <summary>
/// Start Magnetic Field Calibration
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void startFieldCalibrationButton_Click(object sender, EventArgs e)
{
      if (WT901C485.IsOpen() == false)
      {
            return;
      }
      try
      {
            // Unlock registers and send commands
            WT901C485.UnlockReg();
            WT901C485.StartFieldCalibration();
            // The following two lines are equivalent to the above, it is recommended to use the above
            //WT901C485.SendProtocolData(Modbus16Utils.GetWrite(T901C485.GetModbusId(), 0x69,       0xB588));
            //WT901C485.SendProtocolData(new byte[] { 50, 06, 00, 69, B5, 88, 22, A1 });
            //WT901C485.SendProtocolData(Modbus16Utils.GetWrite(T901C485.GetModbusId(), 0x01, 0x0007));
            //WT901C485.SendProtocolData(new byte[] { 50, 06, 00, 01, 00, 07, 94, 49 });
            MessageBox.Show("Start magnetic field calibration, please turn around the three axes of       the sensor XYZ, and click【End Magnetic Field Calibration】");
      }
      catch (Exception ex)
      {
            MessageBox.Show(ex.Message);
      }
}
/// <summary>
///End magnetic field calibration
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void endFieldCalibrationButton_Click(object sender, EventArgs e)
{
      if (WT901C485.IsOpen() == false)
      {
            return;
      }
      try
      {
            // Unlock registers and send commands
            WT901C485.UnlockReg();
            WT901C485.EndFieldCalibration();
            // The following two lines are equivalent to the above, it is recommended to use the above
            //WT901C485.SendProtocolData(Modbus16Utils.GetWrite(T901C485.GetModbusId(), 0x69, 0xB588));
            //WT901C485.SendProtocolData(new byte[] { 50, 06, 00, 69, B5, 88, 22, A1 });
            //WT901C485.SendProtocolData(Modbus16Utils.GetWrite(T901C485.GetModbusId(), 0x01, 0x0000));
            //WT901C485.SendProtocolData(new byte[] { 50, 06, 00, 01, 00, 00, D5, 8B });
      }
      catch (Exception ex)
      {
            MessageBox.Show(ex.Message);
      }
}

More

For other operations, please refer to the sensor manual

Read sensor register

You can read the registers of the sensor through WT901C485.SendReadReg(), or use WT901C485.SendProtocolData()method

After sending the read command, the register value will be saved in WT901C485, you need to get the register data through WT901C485.GetDeviceData()

/// <summary>
/// Read 03 register
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void readReg03Button_Click(object sender, EventArgs e)
      {
      if (WT901C485.IsOpen() == false)
      {
            return;
      }
      try
      {
            // waiting time
            int waitTime = 150;
            // Send a read command and wait for the sensor to return data. If it is not read, you can extend the waitTime, or read it several times
            WT901C485.SendReadReg(0x03, waitTime);
            // The following two lines are equivalent to the above. It is recommended to use the above
            //WT901C485.SendProtocolData(Modbus16Utils.GetRead(WT901C485.GetModbusId(), 0x03, 0x01), waitTime);
            //WT901C485.SendProtocolData(new byte[] { 50, 03, 00, 03, 00, 01, 79, 8B }, waitTime);
            string reg03Value = WT901C485.GetDeviceData("03");
            MessageBox.Show($"Register 03 value is : {reg03Value}");
      }
      catch (Exception ex)
      {
            MessageBox.Show(ex.Message);
      }
}
/// <summary>
/// Read 03 register
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void readReg03Button_Click(object sender, EventArgs e)
{
      if (JY901.IsOpen() == false)
      {
            return;
      }
      try
      {
            // waiting time
            int waitTime = 150;
            // Send a read command and wait for the sensor to return data. If it is not read, you can extend the waitTime, or read it several times
            JY901.SendReadReg(0x03, waitTime);
            // The following line is equivalent to the above. It is recommended to use the above
            //JY901.SendProtocolData(new byte[] { 0xff, 0xaa, 0x27, 0x03, 0x00 }, waitTime);
            string reg03Value = JY901.GetDeviceData("03");
            MessageBox.Show($"Register 03 value is : {reg03Value}");
      }
      catch (Exception ex)
      {
            MessageBox.Show(ex.Message);
      }
}

WT901C485 API

method

illustrate

Parameter introduction

return value

void SetPortName(string portName)

Set the serial port to open

portName:Serial number

void

void SetBaudrate(int baudRate)

Specify the baud rate to open

baudRate:baud rate

void

void Open()

turn on the device

none

void

bool IsOpen()

Is the device turned on

none

Return whether to open open: true close: false

void Close()

turn off the device

none

void

void SendData(byte[] data, out byte[] returnData, bool isWaitReturn, int waitTime , int repetition)

send data

data: the data to be sent

returnData: the data returned by the sensor

isWaitReturn: Whether the sensor needs to return data

waitTime: wait for the sensor to return data time, unit ms, default 100ms

repetition: the number of times to repeat sending

void

void SendProtocolData(byte[] data)

send protocol data

data:data waiting to be sent

void

void SendProtocolData(byte[] data, int waitTime)

Send data with protocol, and specify the waiting time

data: the data to be sent

waitTime: waiting time

void

void SendReadReg(byte reg, int waitTime)

Send the command to read the register

reg:command to send

waitTime:waiting time

void

void UnlockReg()

unlock register

none

void

void SaveReg()

save register

none

void

void AppliedCalibration()

Accelerometer Calibration

none

void

void StartFieldCalibration()

Start Magnetic Field Calibration

none

void

void EndFieldCalibration()

End magnetic field calibration

none

void

void SetReturnRate(byte rate)

set return rate

rate:Return rate to be set

void

string GetDeviceName()

get device name

none

return device name

string GetDeviceData(string key)

Get Key value data

key:data key

return data value

void SetModbusId(byte modbusId)

designated address

modbusId:Modbus address

void

byte GetModbusId()

get device address

none

return device address

English description

📎Modbus Protocol SDK Quick Guide.pdf

Last updated