RS232 Question from EBook

So I have been reading and playing with the RS232 shield from the suggestions here.

Well I hooked up the Panda to one computer via the USB cable and the serial cable to another that I loaded TeraTerm on.

Been working thru the Ebook, got the examples to work except, the loop back one on page 79 & 80. It says to jump the tx and rx lines and I should get a debug message.

Well for some reason the code stalls out at


read_count = UART.Read(rx_data, 0, rx_data.Length);

if (read_count != 3)

I put break points in there and step into it and I can get to the read_count line, but after that it stalls and will not do anything.

On the RS232 shield I have a jumper on the pins, and if I watch it, both tx and rx leds lite up showing me that something is being sent.

Any help??

Mike in MN

ps…working thru this computer programming stuff, ok maybe just the easy stuff…LOL

I believe the Read() method will block until you have filled the buffer. You need to send it rx_data.Length characters before it will end. You can test this by making the buffer one or two characters long.

You can tell how many bytes are in the input buffer by using the BytesToRead() method. Then you can do a read for the bytes that are available.

You can also use the DataReceived event which will fire when there one or more bytes in the buffer.

I think someone mentioned there was a bug in this example where ti locks up. I am not sure if it was fixed.
Modify the example to keep sending the same data every one second and hen try to see the data on teraterm.

Ok, so after much screwing around and resourcing back and forth, I came up with what seems to be a fix, or at least works…


using System;
using Microsoft.SPOT;
using System.IO.Ports;
using System.Threading;
using System.Text;


namespace SerialPortPanda
{
    public class Program
    {
        public static void Main()
        {
        SerialPort UART = new SerialPort("COM1", 115200);
        int read_count = 0;
        byte[] tx_data;
        byte[] rx_data = new byte[3];
        tx_data = Encoding.UTF8.GetBytes("FEZ");
        UART.Open();

            while (true)
            {
            // flush all data
            UART.Flush();
            // send some data
            UART.Write(tx_data, 0, tx_data.Length);
            // wait to make sure data is transmitted
            Thread.Sleep(100);
            // read the data
            int num_of_bytes = UART.BytesToRead;
            read_count = UART.Read(rx_data, 0, rx_data.Length);
            if (num_of_bytes != 3)
            {
                // we sent 3 so we should have 3 back
                Debug.Print("Wrong size: " + read_count.ToString());
            }
            else
            {
                // the count is correct so check the values
                // I am doing this the easy way so the code is more clear
                if (tx_data[0] == rx_data[0])
                {
                    if (tx_data[1] == rx_data[1])
                    {
                        if (tx_data[2] == rx_data[2])
                        {
                            Debug.Print("Perfect data!");
                        }
                    }
                }
            }
            Thread.Sleep(100);
            }
        }
    }
}



I changed the byte buffer ( I believe what Mike was talking about) to 3 instead of 10.


  byte[] rx_data = new byte[3];

And also because if you would type “FEZ123456”, it would still make it through because of the "new byte size number at 3, I also added the BytesToRead method (again Mike pointed out) to use the actual byte number.



            int num_of_bytes = UART.BytesToRead;
            read_count = UART.Read(rx_data, 0, rx_data.Length);
            if (num_of_bytes != 3)

One problem I see is that once it loops it continually adds to the Debug.Print.

Is this a reasonable fix, or is there a better way.

It seems to work like explained in the book this way.

Mike in MN

Yes that can be fix. What is important is you learning how serial ports work :wink:

After thinking about it though, it isn’t really that you only needed 3 inputs, you actually want to compare any amount of inputs you put in and get the same back. The “FEZ” or “Anything” should be the constant, it doesn’t necessarily need to be 3 other then that was the example, it could be 100 characters…but in this example it is 3.

I completely agree Gus, I was surprised that I could even get it to do anything, it’s going to be all the syntax that get me… lol …

When I started learning programming for machining it was learning by doing, and frustration. This is looking to be the same, but it’s still fascinating… :slight_smile:

Mike in MN

You are correct.

So here I go again…

After some thinking about a possible variable compare to a smaller or bigger array, I played (for a long time) and came up with a byte compare “for” loop that will work no matter how big the string, it will adjust for buffer size by a variable.

So if anyone is bored, would this be a better way to lay this compare byte program out. My original one would still stall out if say it didn’t receive any data if the wires weren’t jump, so I moved the “UART.Read(rx_data, 0, rx_data.Length);” data after the check for byte size.



using System;
using Microsoft.SPOT;
using System.IO.Ports;
using System.Threading;
using System.Text;


namespace SerialPortPanda
{
    public class Program
    {
        public static void Main()
        {
        SerialPort UART = new SerialPort("COM1", 115200);
        int read_count = 0;
        byte[] tx_data;
        tx_data = Encoding.UTF8.GetBytes("FEZ rocks!");      //change "FEZ rocks!" to any string length 
        int buffer_size = tx_data.Length;        //added variable for different tx_data buffer length
        byte[] rx_data = new byte[buffer_size];       //variable for buffer size

        UART.Open();

            while (true)
            {
            // flush all data
            UART.Flush();
            // send some data
            UART.Write(tx_data, 0, tx_data.Length);
            // wait to make sure data is transmitted
            Thread.Sleep(100);
            // read the data
            int num_of_bytes = UART.BytesToRead;    //added variable from initial exercise
            //read_count = UART.Read(rx_data, 0, rx_data.Length); //commented out, no need for
            if (num_of_bytes != buffer_size)    //changed to variables instead of hard number
            {
                // we sent "buffer_size" so we should have "buffer_size" back
                Debug.Print("Wrong size: " + num_of_bytes.ToString());
            }
            else
            {
                // the count is correct so check the values
                // I might be doing this the hard way?????
                int length1 = 0;   //added variable to loop array thru, I think?????

                UART.Read(rx_data, 0, rx_data.Length); //read data, moved here so it won't stall out if byte count is wrong(for buffer)

                //added 'for' statement to loop thru to compare bytes, seems to work

                for (int i = 0; i < buffer_size; i++)   // i variable to compare for loop
                {
                    if (tx_data[length1] == rx_data[length1]) //changed tx & rx compare to variable addresses
                    {
                        if (length1 < buffer_size)  //condition to add to variable for loop????
                        {
                            length1++;
                        }
                    }

                }
                Debug.Print("Perfect data!");

            }
                Thread.Sleep(100);
            }
        }
    }
}


It’s kind of messy, but I don’t know any other way yet. Had to get the C# for Dummies out on the “for” statement though… :smiley:

Mike in MN

If you are always transmitting text (ASCII Characters)

Why don’t you convert to strings and the just do one string compare…

It wouldn’t work with binary transfers but if you keep using text as in the example you could do it.

Cheers Ian

On reflection… If you pulled the jumper on this program it will hang. In normal operation of polling serial port you should only check “txfull” flag, once this is set then read the port other wise the program will sit waiting for characters to arrive all day…

IanR

[quote] If you are always transmitting text (ASCII Characters)

Why don’t you convert to strings and the just do one string compare… [/quote]

I don’t know, just working with the example, I don’t know any of the methods/processes/other ways yet. But I will look into it… :slight_smile:

Also, I did pull the jumper and it does Debug.Print the “Wrong size” string, but it does loop endlessly over and over again.

My example, was just get it not to lock up at the receive side, and make it so if you have a different length string, it will compare any length.

My next step will be to look into polling or triggering some way, and then possibly send different data such as a temp reading or pressure reading with a string note, and separate the data.

It’s gonna take me a while, and just looking for feedback and different ways to do it.

There are a tons of methods and syntax that I know nothing about, just taking baby steps.

Mike in MN