This C# class combined with the Arduino sketch allows you to plug an Arduino into a PC's USB port and then have its com port detected by the C# application. Once the com port is known the C# application can then send/receive messages from the Arduino.
I used an Arduino Uno, C# 4.0, Windows 7.
This code does not work on Leonardo's because, apparently, a Leonardo requires setting the DtrEnable property of the SerialPort object to true. I don't have a Leonardo so can't test this but I believe it to be true based on the forum posts.
The concept is quite simple. The C# application polls all the com ports and sends a query using a simple protocol (explained below). Once the Arduino receives the request it replies. The C# application that notes the com port that caused the Arduino to reply and saves the name of the com port. The C# application can then use this com port in subsequent communications.
Comms Protocol
This uses a 4 byte message Byte 0 is the start of command marker. This is always decimal 16 converted to byte (Convert.ToByte(16);)
Byte 1 is the type of command:
127 = Send data to pins
128 = Identify
Byte 2 is the pin to receive data
Byte 3 is the valus for the pin
So send 100 to pin 3 is:
16,127,3,100
And ask the Arduino to return the identify message is:
16,128,0,0
I note the code uses an extra Byte 4. This was an end of message marker but is not used
You can easily add to the protocol. In one projects I use command 129 to request data back from the Arduino.
If you have questions send me a personal message via the forum Richard210363
Sketch
/*
* Serial Port Monitor * * */
//Setup Output int ledPin_3 = 3;
//Setup message bytes
byte inputByte_0;
byte inputByte_1;
byte inputByte_2;
byte inputByte_3;
byte inputByte_4;
//Setup
void setup() {
pinMode(ledPin_3, OUTPUT); Serial.begin(9600); digitalWrite(ledPin_3, HIGH);// delay(250);// digitalWrite(ledPin_3, LOW);// delay(250);//
}
//Main Loop
void loop() {
//Read Buffer
if (Serial.available() == 5)
{
//Read buffer
inputByte_0 = Serial.read();
delay(100);
inputByte_1 = Serial.read();
delay(100);
inputByte_2 = Serial.read();
delay(100);
inputByte_3 = Serial.read();
delay(100);
inputByte_4 = Serial.read();
}
//Check for start of Message
if(inputByte_0 == 16)
{
//Detect Command type
switch (inputByte_1)
{
case 127:
//Set PIN and value
switch (inputByte_2)
{
case 4:
if(inputByte_3 == 255)
{
digitalWrite(ledPin_3, HIGH);
break;
}
else
{
digitalWrite(ledPin_3, LOW);
break;
}
break;
}
break;
case 128:
//Say hello
Serial.print("HELLO FROM ARDUINO");
break;
}
//Clear Message bytes
inputByte_0 = 0;
inputByte_1 = 0;
inputByte_2 = 0;
inputByte_3 = 0;
inputByte_4 = 0;
//Let the PC know we are ready for more data
Serial.print("-READY TO RECEIVE");
}
}
C#
using System;
using System.Threading;
using System.IO.Ports;
using System.IO;
public class ArduinoControllerMain {
SerialPort currentPort;
bool portFound;
private void SetComPort() { try { string[] ports = SerialPort.GetPortNames(); foreach (string port in ports) { currentPort = new SerialPort(port, 9600); if (DetectArduino()) { portFound = true; break; } else { portFound = false"; } } } catch (Exception e) { } }
private bool DetectArduino() { try { //The below setting are for the Hello handshake byte[] buffer = new byte[5]; buffer[0] = Convert.ToByte(16); buffer[1] = Convert.ToByte(128); buffer[2] = Convert.ToByte(0); buffer[3] = Convert.ToByte(0); buffer[4] = Convert.ToByte(4);
int intReturnASCII = 0; char charReturnValue = (Char)intReturnASCII;
currentPort.Open(); currentPort.Write(buffer, 0, 5); Thread.Sleep(1000);
int count = currentPort.BytesToRead; string returnMessage = ""; while (count > 0) { intReturnASCII = currentPort.ReadByte(); returnMessage = returnMessage + Convert.ToChar(intReturnASCII); count--; } ComPort.name = returnMessage;
currentPort.Close();
if (returnMessage.Contains("HELLO FROM ARDUINO"))
{
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
return false;
}
}
}