|
You already have this posted in QA: don't post the same question in two places - all you will do is duplicate work and annoy people. Pick either the C# forum or the Q&A and stick with it.
Annoyed people are less likely to be helpful than happy ones...
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Yea, the following code was one of the examples I tried:
if (e.KeyCode == Keys.F1 && (e.Alt || e.Control || e.Shift))
{
}
It is from the source you mentioned, but i does not work.
Compiler says that
KeyEventArgs does not contain a definition for Alt etc.
Also there is no suggestion of how to fix it.
These are my usings:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Windows.Forms;
|
|
|
|
|
That's because they don't generate keycodes: ALT on it's own does nothing, it needs a keystroke to make it useful - ALT+F2, CTRL+F4 for example.
They are MODIFIER keys[^].
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Hello I'm using this code from microsoft example but the information that I show from the red of the serial port is printed in ASCII, and I would like see in Mathlab.
Please could you help me.
THis is the code:
using System;
using System.IO.Ports;
class PortDataReceived
{
public static void Main()
{
SerialPort mySerialPort = new SerialPort("COM3");
mySerialPort.BaudRate = 56000;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:" );
Console.Write(indata);
}
}
|
|
|
|
|
Please give an example of the data you are receiving, as well as samples of the data you want instead.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
JData Received:
Data Received:
?Data Received:
?@Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
LData Received:
Data Received:
?Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
Data Received:
OData Received:
Data Received:
?
|
|
|
|
|
Victor Gonzalez 2024 wrote: string indata = sp.ReadExisting();
Absolutely no way that could be anything except a string. The encoding depends on various things but what is absolutely true is that binary data should not be accessed in that manner.
Binary data is not string data.
Victor Gonzalez 2024 wrote: and I would like see in Mathlab.
Binary data means you need to treat it like binary data.
Other than that if you are in fact reading data at all then either it is correct or the other end is sending it wrong (so nothing to do with your code.)
|
|
|
|
|
Then, how can I read binary data using c# code?
|
|
|
|
|
Victor Gonzalez 2024 wrote: how can I read binary data using c# code? That is not the right question to be asking. You are trying to get some information from a device attached to the serial port. So the first thing you need to do is to find out what form that information is presented in. If it is a sequence of ASCII characters then simple reads will do it. If it is variable length binary data then you need to read as a sequence of bytes which then need to be re-assembled into the correct form to match the sender. So you need to get that information before you can do anything else.
|
|
|
|
|
Hi Richard,
Thanks for you reply. I stand that you told me and I going to try to explai better.
I downloaded a third software that read information from the serial com, for example (open serial port monitor or serial port monitor). This sofware when I open the conection to the com port, start to read the information and print this information in the monitor.
The information that is printed, is in 3 type of data:
1st format:
à.....L.±......
...(.ëà.....L>¡
.........V.ëà..
...L.¢.........
..ëà.....L.£...
........ëà.....
L.§...........ë
2nd format:
e0 08 15 03 00 04 4c 00 b1 01 00 06 00 00 00
00 00 00 28 00 eb e0 09 15 03 00 04 4c 3e a1
00 06 00 00 00 00 00 00 00 56 00 eb e0 0a 15
03 00 04 4c 00 a2 00 00 00 00 00 00 00 00 00
14 00 eb e0 0b 15 03 00 04 4c 00 a3 00 00 00
00 00 00 00 00 00 16 00 eb e0 0c 15 03 00 04
4c 00 a7 00 00 00 00 00 00 00 00 00 1b 00 eb
3th format:
?
This 3 format that i copied, are the same information, but in different condification.
Then replying you "question": yes ,the device sent the information in different codification.
Then I would like to know how can I do for get the information in byte format, (2nd format of my example), because this information is the information that I need read and then work whit this.
I hope explained better.
Thanks!!
|
|
|
|
|
Victor Gonzalez 2024 wrote: the device sent the information in different codification. No, the device sends some information as a stream of bytes. The three different outputs are just your code printing it in different forms.
But my original response stands: the device (whatever that is) is sending some binary data. But you still need to find out what format that data is in. That is not something anyone here can do for you, as we have no idea what that device is or what information it provides.
|
|
|
|
|
Hi,
1.
to read binary data use the method SerialPort.Read(Byte[], Int32, Int32)[^]
2.
I seldom use the DataReceived event as it is the source of a number of problems. I'd rather use a separate thread (or a BackGroundWorker) that periodically calls a Read method.
3.
I am puzzled by the fact that your second data format shows 15 bytes per line, not 16 as is usual.
4.
I noticed your data seems to have a periodicity of 21 bytes; when reformatted it looks like this:
e0 08 15 03 00 04 4c 00 b1 01 00 06 00 00 00 00 00 00 28 00 eb
e0 09 15 03 00 04 4c 3e a1 00 06 00 00 00 00 00 00 00 56 00 eb
e0 0a 15 03 00 04 4c 00 a2 00 00 00 00 00 00 00 00 00 14 00 eb
e0 0b 15 03 00 04 4c 00 a3 00 00 00 00 00 00 00 00 00 16 00 eb
e0 0c 15 03 00 04 4c 00 a7 00 00 00 00 00 00 00 00 00 1b 00 eb
Hope this helps.
Luc Pattyn [My Articles]
The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.
|
|
|
|
|
Hello all,
Yes periodicaly the data sended is 21 byte, but some times send 63 or 42 bytes.
I think that I found the solution and now I can red the data in decimanl and later I transofrm to "X".
Now I have another problem. When I start the program with out break point for debug, when I read the information i write to the screen, but this write not found, but if I put a break point and debug the progam, yes is writing the messages in the screen.
this is my code.
using System;
using System.IO.Ports;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
class PortDataReceived
{
public static void Main()
{
SerialPort mySerialPort = new SerialPort("COM3");
mySerialPort.BaudRate = 56000;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
int count = sp.BytesToRead;
int count2 = 0;
byte[] data = new byte[count];
sp.Read(data, 0, data.Length);
switch (data.Length)
{
case 63:
Console.WriteLine("inicio carrera o pause off");
if (data[7].ToString("X").Equals("0") && data[8].ToString("X").Equals("A6"))
{
Console.WriteLine("pause off");
}
else
{
if (data[7].ToString("X").Equals("3E") && data[8].ToString("X").Equals("A1"))
{
Console.WriteLine("carrera go!");
}
}
break;
case 21:
if (data[7].ToString("X").Equals("1B") && data[8].ToString("X").Equals("A9"))
{
Console.WriteLine("contador vuelta y tiempo");
}
else
{
if (data[7].ToString("X").Equals("0") && data[8].ToString("X").Equals("A5"))
{
Console.WriteLine("pause on");
}
else
{
if (data[7].ToString("X").Equals("0") && data[8].ToString("X").Equals("A7"))
Console.WriteLine("stop forzado");
}
}
break ;
case 42:
Console.WriteLine(" fin carril");
break ;
}
sp.DiscardInBuffer();
}
|
|
|
|
|
Suggestions:
1.
don't use ToString("X"), use ToString("X2") instead, so you always get two characters
2.
don't use ToString at all, you can simply replace
data[8].ToString("X").Equals("A9") by
data[8]==0xA9
3. be warned, the DataReceived handler executes on a different thread and therefore cannot access GUI Controls directly. See for instance Invalid cross-thread operations[^]
Luc Pattyn [My Articles]
The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.
|
|
|
|
|
Hi Luc Thanks!!
About my problem of the printing data, I detected that is because the program "it's more speed" than the reading of the COM port. I fixed temporaly using a sleep of 5 seconds, but I have another question.
This hardware have some sensors (now 2) and send information from the COM port, and if I "active" these two sensors at the same time, I receive the data in the same time and it's to difficult manipulate the data.
Could you help me to try to find a solution about these topic?
Thanks!!
|
|
|
|
|
Your problem description is way too vague to get useful suggestions.
A couple of points:
1. why are you calling sp.DiscardInBuffer() ?
all the data that you get by executing Read operations is removed from the serial stream automatically, however if any data comes in while your handler is running will be thrown away, more specifically anything that comes in after sp.BytesToRead is not read and discarded.
2. you are ignoring the return value of sp.Read().
this method will not always return the number of bytes requested: when fewer are available, fewer will be returned!
3. you should not switch on the number of bytes read, as sp.BytesToRead may return just any value: it could be as low as 3, or as high as 300, all depending on what your peripheral is sending and how fast Windows is dealing with it.
4. you need to see the incoming data as chunks of one big stream, and provide code to detect the messages in that stream, then act on them. A serial port does not care about messages, it just sends bytes; so a DataReceived handler might get only half a message, or several messages, or ...
5. serial ports (and all interfaces to external devices) may temporarily fail, e.g. loose a few bytes; to get a reliable program your code must be capable of surviving such mishaps.
6. as I mentioned before, I would avoid DataReceived; collecting the incoming data, discovering the messages in the stream, and acting on them is way easier in a dedicated thread.
If you want someone to help, you need to provide lots of very specific information, such as:
1. description of the application. What is it about, is this a commercial peripheral (make & type), is the peripheral's software fixed?
2. is there a document that describes the protocol your peripheral is using on its serial port?
3. how often will a message be sent?
4. is there a master-slave relationship? i.e. send one command to get one response? that would be easy.
or is the peripheral free to send whatever and whenever it likes to do so?
etc.
All this info is needed to come up with a reliable approach.
Luc Pattyn [My Articles]
The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.
|
|
|
|
|
Hi Luc,
You are in the right, I'm wasn't clear and specific.
Hardware that I'm working:
DS-300 Electronic Racing Products.
photo of the product
specifications that I found
This hardware is an a scalextric race control. ( start, pause, stop, laps by slot, time of lap...). slot 1 have 1 sensor and slot 2 have another sensor, and when one of this sensors are actitated, the DS-300 sent the information since the COM PORT.
I checked and this is the information that send:
for example when I push start race I recevied this data:
e0 59 15 03 00 04 4c 3e a1 00 06 00 00 00 00 00 00 00 a6 00 eb
e0 5f 15 03 00 04 4c 00 a2 00 00 00 00 00 00 00 00 00 69 00 eb
e0 60 15 03 00 04 4c 00 a3 00 00 00 00 00 00 00 00 00 6b 00 eb
63 bytes:
byte 8 and 9 indicates that I pushed start.
byte 10 and 11 indicates the counter time, for example 6 minuts of race.
byte 12 and 13 --> number of lap
byte 15,16,17,18 --> time spend of complete the lap.
byte 20 and 21 --> ever the same 00 eb.
this is an example of data for 1 lap.
e0 60 15 03 00 04 4c 00 a3 00 00 00 00 00 00 00 00 00 6b 00 eb
21 byte:
byte 8 and 9 indicates that sensor of lap.
byte 10 and 11 indicates the slot 1 or 2.
byte 12 and 13 --> number of lap
byte 15,16,17,18 --> time spend of complete the lap.
byte 20 and 21 --> ever the same 00 eb.
This is when I force the stop of the race:
e0 61 15 03 00 04 4c 00 a7 00 00 00 00 00 00 00 00 00 70 00 eb
21 byte:
byte 8 and 9 indicates that I pushed start.
byte 10 and 11 indicates the counter time, for example 6 minuts of race.
byte 12 and 13 --> number of lap
byte 15,16,17,18 --> time spend of complete the lap.
byte 20 and 21 --> ever the same 00 eb.
this is the pause on:
e0 6d 15 03 00 04 4c 00 a5 00 00 00 00 00 00 00 00 00 7a 00 eb
21 byte:
byte 8 and 9 indicates that I pushed pause on.
byte 20 and 21 --> ever the same 00 eb.
pause off:
e0 6e 15 03 00 04 4c 00 a6 00 00 00 00 00 00 00 00 00 7c 00 eb
e0 6f 15 03 00 04 4c 00 a2 00 00 00 00 00 00 00 00 00 79 00 eb
e0 70 15 03 00 04 4c 00 a3 00 00 00 00 00 00 00 00 00 7b 00 eb
63 bytes:
byte 8 and 9 indicates that I pushed pause off.
byte 20 and 21 --> ever the same 00 eb.
finish time and finish the race:
e0 02 15 03 00 04 4c 00 c0 00 00 00 00 00 01 00 00 00 2b 00 eb
eb 03 15 03 00 04 4c 00 a4 00 00 00 00 00 00 00 00 00 0f 00 eb
42 bytes
byte 8 and 9 indicates that the race is finished.
byte 20 and 21 --> ever the same 00 eb.
What I would like:
I would like do a software that show all this data for the pilos are playing, because it's very important know how many laps are you having, the time of lap, etc...
I hope be clear and give you mor information.
Thanks in advance.
REgards
|
|
|
|
|
OK, so message traffic would be pretty low, and problems with the serial communication are rather unlikely. This is my first attempt (not tested!), it does NOT include communication recovery, that is: if something goes wrong (say a serial byte gets lost), it will continue to fail.
using System;
using System.IO.Ports;
using System.Threading;
namespace ConsoleApp1 {
class PortDataReceived {
private static SerialPort sp;
private const string PORTNAME = "COM3";
private const int MSGLEN = 21;
public static void Main(string[] args) {
sp = openPort();
Console.WriteLine("Press any key to terminate...");
Console.ReadKey();
if (sp!=null) sp.Close();
}
private static SerialPort openPort() {
try {
SerialPort port = new SerialPort(PORTNAME);
port.BaudRate = 56000;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.DataBits = 8;
port.Handshake = Handshake.None;
port.RtsEnable = true;
port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
port.Open();
output("serial port " + PORTNAME + "opened");
return port;
} catch(Exception exc) {
reportError("Error opening serial port (" + exc.Message + ")");
return null;
}
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
byte[] message = new byte[MSGLEN];
while (true) {
int count = sp.BytesToRead;
if (count == 0) return;
if (count >= MSGLEN) {
int got=sp.Read(message, 0, MSGLEN);
if (got == MSGLEN) {
processMessage(message);
} else {
reportError("Insufficient data bytes in DataReceivedHandler");
}
} else {
Thread.Sleep(100);
}
}
}
private static void processMessage(byte[] bb) {
int count = bb.Length;
string s = "Got message: (len="+count.ToString()+"): ";
foreach (byte b in bb) {
s += b.ToString("X2") + " ";
}
string comment = " ?";
if (count != MSGLEN) comment = " *** ERROR *** Bad length";
else if (bb[0] != 0xE0) comment = " *** ERROR *** Bad first byte";
else if (bb[8] == 0xA5 && bb[9] == 0x00) comment = " = Pause on";
else if (bb[8] == 0xA6 && bb[9] == 0x00) comment = " = Pause off";
output(s + comment);
}
private static void reportError(string message) {
output("Error: "+message);
}
private static void output(string text) {
Console.WriteLine(text);
}
}
}
I expect the above DataReceivedHandler method is OK, you would have to extend or replace the processMessage() method.
Luc Pattyn [My Articles]
The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.
|
|
|
|
|
Hi
I'm did a little test with you code and seems that is working fine, get the data and write the data like as we want.
During these days I'm goint to trying the code and I let you know.
Thanks a lot of you help.
Regards!!
|
|
|
|
|
you're welcome.
Luc Pattyn [My Articles]
The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.
|
|
|
|
|
Has anyone been successful at attaching the Visual Studio remote debugger to any process in the Windows Sandbox VM?
I set my Debug Launch profile to start the application on a remote machine, and it successfully connects to the remote debugger process in the Sandbox, but when it tries to launch the application as configured in the launch profile, it says "Unable to start process <PATH to exe>".
The problem is that the path that it says it's trying to start is the path on my local machine, and not the path I have configured inside the launch profile to start on the remote machine.
Has anyone figured this out?
EDIT: I just realized that this problem is not only with the Sandbox VM, but with any VM on my machine.
The difficult we do right away...
...the impossible takes slightly longer.
modified 5-Apr-24 18:05pm.
|
|
|
|
|
I am attempting to write a short program in C# that deals with resistances (in electronics). I would like to be able to parse string values into floating point values. The string can be in the format like 100, 4.7K, 2.2M, or shorthand equivalents like 100, 4K7, 2M2. They should never have more than 3 digits, at least one of which is a whole number part (no more than 2 decimals). Also I would like to be able to display them in similar formats. I've looked into MS documentation, and I'm more confused than ever. When do I need to use (if at all) IFormatProvider, ICustomFormatter, IFormattable, IParsable, etc. I've gone 'round and 'round, and I'm thoroughly at sea. I'm not a new programmer, just a retired one. I wrote code for about 30 years in everything from COBOL to VB.NET (including some C and C++). I don't need someone to write the code for me, but any hints would be much appreciated.
|
|
|
|
|
Hah been there done that one - try parsing Murex input. We had to build up a set of patterns to test the input against, it took ages to nail the bulk of the patterns that traders would enter as values and they were not limited to 3 characters.
Test each entry against your pattern list, use any found pattern to parse the values, throw an error if no match is found (and add it to your pattern list).
Oh and forget the existing tools as this falls way outside their design specs.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
You mean don't use any of those interfaces, just parse them myself? I'm already kinda of doing that, but I was hoping going the interface method might be more flexible.
|
|
|
|
|
I would also write my own Parser because the rules for this are clear. I'm not sure if I would try against a list because there are not much points to test against :
- 1st I would search for the multiplier (if there is one) - m for 0.001, k for 1000 and M for 1000000
- then I would test the value before the multiplier (if there is one)
- last I would look, if you have a multiplier if there is a value after it
-> now build you output-value
|
|
|
|
|