1

I am trying to port a service written for Windows systems in C# onto Linux, with the aim of replacing Windows altogether. The hardware remains identical in both Windows and Linux environments.

So far this has gone great - I've installed Mono-complete, modified those bits that need modifying to stop it looking for Nuget, compiled the software with only cosmetic errors, run it with mono-service and have established communication with the Serial Port.

That's where things start going wrong.

I am able to open the port, and I am able to send a message to the port which results in the proper response.

By running 'cat /dev/ttyUSB0' I am seeing the proper response from the port - the symbol @

However the symbol is simply not being read by the software and I'm hitting a timeout every time.

I have changed nothing in the code except to open port '/dev/ttyUSB0' instead of 'COM1' (or whatever port it needs).

Why then can I write to, but not read from, the serial port?

I have tried messing with the Encoding of the returning bits, I thought it might be a big-endian / little endian issue but it is correctly sending the signal to the device ("M2" - no quotation marks).

Return communication also looks good - cat /dev/ttyUSB0 shows a series of '@' symbols being returned, each on a new line.

What is not happening though is the software then reading this, instead it is hitting the timeout waiting for the response.

I wondered if it might be a newline issue - but then why would it work as-is on the Windows system, and why would it send perfectly happily (newline currently is explicitly set to '\r\n')

Is there something specific to Linux that I am missing?

Tombas
  • 111
  • 1
  • 10
  • Since you haven't configured the serial port using the *termios* API, you are at the mercy of whatever mode that previously existed before you execute your program (unless Mono, whatever that is, does something for you). Essentially you have the choice of reading lines of ASCII text (canonical mode) or reading bytes of binary data (non-canonical mode). See http://stackoverflow.com/questions/25996171/linux-blocking-vs-non-blocking-serial-read/26006680#26006680 Note that there's a link to the Windows API in a comment. – sawdust Apr 18 '16 at 01:27
  • Indeed your problem is with /r/n, or at least I suppose it as I had exactly the same problem, instead of using ReadLine attach to the data event and use ReadBytes, in this way I got it working. – Gusman Apr 19 '16 at 18:56
  • 1
    Also, if you can read from the device's file, then you always can use an streamreader over it ;) – Gusman Apr 19 '16 at 18:58
  • use Environment.NewLine instead of /(\r|\n)+/ – increddibelly Dec 09 '16 at 08:49

1 Answers1

2

I know this is a while late, but I'd left the project to one side for a while and have only just picked it back up.

It turns out that the problem lies with mono not firing DataReceivedEvents, so when the code ported from Windows .Net came across listening for them they weren't being picked up because they weren't being fired.

I overcame this by spawning a new thread whose sole purpose was to listen on the port, and when serialPort.BytesToRead was greater than 0 run whatever code would have been run on the event firing.

Tombas
  • 111
  • 1
  • 10
  • You sir have saved my life, your solution totally works and fixes the problem of reading the data! Thank you for answering your question! – SubqueryCrunch Jan 18 '22 at 13:23