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

Working with UART


  • Please log in to reply
7 replies to this topic

#1 magarcan

magarcan

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 08 September 2011 - 11:27 AM

I've a problem working with UART. I'm using SerialPortHelper library. But I can only write, not to write anything.

Here is my code:
using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.Threading;
using Microsoft.SPOT;

namespace SerialPortLearn
{
    public class Program
    {
        static SerialPortHelper serialPortHelper1 = new SerialPortHelper();

        public static void Main()
        {
            serialPortHelper1.PrintLine("Initializing...");
            while (true)
            {
                if (line.Length > 0)
                    serialPortHelper1.PrintLine("Readed: " + line);
            }
        }
    }
}

Can anyone help me?? Thanks!!!

Here is the library's code:
using System;
using System.IO.Ports;
using System.Text;
using Microsoft.SPOT;
using SecretLabs.NETMF.Hardware.Netduino;
using System.Threading;

namespace SerialPortLearn
{
    public class SerialPortHelper
    {
        static SerialPort serialPort;

        const int bufferMax = 1024;
        static byte[] buffer = new Byte[bufferMax];
        static int bufferLength = 0;

        public SerialPortHelper(string portName = SerialPorts.COM1, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
        {
            serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
            serialPort.ReadTimeout = 10; // Set to 10ms. Default is -1?!
            serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
            serialPort.Open();
        }

        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            lock (buffer)
            {
                int bytesReceived = serialPort.Read(buffer, bufferLength, bufferMax - bufferLength);
                if (bytesReceived > 0)
                {
                    bufferLength += bytesReceived;
                    if (bufferLength >= bufferMax)
                        throw new ApplicationException("Buffer Overflow.  Send shorter lines, or increase lineBufferMax.");
                }
            }

        }

        public string ReadLine()
        {
            string line = "";

            lock (buffer)
            {
                //-- Look for Return char in buffer --
                for (int i = 0; i < bufferLength; i++)
                {
                    //-- Consider EITHER CR or LF as end of line, so if both were received it would register as an extra blank line. --
                    if (buffer[i] == '\r' || buffer[i] == '\n')
                    {
                        buffer[i] = 0; // Turn NewLine into string terminator
                        line = "" + new string(Encoding.UTF8.GetChars(buffer)); // The "" ensures that if we end up copying zero characters, we'd end up with blank string instead of null string.
                        //Debug.Print("LINE: <" + line + ">");
                        bufferLength = bufferLength - i - 1;
                        Array.Copy(buffer, i + 1, buffer, 0, bufferLength); // Shift everything past NewLine to beginning of buffer
                        break;
                    }
                }
            }

            return line;
        }

        public void Print( string line )
        {
            System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
            byte[] bytesToSend = encoder.GetBytes(line);
            serialPort.Write(bytesToSend, 0, bytesToSend.Length);
        }

        public void PrintLine(string line)
        {
            Print(line + "\r");
        }

        public void PrintClear()
        {
            byte[] bytesToSend = new byte[2];
            bytesToSend[0] = 254;
            bytesToSend[1] = 1;
            serialPort.Write(bytesToSend, 0, 2);
            Thread.Sleep(500); // LCD is slow, pause for 500ms before sending more chars
        }
    }
}


#2 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 08 September 2011 - 12:29 PM

Maybe you forget a piece of code...from where is popped out the "line" variable in the Program class?
Biggest fault of Netduino? It runs by electricity.

#3 Inquisitor

Inquisitor

    Advanced Member

  • Members
  • PipPipPip
  • 91 posts
  • LocationAtlanta, Georgia, USA

Posted 08 September 2011 - 12:59 PM

I've a problem working with UART. I'm using SerialPortHelper library. But I can only write, not to write anything.

Here is my code: ...


As Mario mentioned, the variable named "line" is not defined. But then your compiler would have told you that... so I'm guessing it was accidentally deleted when you posted the code.

You might also add a little more information... like what behavior you are seeing besides "But I can only write, not to write anything." Either you miss-typed this sentence or you are struggling with English as a second language. I'd be glad to help, but I need a little more to go on...
Doing my best to keep the smoke in the little black boxes.
If my message helped you... how 'bout giving me a Posted Image
www.MessingWithReality.com

#4 magarcan

magarcan

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 08 September 2011 - 02:27 PM

I've a problem working with UART. I'm using SerialPortHelper library. But I can only write, not to write anything.

WTF! This happens when you have not asleep enough, sorry. I want to mean, that I'm able to write in UART (this part of code is working well), but I can't read from there.
I've neither written well the code. This is the real code I'm using:
using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.Threading;
using Microsoft.SPOT;

namespace SerialPortLearn
{
    public class Program
    {
        static SerialPortHelper serialPortHelper1 = new SerialPortHelper();

        public static void Main()
        {
            serialPortHelper1.PrintLine("Initializing...");
            while (true)
            {
                string line = serialPortHelper1.ReadLine();
                if (line.Length > 0)
                    serialPortHelper1.PrintLine("Readed: " + line);
            }
        }
    }
}
Thanks!!

#5 Inquisitor

Inquisitor

    Advanced Member

  • Members
  • PipPipPip
  • 91 posts
  • LocationAtlanta, Georgia, USA

Posted 08 September 2011 - 03:48 PM

That sleep thing isn’t overrated. :lol:

This code (at least) compiles. There are several things in it I wouldn’t do, but I don’t see any show stoppers. Your example only uses the one port for sending and receiving, and since you’re sleep deprived… I have to ask the obvious:

Have you got Netduino wired to feedback on itself?

Here’s an example I wrote to test the serial ports, but it uses both serial 1 and 2 on the same Netduino. I know it works, if you wire it up as indicated in the text. Serial Port Communication

Let me know either way… if you’re still having troubles this afternoon, I’ll look at it when I get home.

Good luck
Doing my best to keep the smoke in the little black boxes.
If my message helped you... how 'bout giving me a Posted Image
www.MessingWithReality.com

#6 Inquisitor

Inquisitor

    Advanced Member

  • Members
  • PipPipPip
  • 91 posts
  • LocationAtlanta, Georgia, USA

Posted 08 September 2011 - 07:38 PM

OK, I've tried it now with some hardware.

If you are just trying to mess with the serial port code in general on the Netduino and intended to have it talk to itself, you need to connect a wire from port 1 to port 2 on the digital side. Once you do that, your code will work fine. However, If you did that, you’ll also find that there is no indication that it’s working. Once I added the Debug.Print statement below, you can see that it’s receiving.

using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.Threading;
using Microsoft.SPOT;

namespace SerialPortLearn
{ 
    public class Program 
    { 
        static SerialPortHelper serialPortHelper1 = new SerialPortHelper();
        
        public static void Main() 
        {
            serialPortHelper1.PrintLine("Initializing..."); 
            while (true) 
            {
                string line = serialPortHelper1.ReadLine();
                if (line.Length > 0)
                {
                    Debug.Print(line);
                    serialPortHelper1.PrintLine("Readed: " + line);
                }
            }
        }
    }
}

If you are trying to interface with some other device… like a computer, then I can tell you, your code is fine and then the problem is with your wiring to/from the computer or the computer software on the other side.

Good Luck!
Doing my best to keep the smoke in the little black boxes.
If my message helped you... how 'bout giving me a Posted Image
www.MessingWithReality.com

#7 magarcan

magarcan

    Advanced Member

  • Members
  • PipPipPip
  • 43 posts

Posted 09 September 2011 - 09:22 AM

Finally I've modified ReadLine() method and now it's working, but I'm still having a problem. I've defined two different objects (one for each port) but there is something that is not working.
using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.Threading;
using Microsoft.SPOT;
using System.IO.Ports;

namespace SerialPortLearn
{
    public class Program
    {
        static OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
        
        /*Defaults to: SerialPorts.COM1 (uses D0 and D1), 9600, Parity.None, 8, StopBits.One*/
        static SerialPortHelper serialPortHelper1 = new SerialPortHelper(SerialPorts.COM1, 9600, Parity.None, 8,StopBits.One);
        static SerialPortHelper serialPortHelper2 = new SerialPortHelper(SerialPorts.COM2, 9600, Parity.None, 8, StopBits.One);

        public static void Main()
        {
            serialPortHelper1.PrintLine("Starting!");
            while (true)
            {
                string line = serialPortHelper2.ReadLine();
                if (line.Length > 0)
                {
                    led.Write(true);
                    Thread.Sleep(500);
                    serialPortHelper1.PrintLine("Read: " + line);
                    led.Write(false);
                }
            }
        }
    }
}
The problem is that response, serialPortHelper1.PrintLine("Read: " + line);, is sent to port 2 instead of port 1. I think, maybe it's needed to modify constructor in order to work with both ports at simultaneously.

#8 <Jeremy>

<Jeremy>

    Advanced Member

  • Members
  • PipPipPip
  • 31 posts
  • LocationNorthern Ireland

Posted 10 September 2011 - 06:17 PM

Hi magarcan

I've been having a look at the problem you've described (since I've been working on some serial port things myself).

First, I'm assuming you've got D0 (COM1 Rx) connected to D3 (COM2 Tx), and D1 (COM1 Tx) connected to D2 (COM2 Rx) here.

Given that, if you look in the SerialPortHelper.cs class, the serialPort variable is declared as static (as are buffer and
bufferlength). I think what's happening is that since you've instantiated two separate ports in your class, you're actually sharing
resources between them. So when an event is fired to say "data has been written to COM1", the code reacts to that event
by trying to read from COM2. If you leave the serialPort variable as static, and change the serialPort_DataReceived
method to look like the code below, you'll see what i mean:

private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // i expect these to both return the same port
    // if serial port is static, i find they're different.
    Debug.Print("serial port name = " + serialPort.PortName);
    Debug.Print("sender name = " + ((SerialPort)sender).PortName);
    lock (buffer)
    {
        if (serialPort.BytesToRead > 0)
        {
            int bytesReceived = serialPort.Read(buffer, bufferLength, bufferMax - bufferLength);

            if (bytesReceived > 0)
            {
                bufferLength += bytesReceived;
                if (bufferLength >= bufferMax)
                    throw new ApplicationException("Buffer Overflow.  Send shorter lines, or increase lineBufferMax.");
            }
        }
    }
}

So basically I think if you use the method above, and remove the static modifier from the serialPort variable, you
should make some progress. You might want to remove static from the other two member variables too.

I guess you'll also have noticed I added a little bit to that code to check if there's at least one byte to read from serialPort.
Stepping through your program slowly in debug mode gives me different behaviour to when I just run it
without breakpoints - I found there was an exception in this method because whereas we've been notified that data has
been received, when I actually look at the serialPort.BytesToRead property I find that there's nothing there. I couldn't
work out why the event was being fired, if you have an answer I would be really interested to know!

But this looks like a great library, it's interesting to me as well.

I hope this helps - let me know how it works out.

Jeremy




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.