tbf/TestBenchFramework/BenchControl/Modbus/Common/Modbus.cs
2016-10-07 11:55:44 +02:00

138 lines
3.5 KiB
C#

///
/// Copyright (c) 2015 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO.Ports;
using System.Text;
using System.Threading;
using log4net;
using Config.Entities;
using TBF.BenchControl.Generic;
using TBF.Boxes;
namespace TBF.BenchControl.Modbus.Common
{
/// <summary>
/// Root component for Modbus communication via serial port (RS485)
/// </summary>
public class Modbus : ComponentBase, IDevice, GenericDevices.IModbus
{
private static readonly ILog log = LogManager.GetLogger(typeof(Modbus));
public override string ToString() { return string.Format("Modbus({0})", Cfg.ToString(1)); }
private readonly ModbusCfg modbusCommonCfg;
/// Private fields
SerialPort serialPort;
Thread workerThread;
bool stopWorkerThread;
public Modbus()
{
}
/// <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 Modbus(Generic.IComponentCfg cfg)
: base(cfg)
{
serialPort = null;
modbusCommonCfg = cfg as ModbusCfg;
log.Debug(this.ToString());
}
~Modbus()
{
}
public void Initialize()
{
if (modbusCommonCfg.DebugLevel == DebugMode.Simulate)
{
log.FatalFormat("Simulated device {0}", ToString());
return;
}
string comPortName = "COM" + modbusCommonCfg.ComPortNr.ToString();
serialPort = new SerialPort(comPortName, modbusCommonCfg.BaudRate, modbusCommonCfg.Parity, modbusCommonCfg.DataBits, modbusCommonCfg.StopBits);
serialPort.Handshake = modbusCommonCfg.Handshake;
serialPort.Open();
//stopWorkerThread = false;
//workerThread = new Thread(Worker);
//workerThread.Start();
log.FatalFormat("Successfully initialized device {0}", ToString());
}
/// <summary>
/// Send a modbus message.
/// This function calculates and overwrites the last 2 bytes
/// of the message - CRC as specified in Modbus specification.
/// </summary>
/// <param name="message">Message incl CRC, CRC bytes dont have to be set</param>
public void SendMessage(byte[] message)
{
if (modbusCommonCfg.DebugLevel == DebugMode.Simulate) return;
Telegram.UpdateTelegramCRC(message);
log.Debug(Telegram.LogTelegram("Sending message ", message));
serialPort.Write(message, 0, message.Length);
}
void Worker()
{
while (!stopWorkerThread)
{
Thread.Sleep(250);
if (stopWorkerThread) break;
int nrBytes = serialPort.BytesToRead;
if (nrBytes > 0)
{
char[] buffer = new char[nrBytes];
serialPort.Read(buffer, 0, nrBytes);
string s = Telegram.LogTelegram("Received: ", new string(buffer));
/// ODO: Add handler
//OnQuidoReceived(this, new QuidoReceivedEventArgs(s));
}
}
}
/// <summary>Run this device</summary>
public void RunDeviceBefore()
{
int nrBytes = serialPort.BytesToRead;
if (nrBytes > 0)
{
char[] buffer = new char[nrBytes];
serialPort.Read(buffer, 0, nrBytes);
string s = Telegram.LogTelegram("Received: ", new string(buffer));
/// ODO: Add handler
//OnQuidoReceived(this, new QuidoReceivedEventArgs(s));
}
}
/// <summary>Run this device</summary>
public void RunDeviceAfter()
{
}
/// <summary>Stop this device</summary>
public void StopDevice()
{
if (serialPort != null)
{
//stopWorkerThread = true;
//workerThread.Join(2000);
serialPort.Close();
}
}
}
}