Simple Cerberus + ENC28 Sample Project Needed

I’m trying to revive a project that I shelved a while back because of 4.2 networking issues when it first came out. So, I’ve installed the latest GHI SDK and it still doesn’t work… So, I’m starting to wonder if there’s something in my router or code that’s the root of the problem. Can someone post or point me to a simple Cerberus + ENC28 project that is known to work that I can compare to and test on my network? I see several examples using WiFi but the syntax isn’t quite the same.

If you’re interested in browsing my code, it is here… Note that the call to Initialize_Static should be Initialize_Dhcp if that’s working now.

BTW, if I can get this working this weekend and demonstrate just how easy this is in Gadgeteer there’s a very good possibility that I’ll be convincing a company to move from a native AVR design to a NETMF one after they’ve already spent 6 months trying to get what they have working.

Thanks!

Maybe we can try to find the reason together?

What is “does not work”?
Is it static or dynamic IP? Tried static?
DNS needed? Tried with direct IP connection?
Locally or over the internet?
Are you sure your IP address used is proper?
Did you use a proper valid MAC address? watch out for correct MSB byte

Well, of course. Unfortunately, it’s been a while since I worked on this project and all I did last night was install the new SDK and try to run it a couple different ways. I’m mostly trying to queue up some info for more testing tonight.

“Does not work” at this time means that it will not connect to my network and then connect to Thingspeak. The last time I worked on this, it would work using a static IP but there was a problem in the SDK with DHCP always reporting back an IP of 0.0.0.0 and that made it virtually impossible to determine when you had a good connection. I thought this had been resolved but I was getting the same result last night. Also, connecting with a static IP appeared to work last night but the Thingspeak connection didn’t work. This could be an expired app key or something. I didn’t dig far into that yet.

Yes, DNS would be ideal. I haven’t checked with a direct IP but I will do that tonight.

Internet.

I want DHCP…but I do need to confirm that the IP I have hardcoded from the previous tests with static is not being used by something else now.

I think so… It did work at one time. I’ll try with a new MAC to be sure.

This is getting even more puzzling. I’ve created a very minimal app and it didn’t work. So, then I got a different Cerberus & ENC28 module, upgraded Tinybooter & firmware. It worked! I got an IP back and it was visible through the iface.IPAddress property.

So, I thought maybe there was a problem with the ENC28 module on my other Cerberus. Tried it with the same code & the other ENC28 module. It worked! I swapped back & forth a few more times and it continued to work. Then suddenly it doesn’t work again on either board with either ENC28 module.

Then I opened my router’s app so I could watch for connections handed out by DHCP. I could see the two leases handed out earlier. I released them. Then I ran the app again and a new lease was handed out. However, NETMF did not recognize it and didn’t set the IPAddress property (still 0.0.0.0). So, my app keeps thinking it doesn’t have a connection…

Another bug (?) I think I’ve discovered. If after trying to connect with DHCP, I then try to set a static IP address (in code. See InitializeNetworking_Static) and connect with it then the IPAddress property is set and the device seems to think its happy. However, if I watch my router I never see the static IP (.99) show up. Then a few seconds later my previous DHCP address (.233) shows up! The opposite is also true. If I go to FEZ Config and set a static IP and turn off DHCP and then try to connect through code using DHCP then it will not make a DHCP request and instead hangs onto the static IP. Something is broke here.

I don’t see how this could be router specific, but I’m not a networking expert. My router is a DLink DIR-655.

Here’s my simple test app.

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Gadgeteer.Interfaces;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;
using GT = Gadgeteer;

namespace MinNetworking
{
    public partial class Program
    {
        static readonly byte[] _mac = new byte[] { 0x66, 0x57, 0xBA, 0xBF, 0xA3, 0x6C};
        static NetworkInterface iface = NetworkInterface.GetAllNetworkInterfaces()[0];
      
        void ProgramStarted()
        {
            Debug.Print("Program Started");

            iface.PhysicalAddress = _mac;

            Microsoft.SPOT.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged += (sender, args) =>
            {
                Debug.Print("Network availability changed!  " + args.IsAvailable);
            };

            Microsoft.SPOT.Net.NetworkInformation.NetworkChange.NetworkAddressChanged += (sender, args) =>
            {
                Debug.Print("Network address changed!  " + iface.IPAddress.ToString());
            };

            var netThread = new Thread(InitializeNetworking_Dhcp);
            netThread.Start();

        }

        private static void InitializeNetworking_Dhcp()
        {
            //Set iface to accept ip address automatically
            iface.EnableDhcp();

            //Wait for confirmation that ip address has been given
            while (iface.IPAddress == "0.0.0.0")
            {
                Debug.Print("Awaiting IP Address");
                Thread.Sleep(1000);
            }

            Debug.Print("IP Address Granted: " + iface.IPAddress);
        }

        private static void InitializeNetworking_Static()
        {
            string myIP = "192.168.1.99";
            string subnetMask = "255.255.255.0";
            string gatewayAddress = "192.168.1.1";
            string dnsAddresses = "192.168.1.1";

            Debug.Print("Setting static IP...");
            iface.EnableStaticIP(myIP, subnetMask, gatewayAddress);
            iface.EnableStaticDns(new[] { dnsAddresses });

            Debug.Print("Network ready.");
            Debug.Print(" IP Address: " + iface.IPAddress);
            Debug.Print(" Subnet Mask: " + iface.SubnetMask);
            Debug.Print(" Default Gateway: " + iface.GatewayAddress);
            Debug.Print(" DNS Server: " + iface.DnsAddresses[0]);
        }
    }
}

I just tried with the sample app that Duke just posted and get the exact same results.

https://www.ghielectronics.com/community/codeshare/entry/866

OK that is weird as both of those projects work here. I have a couple of test networks including a DLink 825 running DD-WRT or a Netgear WNDR4500 and typically the only problem I’ve run into is around the network configuration having an incorrect DNS address which overrides the DNS address retrieved from the router so you get host not found errors.

I made a couple of small changes and it works here (like we haven’t heard that before).



using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Gadgeteer.Interfaces;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;
using GT = Gadgeteer;

namespace MinNetworking
{
     public partial class Program
     {
         static readonly byte[] _mac = new byte[] { 0x66, 0x57, 0xBA, 0xBF, 0xA3, 0x6C};
         private static NetworkInterface iface; // = NetworkInterface.GetAllNetworkInterfaces()[0];
       
         void ProgramStarted()
         {
             Debug.Print("Program Started");

             Microsoft.SPOT.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged += (sender, args) =>
             {
                 Debug.Print("Network availability changed!  " + args.IsAvailable);
             };

             Microsoft.SPOT.Net.NetworkInformation.NetworkChange.NetworkAddressChanged += (sender, args) =>
             {
                 Debug.Print("Network address changed!  " + iface.IPAddress.ToString());
             };

             // var netThread = new Thread(InitializeNetworking_Dhcp);
             var netThread = new Thread(InitializeNetworking_Static);
             netThread.Start();

         }

         private static void InitializeNetworking_Dhcp()
         {
             iface = NetworkInterface.GetAllNetworkInterfaces()[0];

             iface.PhysicalAddress = _mac;

             //Set iface to accept ip address automatically
             iface.EnableDhcp();

             //Wait for confirmation that ip address has been given
             while (iface.IPAddress == "0.0.0.0")
             {
                 Debug.Print("Awaiting IP Address");
                 Thread.Sleep(1000);
             }

             Debug.Print("Network ready.");
             Debug.Print("  IP Address: " + iface.IPAddress);
             Debug.Print("  Subnet Mask: " + iface.SubnetMask);
             Debug.Print("  Default Getway: " + iface.GatewayAddress);
             Debug.Print("  MAC Address: " + GetMACAddress(iface.PhysicalAddress));
             foreach (string dnsAddress in iface.DnsAddresses)
             {
                 Debug.Print("  DNS Server: " + dnsAddress);
             }
             Debug.Print("  Is DhCp enabled: " + iface.IsDhcpEnabled);
             Debug.Print("  Is DynamicDnsEnabled enabled: " + iface.IsDynamicDnsEnabled);
             Debug.Print("  NetworkInterfaceType " + iface.NetworkInterfaceType);
         }

         private static void InitializeNetworking_Static()
         {
             string myIP = "192.168.5.131"; //"192.168.1.99";
             string subnetMask = "255.255.255.0";
             string gatewayAddress = "192.168.5.1";
             string dnsAddresses = "192.168.5.1";

             iface = NetworkInterface.GetAllNetworkInterfaces()[0];

             iface.PhysicalAddress = _mac;

             Debug.Print("Setting static IP...");
             iface.EnableStaticIP(myIP, subnetMask, gatewayAddress);
             iface.EnableStaticDns(new[] { dnsAddresses });

             Debug.Print("Network ready.");
             Debug.Print("  IP Address: " + iface.IPAddress);
             Debug.Print("  Subnet Mask: " + iface.SubnetMask);
             Debug.Print("  Default Getway: " + iface.GatewayAddress);
             Debug.Print("  MAC Address: " + GetMACAddress(iface.PhysicalAddress));
             foreach (string dnsAddress in iface.DnsAddresses)
             {
                 Debug.Print("  DNS Server: " + dnsAddress);
             }
             Debug.Print("  Is DhCp enabled: " + iface.IsDhcpEnabled);
             Debug.Print("  Is DynamicDnsEnabled enabled: " + iface.IsDynamicDnsEnabled);
             Debug.Print("  NetworkInterfaceType " + iface.NetworkInterfaceType);
         }

         private static string GetMACAddress(byte[] PhysicalAddress)
         {
             return ByteToHex(PhysicalAddress[0]) + "-"
                                 + ByteToHex(PhysicalAddress[1]) + "-"
                                 + ByteToHex(PhysicalAddress[2]) + "-"
                                 + ByteToHex(PhysicalAddress[3]) + "-"
                                 + ByteToHex(PhysicalAddress[4]) + "-"
                                 + ByteToHex(PhysicalAddress[5]);
         }

         private static string ByteToHex(byte number)
         {
             string hex = "0123456789ABCDEF";
             return new string(new char[] { hex[(number & 0xF0) >> 4], hex[number & 0x0F] });
         }
     }
} 

The principle change I made was around the initialization of the static NetworkInterface iface, and instead moved it into the InitializeNetworking_Dhcp / InitializeNetworking_Static routines.

Output for InitializeNetworking_Dhcp

Output for InitializeNetworking_Dhcp

I’m not sure if you have to have it initialize where you did, but the change made it work for me.

@ Duke Nukem - I’m confused… I thought in your previous reply you said it did work for you. Trying your changes now…

That was in reference to my sample projects, I thought you tried them and said they didn’t work for you.

When I tried your initial code it didn’t work here, so I made a couple of changes and it worked.

Ok. Yea, I did try yours code from the other thread and it didn’t work. However, these changes do seem to work however the IPAddress property is still not reporting properly. It seems that the IPAddress property is set during power up and never changes even if EnableDHCP() gets a new address.

Funny thing is that my real project has everything in basically the same order as yours. However, when going through and comparing I did find several pieces of old code left over from when I was trying to fix this before that were just wrong. If you happen to be looking at the Attic Monitor code, you should pull the latest. At this point I can’t get that project to even do what the small app is doing… It’s 0330 here. I’m turning in for the night. Thanks!

@ ianlee74 - Check what I just found out here:
https://www.ghielectronics.com/tracker/entry/54

@ Reinhard - yes, that’s exactly the problem. Unfortunately, this is also exactly the problem I reported a year ago and I thought was fixed by now… :frowning:

https://www.ghielectronics.com/community/forum/topic?id=10140&page=1

Thank for putting it in the new tracker.

Here’s the Cerberus part of a quick speed test program I wrote. It works reliably for me every time I try it here. We have heard in the past that some routers do not work well with DHCP on the Cerberus. There does seem to be a bug in lwip related to DHCP: lwIP - A Lightweight TCP/IP stack - Bugs: bug #40303, DHCP xid renewed when sending a... [Savannah]

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net;
using Microsoft.SPOT.Net.NetworkInformation;
using System.Threading;
using System.Net;
using System;
using Gadgeteer.Modules.GHIElectronics;

namespace SpeedTest
{
    public partial class Program
    {
        void ProgramStarted()
        {
            var ethernet = NetworkInterface.GetAllNetworkInterfaces()[0];
            
            ethernet.EnableDhcp();
            ethernet.EnableDynamicDns();

            Debug.Print("Waiting");

            while (!button.IsPressed)
                Thread.Sleep(250);

            new Thread(() =>
            {
                Debug.Print("Start");

                while (ethernet.NetworkInterface.IPAddress == "0.0.0.0")
                    Thread.Sleep(250);

                Debug.Print(ethernet.NetworkInterface.IPAddress);

                DateTime start, end;
                byte[] result = new byte[16384];

                for (int i = 0; i < 10; i++)
                {
                    HttpWebRequest req = HttpWebRequest.Create("[URL]") as HttpWebRequest;
                    req.KeepAlive = true;
                    start = DateTime.Now;
                    HttpWebResponse res = req.GetResponse() as HttpWebResponse;
                    var stream = res.GetResponseStream();
                    int read = 0;

                    do
                    {
                        read += stream.Read(result, 0, result.Length);
                    } while (read != res.ContentLength);
                    
                    end = DateTime.Now;

                    var s = end - start;
                    var ms = s.Minutes * 60000 + s.Seconds * 1000 + s.Milliseconds;
                    Debug.Print(i.ToString() + " " + ((res.ContentLength / 1024.0) / (ms / 1000.0)).ToString());
                }
            }).Start();
        }
    }
}

Thanks, John. I’ll try it tonight. If it doesn’t work, I’m tempted to buy a new router just so I can get something working. If I then send you my old router can you fix this?

@ John, I’m not getting anywhere with your example either. It just hangs in the while loop waiting on an IPAddress. However, I think there’s some difference in our NETMF versions. You have…



But NetworkInterface isn't a property that VS recognizes on my machine.  I have to use...


```cs]ethernet.IPAddress[/code


Are you maybe using a new or older version of the framework?

@ Ian Sorry about the example, Ethernet.IPAddress is correct. The Interface bit was left over from tests for other boards that I cut out. If you do wind up finding a router that works, we can always try to take a look at the one you have that does not work.

@ John, Ok. I’m going to take the project to the office one day this week. If it works there then I’ll probably be ordering a new router for myself. However, I have no other devices that have a problem with my network.