FEZ PANDA III UDP Example

Dear All,

What I need?
Communication between a Windows 7 PC and FEZ Panda III via UDP protocol.

What I have?

  1. Windows 7 Laptop
  2. RJ45 cable
  3. FEZ Panda III board
  4. ENC28J60 board connected to FEZ Panda III

What I have done so far?

  1. Installed dot net micro framework
  2. Created couple of FEZ panda project in VS 2013 and played some pdf based applications - LED lighting

What I don’t know:

  1. How to ping FEZ panda III from Windows 7 laptop commad prompt
    example, ping 192.168.0.10 if panda’s IP is that. Also, how to assign static IPs?
  2. How can I write a UDP application in Panda III?

Any sample codes will be appreciated.

My background: C# application developer

If you feel like my question is not enough meaningful, I will explain more. Thank you

Hi,
you can find some help in

Documents → Networking
If you don’t succeed to get an IP, please show how you connected the ENC28 mudule and show your code.
Kind regards
RoSchmi

1 Like

Hi RoSchmi,

This is the link I started initially.For beginers. I have a foundation already. But need next advanced step. Regarding UDP transmission. Any specific post?

You asked how to get a static IP. Do you have verified in your code that your router assigned an IP to your Panda III?

if you have switch you need two cable one for laptop and one for panda

otherwise you need crossover cable to connect panda direct to your pc(laptop)

Hi Roschmi,

I went through the ethernet session in
https://www.ghielectronics.com/docs/30/networking. When I try to add the library

In a normal c#.Net app, I can import System.Net. but in microframework, I can’t.

Hi Valon,
No, I am not using a switch. I am using a single LAN cable to connect.

Ramb

in this way you need crossover cable to cannect pc with panda ethernet directly and follow @RoSchmi instructions above

1 Like

I am trying to follow @RoSchmi. But the tutorial is using dhcp. I need static IP. Attached is a source code I got from ghielectronics forum. Lot of errors. Trying to debug. Sorry if I didn’t format the code sample. I tried alot to find an option to put the code in quotes. the option is not working for me in this forum site.

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Threading;
using System.Text;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Net.NetworkInformation;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace VMS_Socket_Test
{
public partial class Program
{

    bool NetworkReady = false;
    string deviceIp = "192.168.100.14";
    string serverIp = "192.168.100.10";
    byte[] EthMac = new byte[] { 0x9E, 0x12, 0x81, 0x79, 0x3B, 0x04 };
    bool useDHCP = false;

    void ProgramStarted()
    {

        Debug.Print("Program Started");
            
        if (true)
        {
            var EthernetThread = new Thread(
               () => EthernetInitialize());
            EthernetThread.Start();
        }

        Debug.Print("Startup suceeded!");
    }//Main

    
    #region Ethernet
    
    bool EthernetInitialize()
    {

        ethernetJ11D.NetworkInterface.PhysicalAddress = EthMac;
        Debug.Print("Opening interface...");
        ethernetJ11D.NetworkInterface.Open();
        if (useDHCP == false)
        {
            Debug.Print("Set static IP...");
            ethernetJ11D.NetworkInterface.EnableStaticIP(deviceIp, "255.255.255.0", "192.168.100.1");
            ethernetJ11D.NetworkInterface.EnableStaticDns(new string[] { "8.8.8.8", "192.168.100.1" });
        }
        else
        {
            Debug.Print("Get DHCP IP...");
            //// DHCP IP
            if (ethernetJ11D.NetworkInterface.IsDhcpEnabled == false)
            {
                ethernetJ11D.NetworkInterface.EnableDhcp();
                ethernetJ11D.NetworkInterface.EnableDynamicDns();
            }
        }

        ethernetJ11D.UseThisNetworkInterface();

        NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
        NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);

        int cnt = 0;
        while (NetworkReady == false)
        {
            Debug.Print("Waiting for network ready " + (cnt++));
            Thread.Sleep(1500);
        }
        NetworkReady = true;
        Thread.Sleep(3000);
        return NetworkReady;
    }

    void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
    {
        Debug.Print("Network has changed! " + e.IsAvailable.ToString());
        NetworkReady = e.IsAvailable;
    }

    private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
    {
        Debug.Print("New address for the Network Interface ");
        Debug.Print("------------------------------------------------------");
        if (ethernetJ11D.NetworkInterface.IPAddress != "0.0.0.0")
        {
            NetworkReady = true;
        }

        Thread.Sleep(3000);
        MessageHandler.Init();
        Thread.Sleep(3000);
        WorkerStart();
    }


    # endregion

    void WorkerStart()
    {
        Debug.Print("Worker started.");
        string command = "/rcp.xml?command=0x09A5&type=P_OCTET&direction=WRITE&num=1&payload=0x810006011201"; // HTTP request string

        while (true)
        {
            try
            {
                MessageHandler.SendRCPCommand(serverIp, command, "GET_PAN_POS", true);              
                Thread.Sleep(200);
             }
            catch
            {
                Debug.Print("!!!!!!!!!!!!!!!!!  Worker Exception");
                Thread.Sleep(1000);
                Debug.GC(true);
            }

        }
    }


}

public class Message
{
    public string PtuIp = "";
    public string data = "";
    public string command = "";
    public DateTime born = DateTime.UtcNow;
    public bool parseResponse = false;
}

public static class MessageHandler 
{
    private static Queue messagesToSend = new Queue();
    private static Thread sendThread = null;
    private static Thread parseThread = null;

    public static void Init()
    {

        try
        {

            sendThread = new Thread(new ThreadStart(Sender));
            sendThread.Priority = ThreadPriority.AboveNormal;
            sendThread.Start();

            Debug.Print("****** Message Handler Init Suceeded");
        }
        catch
        {
            Debug.Print("!!!!!!!!!! Message Handler Init Failed!");
        }
    }

    static void Sender()
    {
        Debug.Print("Starting Sender() thread.");
        Int32 senderCounter = 0;
        Int32 overallCounter = 0;

        while (true)
        {
            senderCounter = 0;
            try
            {
             
                while (messagesToSend.Count > 0)
                {
                    try
                    {
                        senderCounter++;
                        overallCounter++;

                        Debug.Print("----- Sender queue count: " + messagesToSend.Count.ToString());
                        Debug.Print("----- Sender overal count: " + overallCounter.ToString());

                        Message message = null;

                        lock (messagesToSend)
                        {
                            message = messagesToSend.Dequeue() as Message;
                        }

                        if (message != null)
                        {
                            
                            SendSocket(message, senderCounter);

                        }
                        Thread.Sleep(70);

                        if (messagesToSend.Count > 55)
                        {
                            messagesToSend.Clear();
                            Debug.Print(" !!!!!!! Clear Queue");
                        }

                    }
                    catch
                    {
                        Debug.Print("ERROR Sender");
                    }
                }
            }
            catch (Exception exception)
            {
                Debug.Print("Error 90");
            }
        }
    }

    public static void SendRCPCommand(string IPAdr, string data, string command, bool ParseResponse)
    {
        Message message = new Message();
        message.PtuIp = IPAdr;
        message.data = data;
        message.command = command;
        message.parseResponse = ParseResponse;
        message.born = DateTime.UtcNow;
        EnqueueMessage(message);
    }

    private static void EnqueueMessage(Message message)
    {
        lock (messagesToSend)
        {
            messagesToSend.Enqueue(message);
        }
        Debug.Print("Message. Queue cont: " + messagesToSend.Count.ToString() + " at " + DateTime.UtcNow.TimeOfDay.ToString());
    }

    static void SendSocket(Message message, int count)
    {
        string serverIP = "192.168.100.10";
        int serverPort = 80;
        const Int32 c_microsecondsPerSecond = 100000;
        IPAddress hostEntry = IPAddress.Parse(serverIP);    // UDP
        IPEndPoint hostep = new IPEndPoint(hostEntry, serverPort);  // UDP

        try
        {
             using (Socket serverSocket = ConnectSocket(serverIP, serverPort))
            {
                    String request = "GET " + message.data + " HTTP/1.1\r\n" +
                    "Host:" + serverIP + "\r\n" +
                    "Content-Length:" + message.data.Length + "\r\n" +
                    "Connection:close\r\n" +
                    "Cache-Control:no-cache\r\n" +
                    "\r\n";

                Byte[] bytesToSend = Encoding.UTF8.GetBytes(request);
                serverSocket.Send(bytesToSend, bytesToSend.Length, 0); // TCP
                TimeSpan delay = (DateTime.Now - message.born);
                Debug.Print("Socket sent " + serverSocket.LocalEndPoint.ToString() + " : " + message.command.ToString() + " Length: " + message.data.Length + "  Count: " + count.ToString() + " at " + DateTime.UtcNow.TimeOfDay.ToString() + " m created at: " + message.born.TimeOfDay.ToString() + " delay: " + delay.Milliseconds.ToString() + ". Thread :" + Thread.CurrentThread.ManagedThreadId.ToString());

                if (message.parseResponse)
                {
                    Byte[] buffer = new Byte[1024];
                    String page = String.Empty;

                    while (serverSocket.Poll((30 * c_microsecondsPerSecond), SelectMode.SelectRead))
                    {
                        Array.Clear(buffer, 0, buffer.Length);
                        Int32 bytesRead = serverSocket.Receive(buffer);
                        if (bytesRead == 0)
                            break;
                        page = page + new String(Encoding.UTF8.GetChars(buffer));
                    }

                    if (page != "")
                    {
                        Debug.Print("Page :" +  page);
                    }
                }
            }
            Debug.Print("Socket relased at: " + DateTime.UtcNow.TimeOfDay.ToString());
        }
        catch (Exception e)
        {
            Debug.Print("new Sender Excp");
        }
    }
    
    private static Socket ConnectSocket(String server, Int32 port)
    {
        try
        {
            IPAddress hostEntry = IPAddress.Parse(server);
            IPEndPoint hostep = new IPEndPoint(hostEntry, port);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.SendTimeout = 500;
            socket.Connect(hostep);
            Debug.Print("Socket connected. LocalEndPoint " + socket.LocalEndPoint.ToString() + " RemoteEndPoint " + socket.RemoteEndPoint.ToString());
            return socket;
        }
        catch
        {
            Debug.Print("Socket connection failed: " + server);
        }
        return null;
    }
}

}

ethernet J11 is not ENC28J60 ???

The following code requires the GHI.Networking, Microsoft.SPOT.Hardware, and Microsoft.SPOT.Net assemblies.

also you need correctly connect Enc28j60 pins at panda board

In your code you are using a “Gadgeteer” project. Projects for the Panda III should usually start with the NETMF ConsoleApplication template.

Here is an example how to initialize the network with a static IP for the ENC28 module. The Project is for the Cobra III mainboard and the pins used for SPI initialization have to be adapted for the Panda III.
https://www.ghielectronics.com/community/codeshare/entry/1095

1 Like

Hi Roschmi, Valon,

I tried both of your suggestions. Thank you Roschmi for your code. It is for Cobra, but I use panda, anyway, I got how to write code for static IP. Rest of the portion in that project is for Http so I left it. Please note these points,
a) I configured the EthernetENC28J60 object using following API

public EthernetENC28J60(SPI.SPI_module spi, Cpu.Pin chipSelect, Cpu.Pin externalInterrupt);
//
// Summary:
// Creates a new instance.
//
// Parameters:
// spi:
// The SPI module the device is wired to.
//
// chipSelect:
// The chip select the device is using.
//
// externalInterrupt:
// The external interrupt pin the device is using.
//
// reset:
// The reset pin the device is using.
public EthernetENC28J60(SPI.SPI_module spi, Cpu.Pin chipSelect, Cpu.Pin externalInterrupt, Cpu.Pin reset);

and I called as
ethernetJ11D = new GHI.Networking.EthernetENC28J60(Microsoft.SPOT.Hardware.SPI.SPI_module.SPI2, G120.P0_5, G120.P0_4, G120.P4_28);

based on my board.

I wrote the function in main() as below;

public static void Main()
{
Debug.Print(Resources.GetString(Resources.StringResources.String1));
blinkLED();
setEthernet();
}

    public static void setEthernet()
    {
        NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
        NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
        netif = new GHI.Networking.EthernetENC28J60(Microsoft.SPOT.Hardware.SPI.SPI_module.SPI2, //Verified
                                                FEZPandaIII.Gpio.D20,//This is Chip select, verified    
                                                FEZPandaIII.Gpio.D21,//This is for external interrupt, but not used 
                                                FEZPandaIII.Gpio.D25//Reset // not used
                                                );            
        netif.Open();
        // for static IP
        netif.EnableStaticIP("192.168.1.23", "255.255.255.0", "192.168.1.1");
        netif.EnableStaticDns(new[] { "192.168.1.1" });        
        while (!_hasAddress || !_available)
        {
            Debug.Print("Initializing");
            Thread.Sleep(100);
        }
    }

Thing is that
NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;

Attaching my laptop’s IP address

The RJ45 light is not lighting…

Can you please post a foto whish shows how you connected the ENC28 Module to to the Panda III?

I’d suggest you stop mucking about with cables directly attached to PCs because whether you get a connection there or not is very dependent on the hardware in the PC - if it’s reasonably current it most likely will auto detect, but if it’s a bit older or has certain older network modules, it may not. Plug the ENC module cable into a switch or hub, and then see if you get status lights.

Also, please stop using

because the J11D is a very different network module, and you really don’t want to cause confusion just over the naming of an objectin your code :slight_smile:

And then, your next “problem” on an isolated network is that your view of network subnets will be problematic. Sure, simple comms targeting between the PC and Fez will work, but you should probably set the default gateway on the Fez to the PC’s static IP address. (but I still have to ask - is there any reason you’re trying to do all this with just an isolated network?)

OK I am posting the photos here:

check instruction there – and old tips (use google translate)

and as i say above use crossover cable (to connect direct to pc) otherwise with standard ethernet cable

you need two cable one to connect pc to switch/router and another one to ENC to switch/router
http://www.home-network-help.com/straight.html

The wiring seems to be o.k. I suppose you didn’t forget to connect GND :grinning:

Edit:
The wiring was not correct, ist has to be:
// Mosi: Pin D38 —> Si
// Miso: Pin D36 —> So
// CK: Pin D35 —> CK
// CS: Pin D20 —> CS

Here is my suggestion for the code and Ethernet connection to a switch:
Sorry, I didn’t see how to format code in the new forum.

using System;
using Microsoft.SPOT;
using System.Threading;
using Microsoft.SPOT.Net.NetworkInformation;
using GHI.Pins;

namespace Panda_III_Ethernet_ENC28
{
    public class Program
    {
        static GHI.Networking.EthernetENC28J60 netif;
        static bool _hasAddress;
        private static bool _available;

        public static void Main()
        {
            Debug.Print(Resources.GetString(Resources.StringResources.String1));
            NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
            NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;

            //For Panda III
            netif = new GHI.Networking.EthernetENC28J60(Microsoft.SPOT.Hardware.SPI.SPI_module.SPI2, FEZPandaIII.Gpio.D20, FEZPandaIII.Gpio.D21, FEZPandaIII.Gpio.D25);
            netif.Open();

            // for static IP
            netif.EnableStaticIP("192.168.1.23", "255.255.255.0", "192.168.1.1");
            netif.EnableStaticDns(new[] { "192.168.1.1" });         

            while (!_hasAddress || !_available)
            {
                Debug.Print("Initializing");
                Thread.Sleep(100);
            }
        }

        static void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            Debug.Print("The network address has changed.");
            _hasAddress = netif.IPAddress != "0.0.0.0";
            Debug.Print("My IP is: " + netif.IPAddress);
        }

        static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            //Debug.Print("Network available: " + e.IsAvailable.ToString());
            _available = e.IsAvailable;
        }
    }
}

Dear All,

I went through the last code you have shared. (Just before this post). See, you have registered 2 callbacks.
a) NetworkChange_NetworkAddressChanged and
b)NetworkChange_NetworkAvailabilityChanged

This is not triggering mate, in my case. Also, you guyz suggested to use cross over cables. My IT engineer informed me that, my laptop is Windows7 and the OS will manage the ethernet. So I have not used it. But I will try that. Because, I don’t have it and need to make 2 cables.

The application is printing “initializing” in the while loop. Also, during this process, I tried

ping 192.168.1.23 in windows command prompt. And failed to ping the MCU’s IP.

So as a next step, I am trying “is this ECN28J60 MCU works or not?” So I opened Adruino IDE , connected to a Adruino Mega Board and downloaded ethercard-master(from GitHub). All these are my research in embedded world and still keep on failing to ping the Adruino board too… :slight_smile:

Best
Ramb

Dear Brett,

Thanks for your suggestion. My project’s requirement is to dump a file content via UDP from laptop to Panda III’s SD Card. No need to connect to internet.

Ramb

Is not true

Try to connect two laptops with no crossover cable it not work

In same way work your laptop with enc28j60
Because tx on laptop communicate with rx on enc28j60 and vice versa tx on enc28j60 will communicate with rx on laptop that is a reason for cross over otherwise you need switch and connect each device in switch with their cable.(two ethernet cables one for laptop and one for enc28j60 to connect on switch)

I’m sure for that because i have been in loop like you and have same problems years ago.