.net Serial Communications with mbed

22 Mar 2010

Hi All,

This is my first mbed forum post as I only got my mbed 3 days ago.

I have been trying to control LED1 brightness via a .net (VB) program communicating over serial connection to the mbed. I have been having issues with sending floats from .net to mbed. A simplified version of the server .net code is shown below:

Imports System
Imports System.IO.Ports

Public Class Form1

Dim MyPort As New SerialPort("COM4", 9600, Parity.None, 8, StopBits.One)
Dim brightness as Double = 0.02

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Not MyPort.IsOpen Then MyPort.Open()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MyPort.WriteLine(brightness)
End Sub

This mbed code is shown here (a modified version of the "u" "d" tutorial:

#include "mbed.h"

Serial pc(USBTX, USBRX);
PwmOut led(LED1);

float brightness = 0.0;

int main() {

    while (1) {
        float c = pc.getc();
        brightness = c;
        led = brightness;
    }
}
It is probably something to do with the getc() function. I have tried scanf("%f",brightness) but this seems not to yield a result.

 

I hope this is something obvious I am missing.

Thanks in advance.

GuerrillaCoder

22 Mar 2010

Just realised this should probably be in the beginners forum.

Moderator can move it if needed :)

22 Mar 2010 . Edited: 22 Mar 2010

Hi Guerrilla,

Main thing to look at here is what

MyPort.WriteLine(brightness)

actually sends.

According to the Serial Port WriteLine method, it seems to write a text representation of the float, followed by a NewLine character (i'm assuming it converts it to text based on the description in Console.WriteLine). This is ideal, as it is a readable text value followed by a delimiter. I'm not sure what the NewLine character is (you can probably work this out), but effectively you need to recieve the same:

pc.scanf("%f\n", &brightness);

Note the & to pass the address of brightness, and \n to indicate the delimiter.

Maybe also indicate it has received a value using another led:

#include "mbed.h"

Serial pc(USBTX, USBRX);
PwmOut led(LED1);
DigitalOut led2(LED2);
 
float brightness = 0.0;

int main() {

    while (1) {
        float c = pc.scanf("%f\n", &brightness);
        led2 = !led2;
        led = brightness;
    }
}

You may need to investigate if '\n' is really what is sent as a newline, but something like this should work.

Simon

22 Mar 2010

When I used the code directly, I was having to pass two commands to get LED1 to change. I then noticed that you can change the terminating character/delimiter.

To get \n to be the delimiter, I had to set up the port to have

MyPort.NewLine = "\n"

This worked perfectly.

 

Thanks a lot. I think I need to work on my pointer knowledge :)

22 Mar 2010

That is great! I'd be interested to know what NewLine is set to by default? If you can't find out, perhaps write a little VB program that just prints it on the screen. Maybe they are sending '\r' or even "\r\n".

If you get a chance, I'd be very grateful if you could write up a notebook page on the basics of how you got communication between VB and mbed working; I'm sure you wont be the last to want to do this.

Simon

22 Mar 2010

It seems the default is taken from Environment.NewLine which is

A string containing "\r\n" for non-Unix platforms,
or
a string containing "\n" for Unix platforms.

says MSDN.

22 Mar 2010

I will write it up for .net serial communication, will have to do it from work tomorrow as I don't have visual studio at home :(

Yeah I think for .net it is a carriage return followed by a line feed. So \r\n or VbCrLf in VB.net :-)

See Link

22 Mar 2010

Thanks so much Guerrilla for bringing this topic up (even though I brought a similar one right before you).  I ported your code to C# and then ran it thinking that simply using Serial and setting NewLine to "\n" helped the program actually work.  Therefore, I went ahead and added a textBox hooked to a SerialPort.DataReceived event with a printf("Hello World") in the mbed program right after it received the brightness value and it thankfully worked!  So, I went ahead with other tests to see how they would follow through.  Unfortunately, the first test I tried, which was just a loop of printf("Hello World") with a 0.25 second delay after each once the mbed received the brightness value, only returned 1 "Hello World".  From that I believe program such as TeraTerm and Hyperterminal just send out a constant stream of blank (or full?) data to let the device know that it should send data.  Hopefully, someone here can help me solve this mystery.

Sincerely,

Dylan Dalrymple

2010 Intel ISEF Entrant

22 Mar 2010

You may have to set your C# code to respond to the DataReceived event on a separate thread using delegation. This worked for me to get over the ReadLine() issue.

I will have a look at your code and post some tomorrow to help you out.

23 Mar 2010

Well, I finally got my program to receive data from my mbed by simply sending an ASCII ACK byte through the serial port at the first instance of opening it and every time data is received.  I'm not sure if the ACK byte thing is necessary, but it sure does seem to work.  If anyone else comes up with a more elegant way of doing this, I'd be happy to here your input.

Sincerely,

Dylan Dalrymple

2010 Intel ISEF Entrant

18 Nov 2010

I don't know how relevant this is, but I've done some porting of VB to C# in playing around with the mbed and I've found that by using serial.write("/DigitalOut/new LED1 led1\r\n") for C#, the mbed will not receive the RPC command (works for VB). This is because C# stores strings in Unicode format. To get the output to send the string in ASCII, I did something like this:

string srcString = "/DigitalOut/new LED1 led1\r\n";

byte[] asciiString = Encoding.ASCII.GetBytes(srcString);

serialPort1.Write(asciiString, 0, asciiString.Length);

That seems to work. Again, if you are sending any kind of character or string from C# to mbed, make sure it is converted from Unicode to ASCII. Hope this helps with any communications problems you might have with C#.