deivid77
Posts: 30
Joined: Wed Jun 24, 2015 6:09 pm
Location: Spain

Re: Serial port support for the raspi?

Thu Oct 29, 2015 10:30 am

It works for me with CP2102 USB 2.0 to TTL Module Serial Converter.

Bidirectional communication works!

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Thu Oct 29, 2015 10:31 am

Care to share your code?
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Thu Oct 29, 2015 10:33 am

Anyone having any success reading/writing to the UART since 10556 was released?
Basically it does work, it is just that something else you are doing is likely producing what you see.
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

deivid77
Posts: 30
Joined: Wed Jun 24, 2015 6:09 pm
Location: Spain

Re: Serial port support for the raspi?

Thu Oct 29, 2015 10:48 am

My code is the same:
https://github.com/ms-iot/samples/tree/ ... ialSample/

No changes made.

Does your TTL Adapter has the CP2102 chip?

craigdudley
Posts: 11
Joined: Thu Oct 15, 2015 6:32 pm

Re: Serial port support for the raspi?

Thu Oct 29, 2015 10:57 am

No changes to Serial Sample code, and I'm using the on-board Pi2 UART.

Can't see what else I can be doing wrong.

Out of interest, those using the on-baord UART, which pin are people using as GND?

funvill
Posts: 6
Joined: Fri Aug 24, 2012 6:09 pm

Re: Serial port support for the raspi?

Thu Oct 29, 2015 8:42 pm

craigdudley wrote:Out of interest, those using the on-baord UART, which pin are people using as GND?
I am using pin #6 as my GND

User avatar
DougieLawson
Posts: 36312
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: Serial port support for the raspi?

Thu Oct 29, 2015 8:48 pm

funvill wrote:
craigdudley wrote:Out of interest, those using the on-baord UART, which pin are people using as GND?
I am using pin #6 as my GND
All GND pins are made equal as they're connected together on the board. So it doesn't matter which one.
http://pi.gadgetoid.com/pinout/ground gives details.
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

craigdudley
Posts: 11
Joined: Thu Oct 15, 2015 6:32 pm

Re: Serial port support for the raspi?

Fri Oct 30, 2015 5:00 pm

Thanks Dougie, that's useful info.

Sorted out my issue by getting a new serial/USB adapter - seems my older model doesn't drop the voltage to 3v3 accurately. I really must buy a multi-meter.

streammylife
Posts: 4
Joined: Tue Dec 22, 2015 7:00 pm

Re: Serial port support for the raspi?

Tue Dec 22, 2015 7:08 pm

Does anyone know how to directly access the UART outside of the ways described in the simple serial example? I have a fairly time sensitive application where the external device expects a response within a timely manner. However, the asynchronous read operations seem to be extremely slow. I'm toggling an I/O before and after the await LoadAsync() task as a timing signal. On a logic analyzer I can see that the task can take anywhere from 10-30ms AFTER the byte has been received to actually complete the task. I could probably live with 5ms of a delay between receive and transmission of a response.

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Wed Dec 23, 2015 1:02 am

Are you using a dataReader attached to the stream on the input?

Sort of like

Code: Select all

                    dataReaderObject = new DataReader(serialPort.InputStream);
                    ...
                    byte b = dataReaderObject.ReadByte();
Are you starting the read thread as part of the timings?

I am not sure how much of the time your quote is from the delay to the GPIO or the delay to the Rx.

I would use a Stopwatch to get timings in code.

Can you post some code?

My interactions with the Serial port are like below

Code: Select all

            try
            {
                serialPort = await SerialDevice.FromIdAsync(AdapterName);
                Debug.WriteLine("Serial Device {0} {1}", AdapterName, serialPort != null);

                if (serialPort != null)
                {
                    // Configure serial settings
                    serialPort.BaudRate = 115200;
                    serialPort.Parity = SerialParity.None;
                    serialPort.StopBits = SerialStopBitCount.One;
                    serialPort.DataBits = 8;

                    dataWriterObject = new DataWriter(serialPort.OutputStream);
                    dataReaderObject = new DataReader(serialPort.InputStream);
                }
                else
                {
                    throw (new xxxxException("No Serial Port Error"));
                }
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.Message.ToString());

                throw (new xxxException(ex.Message.ToString()));
            }
and it you are interested in very high speed reactions then push the work to a high priority thread rather than operate in the UI one.

Code: Select all

//startup the high priority worker thread from the pool
        public void Start()
        {
            //#pragma is because target is 'no warnings' before release
#pragma warning disable 4014
            ThreadPool.RunAsync(OutputThread, WorkItemPriority.High);
#pragma warning restore 4014
        }
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

streammylife
Posts: 4
Joined: Tue Dec 22, 2015 7:00 pm

Re: Serial port support for the raspi?

Wed Dec 23, 2015 1:59 pm

I am using the datareader attached to the input stream as you described and was described in the MS provided example. AFAIK, I can't just call the read routine. I have to call the LoadAsync() routine and wait for it to recognize that there is some data available, and then I call the read routines.

The problem is that the LoadAsync() doesn't complete until a long time after the last byte has actually been rx'd. I reduced my read timeout to 5ms although I'm not exactly sure how that's utilized.

I also added a manual timeout when I'm waiting for data.

Code: Select all

        
private async Task<UInt32> WaitForDataRx()
        {
            UInt32 rdyBytes = 0;
            Task[] newTasks = new Task[2];
            CancellationTokenSource CancelWaitForData = new CancellationTokenSource();
            ToggleTestPin();

            dataReaderObject = new DataReader(serialPort.InputStream);

            dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;

            //newTasks[0] = Task.Run(() => dataReaderObject.LoadAsync(1024), CancelWaitForData.Token);
            newTasks[0] = dataReaderObject.LoadAsync(8).AsTask<UInt32>(CancelWaitForData.Token);
            newTasks[1] = Task.Delay(1000, CancelWaitForData.Token);

            await Task.WhenAny(newTasks);


            ToggleTestPin();

            if (newTasks[0].Status == TaskStatus.RanToCompletion)
            {
                rdyBytes = ((Task<UInt32>)newTasks[0]).Result;
            }

            //Cancel the rest
            CancelWaitForData.Cancel();

            return rdyBytes;
            
        }
The delay was measured by monitoring the TestPin. It's toggled prior to the await and then after. I have this on the same shot as the rx input on a logic analyzer and I noticed that there is a long delay between when the data is received and that second toggle is hit.

When I tried the reads without waiting on the LoadAsync() it wasn't working.

I'll look into your higher priority thread idea. I'm a firmware engineer and I'm just getting my feet wet with app dev so this is a little bit of new territory to me. :)

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Wed Dec 23, 2015 5:40 pm

Well you have to understand what async does. It allows the UI thread to 'pause' continuation without being blocked. Things progress normally until the code reaches an await. It puts a bookmarker (task completion) at that point and resumes the UI loop. The Task finishes as some point. That is noticed by the UI thread and it resumes at the bookmark. Same happens if you run async in other threads as well. Not really anything other than preventing coders from locking up the UI (which is what Windows 8 was all about. Protecting us from ourselves).

All interfaces have overheads. Using a Stopwatch as an execution timing method is well documented.

Running at a high priority in a Pool thread is the most efficient way to do things fast.
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Wed Dec 23, 2015 6:43 pm

48. Why is it that writing applications that contain 'async void' can be such a bad idea

https://channel9.msdn.com/Series/Three- ... -for-Async

https://channel9.msdn.com/Series/Three- ... dlers-only

for some examples of what async is and does.
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

pauldy
Posts: 54
Joined: Tue Jun 12, 2012 3:34 pm

Re: Serial port support for the raspi?

Tue Dec 29, 2015 3:58 am

Some points of interest are that it doesn't appear the raps supports the onboard part at this time. I was able to get read working without some weirdness but I was unable to write. Looking for documentation I came across that the port is reserved for the kernel and the following pinout mapping. I would love to see this opened back up for use because the last thing I need is another usb device handing off the raps when all I need is a max 232 and female db9 wired up drawing much less power.

https://ms-iot.github.io/content/en-US/ ... gsRPi2.htm

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Tue Dec 29, 2015 12:13 pm

That diagram is out of date and I have issue lodged over on GitHub to change it.

Uart Rx/Tx are now supported from 10586 on.

Any Serial over USB functionality you may need has to be built over that simple layer. That can be quite complex because of how USB to Serial is hooked up in 10 IoT. There are examples out there on how to start all of this. Look under Generic Serial over USB.

To use it directly just use the Windows.xxxx classes for Serial Ports/Devices.
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

pauldy
Posts: 54
Joined: Tue Jun 12, 2012 3:34 pm

Re: Serial port support for the raspi?

Tue Dec 29, 2015 2:08 pm

I'm running 10.0.10586 and the TX line won't even pulse when I write to it. All the flush calls return method not implemented.

Code: Select all

        protected static async void runSerialTest()
        {
            try
            {
                Windows.Devices.Enumeration.DeviceInformationCollection devs = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelector("UART0"), null);
                SerialDevice dev = await SerialDevice.FromIdAsync(devs[0].Id);
                dev.WriteTimeout = TimeSpan.FromSeconds(1);
                dev.ReadTimeout = TimeSpan.FromSeconds(1);
                dev.BaudRate = 9600;
                dev.Parity = SerialParity.None;
                dev.StopBits = SerialStopBitCount.One;
                dev.DataBits = 8;
                dev.Handshake = SerialHandshake.XOnXOff;
                StreamWriter sw = new StreamWriter(dev.OutputStream.AsStreamForWrite());
                StreamReader sr = new StreamReader(dev.InputStream.AsStreamForRead());

                Char test = 'A';
                while (true)
                {
//                    string temp = sr.ReadLine();
                    sw.Write(test++);
                    if (test == 'Z')
                    {
                        test = 'A';
                        sw.WriteLine();
                    }
                    await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(1));
                }
            }
            catch (Exception ex)
            {
            }
        }
Invoked with :

Code: Select all

System.Threading.Tasks.Task.Run(() => { runSerialTest(); });

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Tue Dec 29, 2015 3:47 pm

There is no handshake implemented on the miniUart.

The 1 sec read/write timeouts are unnecessary (in most cases). They do affect what happens quite dramatically.
https://msdn.microsoft.com/en-us/librar ... 2147217396 EDIT: that should be the WIndows... ref - not the System... one

You don't need the wait if you running in a non UI thread which is the best way of dealing with this. Make your Uart handling code run outside the UI thread with sync calls to Read and Write so that is does not get entangled with UI timings and restraints.

I know it works. I have had it running here. I just don't know what detail is missing in your code. Sorry.

I use the below as an easier way to launch non UI threads

Code: Select all

        //startup the high priority worker thread from the pool
        public void Start()
        {
            //#pragma is because target is 'no warnings' before release
#pragma warning disable 4014
            ThreadPool.RunAsync(OutputThread, WorkItemPriority.High);
#pragma warning restore 4014
        }
Try just compiling and running

https://ms-iot.github.io/content/en-US/ ... Sample.htm
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

pauldy
Posts: 54
Joined: Tue Jun 12, 2012 3:34 pm

Re: Serial port support for the raspi?

Tue Dec 29, 2015 4:30 pm

The pause was just so I could watch the pulses easier on the logic probe without having to dig for the scope in the garage. I didn't realize no flow control was available, even software not sure how I missed that in all I read. I removed it and output worked as expected. The only issues I see now might just be related to the prioritization issue you described. There is a nice stream of A-Y and a line feed. Then I get random L-Y line feed. I'm not sure how to get the priority set but I can look that up and try that later.

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Tue Dec 29, 2015 4:39 pm

"WorkItemPriority.High"

or other options.

Always use Stopwatch (52 nSec resolution) rather than external signals to do timings in code. Less uncertainty.
P.S. I have obe of those cheap USB 8 bit parallel digital 'scope' myself (and a software oscilloscope).
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Tue Dec 29, 2015 5:28 pm

One of the projects I have underway with MS is to provide a 'no hardware'/ 'some small hardware' type of class based solution to problems in IoT. All running the same UI classes.

As an example that started from a comment I made to a Hackster.io project to do with OneWire.

1. A simple GPIO version - which has poor outcomes.
2. A Uart based one - which is capable of excellent outcomes and still no added hardware.
3. A I2C hardware addon - that provides an hardware driven bus.

All running from the same User class so that the code people write runs on all three without change :-)

There are many other examples that are on the 'list of things to do'.
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

cobusstroebel
Posts: 1
Joined: Tue Jan 05, 2016 1:38 pm

Re: Serial port support for the raspi?

Tue Jan 05, 2016 1:41 pm

@craigdudley

I am experiencing the same problem with serial comms on the raspberry pi 2.
Have you managed to fix the encoding or pattern issue?

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Serial port support for the raspi?

Wed Jan 06, 2016 9:28 am

I don't have that problem. See Serial Example on GitHub for code to drive the Serial tx/rx. You need to go deep in the code to find simple lines to re-use. And take a look at the FAQ, It already has answers to some of your questions, If you need more help I'll try and add more
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

streammylife
Posts: 4
Joined: Tue Dec 22, 2015 7:00 pm

Re: Serial port support for the raspi?

Wed Jan 06, 2016 2:48 pm

I still don't think I understand how to launch the thread outside of the UI thread. Also, I don't know how I can use the threadpool to call functions with return values. The UART functions either return number of bytes available in the stream or the data that you're reading from the stream, depending on which function you're using at a given time. Here is what I want to do.

Write byte to UART
Read response back from UART (timeout if no response within 100ms)
...repeat
...
...

But to read, I have to wait until the data is available in the stream and then it returns the number of bytes available.
Then I need to actually read the byte or bytes, which returns data as well.

How can I do this with the threadpool?

I was thinking about just using the stopwatch and creating a while loop that polls the input stream(LoadAsync) to see if data is available and then times out if data isn't received within 100ms.

streammylife
Posts: 4
Joined: Tue Dec 22, 2015 7:00 pm

Re: Serial port support for the raspi?

Wed Jan 06, 2016 3:52 pm

...like this

Code: Select all


            dataReaderObject = new DataReader(serialPort.InputStream);

            dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;

            listenTask = dataReaderObject.LoadAsync(8).AsTask<UInt32>(CancelWaitForData.Token);

            while(stopwatch.ElapsedTicks<finalTick)
            {
                //if (newTasks[0].Status == TaskStatus.RanToCompletion)
                if (listenTask.Status == TaskStatus.RanToCompletion)
                {
                    elapsedTicks = stopwatch.ElapsedTicks - initialTick;
                    rdyBytes = listenTask.Result;
                    break;
                }
            }

Return to “Windows 10 for IoT”