Even though I bought a new RS232 - USB connector and installed it successfully, I couldn't get the data from the device. I tried Realterm but no data is coming surprisingly. The parameters are correct with the device but somehow no data is captured.
Here is the updated code for my situation:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.IO.Ports;
using System.Text;
using System.Text.Json;
namespace VehicleWeightMeasurement;
public class WeightMeasurementService : IDisposable
{
private readonly ILogger<WeightMeasurementService> _logger;
private readonly IConfiguration _configuration;
private SerialPort? _serialPort;
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private bool _dataReceived = false;
private readonly string _clientId;
public WeightMeasurementService(ILogger<WeightMeasurementService> logger, IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
_serialPort = null;
_clientId = _configuration["ClientId"] ?? Guid.NewGuid().ToString(); // Get from config or generate
}
public async Task StartMeasuringAsync(CancellationToken cancellationToken)
{
const int baudRate = 1200;
var availablePorts = SerialPort.GetPortNames();
if (availablePorts.Length == 0)
{
LogWithColor("No COM ports are available.\n", ConsoleColor.Red);
return;
}
LogWithColor($"Available COM ports: {string.Join(", ", availablePorts)}\n", ConsoleColor.Green);
foreach (var portName in availablePorts)
{
LogWithColor($"Attempting to connect to {portName} at {baudRate} baud\n", ConsoleColor.Yellow);
try
{
_serialPort = new SerialPort("COM5", baudRate)
{
DataBits = 8,
Parity = Parity.None,
StopBits = StopBits.One,
Handshake = Handshake.None,
};
_serialPort.Open();
LogWithColor($"*** Successfully *** connected to {_serialPort.PortName} at {baudRate} baud\n", ConsoleColor.Green);
_serialPort.DataReceived += SerialPort_DataReceived;
// Continuously listen for valid data reception
while (!cancellationToken.IsCancellationRequested)
{
if (_dataReceived)
{
LogWithColor("Valid weight data received successfully.\n", ConsoleColor.Green);
_dataReceived = false; // Reset flag for next data reception
}
await Task.Delay(4500, cancellationToken); // Adjust delay as necessary
}
}
catch (UnauthorizedAccessException)
{
LogWithColor($"Access to the port {portName} is denied. The port may be in use by another application.\n", ConsoleColor.Red);
}
catch (IOException)
{
LogWithColor($"An I/O error occurred while accessing the port {portName}.\n", ConsoleColor.Red);
}
catch (Exception)
{
LogWithColor("An unexpected error occurred while starting measurement.\n", ConsoleColor.Red);
}
finally
{
ClosePort();
}
}
LogWithColor("Failed to receive valid weight data from any port.\n", ConsoleColor.Red);
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
LogWithColor("DataReceived event triggered.\n", ConsoleColor.Cyan);
if (_cts.IsCancellationRequested) return;
try
{
if (_serialPort == null || _serialPort.BytesToRead <= 0) return;
// Read the bytes from the serial port
byte[] buffer = new byte[_serialPort.BytesToRead];
_serialPort.Read(buffer, 0, buffer.Length);
// Convert the bytes to a string
string data = BitConverter.ToString(buffer).Replace("-", string.Empty);
LogWithColor($"Raw data received: {data}\n", ConsoleColor.Cyan);
// Parse the data according to the specified format
if (TryParseWeightData(data, out float weight))
{
_dataReceived = true;
ProcessWeight(weight);
}
else
{
LogWithColor($"Received unexpected data format: {data}\n", ConsoleColor.Yellow);
}
}
catch (TimeoutException)
{
LogWithColor("Timeout occurred while reading from serial port.\n", ConsoleColor.Yellow);
}
catch (Exception)
{
LogWithColor("Error processing received data.\n", ConsoleColor.Red);
}
}
private async void ProcessWeight(float weight)
{
var minWeight = float.Parse(_configuration["WeightLimits:MinWeight"] ?? string.Empty);
var maxWeight = float.Parse(_configuration["WeightLimits:MaxWeight"] ?? string.Empty);
if (weight < minWeight)
{
LogWithColor($"Weight below minimum: {weight} kg\n", ConsoleColor.Yellow);
}
else if (weight > maxWeight)
{
LogWithColor($"Weight above maximum: {weight} kg\n", ConsoleColor.Yellow);
}
else
{
LogWithColor($"Valid weight measured: {weight} kg\n", ConsoleColor.Green);
}
// Send the weight data to the web API
var measurement = new { Value = weight, Unit = "Kg", Timestamp = DateTime.Now, ClientId = _clientId, PlateNumber = "06AB001", VehicleType = "Truck" };
var httpClient = new HttpClient();
var content = new StringContent(JsonSerializer.Serialize(measurement), Encoding.UTF8, "application/json");
await httpClient.PostAsync("https://localhost:7008/api/Measurements", content);
// Wait for a random time between 1 and 5 seconds
await Task.Delay(new Random().Next(5000, 20000));
// Send the weight data to the web API
measurement = new { Value = weight - 1000, Unit = "Kg", Timestamp = DateTime.Now, ClientId = "Yeşilköy", PlateNumber = "34DE002", VehicleType = "Van" };
httpClient = new HttpClient();
content = new StringContent(JsonSerializer.Serialize(measurement), Encoding.UTF8, "application/json");
await httpClient.PostAsync("https://localhost:7008/api/Measurements", content);
}
private void ClosePort()
{
if (_serialPort?.IsOpen == true)
{
_serialPort.DataReceived -= SerialPort_DataReceived;
_serialPort.Close();
_serialPort.Dispose();
LogWithColor("Serial port closed and disposed.\n", ConsoleColor.Green);
}
}
public void Dispose()
{
_cts.Cancel();
ClosePort();
}
private void LogWithColor(string message, ConsoleColor color)
{
// Include color information in the message
var coloredMessage = $"[Color:{color}] {message}";
// Fallback to default logging if the logger is not SimpleConsoleLogger
_logger.Log(LogLevel.Information, coloredMessage);
}
private bool TryParseWeightData(string data, out float weight)
{
weight = 0;
// Check if the data length is 16 characters (8 bytes in HEX) and ends with '0D' (CR in HEX)
if (data.Length != 16 || !data.EndsWith("0D"))
{
return false;
}
// Convert HEX to ASCII
string asciiData = string.Empty;
for (int i = 0; i < data.Length - 2; i += 2)
{
asciiData += (char)Convert.ToByte(data.Substring(i, 2), 16);
}
// Extract the sign and the numeric part
char sign = asciiData[0];
string numericPart = asciiData.Substring(1, 6);
// Check if the sign is valid
if (sign != '+' && sign != '-')
{
return false;
}
// Try to parse the numeric part as a float
if (float.TryParse(numericPart, out float parsedWeight))
{
// Apply the sign to the parsed weight
weight = sign == '+' ? parsedWeight : -parsedWeight;
return true;
}
return false;
}
}