Comet Ambient modbus protocol implemented.

This commit is contained in:
Milan Hanajik
2015-04-17 18:22:08 +02:00
parent 754bcd3dc6
commit 63b4004d85
3 changed files with 45 additions and 53 deletions
@@ -25,7 +25,6 @@ namespace TBF.BenchControl.Ambient.Comet
/// Private fields
SerialPort serialPort;
StringBuilder measurementBuilder;
/// <summary>The state of the measurement</summary>
MsrmntState msrmntState;
@@ -69,7 +68,6 @@ namespace TBF.BenchControl.Ambient.Comet
serialPort = new SerialPort(comPortName, ambientCfg.BaudRate, ambientCfg.Parity, ambientCfg.DataBits, ambientCfg.StopBits);
serialPort.Handshake = ambientCfg.Handshake;
serialPort.Open();
measurementBuilder = new StringBuilder(40);
msrmntState = MsrmntState.Busy;
log.FatalFormat("Successfully initialized device {0}", ToString());
@@ -84,52 +82,28 @@ namespace TBF.BenchControl.Ambient.Comet
return;
}
measurementBuilder.Append(serialPort.ReadExisting());
int len = measurementBuilder.Length;
int receivedBytes = serialPort.BytesToRead;
///
/// Device sends each 20 sec one line of ASCII text with data in the following format:
/// (temp) 6 characters, two decimal digits, with leading spaces
/// TAB 1 character
/// (humi) 6 characters, two decimal digits, with leading spaces
/// TAB 1 character
/// (pressure) 6 characters, one decimal digits, with leading spaces is LT 1000
/// CR + LF 2 characters
/// Example:
/// 23.42 38.08 1061.1
/// 23.39 38.04 1060.8
/// 23.39 38.08 1061.4
///
if (len >= 22)
if (receivedBytes >= 13)
{
string measurement = measurementBuilder.ToString();
measurementBuilder.Clear();
byte[] byteArr = new byte[receivedBytes];
for (int i = 0; i < receivedBytes; i++) byteArr[i] = (byte)serialPort.ReadByte();
log.Debug( Telegram.LogTelegram("Received ", byteArr));
float t = 0;
float h = 0;
float p = 0;
if (float.TryParse(measurement.Substring(len - 22, 6), NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out t) &&
measurement[len - 16] == '\t' &&
float.TryParse(measurement.Substring(len - 15, 6), NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out h) &&
measurement[len - 9] == '\t' &&
float.TryParse(measurement.Substring(len - 8, 6), NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite,
CultureInfo.InvariantCulture, out p) &&
measurement[len - 2] == '\r' &&
measurement[len - 1] == '\n')
if ((receivedBytes == 13) && (byteArr[0] == 1) && (byteArr[1] == 3) && (byteArr[2] == 8) && Telegram.VerifyTelegramCRC(byteArr))
{
temperature = t;
humidity = h;
pressure = p;
int value = (int)byteArr[3] * 256 + (int)byteArr[4];
temperature = (float)value / 10.0f;
value = (int)byteArr[5] * 256 + (int)byteArr[6];
humidity = (float)value / 10.0f;
value = (int)byteArr[9] * 256 + (int)byteArr[10];
pressure = (float)value / 10.0f;
msrmntTimeStamp = StateMachine.Time;
msrmntState = MsrmntState.Valid;
log.InfoFormat("Msrmnt OK: time = {0}, temp={1}, humi={2}, pres={3}", msrmntTimeStamp, t, h, p);
}
else
{
log.Warn("Invalid string received: " + measurement);
log.InfoFormat("Ambient: temperature = {0} C, humidity = {1} %, pressure = {2} hPa", temperature.ToString("F1"), humidity.ToString("F1"), pressure.ToString("F0"));
}
}
}
@@ -137,6 +111,26 @@ namespace TBF.BenchControl.Ambient.Comet
/// <summary>Run this device</summary>
public void RunDeviceAfter()
{
/// Each 10 seconds
if ((StateMachine.Time % 10) == 0)
{
/// Read four registers: 0x31, 0x32, 0x33, 0x34
UInt16 regAddr = 0x0030; /// register addr. = 0x31 (Modbus!)
UInt16 count = 4;
/// Prepare data to be sent
byte[] msg = new byte[8];
msg[0] = 1; /// (byte)ambientCfg.BusAddress;
msg[1] = 3; /// CMD = Read registers
msg[2] = (byte)(regAddr >> 8); /// Control Word Hi
msg[3] = (byte)(regAddr & 0xFF); /// Control Word Lo
msg[4] = (byte)(count >> 8); /// Serial Com Reference Hi
msg[5] = (byte)(count & 0xFF); /// Serial Com Reference Lo
Telegram.UpdateTelegramCRC(msg);
log.Debug(Telegram.LogTelegram("Sending ", msg));
serialPort.Write(msg, 0, msg.Length);
}
}
/// <summary>Stop this device</summary>
@@ -59,7 +59,7 @@ namespace TBF.BenchControl.Ambient.Greco
{
temperature = 20.0f;
humidity = 40.0f;
pressure = 1.0f;
pressure = 1000.0f;
msrmntTimeStamp = StateMachine.Time;
msrmntState = MsrmntState.Valid;
return;
@@ -125,7 +125,7 @@ namespace TBF.BenchControl.Ambient.Greco
msrmntTimeStamp = StateMachine.Time;
msrmntState = MsrmntState.Valid;
log.InfoFormat("Msrmnt OK: time = {0}, temp={1}, humi={2}, pres={3}", msrmntTimeStamp, t, h, p);
log.InfoFormat("Ambient: temperature = {0} C, humidity = {1} %, pressure = {2} hPa", temperature.ToString("F1"), humidity.ToString("F1"), pressure.ToString("F0"));
}
else
{
@@ -64,10 +64,8 @@ namespace TBF.BenchControl.Danfoss.VLT2800
PresetSingleRegister = 0x06,
PresetMultipleRegisters = 0x10,
}
/// <summary>
/// Ambient temperature / humidity / pressure meter 'Greco' connected via serial interface (RS232)
/// Connection settings: 19200 Bd 8-bits No-parity 1-stop-bit Flow control: none or hardware.
/// </summary>
public class Pump : ComponentBase, IDevice, IOperation, GenericDevices.IPumpFM, GenericDevices.IValve
{
private static readonly ILog log = LogManager.GetLogger(typeof(Pump));