Go Down

Topic: Arduino Ethernet Board UDP communication between C# and Arduino (Read 23277 times) previous topic - next topic

max1957

Hi folks. First let me say this is my first post. I am fairly new to Arduino and fairly new to network programming in general. That being said, I'll try to make my question clear.
I have an Arduino Ethernet Board connected to a hub and a PC (Windows 8) connected to an Ethernet port (different subnets) FWIW, the PC is an IPSEC Boundary machine.
My goal is simple proof-of-concept wherein I am trying to send a simple command to the Arduino from the C# program. The Arduino processes the input: '1' will turn the LED at PIN 9 on, '0' turns it off. After Arduino processes the command character, it should return information to the calling C# program.
The first half works famously: Arduino receives the command character and turns the LED on or off as expected. However, I cannot get anything back to the C# program.
I've looked at Wireshark capture and the Arduino Source keeps reporting "Destination unreachable (Port unreachable)" while the PC Source reports "Unknown 243" followed by "Identity Protection (Main Mode)". I've tried looking both of these messages up without much luck.
I am inserting both the Arduino sketch and the C# code below. Please note that I've been working on this for a couple weeks and while I've tried to clean up the code before posting it, it may look a bit messy...

Sketch:
Code: [Select]
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

//MAC on board: 90-A2-DA-0E-D9-91
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0E, 0xD9, 0x91 };
IPAddress ip(172, 29, 38, 80);

int led = 9;

unsigned int localPort = 8888;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

//Initialize EthernetUDP
EthernetUDP Udp;

char replyMsg[] = "Value Received";
char errMsg[] = "Problem";

void setup()
{
  //Start Ethernet and UDP
  pinMode(led, OUTPUT);
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop()
{
  int packetSize = Udp.parsePacket();
  char noNo[] = "Hello";

  if(packetSize)
  {
    for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;

    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    char valIn[packetSize]; // = packetBuffer;
   
    for(int i = 0; i < packetSize; i++)
    {
      valIn[i] = packetBuffer[i];
    }
    String theVal = valIn;

    int strIndex = theVal.length();

    if(theVal.substring(0,1) == "1")
    {
      Serial.println(Udp.remotePort());
      Serial.println(Udp.remoteIP());
      Serial.println("On ");
      digitalWrite(led, HIGH);
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.write("Hello");
      Udp.endPacket();
    }
    else if(theVal.substring(0,1) == "0")
    {
      Serial.println(Udp.remotePort());
      Serial.println(Udp.remoteIP());
      Serial.println("Off");
      digitalWrite(led, LOW);
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.write("GoodBye");
      Udp.endPacket();     
    }
    else
    {
      Serial.println(Udp.remotePort());
      Serial.println(Udp.remoteIP());
      Serial.println("Err");
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.write(errMsg);
      Udp.endPacket();
    }
  }
  delay(10);
}



C# code:
Code: [Select]
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace SendReceiveUDP
{
    class Program
    {
        static void Main(string[] args)
        {
            //Port and IP Data for Socket Client
            string IP = "172.29.38.80";
            int port = 8888;

            string inputVal = "1";
            while (inputVal != string.Empty)
            {
                var udpClient = new UdpClient();
                var clientReturn = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                inputVal = string.Empty;
                inputVal = Console.ReadLine();

                if (inputVal == string.Empty) break;
                try
                {
                    int inputInt;
                    int.TryParse(inputVal, out inputInt);

                    udpClient.Connect(IPAddress.Parse(IP), port);

                    // Sends a message to the host to which you have connected.
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(inputInt.ToString());

                    udpClient.Send(sendBytes, sendBytes.Length);

                    //System.Threading.Thread.Sleep(5000);

                    //IPEndPoint object will allow us to read datagrams sent from any source.
                    int newport = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port;

                    Console.WriteLine("newport= " + newport);

                    var remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);

                    Console.WriteLine("Parsed IP= " + remoteIpEndPoint.Address);
                    string returnData = string.Empty;
                    // Blocks until a message returns on this socket from a remote host.
                    try
                    {
                        try
                        {
                            clientReturn.Bind(remoteIpEndPoint);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Trying to Bind: " + ex.Message);
                        }

                        Byte[] receiveBytes = new byte[1024];

                        //The C# code stops execution here, waiting for a packet
                        clientReturn.Receive(receiveBytes, 0, receiveBytes.Length,SocketFlags.None);

                        returnData = Encoding.ASCII.GetString(receiveBytes);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Trying to Receive: " + ex.Message);
                    }

                    // Uses the IPEndPoint object to determine which of these two hosts responded.
                    Console.WriteLine("Message Received: " +
                                      returnData.ToString());
                    Console.WriteLine("Send from: " +
                                      remoteIpEndPoint.Address.ToString() +
                                      " on their port number " +
                                      remoteIpEndPoint.Port.ToString());

                    udpClient.Close();
                    clientReturn.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            }
        }
    }
}


Note: I have also tried running the C# code from a PC on the same subnet as the Arduino and while it processes the command character described and the C# code hangs where noted in the code block above, all I see in Wireshark is:
Source PC: Info = Source port: 54463 Destination port: ddi-udp-1
Source Arduino: Info = Source port: ddi-udp-1 Destination port: 54463

Any and all help and/or recommendations are appreciated!

max1957

Quick note to anyone looking at this post: I've worked out my fix. Will post soon as able.

ceesharpie

I've been getting a very similar error, my C# code will send the integer and perform the command on the arduino side but Arduino will not communicate back with my device. How did you possibly fix it I've been trying to for about a three days now.

max1957

ceesharpie, here is the code I used:

C#
Code: [Select]

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace SendReceiveUDP
{
    class Program
    {
        static void Main(string[] args)
        {
            //Port and IP Data for Socket Client
            var IP = IPAddress.Parse("172.29.38.80");

            int port = 8888;

            string inputVal = "1";
            while (inputVal != string.Empty)
            {
                var udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                var sendEndPoint = new IPEndPoint(IP, port);
                var receiveEndPoint = new IPEndPoint(IP, port);

                var clientReturn = new UdpClient(port);
                inputVal = string.Empty;
                inputVal = Console.ReadLine();

                if (inputVal == string.Empty) break;
                try
                {
                    int inputInt;
                    int.TryParse(inputVal, out inputInt);

                    // Sends a message to the host to which you have connected.
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(inputInt.ToString());

                    udpClient.SendTo(sendBytes, sendEndPoint);
                    string returnData = string.Empty;
                    // Blocks until a message returns on this socket from a remote host.

                    Byte[] receiveBytes;

                    receiveBytes = clientReturn.Receive(ref receiveEndPoint);
                    returnData = Encoding.ASCII.GetString(receiveBytes);

                    // Uses the IPEndPoint object to determine which of these two hosts responded.
                    Console.WriteLine("Message Received: " +
                                      returnData.ToString());

                    if (inputInt == 3)
                    {
                        receiveBytes = clientReturn.Receive(ref receiveEndPoint);
                        returnData = Encoding.ASCII.GetString(receiveBytes);

                        // Uses the IPEndPoint object to determine which of these two hosts responded.
                        Console.WriteLine("Message Received: " +
                                          returnData.ToString());
                    }

                    udpClient.Close();
                    clientReturn.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            }
        }
    }
}


Arduino sketch:
Code: [Select]

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

//MAC on board: 90-A2-DA-0E-D9-91
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0E, 0xD9, 0x91 };
IPAddress ip(172, 29, 38, 80);

int led = 9;

unsigned int localPort = 8888;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

//Initialize EthernetUDP
EthernetUDP Udp;

char replyMsg[] = "Value Received";
char errMsg[] = "Problem";

void setup()
{
  //Start Ethernet and UDP
  pinMode(led, OUTPUT);
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop()
{
  int packetSize = Udp.parsePacket();
  char noNo[] = "Hello";

  if(packetSize)
  {
    for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;

    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    char valIn[packetSize]; // = packetBuffer;
   
    for(int i = 0; i < packetSize; i++)
    {
      valIn[i] = packetBuffer[i];
    }
    String theVal = valIn;

    int strIndex = theVal.length();

    if(theVal.substring(0,1) == "1")
    {
//      Serial.println(Udp.remotePort());
//      Serial.println(Udp.remoteIP());
//      Serial.println("On ");
      digitalWrite(led, HIGH);
      Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write("Flame On!");
      Udp.endPacket();
    }
    else if(theVal.substring(0,1) == "0")
    {
//      Serial.println(Udp.remotePort());
//      Serial.println(Udp.remoteIP());
//      Serial.println("Off");
      digitalWrite(led, LOW);
      Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write("Flame off.");
      Udp.endPacket();     
    }
    else if(theVal.substring(0,1) == "3")
    //Blinks the LED - off, on; ending off
    {
//      Serial.println(Udp.remotePort());
//      Serial.println(Udp.remoteIP());
//      Serial.println("Blinking");
      digitalWrite(led, LOW);
      Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write("Fade in...");
      Udp.endPacket();
      int i = 1;
      for(int x = 0; x > -1; x = x + i)
      {
        analogWrite(led, x);
        if(x == 255) i = -1;
        delay(20);
//        digitalWrite(led, HIGH);
//        delay(2000);
      }
            Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write("Fade out...");
      Udp.endPacket();
      digitalWrite(led, LOW);
    }
    else
    {
//      Serial.println(Udp.remotePort());
//      Serial.println(Udp.remoteIP());
//      Serial.println("Err");
      Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write(errMsg);
      Udp.endPacket();
    }
  }
  delay(10);
}


Please ignore the commented lines in the sketch. Also, if you compare it to the original sketch, you will see I made some functional changes (Fade in and Fade out of the LED, rather than on and off).

Hope this helps!

abhi9912


Maja

this is the error am getting in the script at the 8th line. any help please?

the namespace 'SendReceiveUDP' already contains a definition for 'Program'

PaulS

You can NOT name your class Program. You can use ANY other name. That is basic C#.
The art of getting good answers lies in asking good questions.

Maja

You can NOT name your class Program. You can use ANY other name. That is basic C#.
am new to c# so dont know much. the program uploaded here writes class program, so what shal i do?

PaulS

Quote
so what shal i do?
Zip up your entire solution folder and attach it here.

There is a lot about that program that I do not like. new Socket returns a Socket instance. Storing that in a var is a poor idea. The same holds true for every other var type variable that you have. Use the proper types.

Code: [Select]
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(inputInt.ToString());
You just converted a string containing an integer representation to an int. It is silly to convert that int back to a string.

The art of getting good answers lies in asking good questions.

Maja

am doing nothing just copied this c# program and made a script in Unity but it doesn't works. First it was about namespace now it says that i have to use monobehaviour but how?

PaulS

Quote
now it says that i have to use monobehaviour but how?
Would you like 1/10th of an answer? If not, why do you post 1/10th of an error message?
The art of getting good answers lies in asking good questions.

Maja


Maja


PaulS

Quote
this is what i get
That is a problem between Unity and the C# app. It has NOTHING to do with the Arduino.
The art of getting good answers lies in asking good questions.

Maja

yes but if i solve this then and only then i will be able to get an output on the arduino

Go Up