Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Multiple Com ports, receive on COM2 and send/receive on COM1


Best Answer Chris Walker, 01 January 2014 - 03:09 PM

Hi mbargar13, Events are generally raised sequentially on NETMF. So what you're seeing is probably by design...NETMF is waiting for your DataReceived event to complete before pushing additional data to your event handlers. Here's a solution for you, if you want to run these on long-running background threads: 1. Create a data processing event on a background thread. 2. Create an AutoResetEvent that's visible to all code in your module. 3. In your DataReceived event, call .Set() on the AutoResetEvent. 4. In your background thread, wait for DataReceived by calling .WaitOne() on the AutoResetEvent. Then process your logic (and wait again, all in a loop). 5. I would also recommend checking to see if the SerialPort is closed -- if(_Serial == null || !_Serial.IsOpen) -- and exit the thread if it is closed. Does that help? Chris Go to the full post


  • Please log in to reply
14 replies to this topic

#1 mbargar13

mbargar13

    Member

  • Members
  • PipPip
  • 22 posts

Posted 30 December 2013 - 09:10 PM

I have an application that takes the input from a bar code reader on COM2 and sends that data to COM1. Now on the data received event in COM2 is where I am sending the data, but nothing will seem to go out on the COM2 data received event thread. If I take the data and store it and have a separate thread to send the data to COM1 then that seems to work just fine. Are there any limitations about receiving from one com port and send to the other com port in the same event?



#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 31 December 2013 - 07:10 AM

Hi mbargar13, Everything should be queued and relatively thread-safe, so you should be able to send data from any thread. If you add some Debug.Print statements to your event that's not sending data, do you see the other event code successfully working? Chris

#3 mbargar13

mbargar13

    Member

  • Members
  • PipPip
  • 22 posts

Posted 31 December 2013 - 01:26 PM

So the event with the barcode reader (COM1) works and can send data out on (COM2) and i can see the TX light flash and everything, but and when the data comes in the COM2 the RX light flashes as well but the COM2 data received event is never fired. But if i start a timer and then watch for a variable to be set the COM2 RX data received event gets fired just fine.



#4 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 31 December 2013 - 02:32 PM

Hi mbargar13, Is there any chance that your SerialPort was created inside a function and is getting garbage collected? Chris

#5 mbargar13

mbargar13

    Member

  • Members
  • PipPip
  • 22 posts

Posted 31 December 2013 - 02:48 PM

I have both declared globally



#6 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 31 December 2013 - 03:43 PM

Hi mbargar13, Which Netduino mainboard are you using? Which firmware version? If you can reduce this down to a program with less than 10-15 lines of code, we can test it out here and see what's going on. To test it, we'd just need to send data from HyperTerminal/Teraterm to one of the serial ports while watching the other one for outgoing data, correct? Chris

#7 mbargar13

mbargar13

    Member

  • Members
  • PipPip
  • 22 posts

Posted 31 December 2013 - 03:49 PM

I am using the N2+ with the firmware 4.2.2

 

I will see if I can make something that will work like that.



#8 mbargar13

mbargar13

    Member

  • Members
  • PipPip
  • 22 posts

Posted 31 December 2013 - 04:28 PM

It is down to bare bones code. 86 lines total. I have the barcode reader on COM1 (but it can be any input) and i have it going out COM2 with a loop that will send 20 responses. I can send data to COM2, but the moment I send the data from inside the COM1 data received event, the COM2 data received event does nothing. I have a Hyperterminal type program that is sending the data back over COM2 and i can see the RX light light up when i send the data across but the still the event does not fire.The code is attached. Let me know if you need anythign else. It does use the library for .Net Micro Framework (Toolbox.NETMF.Core) to convert the bytes to something easily readable. Le me know if you need anything else.

Attached Files



#9 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 31 December 2013 - 05:25 PM

Hi mbargar13, What can we do to whittle down the code to 10 lines, 20 max? If it's 86 lines long, there's a good chance that there's something else going on which is causing the issue. Please try removing one item at a time, simplifying the code bit by bit, until you find the point as which it starts working. This should isolate the issue as something that's either a bug in the C# code (at which point you're good to go) or a bug in the firmware (at which point we can analyze it and work on a core fix). Chris

#10 mbargar13

mbargar13

    Member

  • Members
  • PipPip
  • 22 posts

Posted 31 December 2013 - 05:40 PM

This is the smallest i can get.

namespace SerialTester{    public class Program    {        static SerialPort _Serial = new SerialPort(SerialPorts.COM1, 38400, Parity.None, 8, StopBits.One);        static SerialPort _Serial2 = new SerialPort(SerialPorts.COM2, 115200, Parity.None, 8, StopBits.One);        public static void Main()        {                        _Serial.DataReceived += new SerialDataReceivedEventHandler(_Serial_DataReceived);            _Serial2.DataReceived += new SerialDataReceivedEventHandler(_Serial2_DataReceived);            while (!_Serial.IsOpen) _Serial.Open();            while (!_Serial2.IsOpen) _Serial2.Open();            Thread.Sleep(Timeout.Infinite);        }        static void _Serial2_DataReceived(object sender, SerialDataReceivedEventArgs e)        {            Debug.Print("[REPLY2] (" + DateTime.Now + ") Data received");          }        static void _Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)        {                        Debug.Print("[REPLY] (" + DateTime.Now + ") Data received");              int x = 0;            while (x++ <= 20)            {                var dataTx = "r";                byte[] serialDataOut = new byte[] { (byte)Convert.ToInt32("1D", 16) };                _Serial2.Write(serialDataOut, 0, serialDataOut.Length);                Thread.Sleep(2000);            }        }            }}


#11 Gutworks

Gutworks

    Advanced Member

  • Members
  • PipPipPip
  • 363 posts
  • LocationOttawa, Ontario

Posted 31 December 2013 - 06:13 PM

Hi [color=rgb(40,40,40);font-family:helvetica, arial, sans-serif;]mbargar13,[/color]

 

I noticed you have different baud rates for both of your Serial Ports. Have you tried making sure they are all the same including your HyperTerminal settings?

 

Cheers,

Steve



#12 mbargar13

mbargar13

    Member

  • Members
  • PipPip
  • 22 posts

Posted 31 December 2013 - 06:18 PM

Yup, how i actually had it hooked up was using a barcode scanner (just for input and its rate is 38400), then the other COM i hooked up to the PC (USB-> Serial) and set its speed to 115200.

 

The thing is that when i send data to to COM2 (115200) without being inside the COM1 data received event, it shows that it is receiving the data just fine. It is just the moment i am inside the COM1 event is when the COM2 event is not fired.



#13 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 01 January 2014 - 06:00 AM

mbargar13, I have assigned an internal work item to this, for an upcoming Netduino 4.3 beta firmware release. We'll try to reproduce the issue and then report back here. In the meantime, can you try two things really quickly? 1. Try moving your SerialPort instantiation to the Main function, instead of creating them in the Static functions. In .NET MF, it's generally best to not instantiate Static objects before the Main() function is called. 2. Get rid of the "while (x++ <= 20)" and "Thread.Sleep" in your COM1 data received event. Does data get sent out then? I'm wondering if the event's 40 second wait time is blocking the serial port from sending data. It's probably a glitch in NETMF if that's what's happening...but removing those two lines will get us a step closer toward finding out. Also, just for sanity's sake... I would recommend changing the "while" in "while (!_Serial.IsOpen) _Serial.Open();" to "if". You should never need a "while" loop there...a conditional "if" statement is fine though. Chris

#14 mbargar13

mbargar13

    Member

  • Members
  • PipPip
  • 22 posts

Posted 01 January 2014 - 01:55 PM

FYI: it is the COM2 data received event not firing, send the data over the com ports works just fine it is only receiving data on the second com port that is having the issue.

 

Ok I did all of the recommendations. The only one that made a difference was the "while(x++ <= 20)" loop. When that was removed the COM2 data received event fired correctly. So then I tried the following and it also worked just fine. I moved the sending of the data into a separate thread inside of the COM1 data received event. It does appear that the first data received event is blocking the second (or possibly any other data received events) data received events. Though data does go out, nothing is allowed to come back in.

public class Program    {        static SerialPort _Serial;        static SerialPort _Serial2;        public static void Main()        {                   _Serial = new SerialPort(SerialPorts.COM1, 38400, Parity.None, 8, StopBits.One);            _Serial2 = new SerialPort(SerialPorts.COM2, 115200, Parity.None, 8, StopBits.One);            _Serial.DataReceived += new SerialDataReceivedEventHandler(_Serial_DataReceived);            _Serial2.DataReceived += new SerialDataReceivedEventHandler(_Serial2_DataReceived);            while (!_Serial.IsOpen) _Serial.Open();            while (!_Serial2.IsOpen) _Serial2.Open();            Thread.Sleep(Timeout.Infinite);        }        static void _Serial2_DataReceived(object sender, SerialDataReceivedEventArgs e)        {            Debug.Print("[REPLY2] (" + DateTime.Now + ") Data received");                     }        static void _Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)        {                        Debug.Print("[REPLY] (" + DateTime.Now + ") Data received");                       int x = 0;            new Thread(() =>            {                while (x++ <= 20)                {                    var dataTx = "r";                    byte[] serialDataOut = new byte[] { (byte)Convert.ToInt32("1D", 16) };                    _Serial2.Write(serialDataOut, 0, serialDataOut.Length);                    Thread.Sleep(2000);                }            }).Start();                    }                    }


#15 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 01 January 2014 - 03:09 PM   Best Answer

Hi mbargar13, Events are generally raised sequentially on NETMF. So what you're seeing is probably by design...NETMF is waiting for your DataReceived event to complete before pushing additional data to your event handlers. Here's a solution for you, if you want to run these on long-running background threads: 1. Create a data processing event on a background thread. 2. Create an AutoResetEvent that's visible to all code in your module. 3. In your DataReceived event, call .Set() on the AutoResetEvent. 4. In your background thread, wait for DataReceived by calling .WaitOne() on the AutoResetEvent. Then process your logic (and wait again, all in a loop). 5. I would also recommend checking to see if the SerialPort is closed -- if(_Serial == null || !_Serial.IsOpen) -- and exit the thread if it is closed. Does that help? Chris




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.