WaterMeters folder created, WaterMeter component relocated within the project, iPerl component added WaterMeters.iPerl implements IRegisterReader interface, TODO: Implement WaterMeter.ReadPulses( ) function iPerlAdjustment test method added
125 lines
3.1 KiB
C#
125 lines
3.1 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 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(ModbusCfg cfg, IList<Generic.IComponent> components)
|
|
: base(cfg)
|
|
{
|
|
serialPort = null;
|
|
modbusCommonCfg = cfg;
|
|
log.Debug(this.ToString());
|
|
}
|
|
|
|
~Modbus()
|
|
{
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
if (modbusCommonCfg.DebugLevel == Entities.DebugMode.Simulate)
|
|
{
|
|
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)
|
|
{
|
|
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()
|
|
{
|
|
}
|
|
|
|
/// <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();
|
|
}
|
|
}
|
|
}
|
|
}
|