private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (Clos_flag) return;
try
{
Listening = true;
if (serialPort.IsOpen)
{
this.txt_weight.Invoke(new MethodInvoker(delegate
{
serialPort.NewLine = "\r";
string weight = serialPort.ReadLine();
weight = weight.Trim();
MessageBox.Show(weight);
if (weight.IndexOf("i") > 0)
{
weight = weight.Substring(3, 8);
txt_weight.Text = weight.Substring(0, weight.LastIndexOf("0") + 1);
}
}));
}
}
catch (Exception eg)
{
MessageBox.Show(eg.ToString());
}
finally
{
Listening = false;
}
}
I use the above code to read the weighing machine, but it keep on prompt the timeout error I'm not sure which part of the coding is wrong.
You check your configure serialport.
It may be error while run code serialPort.Open().
you can refer code:
void InitialComport1()
{
mySerialPort1 = new SerialPort(Temp._comport1);
if (mySerialPort1.IsOpen)
{
mySerialPort1.Close();
}
mySerialPort1.BaudRate = Temp._baudRate1;
mySerialPort1.Parity = Parity.None;
mySerialPort1.StopBits = StopBits.One;
mySerialPort1.DataBits = Temp._dataBit1;
mySerialPort1.Handshake = Handshake.None;
mySerialPort1.RtsEnable = true;
mySerialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler1);
try
{
mySerialPort1.Open();
}
catch
{
Messagebox.Show("Error myserialPort1")
}
}
private void DataReceivedHandler1(object sender, SerialDataReceivedEventArgs e)
{
try
{
string indata = mySerialPort1.ReadLine();
try
{
string mass = indata.Substring(7, 7);
SetText1((Convert.ToInt32(mass)).ToString());
}
catch
{
string mass = indata.Substring(3, 7);
SetText1((Convert.ToInt32(mass)).ToString());
}
}
catch (Exception eg)
{
MessageBox.Show(eg.ToString());
}
}
Related
First of all I am a complete begineer in C# and literally don't know how to use async/await/cancellation/Tasks, I come from a embedded systems background with basic-moderate C/C++ knowledge. So i just get the idea what those async functions do here. the async task codes are copied from samples from microsoft, they simply keep on reading the serial port for new bytes. I made some animations for the UI through Blend, and that's just it nothing more fancy.
This app runs on a raspberry with IOT core, and its sole job is to provide a UI for user to control a microcontroller with plain text instructions send through serial port. All these buttons simply send some strings to serial port which my microcontroller reads and acts accordingly.
Problem 1: I modified a line in the ReadAsync function uint ReadBufferLength = 1; the value was 128 in sample code, my microcontroller sends a complete instruction or data ending with "\r\n". This meant it will keep on reading bytes in serial that come from the microcontroller until the buffer is full and call the ReadAsync function again. since it was reading until the buffer (128) was full, multiple instructions come and fill the buffer. So i had no way to figure out what is the instruction in the buffer. So my work around here was to change the buffer to 1 and append a string with new bytes from serial port until it finds Environment.NewLine and then build logic based on the complete instruction in the string.
Question 1: How do I modify the code to not change the uint ReadBufferLength = 1; and make the ReadAsync function store my serial incoming data until it finds \r\n ?
MAJOR Problem 2: As soon as I enter Manual/Auto mode by clicking the front panel button, my microcontroller starts sending temperature sensor value through serial port as fast as possible without any delay between instructions. I know the raspberry pi (win10 iot core) is fast enough to not miss any instruction or the physical serial port buffer of the PI getting overfilled. It works fine, there is no problem at this point in the app, no crash or slowdowns. But overtime I can see that the app is consuming more and more RAM. the behavior is same in PC if I build it in x86 mode. after running it for 1 hour it will consume over 120 megabytes whereas it starts at 30-50 megabytes initially.
To recreate the problem, please change string qFilter = SerialDevice.GetDeviceSelector("UART0"); UART0 to appropriate com port in windows. otherwise the app will not run. Probably a Virtual COM port needs to be installed or a usb to ttl module might be required.
Problem 3: Cannot build the app in release mode using the option "Compile with .NET Native tool chain", without this it runs fine in the raspberry.
Internal compiler error: MCG0024:UnresolvableTypeReference Unresolvable type reference 'System.Runtime.InteropServices.WindowsRuntime.IRestrictedErrorInfo' in 'Assembly(Name=System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)' found. Please check the references in your build system. A reference is either missing or an assembly is missing an expected type. hvac_version_4
github project file
using Windows.UI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.Devices.SerialCommunication;
using Windows.Storage.Streams;
using System.Threading;
using Windows.Devices.Enumeration;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Animation;
using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace hvac_version_2
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
SolidColorBrush greenBrush = new SolidColorBrush(Colors.Green);
SolidColorBrush redBrush = new SolidColorBrush(Colors.Red);
SolidColorBrush greyBrush = new SolidColorBrush(Colors.DarkSlateGray);
//private bool updatingValues;
private CancellationTokenSource ReadCancellationTokenSource;
private SerialDevice serialPort = null;
DataWriter dataWriteObject = null;
DataReader dataReaderObject = null;
public string strFromPort;
private string final_string;
private int compressorAkey=0;
private int compressorBkey=0;
private int pump_entry = 0;
private int compAentry=0;
private int compBentry=0;
private int fan1entry = 0;
private int fan2entry = 0;
private double Blur_amount = 0;
public MainPage()
{
this.InitializeComponent();
stop_button.IsEnabled = false;
set_temperature.IsEnabled = false;
set_switching_time.IsEnabled = false;
auto_mode.IsEnabled = false;
manual_mode.IsEnabled = false;
compressorA_button.IsEnabled = false;
compressorB_button.IsEnabled = false;
fanA_button.IsEnabled = false;
fanB_button.IsEnabled = false;
init.IsEnabled = false;
init_timing.IsEnabled = false;
pump_button.IsEnabled = false;
load_animation.Begin();
}
private async void stop_button_Click(object sender, RoutedEventArgs e)
{
//do something
start_animation.Stop();
if (serialPort == null) return;
await sendToPort("end");
set_temperature.IsEnabled = false;
set_switching_time.IsEnabled = false;
manual_mode.IsEnabled = true;
auto_mode.IsEnabled = true;
stop_button.IsEnabled = false;
compressorA_button.IsEnabled = false;
compressorB_button.IsEnabled = false;
fanA_button.IsEnabled = false;
fanB_button.IsEnabled = false;
init.IsEnabled = false;
init_timing.IsEnabled = false;
pump_button.IsEnabled = false;
start_button.IsEnabled = true;
pump_entry = 0;
compAentry = 0;
compBentry = 0;
fan1entry = 0;
fan2entry = 0;
stop_animation.Begin();
start_button.Width = 162;
GC.Collect();
}
private async void set_temperature_changed(object sender, EventArgs e)
{
//System.Diagnostics.Debug.WriteLine("entered the async void set_temp.............");
}
private async void set_switching_time_value_changed(object sender, EventArgs e)
{
//System.Diagnostics.Debug.WriteLine("entered the async void switching time.............");
}
private async void manual_mode_Click(object sender, RoutedEventArgs e)
{
if (serialPort == null) return;
await sendToPort("manual");
auto_mode.IsEnabled = false;
manual_mode.IsEnabled = false;
stop_button.IsEnabled = true;
set_temperature.IsEnabled = true;
set_switching_time.IsEnabled = true;
pump_button.IsEnabled = true;
fanA_button.IsEnabled = true;
fanB_button.IsEnabled = true;
compressorA_button.IsEnabled = true;
compressorB_button.IsEnabled = true;
init.IsEnabled = true;
init_timing.IsEnabled = true;
}
private async void auto_mode_Click(object sender, RoutedEventArgs e)
{
set_switching_time.IsEnabled = true;
set_temperature.IsEnabled = true;
init.IsEnabled = true;
stop_button.IsEnabled = true;
init_timing.IsEnabled = true;
if (serialPort == null) return;
await sendToPort("auto");
}
private async void start_button_Click(object sender, RoutedEventArgs e)
{
stop_animation.Stop();
await sendToPort("ready");
auto_mode.IsEnabled = true;
manual_mode.IsEnabled = true;
start_button.IsEnabled = false;
start_animation.Begin();
System.Diagnostics.Debug.WriteLine("sending ready command");
}
private async void compressorA_button_Click(object sender, RoutedEventArgs e)
{
if (compAentry == 0)
{
if (serialPort == null) return;
await sendToPort("compressorAON"); //sending key
compAentry = 1;
}
else
{
if (serialPort == null) return;
await sendToPort("compressorAoff"); //sending key
compAentry = 0;
}
}
private async void compressorB_button_Click(object sender, RoutedEventArgs e)
{
if (compBentry == 0)
{
if (serialPort == null) return;
await sendToPort("compressorBON"); //sending key
compBentry = 1;
}
else
{
if (serialPort == null) return;
await sendToPort("compressorBoff"); //sending key
compBentry = 0;
}
}
private async void fanA_button_Click(object sender, RoutedEventArgs e)
{
if (fan1entry == 0)
{
if (serialPort == null) return;
await sendToPort("fan1on");
fan1entry = 1;
}
else
{
if (serialPort == null) return;
await sendToPort("fan1off");
fan1entry = 0;
}
}
private async void fanB_button_Click(object sender, RoutedEventArgs e)
{
if (fan2entry == 0)
{
if (serialPort == null) return;
await sendToPort("fan2on");
fan2entry = 1;
}
else
{
if (serialPort == null) return;
await sendToPort("fan2off");
fan2entry = 0;
}
}
private async void pump_button_Click(object sender, RoutedEventArgs e)
{
if (pump_entry == 0)
{
if (serialPort == null) return;
await sendToPort("pumpon");
pump_entry = 1;
}
else
{
if (serialPort == null) return;
await sendToPort("pumpoff");
pump_entry = 0;
}
}
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
string qFilter = SerialDevice.GetDeviceSelector("UART0");
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(qFilter);
if (devices.Any())
{
string deviceId = devices.First().Id;
await OpenPort(deviceId);
}
ReadCancellationTokenSource = new CancellationTokenSource();
while (true)
{
//System.Diagnostics.Debug.WriteLine("program came before await listen");
await Listen();
}
}
private async Task OpenPort(string deviceId)
{
serialPort = await SerialDevice.FromIdAsync(deviceId);
if (serialPort != null)
{
serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(50);
serialPort.BaudRate = 115200;
serialPort.Parity = SerialParity.None;
serialPort.StopBits = SerialStopBitCount.One;
serialPort.DataBits = 8;
serialPort.Handshake = SerialHandshake.None;
//Console.WriteLine("Serial port configured successfully");
//txtStatus.Text = "Serial port configured successfully";
}
}
private async Task Listen()
{
try
{
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
catch (Exception ex)
{
txtStatus.Text = ex.Message;
}
finally
{
if (dataReaderObject != null) // Cleanup once complete
{
dataReaderObject.DetachStream();
dataReaderObject = null;
}
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 1; // only when this buffer would be full next code would be executed
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken); // Create a task object
//string debug = dataReaderObject.ReadString(bytesRead2);
//System.Diagnostics.Debug.WriteLine("writing string debug"+ debug);
UInt32 bytesRead = await loadAsyncTask; // Launch the task and wait until buffer would be full
if (bytesRead > 0)
{
strFromPort = dataReaderObject.ReadString(bytesRead);
final_string = final_string + strFromPort;
//txtStatus2.Text = final_string;
if (final_string.Contains(Environment.NewLine))
{
string logicstring = final_string;
final_string = "";
//System.Diagnostics.Debug.WriteLine("writing logic string " + logicstring);
if (logicstring.StartsWith("A"))
{
if(logicstring.Contains("-"))
{
//it is a negative number
logicstring = Regex.Match(logicstring, #"\d+").Value;
int gauge1_pass = int.Parse(logicstring) * -1;
tempgauge1.Value = gauge1_pass;
}
else
{
logicstring = Regex.Match(logicstring, #"\d+").Value;
int gauge1_pass = int.Parse(logicstring);
tempgauge1.Value = gauge1_pass;
}
}
if (logicstring.StartsWith("B"))
{
if (logicstring.Contains("-"))
{
//it is a negative number
logicstring = Regex.Match(logicstring, #"\d+").Value;
int gauge2_pass = int.Parse(logicstring) * -1;
tempgauge1.Value = gauge2_pass;
}
else
{
logicstring = Regex.Match(logicstring, #"\d+").Value;
int gauge2_pass = int.Parse(logicstring);
tempgauge2.Value = gauge2_pass;
}
}
if (logicstring.StartsWith("setting"))
{
if (logicstring.Contains("-"))
{
//it is a negative number
logicstring = Regex.Match(logicstring, #"\d+").Value;
int previous_temp_setting = int.Parse(logicstring) * -1;
set_temperature.Value = previous_temp_setting;
}
else
{
logicstring = Regex.Match(logicstring, #"\d+").Value;
int previous_temp_setting = int.Parse(logicstring);
set_temperature.Value = previous_temp_setting;
}
}
if (logicstring.StartsWith("pumpon"))
{
pump_status_light.Fill = greenBrush;
Storyboard_Pump_Led.RepeatBehavior = RepeatBehavior.Forever;
Storyboard_Pump_Led.Begin();
}
if (logicstring.StartsWith("pumpoff"))
{
pump_status_light.Fill = redBrush;
Storyboard_Pump_Led.Stop();
}
if (logicstring.StartsWith("pumpfail"))
{
if (!FailPopup.IsOpen)
{
FailPopup.IsOpen = true;
}
}
if (logicstring.StartsWith("clear the popup"))
{
if (FailPopup.IsOpen)
{
FailPopup.IsOpen = false;
}
}
if (logicstring.StartsWith("switch_interval"))
{
logicstring = Regex.Match(logicstring, #"\d+").Value;
int previous_interval_setting = int.Parse(logicstring);
set_switching_time.Value = previous_interval_setting;
}
if (logicstring.StartsWith("timer"))
{
logicstring = Regex.Match(logicstring, #"\d+").Value;
int remaining_time = int.Parse(logicstring);
remaining_time = remaining_time / 1000;
timer_box.Text = remaining_time.ToString();
}
if (logicstring.StartsWith("Free RAM = "))
{
logicstring = Regex.Match(logicstring, #"\d+").Value;
int remaining_memory = int.Parse(logicstring);
free_memory.Text = remaining_memory.ToString();
}
if (logicstring.StartsWith("fan1on"))
{
fan1_status_light.Fill = greenBrush;
storyboard_fan1_led.RepeatBehavior = RepeatBehavior.Forever;
storyboard_fan1_led.Begin();
}
if (logicstring.StartsWith("fan1off"))
{
fan1_status_light.Fill = redBrush;
storyboard_fan1_led.Stop();
}
if (logicstring.StartsWith("fan2on"))
{
fan2_status_light.Fill = greenBrush;
storyboard_fan_2.RepeatBehavior = RepeatBehavior.Forever;
storyboard_fan_2.Begin();
}
if (logicstring.StartsWith("fan2off"))
{
fan2_status_light.Fill = redBrush;
storyboard_fan_2.Stop();
}
if (logicstring.StartsWith("compressorAON")) //key
{
compressorA_status_light.Fill = greyBrush;
compressorAkey = 1;
}
if (logicstring.StartsWith("compressorAoff")) //key
{
compressorA_status_light.Fill = redBrush;
compressorAkey = 0;
}
if (logicstring.StartsWith("compressorBON")) //key
{
compressorB_status_light.Fill = greyBrush;
compressorBkey = 1;
}
if (logicstring.StartsWith("compressorBoff")) //key
{
compressorB_status_light.Fill = redBrush;
compressorBkey = 0;
}
if (logicstring.StartsWith("compressorA on")) // actually compressor on
{
compressorA_status_light.Fill = greenBrush;
storyboard_compA_Led.RepeatBehavior = RepeatBehavior.Forever;
storyboard_compA_Led.Begin();
}
if (logicstring.StartsWith("compressorB on")) // actually compressor on
{
compressorB_status_light.Fill = greenBrush;
storyboard_compB_led.RepeatBehavior = RepeatBehavior.Forever;
storyboard_compB_led.Begin();
}
if (logicstring.StartsWith("compressor off")) // actually compressor off
{
if (compressorBkey == 1)
{
compressorB_status_light.Fill = greyBrush;
storyboard_compB_led.Stop();
}
if (compressorAkey == 1)
{
compressorA_status_light.Fill = greyBrush;
storyboard_compA_Led.Stop();
}
if (compressorBkey == 0)
{
compressorB_status_light.Fill = redBrush;
storyboard_compB_led.Stop();
}
if (compressorAkey == 0)
{
compressorA_status_light.Fill = redBrush;
storyboard_compA_Led.Stop();
}
}
if (logicstring.StartsWith("compressorA off")) // actually compressor off
{
compressorA_status_light.Fill = redBrush;
storyboard_compA_Led.Stop();
}
if (logicstring.StartsWith("compressorB off")) // actually compressor off
{
compressorB_status_light.Fill = redBrush;
storyboard_compB_led.Stop();
}
}
}
}
private async Task WriteAsync(string text2write)
{
Task<UInt32> storeAsyncTask;
if (text2write.Length != 0)
{
dataWriteObject.WriteString(text2write);
storeAsyncTask = dataWriteObject.StoreAsync().AsTask(); // Create a task object
UInt32 bytesWritten = await storeAsyncTask; // Launch the task and wait
if (bytesWritten > 0)
{
//txtStatus.Text = bytesWritten + " bytes written at " + DateTime.Now.ToString(System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat.LongTimePattern);
}
}
else { }
}
private async Task sendToPort(string sometext)
{
try
{
if (serialPort != null)
{
dataWriteObject = new DataWriter(serialPort.OutputStream);
await WriteAsync(sometext);
}
else { }
}
catch (Exception ex)
{
txtStatus.Text = ex.Message;
}
finally
{
if (dataWriteObject != null) // Cleanup once complete
{
dataWriteObject.DetachStream();
dataWriteObject = null;
}
}
}
private void CancelReadTask()
{
if (ReadCancellationTokenSource != null)
{
if (!ReadCancellationTokenSource.IsCancellationRequested)
{
ReadCancellationTokenSource.Cancel();
}
}
}
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
CancelReadTask();
if (serialPort != null)
{
serialPort.Dispose();
}
serialPort = null;
}
private async void init_Click(object sender, RoutedEventArgs e)
{
double sendtempvalue = (double)set_temperature.Value;
if (serialPort == null) return;
await sendToPort("settemp," + sendtempvalue);
//System.Diagnostics.Debug.WriteLine("EEPROM " + sendtempvalue);
}
private async void init_timing_Click(object sender, RoutedEventArgs e)
{
double switching_time_minute = (double)set_switching_time.Value;
if (serialPort == null) return;
await sendToPort("switch_interval," + switching_time_minute);
//System.Diagnostics.Debug.WriteLine("EEPROM " + switching_time_minute);
}
/*
private void Page_Unloaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
}*/
}
}
Question 1: How do I modify the code to not change the uint
ReadBufferLength = 1; and make the ReadAsync function store my serial
incoming data until it finds \r\n ?
Please try to use following code. When using ReadBufferLength = 1, the transmission efficiency will be lower.
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 128; // only when this buffer would be full next code would be executed
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken); // Create a task object
//string debug = dataReaderObject.ReadString(bytesRead2);
//System.Diagnostics.Debug.WriteLine("writing string debug"+ debug);
UInt32 bytesRead = await loadAsyncTask; // Launch the task and wait until buffer would be full
if (bytesRead > 0)
{
strFromPort = dataReaderObject.ReadString(bytesRead);
final_string = final_string + strFromPort;
//txtStatus2.Text = final_string;
if (final_string.Contains(Environment.NewLine))
{
string logicstring = final_string;
final_string = final_string.Substring(final_string.IndexOf(Environment.NewLine) + 1);
//System.Diagnostics.Debug.WriteLine("writing logic string " + logicstring);
}
}
}
Problem 2: after running it for 1 hour it will consume over 120
megabytes whereas it starts at 30-50 megabytes initially.
Please try to build the app in release but not using the .NET native toolchain.It's a known issue. Please see here.
Problem 3: Cannot build the app in release mode using the option
"Compile with .NET Native tool chain", without this it runs fine in
the raspberry.
Please remove the references runtime.win10-arm-aot.Microsoft.NETCore.UniversalWindowsPlatform and runtime.win10-arm.Microsoft.NETCore.UniversalWindowsPlatform in your project. The project will be compiled with .Net native tool chain successfully without the two libraries, since that these two libs depends on the native lib of System.Runtime.InteropServices.
I've made and application using WPF and I have to implement serial communication.
Bellow i have the DataReceived function.
The main problem is that the function triggers only sometimes, does anybody have a better solution to DataReceived trigger in WPF?
Below is the connection Connection to ComPort
public static void connnect(string recPort)
{
System.Windows.Threading.DispatcherTimer MyTimer = null;
bool error = false;
String serialpname = recPort;
ComPort = new SerialPort();
if (ComPort.IsOpen == false)
{
ComPort.PortName = serialpname;
ComPort.BaudRate = 38400;
ComPort.Parity = Parity.None;
ComPort.DataBits = 8;
ComPort.StopBits = StopBits.One;
ComPort.DataReceived += new SerialDataReceivedEventHandler(OnSerialDataReceived);
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
try
{
if (ComPort.IsOpen == false)
{
//Open Port
ComPort.Open();
dispatcherTimer.Start();
}
}
catch (System.IO.IOException) { error = true; }
}
}
Below is the timer that interogates the port
private static void dispatcherTimer_Tick(object sender, EventArgs e)
{
try
{
ComPort.Write(eot + "11" + STX + "2170" + ENQ); // get pos
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
The datareceived event
public static void OnSerialDataReceived(object sender,
SerialDataReceivedEventArgs args)
{
bool isString = true;
try
{
Thread.Sleep(100);// this solves the problem
byte[] readBuffer = new byte[ComPort.ReadBufferSize];
int readLen = ComPort.Read(readBuffer, 0, readBuffer.Length);
string readStr = string.Empty;
if (isString)
{
readStr = Encoding.Default.GetString(readBuffer, 0, readLen);
if(readStr.Length > 10)
{
if (readStr.StartsWith("\u0002"))
{
Position = (Mid(readStr, 2, 5));
Messenger.Default.Send("NewPos");
}
else
{
Position = (Mid(readStr, 31, 4));
Messenger.Default.Send("NewPos");
}
}
}
else
{
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < readLen; i++)
{
stringBuilder.Append(readBuffer[i].ToString("X2") + " ");
}
readStr = stringBuilder.ToString();
}
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
Console.WriteLine(ex);
}
}
Problem solved, i have added a Thread.Sleep(100); in the datareceived function. The buffer was not filled with the incoming data and seems that was the cause.
Thank you.
so I wrote a terminal in c# and I need to communicate with a kl25z microprocessor.
the application needs to support the option to choose the number of stop bits, the baud rate and the parity method.
I managed to sort it out with the baud rate but when I try to change the stop bits something goes out of sync and I cant figure out what.
the problem is that the uart is getting jibrish kind of chars instead of what I intended it to get, it does work well when I use one stop bit so I assume I just missed something in my code
I'll add the part of the code that gives me hard time:
this is only the c# part, my terminal I'm pretty sure that the problem is here
and not in the kl25z code
public Form1() {
InitializeComponent(); //init all variables
getAvailablePorts(); //fill the ports combo box with all the ports
}
void getAvailablePorts() {
String[] ports = SerialPort.GetPortNames(); //get the names of all availoable ports
comboBox1.Items.AddRange(ports); //add all the ports names to the combo box
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
try {
SerialPort sp = (SerialPort) sender;
if (serialPort1.IsOpen & sp.IsOpen) {
string indata = sp.ReadLine();
Invoke(new Action(() => textBox1.Text = indata));
if (indata.Equals("new settings been set") ||
indata.Equals("\0new settings been set") ||
indata.Equals("new settings been set??")) {
// baud rate
Invoke(new Action(() => baud = Convert.ToInt32(comboBox3.Text)));
Invoke(new Action(() => serialPort1.BaudRate = baud));
//end bits
Invoke(new Action(() => serialPort1.StopBits = end));
}
}
} catch (System.IO.IOException error) {
return;
} catch (System.InvalidOperationException error) {
return;
}
}
//here i open the port
private void button3_Click(object sender, EventArgs e) { //start port
try { // give the micro processor the info it needs about the settings
serialPort1.Handshake = Handshake.RequestToSendXOnXOff;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
serialPort1.PortName = comboBox1.Text; //port
serialPort1.BaudRate = baud; //baud rate current
// serialPort1.Parity= parity;//parity current
serialPort1.StopBits = end; //stopBits current
serialPort1.DataBits = bits; //current
//sort strings to send
String baudString = comboBox3.Text;
String StopString = comboBox6.Text;
String bitsString = comboBox2.Text;
String parityString = comboBox4.Text;
String startString = comboBox5.Text;
serialPort1.Open(); //open port
bitsString = "8";
//send properties to klz
serialPort1.Write("prop" + "$" + baudString + "$" + StopString + "$" + bitsString + "$" + parityString + "$" + startString + "$");
if (Convert.ToInt32(comboBox6.Text) == 1) {
end = StopBits.One;
} else {
end = StopBits.Two;
}
bits = Convert.ToInt32(comboBox2.Text);
} catch (UnauthorizedAccessException) {
textBox1.Text = "Unauthorized Access";
}
try {
progressBar1.Value = 100;
button1.Enabled = true;
button2.Enabled = true;
button3.Enabled = false;
button4.Enabled = true;
textBox2.Enabled = true;
} catch (UnauthorizedAccessException) {
textBox1.Text = "Unauthorized Access";
}
}
I am trying to On/Off a led from desktop app on C# to Arduino using Ethernet (for serial port communication works), I am connecting to an IP Address to communicate with Arduino, but it looks something wrong with my code or my sketch for Arduino. (I am working with Ethernet shield)
my code Arduino
//////////INCLUDE HEADER FILES //////////////////
#include <Ethernet.h>
#include <SPI.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <SD.h>
#include <Wire.h>
EthernetServer server(23 );
String content;
File myFile;
int ledPin = 7;
int outputpin = 0;
void setup()
{
IPAddress ip( 192, 168,1,110);
byte mac[] = {
0xDE,0xAE,0xBE,0xEF,0xFE,0xED
};
Ethernet.begin( mac, ip );
server.begin();
if ( ! SD.begin( 4 ) )
{
return;
}
Serial.begin(9600);
}
void loop()
{
waitIncommingConnection();
}
void waitIncommingConnection()
{
String pwd = "";
String inData = "";
EthernetClient client = server.available();
if ( client )
{
while ( client.connected() )
{
if ( client.available() > 0)
{
char recieved = client.read();
inData += recieved;
if (recieved == '\n')
{
switch( inData[0] )
{
case (char)'o' :
client.println("o");
digitalWrite(ledPin, HIGH);
break;
case (char)'f' :
client.println("f");
digitalWrite(ledPin, LOW);
break;
case (char)'*' :
Logout(client);
break;
default:
client.println('d');
break;
}
inData = "";
}
}
}
}
else
{
client.println('v');
}
}
void Logout(EthernetClient client )
{
client.print('x');
client.stop();
}
My C# code
public partial class Form1 : Form
{
public Client client;
public delegate void FeedBackCallback(string text);
public delegate void UpdateMessageBoxCallback(string text);
public Form1()
{
InitializeComponent();
}
private void connect_Click(object sender, EventArgs e)
{
string ipAddr = ip1.Text + "." + ip2.Text + "." + ip3.Text + "." + ip4.Text;
string port = portInput.Text;
if (IsValidIPAddress(ipAddr) == true)
{
try
{
if (client == null)
client = new Client(this);
client.Connect(ipAddr, port);
// client.Send(Encoding.GetEncoding(Constant.EncodingFormat).GetBytes("c"+'\n'));
disconect.Enabled = true;
connect.Enabled = false;
on.Enabled = true;
}
catch (SocketException se)
{
MessageBox.Show("Unable to Connect.\r\n" + se.ToString());
}
}
else
{
MessageBox.Show("Invaild Ip Adrress", "Invaild Ip Adrress", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private bool IsEmptyUserNamePasswordFields(string userName, string password)
{
if (userName.Length == 0 || password.Length == 0)
{
MessageBox.Show("Password and Username field is required!", "Required Fileds Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
else
{
return true;
}
}
private bool IsValidIPAddress(string ipaddr)//Validate the input IP address
{
try
{
IPAddress.Parse(ipaddr);
return true;
}
catch (Exception e)
{
return false;
}
}
private void on_Click(object sender, EventArgs e)
{
disconect.PerformClick();
connect.PerformClick();
try
{
if (client == null)
client = new Client(this);
client.Send(Encoding.GetEncoding(Constant.EncodingFormat).GetBytes("o" + '\n'));
off.Enabled = true;
on.Enabled = false;
}
catch (SocketException se)
{
MessageBox.Show("Unable to Connect.\r\n" + se.ToString());
}
}
private void off_Click(object sender, EventArgs e)
{
disconect.PerformClick();
connect.PerformClick();
try
{
if (client == null)
client = new Client(this);
client.Send(Encoding.GetEncoding(Constant.EncodingFormat).GetBytes("f" + '\n'));
on.Enabled = true;
off.Enabled = false;
}
catch (SocketException se)
{
MessageBox.Show("Unable to Connect.\r\n" + se.ToString());
}
}
private void disconect_Click(object sender, EventArgs e)
{
connect.Enabled = true;
disconect.Enabled = false;
client.Disconnect();
}
}
images for the Arduino
I don't know where is my problem, the app connect to the arduino, but the On/Off button not works for the led.
if u want to see the code foe serial port communication this is the link here, Serial Port
I have a application where I switched out the communication from TCPClient to using SocketAsyncEventArgs, but I do have a problem that occures when the application been running for a few hours, and I cant seem to find it. Here is my Stack Trace, anyone got an idea?:
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.OutOfMemoryException
Stack:
at System.Threading.ThreadPoolWorkQueue.Enqueue(System.Threading.IThreadPoolWorkItem, Boolean)
at System.Threading.ThreadPool.QueueUserWorkItemHelper(System.Threading.WaitCallback, System.Object, System.Threading.StackCrawlMark ByRef, Boolean)
at System.Threading.ThreadPool.QueueUserWorkItem(System.Threading.WaitCallback, System.Object)
at System.IO.Ports.SerialStream+EventLoopRunner.CallEvents(Int32)
at System.IO.Ports.SerialStream+EventLoopRunner.WaitForCommEvent()
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
Code:
public Client(Form1 parent)
{
todo = new ArrayList();
buffert = new List<MsgStruct>();
this.parent = parent;
this.ip = ini.GetFromIni("CONFIG", "IP");
this.port = ini.GetFromIni("CONFIG", "PORT");
data = new byte[100000];
// Addres of the host.
IPAddress[] addressList = host.AddressList;
// Instantiates the endpoint and socket.
this.hostEndPoint = new IPEndPoint(addressList[addressList.Length - 1], Convert.ToInt32(port));
this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
startTimer = new System.Timers.Timer();
startTimer.Elapsed += new ElapsedEventHandler(startSendLoop);
startTimer.Interval = 1000;
startTimer.Start();
sendTimer = new System.Timers.Timer();
sendTimer.Elapsed += new ElapsedEventHandler(sendloop);
sendTimer.Interval = 500;
sendTimer.Start();
pingTimer = new System.Timers.Timer();
pingTimer.Elapsed += new ElapsedEventHandler(pingTimer_Elapsed);
pingTimer.Interval = 13000;
pingTimer.Start();
}
internal void Disconnect()
{
try
{
clientSocket.Disconnect(true);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.ToString());
MessageBox.Show(e.ToString());
}
}
public void Dispose()
{
try
{
autoConnectEvent.Close();
autoSendReceiveEvents[SendOperation].Close();
autoSendReceiveEvents[ReceiveOperation].Close();
if (this.clientSocket.Connected)
{
this.clientSocket.Close();
}
}
catch (Exception ex)
{
}
}
public void pingTimer_Elapsed(object sender, ElapsedEventArgs e)
{
sendPing = true;
}
public void startSendLoop(object sender, ElapsedEventArgs e)
{
try
{
if (!this.clientSocket.Connected)
{
connectArgs = new SocketAsyncEventArgs();
connectArgs.UserToken = this.clientSocket;
connectArgs.RemoteEndPoint = this.hostEndPoint;
connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
clientSocket.ConnectAsync(connectArgs);
bool test = autoConnectEvent.WaitOne(5000);
gotData = true;
lastTime = DateTime.Now;
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
private void ProcessError(SocketAsyncEventArgs e)
{
Socket s = e.UserToken as Socket;
if (s.Connected)
{
// close the socket associated with the client
try
{
s.Shutdown(SocketShutdown.Both);
}
catch (Exception)
{
// throws if client process has already closed
}
finally
{
if (s.Connected)
{
s.Close();
}
}
}
}
private void OnConnect(object sender, SocketAsyncEventArgs e)
{
try
{
autoConnectEvent.Set();
// Set the flag for socket connected.
this.connected = (e.SocketError == SocketError.Success);
}
catch (Exception ex)
{
}
}
private void OnReceive(object sender, SocketAsyncEventArgs e)
{
try
{
while (true)
{
if (canReceive)
{
canReceive = false;
string stringData;
int recv = 0;
for (int i = 0; i < e.Buffer.Length; i++)
{
if (e.Buffer[i] != 0)
recv++;
else
break;
}
if (recv > 0)
{
int count = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] != 0)
count++;
else
break;
}
e.Buffer.CopyTo(data, count);
lastTime = DateTime.Now;
gotData = true;
if ((byte)data[count + recv - 1] == (byte)255)
{
int cnt = -1;
for (int i = 0; i < count + recv; i++)
{
if (data[i] == (byte)254)
{
cnt = i;
break;
}
}
int nr = (count + recv) - cnt - 2;
byte[] tmp = new byte[nr];
for (int i = 0; i < nr; i++)
{
tmp[i] = data[cnt + i + 1];
}
string crc = Encoding.UTF8.GetString(tmp);
stringData = Encoding.UTF8.GetString(data, 0, cnt);
MsgStruct msgs = new MsgStruct(stringData);
msgs.setCrc(crc);
todo.Add(msgs);
data = new byte[100000];
}
}
canReceive = true;
break;
}
else
Thread.Sleep(10);
}
handleToDo();
autoSendReceiveEvents[SendOperation].Set();
e.Dispose();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
private void OnSend(object sender, SocketAsyncEventArgs e)
{
try
{
// Signals the end of send.
sendSuccess = true;
autoSendReceiveEvents[ReceiveOperation].Set();
if (e.SocketError == SocketError.Success)
{
if (e.LastOperation == SocketAsyncOperation.Send)
{
// Prepare receiving.
Socket s = e.UserToken as Socket;
byte[] receiveBuffer = new byte[100000];
e.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
e.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
s.ReceiveAsync(e);
}
}
else
{
this.ProcessError(e);
}
}
catch (Exception ex)
{
}
}
public void sendloop(object sender, ElapsedEventArgs e)
{
try
{
sendTimer.Enabled = false;
if (this.clientSocket.Connected)
{
byte[] data = new byte[1024];
bool extendedTime = false;
DateTime tmpDate = lastTime.AddSeconds(30);
if (DateTime.Now > tmpDate)
{
gotData = false;
}
if (canUseBuffert && sendSuccess)
{
canUseBuffert = false;
if (buffert.Count > 0)
{
if (buffert[0] != null && buffert[0].getMsg().Length != 0)
{
byte[] ba = Encoding.UTF8.GetBytes(buffert[0].getMsg());
if (buffert[0].getCrc() == "")
{
ulong tmp = CRC.calc_crc(ba, ba.Length);
buffert[0].setCrc(tmp.ToString("X"));
}
if (buffert[0].canSendByTimeout())
{
string crcStr = "?" + buffert[0].getCrc() + "?";
byte[] bb = Encoding.UTF8.GetBytes(crcStr);
crcStr = Encoding.UTF8.GetString(bb);
byte[] fullMsg = new byte[ba.Length + bb.Length];
bb[0] = 254;
bb[bb.Length - 1] = 255;
ba.CopyTo(fullMsg, 0);
bb.CopyTo(fullMsg, ba.Length);
string s = System.Text.UTF8Encoding.ASCII.GetString(fullMsg);
this.clientSocket.NoDelay = false;
completeArgs = new SocketAsyncEventArgs();
completeArgs.SetBuffer(fullMsg, 0, fullMsg.Length);
completeArgs.UserToken = this.clientSocket;
completeArgs.RemoteEndPoint = this.hostEndPoint;
completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
sendSuccess = false;
// Start sending asyncronally.
clientSocket.SendAsync(completeArgs);
}
}
}
else
{
extendedTime = true;
byte[] bba = Encoding.UTF8.GetBytes("X");
this.clientSocket.NoDelay = true;
completeArgs = new SocketAsyncEventArgs();
completeArgs.SetBuffer(bba, 0, bba.Length);
completeArgs.UserToken = this.clientSocket;
completeArgs.RemoteEndPoint = this.hostEndPoint;
completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
sendSuccess = false;
// Start sending asyncronally.
clientSocket.SendAsync(completeArgs);
}
}
canUseBuffert = true;
if (!clientSocket.Connected && !gotData)
Disconnect();
}
sendTimer.Enabled = true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
sendTimer.Enabled = true;
}
}
I would have a serious look at the data = new byte[100000]; calls in your communication routines. Because it is larger than 85KB (85,000 bytes to be exact) memory blocks you're filling up (and fragmenting) your LOH. This can cause OutOfMemoryException issues. See this link