Raptor with RS485 & Ethernet Fails

Hi,

I want to read my PV-installation with a RS485 module on my raptor. Then I want to upoad the data to an Azure Eventhub via the AMQP protocol.
Both parts of the code works if I test them seprate but if I combine those 2 modules and code, the RS485 module does not always receives the correct data. Also the ethernet starts to fail. (Exception was thrown: System.Net.Sockets.SocketException-Microsoft.SPOT.Net.SocketNative::getaddrinfo-System.Net.Dns::GetHostEntry)

I’ve upgraded the raptor to the latest firmware (2015 relaese) but the problem remains.

Does anyone has the same problem?

regards
Joris

using System;
using System.Collections;
using System.Threading;
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 Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using Amqp;
using Amqp.Framing;
using Json.NETMF;
using System.Text;
using Amqp.Types;
using System.IO;
using System.IO.Ports;
using GHI.Networking;
using Microsoft.SPOT.Net.NetworkInformation;
using Microsoft.SPOT.Hardware;
using Gadgeteer;

namespace TestRaptorSB
{
    public partial class Program
    {

        private const string eventhubAddress = "amqps://...";
        private const string EntityPath = "testeh";
        GT.Timer timer;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            Program.Mainboard.LDR1.OnInterrupt += LDR1_OnInterrupt;

            address = new Address(eventhubAddress);

            timer = new GT.Timer(10000); // every second (2000ms)
            timer.Tick += timer_Tick;

            this.ethernetENC28.NetworkUp += ethernetENC28_NetworkUp;
            this.ethernetENC28.UseThisNetworkInterface();
            this.ethernetENC28.UseStaticIP("192.168.0.3", "255.255.255.0", "192.168.0.1", new string[] { "195.130.131.4", "195.130.130.132" });


            rs485Left.Configure();
            rs485Left.Port.LineReceived += Port_LineReceived;
            rs485Left.Port.Open();



            Amqp.Trace.TraceListener = this.Tracer;
            Amqp.Trace.TraceLevel = TraceLevel.Verbose;

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");


        }

        private void Tracer(string format, params object[] args)
        {
            this.Log("Amqp: " + Amqp.Fx.Format(format, args));
        }

        private void Port_LineReceived(GT.SocketInterfaces.Serial sender, string line)
        {
            this.Log("RS485: " + line);
        }

             void ethernetENC28_NetworkUp(GTM.Module.NetworkModule sender, GTM.Module.NetworkModule.NetworkState state)
        {
            Debug.Print(sender.NetworkSettings.IPAddress);
            this.startNetwork();
        }

        void startNetwork()
        {
            Microsoft.SPOT.Time.TimeService.SetTimeZoneOffset(2 * 60); // default to GMT Offset * 60 minutes
            Microsoft.SPOT.Time.TimeServiceSettings tsettings = new Microsoft.SPOT.Time.TimeServiceSettings();
            string primary = "ntp.telenet.be";
            string secondary = "time-a.nist.gov";
            System.Net.IPHostEntry primaryIP = System.Net.Dns.GetHostEntry(primary);
            System.Net.IPHostEntry secondaryIP = System.Net.Dns.GetHostEntry(secondary);
            tsettings.ForceSyncAtWakeUp = false;
            tsettings.RefreshTime = 5 * 60;
            tsettings.PrimaryServer = primaryIP.AddressList[0].GetAddressBytes();
            tsettings.AlternateServer = secondaryIP.AddressList[0].GetAddressBytes();
            tsettings.AutoDayLightSavings = true;
            Microsoft.SPOT.Time.TimeService.Settings = tsettings;
            Microsoft.SPOT.Time.TimeService.SystemTimeChanged += TimeService_SystemTimeChanged;
            Microsoft.SPOT.Time.TimeService.UpdateNow(5);
            Microsoft.SPOT.Time.TimeService.Start();

            timer.Start();
        }

        void TimeService_SystemTimeChanged(object sender, Microsoft.SPOT.Time.SystemTimeChangedEventArgs e)
        {
            this.Log(string.Concat("SystemTimeChanged. New Time: ", DateTime.Now));
        }


        Address address = null;
        Connection connection = null;
        Session session = null;
        SenderLink sender = null;

        private void InitializeAmqp()
        {
            this.Log("InitializeAmqp-1");
            connection = new Connection(address);
            this.Log("InitializeAmqp-2");
            session = new Session(connection);
            this.Log("InitializeAmqp-3");
            sender = new SenderLink(session, "sender-" + EntityPath, EntityPath);
            this.Log("InitializeAmqp-4");
            connection.Closed = this.onConnectionClosed;
            this.Log("InitializeAmqp-5");
        }

        private void onConnectionClosed(AmqpObject sender, Error error)
        {

            connection = null;
            session = null;
            sender = null;

            this.Log("onConnectionClosed: " + sender.GetType().FullName);
            this.Log("    Description: " + error.Description);
            this.Log("    Condition: " + error.Condition.ToString());
            this.Log("    Descriptor.Code: " + error.Descriptor.Code);
            this.Log("    Descriptor.Name : " + error.Descriptor.Name);
            foreach (var x in error.Info.Keys)
                this.Log("        Info: " + x + " - " + error.Info[x]);

        }

        private void Log(string message)
        {
            try
            {
                Debug.Print(message);
                if (this.sdCard.IsCardMounted)
                {
                    lock (this.sdCard)
                    {
                        using (var filestream = new FileStream(Path.Combine(this.sdCard.StorageDevice.RootDirectory, "Test.log"), FileMode.Append))
                        {
                            using (var streamWriter = new StreamWriter(filestream))
                            {
                                streamWriter.WriteLine(string.Concat(DateTime.Now, "\t", message));
                                streamWriter.Flush();
                                streamWriter.Close();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }



        void timer_Tick(GT.Timer timer)
        {
            if (!this.ethernetENC28.IsNetworkUp)
            {
                this.Log("!IsNetworkUp");
                return;
            }
            if (!this.ethernetENC28.IsNetworkConnected)
            {
                this.Log("!IsNetworkConnected");
                return;
            }

            timer.Stop();
            try
            {
                if (connection == null) this.InitializeAmqp();

                Hashtable hashtable = new Hashtable();
                hashtable.Add("Datum", DateTime.Now);

                // Serialize hashtable into JSON
                JsonSerializer serializer = new JsonSerializer(DateTimeFormat.Default);
                string payload = serializer.Serialize(hashtable);

                // Create the AMQP message
                var message = new Message();
                var data = new Data();
                data.Binary = Encoding.UTF8.GetBytes(payload);
                message.BodySection = data;
                message.Properties = new Properties()
                {
                    Subject = "wthr",
                    CreationTime = DateTime.UtcNow,
                    ContentType = "text/json",
                };

                message.MessageAnnotations = new MessageAnnotations();
                message.MessageAnnotations[new Symbol("x-opt-partition-key")] = "FezRaptor";
                message.ApplicationProperties = new ApplicationProperties();
                message.ApplicationProperties["time"] = message.Properties.CreationTime;
                message.ApplicationProperties["from"] = "FezRaptor";
                message.ApplicationProperties["dspl"] = "FezRaptor";

                this.Log("        Sending");
                sender.Send(message);
                this.Log("        Send: ");
            }
            catch (Exception ex)
            {
                this.Log(ex.Message + "-" + ex.StackTrace);
            }
            finally
            {
                timer.Start();
            }
        }

        void LDR1_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            try
            {
                Debug.Print("LDR1_OnInterrupt");
                if (this.sdCard.IsCardMounted) this.sdCard.StorageDevice.Volume.FlushAll();
            }
            catch (Exception) { }
        }

    }
}

@ Tielemaj - It’ll be difficult for us to test your code with the Azure parts in it. If possible, can you create a smaller example that downloads a random page and sends/receives over the RS485?

@ John.
I’ve changed the code to the code below and the problem remains.
The RS485 is missing some data. Also the ethernet stops working. Are there other things I can try?

using System;
using System.Collections;
using System.Threading;
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 Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using Json.NETMF;
using System.Text;
using System.IO;
using System.IO.Ports;
using GHI.Networking;
using Microsoft.SPOT.Net.NetworkInformation;
using Microsoft.SPOT.Hardware;
using Gadgeteer;
using System.Net;

namespace TestRaptorSB
{
    public partial class Program
    {

        GT.Timer timer;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            Program.Mainboard.LDR1.OnInterrupt += LDR1_OnInterrupt;


            timer = new GT.Timer(9000); // every second (2000ms)
            timer.Tick += timer_Tick;

            this.ethernetENC28.NetworkUp += ethernetENC28_NetworkUp;
            this.ethernetENC28.UseThisNetworkInterface();
            this.ethernetENC28.UseStaticIP("192.168.0.3", "255.255.255.0", "192.168.0.1", new string[] { "195.130.131.4", "195.130.130.132" });

            rs485Left.Configure();
            rs485Left.Port.LineReceived += Port_LineReceived;
            rs485Left.Port.Open();
            
            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
        }

        private void Port_LineReceived(GT.SocketInterfaces.Serial sender, string line)
        {
            this.Log("RS485: " + line);
        }

        void ethernetENC28_NetworkUp(GTM.Module.NetworkModule sender, GTM.Module.NetworkModule.NetworkState state)
        {
            Debug.Print(sender.NetworkSettings.IPAddress);
            this.startNetwork();
        }

        void startNetwork()
        {
            Microsoft.SPOT.Time.TimeService.SetTimeZoneOffset(2 * 60); // default to GMT Offset * 60 minutes
            Microsoft.SPOT.Time.TimeServiceSettings tsettings = new Microsoft.SPOT.Time.TimeServiceSettings();
            string primary = "ntp.telenet.be";
            string secondary = "time-a.nist.gov";
            System.Net.IPHostEntry primaryIP = System.Net.Dns.GetHostEntry(primary);
            System.Net.IPHostEntry secondaryIP = System.Net.Dns.GetHostEntry(secondary);
            tsettings.ForceSyncAtWakeUp = false;
            tsettings.RefreshTime = 2 * 60 * 60;
            tsettings.PrimaryServer = primaryIP.AddressList[0].GetAddressBytes();
            tsettings.AlternateServer = secondaryIP.AddressList[0].GetAddressBytes();
            tsettings.AutoDayLightSavings = true;
            Microsoft.SPOT.Time.TimeService.Settings = tsettings;
            Microsoft.SPOT.Time.TimeService.SystemTimeChanged += TimeService_SystemTimeChanged;
            Microsoft.SPOT.Time.TimeService.UpdateNow(5);
            Microsoft.SPOT.Time.TimeService.Start();

            timer.Start();
        }

        void TimeService_SystemTimeChanged(object sender, Microsoft.SPOT.Time.SystemTimeChangedEventArgs e)
        {
            this.Log(string.Concat("SystemTimeChanged. New Time: ", DateTime.Now));
        }


        private void Log(string message)
        {
            try
            {
                Debug.Print(message);
                if (this.sdCard.IsCardMounted)
                {
                    lock (this.sdCard)
                    {
                        using (var filestream = new FileStream(Path.Combine(this.sdCard.StorageDevice.RootDirectory, "Test.log"), FileMode.Append))
                        {
                            using (var streamWriter = new StreamWriter(filestream))
                            {
                                streamWriter.WriteLine(string.Concat(DateTime.Now, "\t", message));
                                streamWriter.Flush();
                                streamWriter.Close();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        void timer_Tick(GT.Timer timer)
        {
            if (!this.ethernetENC28.IsNetworkUp)
            {
                this.Log("!IsNetworkUp");
                return;
            }
            if (!this.ethernetENC28.IsNetworkConnected)
            {
                this.Log("!IsNetworkConnected");
                return;
            }

            timer.Stop();
            try
            {
                this.makeGenericHTTPRequest();
            }
            catch (Exception ex)
            {
                this.Log(ex.Message + "-" + ex.StackTrace);
            }
            finally
            {
                timer.Start();
            }
        }


        void makeGenericHTTPRequest()
        {
            try
            {
                string url = "http://www.microsoft.com/";
                using (var req = System.Net.HttpWebRequest.Create(url))
                {
                    using (var res = req.GetResponse())
                    {
                        this.Log("HTTP Response was this long: " + res.ContentLength.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        void LDR1_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            try
            {
                Debug.Print("LDR1_OnInterrupt");
                if (this.sdCard.IsCardMounted) this.sdCard.StorageDevice.Volume.FlushAll();
            }
            catch (Exception) { }
        }

    }
}

When you test the ethernet only portion or the RS485 only portion of your code do you leave all the hardware connected? You might be getting a ground loop or other EMI from all the three systems (debug computer, ethernet and rs485) connected together which can cause packet loss in both networks.

@ skeller - Yes, All the harware stays connected. It is powered with an extenal power supply and no computer is attached.

Have you tried with a different external power supply? What is the capacity of the supply you are using?