I have a device connected to my computer that sends serial data to the computer every 5 mins. I want to write a basic program to capture this serial data every 5 mins and put it into a database. I was hoping to use C# because I have used C# with databases before and found it quite easy.
Can anybody offer me any advice on how I might do this, I really have no idea where to start and I know in theory it sounds easy but when I started it I actually found it really hard.
Using C#, you can use the System.IO.Ports namespace to communicate over the serial ports - there's a nice article here.
Alternatively, you can use Python and the pySerial module. I've written an app to communicate over the serial port using pySerial - it's quite easy to use, and can run on many different operating systems including OSX and Windows (I'm assuming you're using Windows). Python also has built-in support for SQLite.
The problem with capturing data on a serial port is that serial ports aren't thread-safe, so if there is more than one listener, data will be corrupted.
If you are absolutely sure that you're the only one listening for data on this port, .NET has a built-in wrapper, System.IO.Ports.SerialPort, which you can use to connect to COM1, COM2, etc. You'll need to know the rate in bits/sec at which this device sends data (its baud rate), its error-checking (parity) protocol, and the format of the data it is sending (you'll get it as a byte array, which you must convert byte-by-byte into data you can work with). Then, your program should be able to open the port and listen for DataReceived events with a handler that will read and digest the data. Again, it's VERY important that you never have two threads trying to read at once; the easiest way is to set a volatile boolean indicating that a handler is reading data; if another handler is ever spawned while a previous one is still running, the first thing the new one should do is read that value, and since it's set, exit the new handler immediately.
Related
I'm looking for a way to detect when COM device is plugged into PC. I'm not limited to .NET but final application is written in .NET.
Best option would be to connect to some event, if exists.
But in reality I can even list all devices in a loop.
Checking for new devices in a loop is acceptable as a delay of few seconds is not a real problem and application does it only one in a whole lifetime.
I can read this question 2 different ways:
1. How to I detect when a USB->Serial adapter has been inserted.
In this case you could do SerialPort.GetPortNames in a loop and see when that changes
2. How do I detect when I'm connected to a device through my serial port.
There is no surefire way to be able to determine when something is connected to the com port without sending data. There are some additional pins that are meant to be used in this way, but it really depends on the cabling involved. See this post for more details on the types of cables, benefits, and drawbacks.
If you can guarantee the pinout of the cable and that the device you're connecting sets DTR high, then this may be a viable approach.
If not, then you may have to poll each com port and send some data and see if you get any response.
I am using the C# Serial port library for communicating with a sensor and PC .
I am frequently getting timeouts with the SerialPort.Read() method even though there is data in there. I used serial sniffers to check that I am receiving all the packet at the port but some how .NET does not pick all of them and times out. I am reading bytes and the bytes I am receiving is 2112 less than the serial port buffer size. I tried multiple things and now thinking of using native C/C++ and calling it in C#. Can someone share more thoughts or used native C/C++ code in C#.
running at baud rates 460800 to 921600
Those are pretty strange baud rates, rather high. Clearly you are not using the DataReceived event so it gets rather critical how often you call the Read() method. Take some time off doing something else, including Windows thinking that something more important needs to be done and context-switches away from your thread, and the receive buffer will quickly overflow. Not implementing the SerialPort.ErrorReceived event is a standard mistake so you just don't see those overflows, all you see is missing data.
Writing this code in C++ is very unlikely to bring relieve. There's only one api for serial ports, SerialPort is just a thin wrapper and uses the winapi functions like your C++ code would.
So take all of the following steps:
Implement the ErrorReceived event so you know that overflows occur
Favor using the DataReceived event so you don't depend on calling Read() frequently enough
Set the ReadBufferSize to a nice big number so the driver can take up the slack
Set the Handshake property so the driver can tell the device to stop sending when the buffer is full
Check if you can implement a protocol so the device doesn't just fire-hose the machine
Lower the baud rate if it still isn't reliable enough.
I'm developing a solution to send data from a microcontroller with a GPRS modem ( server) to my application in the computer ( the one client) over a TCP/IP connection.
I designed first my application working with a serial port connection (to go step-by-step that was easier) and now I have to adapt it in order to receive from a socket instead of serial port, which I'm totally new in and I thought it would be more straight.
I've been reading for days and I didn't get anything clear. Most of the solutions I see work just to send and receive a single packet, or are too complicated.
My server is going to be sending packets every second and the client has to read them and then analyze them.
I want something like this:
this.serialPort.DataReceived += new SerialDataReceivedEventHandler(this.routineRx);
But for NetworkStream. Something that wakes up the reading process ( RoutineRx) when there's something to read.
Maybe I have to change my mind and forgetting about this kind of stuff. I'm trying to make the most of my old code.
Maybe I'm asking something that has been asked many times before, but I really didn't find it. If so,sorry.
There is no DataReceived event for a NetworkStream. You can use the DataAvailable property to determine when there is data read for you to read, and use Read to read that data.
There are indeed many examples of reading/writing TCP data in c#. It's different from reading serial port data, and you may have to rethink your design somewhat.
I've been looking into using TCP to send a message over the network.
My current situation is that I have multiple instances of a single application running on a computer. I want to send out a single TCP message and let all the applications receive the message and act upon it.
All I've been able to find examples where there was 1 sender and 1 receiver. I wan't to just send a TCP message up into the network and let all the listening application receive the same message.
I've tried to use this guide but it does not seem to work with multiple receivers either.
Can anyone point me into the right direction to a guide that does what I described here above or maybe post some example?
EDIT: All I am trying to sends is a string of 10 characters, maybe there is also another way to send/receive something like that?
You can use Shared Memory in C# to implement your requirement.
Let me explain a simple solution:
Ex:
Create a mapped file (with a specific name, say "XXX"),
It will create an array in bytes in memory,
Set the first byte is zero (0) or value something that you can define your own. (this byte will determine incoming message)
If one application wants to send message to others:
Write data (converted to bytes array using UTF-8 or any encoding) to memory array from the third element (index = 2)
Set the first byte (index =0) is 1
Set second byte to a random value (why do I use this byte? I will explain below.)
On the receiving side, they also open mapped file with the same name "XXX"
They need to trigger on first byte to detect incoming message. You can use Timer (with interval can be 500 miliseconds) to check that byte
If first byte is 1 -> it has incoming message, then read data from third element (from index 2)
You can now receive messages from other applications, but there is a small problem:
in the next trigger, the application still continues treating it like there is a new incoming message.
So at this time, you need to read value of second (randomised) byte and store it as a backup for comparison in next trigger.
That is a real new incoming message if backup id is not equal to new id
Hope this explains how you can solve the problem
Probably dumb but simple and possible.. and when abstracted through a clean interface probably a good start: choose a shared directory for the applications, write files containing the messages into this directory and use a FileWatcher to listen for changes in the directory.
Once your applications needs rise, replace the interfaces implementation with one that uses MSMQ or something similarly enterprisey.
Another simple solution would be shared memory / memory mapped files. The API is included in the .NET framework since v4. You'll have to manually do the read/write synchronization though.
Are these GUI applications? If yes, you could use SendMessage or PostMessage with a destination of HWND_BROADCAST. (although this will only let you send a pair of numbers, not a "string")
More complex, but designed exactly for this purpose, is a mailslot.
Mailslots, on the other hand, are a simple way for a process to broadcast messages to multiple processes
If you want to send message to all application instances, you may look at SignalR.
There are several posts that do introduce this framework:
Asynchronous scalable web applications with real-time persistent long-running connections with SignalR
Tutorial: Getting Started with SignalR (C#)
ASP.NET MVC 3 Real Time Collaborative Apps with SignalR
I am trying to send over image data from a compiled C++ process to a compiled C# process. The C++ process is accessing the webcam and doing some processing on the image. The image is represented by an 2D array of pixels with each pixel value being an 8 bit value (0-255) which is the gray-scale value of that pixel.
The image size is 640 by 480.
The C# application does some more processing and displays this image onto the screen. The processes are both running at the same time on my laptop (Windows 7 OS) but I cannot make a single process that does all the steps which is why I need my C++ and C# code to communicate.
I was wondering what is the best way to do this? I read about writing a UDP or TCP server in the C# part and a client on the C++ part, I can then send over the image data as a datagram. I was wondering if this is the best way and if it is whether UDP or TCP would be better?
EDIT: The C++ process is unmanaged C++, I don't have the option to run it as a managed DLL. Could I use named pipes to send over the image?
Finally is UDP guaranteed in order if it is communicating locally? I realise the image would be over the limit for UDP but if it is inorder I should be able to split the images up to send over.
Interprocess communication can be done via sockets or pipes.
With sockets(TCP and UDP) you're essentially sending the data over the internet to yourself. Luckily since your comp knows itself, the data shouldn't leave the comp so this should be pretty quick. TCP is guaranteed to be in order and has a bunch of other nice features while UDP is pretty much slap some headers onto the data and hope for the best. For this application TCP should be fine. UDP adds unneeded complexity.
Pipes are the other way to have two processes to communicate. You basically have the C++ or C# process create a pipe and start the other process. You just use the pipe like a file: write to and read from it. This can be done in C/C++ using a combination of the pipe, fork, and exec functions or simply using the popen function. C# probably has similar functions.
I suggest using a pipe using _popen, (popen for windows) and writing a series of ints to the pipe and reading it from the other side. This is probably the easiest way... besides using one language of course...
If you are writing both of the programs, you can compile C++ one as DLL, and call function that returns an array or some structure from your C# program with DllImport Attribute in System.Runtime.InteropServices namespace.
Why can't you do it in the same process? Is it because you need to mix C# and C++? In that case C++/CLI can be used as a bridge between the environments to have both C# code for the .NET CLR and C++ code compiled natively in one process.
If you really need two processes there are several options when running on a local machine, but a small TCP-based service is probably best. The size of each image will be 307kb which is larger than the 65kb limit of UDP.
I was wondering if this is the best way and if it is whether UDP or TCP would be better?
You usually resort to UDP as a speed optimization when TCP is not fast enough and packet loss is inconvenient rather than when it can't be handled. If you can't handle losing part of the image in the transmission I doubt you can resort to UDP.
Moreover, UDP is unlikely to give a performance boost in your case since you'll be using the loopback interface. This means that all TCP packets are likely to arrive in order and without loss, making TCP extra cheap.
If you write your application using TCP and in the future, for some reason, you decide the processes no longer run on the same machine, you won't have to change your code.
Finally, TCP sockets are just easier to use, so unless TCP is not fast enough on your machine, I would stick with TCP sockets.
is UDP guaranteed in order if it is communicating locally?
AFAIK, this behavior is not guaranteed. It is very likely to work most of the time, but unless you can find a quote from relevant documentation, I wouldn't count on this.
Could I use named pipes to send over the image?
Yes, named pipes are very similar to sockets, but they're known to be slow.
Once way of doing it apart from sockets would be to save the image data onto the disk from your C++ application and read it off the disk in your C# application. Of course you will need to make sure some sort of read/write synchronisation so that the file is not read before its fully written.
Or you finally decide to use UDP or TCP, try using RTP. RTP uses UDP with an extra layer of time stamps, sequence numbering to ensure correct order of data delivery. You should be able to find C++ and C# implementations of the protocol. Specifically to mention is that you can send images over a RTP/MJPEG stream if your application is producing JPEG images.
Just move to completely managed code :p (To keep it all in the same process)
https://net7mma.codeplex.com/SourceControl/latest has a C# RtspServer and RtpClient