Pages: [1] 2   Go Down
Author Topic: Controlling Arduino with C#  (Read 7247 times)
0 Members and 1 Guest are viewing this topic.
New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello everyone,

can any body tell me how to link more than one pin from Arduino to C#?
I'm trying to control Arduino directly from a small code from C# but i can't get it to work.  ;D
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

0
Offline Offline
God Member
*****
Karma: 39
Posts: 986
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One technique you might consider is to put Bitlash on the Arduino and send commands through the serial port to control the digital IO.

Bitlash is an interpreter that runs on Arduino, available at http://bitlash.net

-br
http://bitlash.net
http://entropymouse.com
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46090
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a C# application that sends serial data to the Arduino, and reads any responses.

Altering that application to send specific commands to the Arduino when specific buttons are pressed is easy.

Making the Arduino do something in response to a serial command is easy. That can include sending serial data back to the C# application.

Quote
I'm trying to control Arduino directly from a small code from C# but i can't get it to work.
Post your C# code and Arduino code. We can then help you figure out what the problem is.
Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is my Arduino code:
Code:
int ledPinA = A1;//Setting Pin A1 for the LED
int ledPin = 2;//Setting Pin 2 for the LED

void setup()
{
  pinMode(ledPin, OUTPUT);//ledPin as an output
  Serial.begin(9600);
}

void loop()
{
  
if(Serial.available())//checking for serial
  {
    int LedStatus = Serial.read();//reading from serial ports
    if (LedStatus == '1')
    {    
      digitalWrite(ledPin,HIGH);//turn on LED
    }
    else if (LedStatus == '0')
    {
     digitalWrite(ledPin,LOW);
     int LedIntensity_Scroll = Serial.read();//reading from serial port
     analogWrite(ledPinA, LedIntensity_Scroll);//What to use this to change the intensity of the led light.
    }
    Serial.flush();
  }
}



This is the C# code:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;

namespace ArduinoLedControl
{
    public partial class ArduinoLEDControl : Form
    {
        bool ledState = false;//setting initial led status

        public ArduinoLEDControl()
        {
            InitializeComponent();
        }

        private void LedOn_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write("1");//tells arduino that the port is ON
                LedStatusBox.Text = "THE LED IS ON";//tells the user that the led is ON
                LedOnButton.Enabled = false;//disable the ON button
                LedOffButton.Enabled = true;//enable the OFF button
                ledState = true;//turn on LED
                LedIntensity.Enabled = false;//disabling he led intensity track bar
            }
            else
            {
                MessageBox.Show("There is no Serial Ports open.");//message box telling user that there is not ports open
            }
        }

        private void LedOff_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write("0");//tells arduino that the port is OFF
                LedStatusBox.Text = "THE LED IS OFF";//tells the user that the led is OFF
                LedOnButton.Enabled = true;//enable the ON button
                LedOffButton.Enabled = false;//disable the OFF button
                ledState = false;//turn off LED
                LedIntensity.Enabled = true;//enabling he led intensity track bar
            }
            else
            {
                MessageBox.Show("There is no Serial Ports open.");//message box telling user that there is not ports open
            }
        }

        private void ArduinoLEDControl_Load(object sender, EventArgs e)
        {

        }

        private void LedStatusBox_TextChanged(object sender, EventArgs e)
        {

        }

        private void StartPortButton_Click(object sender, EventArgs e)
        {
            if (SelectPortBox.SelectedItem == null)
            {
                MessageBox.Show("No Serial Ports was selected, Try again.");//message box telling user that there is not ports open
            }

            else
            {
                serialPort1.PortName = SelectPortBox.SelectedItem.ToString();//setting serialPort1 to a selected port by user
                serialPort1.BaudRate = 9600;//this value most be the same as in serial.begin(9600) of arduino's code

                if (serialPort1.IsOpen == true)
                {
                    serialPort1.Write("0");
                    serialPort1.Close();//closing port if previously open
                    LedStatusBox.Clear();
                }
                else
                {
                    serialPort1.Open();//opening port when the program starts
                }
            }
        }

        private void SelectPortBox_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void ClosePortButton_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == true)//checking if any port is open in order to close it
            {
                serialPort1.Write("0");
                serialPort1.Close(); //close serialPort1
                MessageBox.Show("Serial Port: " + serialPort1.PortName + " have been closed.");//message box telling user that the port is closed
                LedStatusBox.Clear();
            }
            else
            {
                MessageBox.Show("There is no Serial Ports open.");//message box telling user that there is not ports open
                LedStatusBox.Clear();
            }
        }

        private void LedIntensity_Scroll(object sender, EventArgs e)
        {
            serialPort1.Write(LedIntensity.Value.ToString());//This is where the problem happens
            //Console.WriteLine(LedIntensity.Value.ToString());
        }
    }
}


I can not operate arduino with the line :   serialPort1.Write(LedIntensity.Value.ToString());      and receive the command/data at arduino with  int LedIntensity_Scroll = Serial.read();



I will really appreciate your help, also, how many ports can i use with the Duemilanove ATmega328P? :-/

Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46090
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lets take the questions in reverse order.

Quote
how many ports can i use with the Duemilanove ATmega328P?
All of them. All one of them, to be specific. The Duemilanove has just one hardware serial port, connected to the USB port.

Quote
I can not operate arduino with the line :   serialPort1.Write(LedIntensity.Value.ToString());      and receive the command/data at arduino with  int LedIntensity_Scroll = Serial.read();
You are getting the numeric value from a field and converting it to a string, and sending that string to the serial port.

You are then trying to read the number that was sent.  Where is the magic conversion of the string back to a number supposed to occur?

You are trying to read the 2nd byte of the string as a number only if the first byte is not a 1 (which it never is, since 1 is not a printable ASCII value, and you are only sending printable ASCII values).

Code:
   Serial.flush();
Throw away the rest of the string. Good idea. NOT.

First, you need to define a protocol. You want the sending application to be able to turn an LED on or off, using digitalWrite on the Arduino OR control the brightness of an LED using analogWrite. Currently, you are not telling the Arduino WHICH action it is to perform, just the data that it needs to perform the action, if it knew which action to perform.

You should be sending something like <D0>, <D1>, or <A32>, where < is a start of packet marker, D and A are commands, 0, 1, and 32 are values for the commands, and > is an end of packet marker.

All data is to be sent as strings.

Then, the Arduino needs to read the strings, store the data in an array, parse the array when the end of the packet arrives, and use the command and value to perform an action.

Search the forum for "started && ended" for an example of how to receive strings with start and end markers. There is a section in the code that I posted where you then perform the parsing and action.

Parsing is simple in your case. The command is a single letter. After determining the command, replace that letter with a 0, and call atoi with the rest of the string, to get an integer value. If the command is D, test the integer value for 0 or 1. If the command is A, analogWrite can be passed the value.
Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you PaulS, your post was of great guidance to me specially because I'm not familiar with Arduino or coding over all. Is this the post you are refering to http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282127488/24 ??? Can you provide me any other examples related to what I want to do? ;D
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46090
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Reply #20 in that thread has one example of the code I was referring to.

You can send serial data to the Arduino, and have it do nothing but echo the data back.

This allows you to develop the sending application, first. Make the LED On button send <D1>. Then, make the LED Off button send <D0>. Then, make the slider callback send <Axxx> where the string returned by LedIntensity.Value.ToString();.

When all three callbacks send the right data, then work on the collecting, parsing, and using code on the Arduino, one step at a time. Collect the data, and echo it back to the C# application. Then, parse it, and echo the parsed information. Finally, use the parsed data to control stuff.
Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a lot Paul, I'm going on my epic journey to find the secrets of communicating with Arduino.  ;D
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello again,

I stored the data received from C# into a buffer. I managed to get the on and off ( <D0> and <D1> ) work ( Thank a lot PaulS ), but how can I get the analog ( <Axxx> ). I can identify the A, but how can i get the number xxx to be in int???  
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46090
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I can identify the A, but how can i get the number xxx to be in int???
After determining that the first character in the array is indeed an 'A', replace the 'A' with a '0'. Then, call atoi() with the string as the argument.

Code:
char inData[] = "A382";
if(inData[0] == 'A')
{
   inData[0] = '0'; // inData now holds '0', '3', '8', '2', NULL

   int val = atoi(inData); // val now holds 382
}
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12451
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

0r start conversion at index 1, just after the A. This keeps the original string intact, optionally for later use. Note: added a var cmd to hold the type of command.

Code:
char cmd = inData[0];
int val = atoi( &inData[1] );  
« Last Edit: November 02, 2010, 07:37:34 am by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I finally got the code to work properly. This is the final version of the code. Actually, I could say my real first code  8-). PaulS should make a book of advises/codes and sell it...
Code:
/*
Code by: Reynal74
special thanks to PaulS for all his help
*/
//Variable Declaration
int ledPin = 9;//Setting Pin 9PWM for the LED
boolean started = false;
boolean ended = false;
char buffer[300];//creating buffer large enough
int serialIn = 0;//counter for the incoming data
int atoiHolder = 0;//holds the value of atoi

void setup(){
  pinMode(ledPin, OUTPUT);//ledPin as an output
  Serial.begin(9600);
}

void loop(){
  while(Serial.available() > 0){
    char incomingData = Serial.read(); //reading from the serial ( data from C# )

    if(incomingData == '<'){//check for started packet
      started = true;//the string started
      ended = false;
    }
    else if(incomingData == '>'){//check for ended packet
      ended = true;//indicated end of the reading
      break; //break out of the loop
    }
    else{
      buffer[serialIn] = incomingData;//begining to store data in the buffer
      serialIn++;
      buffer[serialIn] = '\0';// NULL terminate the array
    }
  }//END OF WHILE LOOP
  //--------------CHECKING & TESTING -------------------
  if(started && ended){
    //GETTING THE ON AND OFF BUTTON FROM C# WORKING
    if(buffer[0] == 'D' && buffer[1] == '0'){//turn off the light
      digitalWrite(ledPin,LOW);
    }
    else if(buffer[0] == 'D' && buffer[1] == '1'){//turn on the light
      digitalWrite(ledPin,HIGH);
    }
    //GETTING THE TRACK BAR FROM C# WORKING (TO VARY THE LED LIGHT INTENSITY)
    else if(buffer[0] == 'A'){
      buffer[0] = '0';//replaces A by '0' and now buffer holds '0','X','X','X',NULL
      atoiHolder = atoi(buffer);//atoiHolder (LED Intensity) now holds XXX
      
      /*ALTERNATIVE METHOD SUGGESTED BY: robtillaart
      start conversion at index 1, just after the A. This keeps the original string intact,
      optionally for later use. Note: added a var cmd to hold the type of command.
          char cmd = inData[0];
          int val = atoi( &inData[1] );
      */
      analogWrite(ledPin,atoiHolder);
    }
    else {
      //If no data matches the descriptions above, give a blinking light to indicate an error
      digitalWrite(ledPin,HIGH);
      delay(100);
      digitalWrite(ledPin,LOW);
      delay(100);
    }
    serialIn = 0;//resetting serialIn
    buffer[serialIn] = '\0';//Null the buffer array
    started = false; //reset to false
    ended = false; //reset to false
  }//END OF CHECKING & TESTING
}

Can Arduino tell C# or any other program what to do ( like control the other program )? If so, can those commands be made into graphic? what is the maximum amount of FLOPS that Arduino can put out? Can Arduino board program any other chips?
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46090
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can Arduino tell C# or any other program what to d
The Arduino can send data to the serial port, which the C# application can read. It is up to you to define commands for the Arduino to send, and to write the code to make the C# application respond in appropriate ways.

Quote
If so, can those commands be made into graphic?
I have a pretty neat 3D graphics application written in C#. Has nothing to do with Arduino, and it's company proprietary so I can't share it. But, C# can do graphics. If you send sensor data to the application, C# could create a plot of it.

Quote
what is the maximum amount of FLOPS that Arduino can put out?
The Arduino executes 16,000,000 instructions per second.

Logged

Melbourne, Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure if it is relevant, however I'm building an open C# application to send instructions to and receive "telemetry" from the Arduino.  (I'll have to post the link in a second reply because I'm new here!)

There is a brief tutorial there on parsing messages on the Arduino and the C# code is available on github.
Logged

Melbourne, Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

http://mechariusprojects.com/thunderbolt
Logged

Pages: [1] 2   Go Up
Jump to: