NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » Windows Programming using NerdKits

August 01, 2009
by rajabalu21
rajabalu21's Avatar

This material would be suitable for those who are familiar and comfortable with windows programming but have never attempted to interface with NerdKits.

Problem Statement: Read temperature values from the serial port and display the details as a chart on screen.

Solution: Let us first see a sample of our end application and then I’ll walk you through the steps to accomplish that. My finished application looks like this.

Development Platform: .NET Framework 2.0, Visual Studio Express 2005 and above. These are free downloads from Microsoft. Check it out here.

Language: C#.NET. Operating System: Windows Vista or Windows XP.

I will explain the basics of reading the data from the serial port in this post. Once you understand that, data is just data and you can do whatever you want with it. Let us just display the information as text on screen as shown in this video.

Microsoft has abstracted Serial Port in System.IO.Ports namespace. We could use that to our advantage and just with few lines of code we could start communicating with the serial port.

 // include the namespace
 using System.IO.Ports;

 // add a class variable sp as a SerialPort
 private SerialPort sp;

    // add the following code to any button click event handler
    private void btnCapture_Click(object sender, EventArgs e)
    {
        // creating a new instance of SerialPort
        sp = new SerialPort();
        // make sure that serial port is not already open
        // if so close it and open again
        if (sp.IsOpen)
        {
            sp.Close();
        }
        // You may want to change the port name from COM1 to the one that 
        // that is appropriate for your installation
        sp.PortName = “COM1”; // SerialPort.GetPortNames() will give you all active serial ports
        // Communication speed. Default is 9600 and you will get 
        // only garbled characters if you skip this step
        sp.BaudRate = 115200;

        try
        {
            // Open the serial port
            sp.Open();
            // set up handler to notify us when data is received 
            sp.DataReceived += sp_DataReceived;
        }
        catch(Exception ex)
        {
            // display error message in the event of failure
            MessageBox.Show(ex.Message, 
                            "Error Opening COM Port",  
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

So whenever data is received from the serial port our program will be notifed by the operating system by calling sp_DataReceived along with the parameters of interest. Now all we have to do is to just read the values as we receive them like any other normal function.

    void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        // this is the value we received from serial port
        string msg = sp.ReadExisting();

        if (!string.IsNullOrEmpty(msg))
        {
            // this function works in the background thread
            // so it cannot interact with the UI elements directly
            // Assignment such as txtTemp.Text = msg; will result in error
            // we need to marshal here and call a delegate for us update the textbox
            if (txtTemp.InvokeRequired)
            {
                SetTextCallback d = SetText;
                Invoke(d, new object[] {msg});
            }
            else
            {
                SetText(msg);
            }
        }
    }

    // this is the delegate and it has the same signature as our SetText function
    delegate void SetTextCallback(string text);

    // this is the round about way to set the text as it will be called 
    // from a different thread
    private void SetText(string temp)
    {
        txtTemp.Text += temp;
        // allow our form to render with the addition of new text
        Application.DoEvents();
    }

I will try to explain how to draw the graph on screen if anyone is interested.

Happy Coding!

Raja

August 02, 2009
by mcai8sh4
mcai8sh4's Avatar

Raja, nice work. I think this type of interfacing really helps to merge the real world electronics with computing.

Sadly I don't tend to spend much time in the realm of windows - but when I do need to, I'll certainly be shouting out to you for some advise.

I'll look forward to seeing some more of your projects.

December 27, 2009
by saleem
saleem's Avatar

HI Raja,

I really like this idea of serial port communication with windows. Do u have the complete code project for this with instructions on connecting with nerdkit please. I am very intersted in trying this out. I want to be able to send data to serial port using windows as well as receiving them from serial port.

Thx

Saleem

December 27, 2009
by rajabalu21
rajabalu21's Avatar

Saleem,

I have used the Temperature Sensor project of NerdKit as per the user manual and so the circuitry is the same but I have made minor changes to the software. I can send you the C# project and the NerdKit program if you could email me at rajabalu21 at gmail dot com.

Regards,

Raja

May 01, 2011
by kle8309
kle8309's Avatar

I just want to share this link which has serial port sample codes in several different languages link

This helped me a bunch

Note for visual c++ express 2010 build. Make sure you change the property setting to enable /clr (Common Language Runtime Support)

October 26, 2011
by axle38
axle38's Avatar

kle8309,

Thanks for the link to the C++ code. I don't have a programming background or any formal classes in programming so the examples help immensely. While the code to capture the data being sent across the serial port is beyond me, I did get the program to work so that it functions similarly to the Hyperterminal I use in XP. I've been graphing the rise and fall in temperature when I apply, and then remove, heat from the temperature sensor. (my fingers are the heat source) I go about this by opening the Hyperterminal, establishing a connection, selecting Transfer, creating a file to store the data, then capture text. After I apply power to the MCU, I collect several hundred data points then close the connection which then saves the data to the text file I created. I then open a spreadsheet, import the text file to .csv then graph the data. My question is this.

How do I get the C++ program to collect a set amount of data and then stop? I would like to collect 500 data points, then have the program automatically generate a file that will store the data. That way all I have to do is open the spreadsheet, import the file and graph it. Any suggestions?

Thanks, Alex

October 26, 2011
by sask55
sask55's Avatar

kle8309: I have used VBA modules to place serial data originating from digital callipers, temperature sensors, a haul effect current sensor, a keyboard and a resistor ladder circuit. Directly into excel sheets. I have posted some of the results that I obtained in the cases of the digital calliper and resistor ladder. If anyone is interested see,

http://www.nerdkits.com/forum/thread/683/ and http://www.nerdkits.com/forum/thread/1815/

There are a number of sites on the net that have VBA code available that will do the actual serial connection communication. The modules I have used as a basis for my serial communication between the micro and excel can be found at

http://dev.emcelettronica.com/serial-port-communication-excel-vba.

Any VBA code available on line will likely require some modification to parse the incoming data stream into a more useful form in your excel sheet. Without any changes the entire stream of incoming data will end up as one large string(text) in only one cell. The data parsing process can be carried out as the data is read into the sheet by a VBA module, or later if the quantity of data is small enough to be temporarily held in one cell.

I have made use of two way serial communication between the VBA (excel sheet) and the micro to control data flow. If anyone is interested I could supply a number of VBA example modules as well as the C code used on the micro. I am not programmer so I am quite sure that there are better ways to write these modules. I did get the get the data results that I was hoping for so in that respect they work fine. I suppose I could say I have examples of something that works not necessarily the best possible code. In any event I could elaborate if anyone wants to go down that road.

Darryl

October 27, 2011
by Ralphxyz
Ralphxyz's Avatar

If anyone is interested I could supply a number of VBA example modules as well as the C code used on the micro.

Darryl, there is a "How To" and "Projects" folders in the Nerdkit Community Library just waiting for your contributions.

Ralph

October 29, 2011
by axle38
axle38's Avatar

Hi Ralph, I was the one that asked about reading the MCU across the serial port into a file. I can't use VBA because I use OpenOffice spreadsheets so the tutorials on VBA aren't applicable. What I really would like is to define a set amout of data points to be collected and then have the program stop collecting data. The work of me loading the data into a spreadsheet isn't really a concern, just an added feature. Here is the code I use written in C++, compiled using Microsoft's Express 2010 edition, and built using CLR (common language runtime), not WIN32. The code is not mine but loaded from Microsoft's library of common functions. The link came from kle8309's post.

// ReadSerialPort.cpp : main project file.

#include "stdafx.h"
#using <System.dll>

using namespace System;
using namespace System::IO::Ports;

ref class PortDataReceived
{
public:
    static void Main()
    {
        SerialPort^ mySerialPort = gcnew SerialPort("COM5");

        mySerialPort->BaudRate = 115200;
        mySerialPort->Parity = Parity::None;
        mySerialPort->StopBits = StopBits::One;
        mySerialPort->DataBits = 8;
        mySerialPort->Handshake = Handshake::None;

        mySerialPort->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);

        mySerialPort->Open();

        Console::WriteLine("Press any key to continue...");
        Console::WriteLine();
        Console::ReadKey();
        mySerialPort->Close();
    }

private:
    static void DataReceivedHandler(
                        Object^ sender,
                        SerialDataReceivedEventArgs^ e)
    {

        SerialPort^ sp = (SerialPort^)sender;
        String^ indata = sp->ReadExisting();
        //Console::WriteLine("Data Received:");
        Console::Write(indata);

    }
};

int main()
{
    PortDataReceived::Main();
}

I tweaked the code in the program and on the MCU by just a few lines but primarily for formatting concerns. I know that the above code was not written for a device that continually sends data over the serial port but it's the best I could do for now. Clearly the code was meant to be run once and when the file was transferred, stop, and tell the user that the transfer was complete. Anyway to rewrite this to collect data in a loop and then exit the loop when enough data was collected?

Alex

October 29, 2011
by axle38
axle38's Avatar

I need to follow up on my last post; I failed to mention that I have tried running a loop. Specifically, I ran the the loop on the section of code below...

{

    SerialPort^ sp = (SerialPort^)sender;
    String^ indata = sp->ReadExisting();
    //Console::WriteLine("Data Received:");
    Console::Write(indata);

}

I use a while loop, i++ and i<100 but this certainly does not work as intended and I removed these lines of code to not cause any confusion. I'm not familiar with the above type of statements. Last time I imported data from an external source, it was in 2004 while in high school using Borland C++. Some things have changed.

December 15, 2012
by dvdsnyd
dvdsnyd's Avatar

Raja,

I know this post is old...

But I would really be interested in the details of how you did the graphing in your solution.

Thanks, David

Post a Reply

Please log in to post a reply.

Did you know that sound travels via pressure waves in the air, and you can make these with a piezoelectric buzzer? Learn more...