Tuesday 14 April 2009

USB, C# and Velleman K8055 USB Interface Board

The first step to using a PIC with USB connectivity was to find out a bit about USB communications.
The first thing to do was read up about USB protocol.
The 650ish page USB document is something I have not yet read (I have a little bit of a life) but I think there will be times I need to reference it.
The guide 'USB in a nutshell' is a great simple starter document.
So I read that and had a bit of an idea about the USB protocol. I learn better by doing practical things so I set myself a challenge to write a simple program to talk via USB to some inputs/outputs.
I saw the Velleman kit K8055 USB Experiment Interface Board from Maplin Electronics (around £30) and thought that would be useful to have a play around with. This was to learn about the host computer side of USB interfacing with a known and working hardware board. I could then play with the PIC hardware later.
I had decided to write my code in C# using the visual studio 2008 express edition as I had been told of the benefits - ease of use and benefits of both visual basic and C++. I'd not used it before so that will also be a learning curve.

The kit K8055 came with some example code written in Visual Basic and some code written in C++. It also came with a DLL to talk to the board (K8055D.dll).

I have now played around with C# and have managed to figure out how C# code can be written in order to use the functions within the K8055D.dll. This took a while so I'll try and explain it here...

Firstly the K8055D.dll file must be put into the C:\Windows\System32 folder.
(I made the mistake of using the updated .dll file that Velleman supply. This caused an amount of head scratching as the open device functions are slightly different.
I reverted back to the older K8055D.dll file.)

The functions within the .dll are outlined in the document: "MAN_UK_K8055_DLL.pdf" supplied with the kit. This gives all the names of the functions and some descriptions of their function - though it's pretty obvious.

Next came sorting out the C# code. The process involves using the DllImport command which imports the various functions from the .dll.

Two main things to realise:

1: You must put the following with the 'using' commands at the top of the code:
using System.Runtime.InteropServices;

This will allow the DllImport command to work.

2: You then have to import the .dll function.
This is done with the generic code:
[DllImport("DllName.dll")]
static extern type functionName(param1, param2....);

Where the bits in italic are changed depending upon your application.
An actual example from my code is:
[DllImport("K8055D.dll")]
static extern long OpenDevice(long CardAddress);

This Opens the device depending upon the card address. The function can then be called, for example:
DevOpen = OpenDevice(0);

This opens device 0 and returns the card address (which is a long integer).

The code in full is here:

Within my program.cs:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MyProject1
{
static class Program
{
/// The main entry point for the application.


static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

}
}

And within a form:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MyProject1
{
public partial class Form1 : Form
{
[DllImport("K8055D.dll")]
static extern long OpenDevice(long CardAddress);
[DllImport("K8055D.dll")]
static extern void CloseDevice();
[DllImport("K8055D.dll")]
static extern int SearchDevices();
[DllImport("K8055D.dll")]
static extern void SetAllDigital();
[DllImport("K8055D.dll")]
static extern void ClearAllDigital();
[DllImport("K8055D.dll")]
static extern void SetDigitalChannel(long SetChannel);

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
long DevOpen;
DevOpen = OpenDevice(0);
textBox1.Text = Convert.ToString(DevOpen);
button1.Text = "Device Connected";
SetDigitalChannel(1);
}

private void LED1_Click(object sender, EventArgs e)
{

if (LED1.Text == "I am ON")
{
LED1.Text = "I am OFF";
ClearAllDigital();
}
else
{
LED1.Text = "I am ON";
SetAllDigital();

}
}

private void button2_Click(object sender, EventArgs e)
{
CloseDevice();
// this.Close();

}


}

}


I hope that is helpful to people trying to do the same thing.
One thing to note is the with de-bugging turned on, when the form is closed then you will get a "vshost.exe has stopped working" error. This does not happen if you run without de-bugging, or if you run the .exe file for the project. I am unsure why this happens - if anyone has an idea of how to correctly stop this problem, please add a comment or email.

3 comments:

  1. Nice one, thnx for this !

    ReplyDelete
  2. Thanks alot. This will deffinetly help me.

    ReplyDelete
  3. Do you send for me Project file (C#).
    My Gmail is diepa9k39@gmail.com
    Thank you so much!

    ReplyDelete