Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.

berr08's Content

There have been 9 items by berr08 (Search limited from 29-March 23)


By content type

See this member's

Sort by                Order  

#59663 Trying to recreate Arduino Code for Netduino, running into issues.

Posted by berr08 on 11 August 2014 - 01:36 PM in Netduino Plus 2 (and Netduino Plus 1)

Interesting, I will give this a shot, thanks for the feedback!




#59662 Slow I2C Sensor Reads, is this normal?

Posted by berr08 on 11 August 2014 - 01:35 PM in Netduino Plus 2 (and Netduino Plus 1)

Thanks guys, it seems that the netduino isn't the way to go for this project atleast since the speed of the readings needs to be so high.  I look forward to using this again when the project requirements will allow.  Thanks again to all for your help with this!

 

Robert.




#59608 Slow I2C Sensor Reads, is this normal?

Posted by berr08 on 08 August 2014 - 03:46 PM in Netduino Plus 2 (and Netduino Plus 1)

Thanks that did speed it up some more doing the 1 read of 6 bytes.  I implemented the stopwatch function and here are the findings:

 

Setting the Device Config: 0Ms - 40Ms

magDevice.Config = mag0;

Sending the setup routine:  159Ms - 165Ms

magDevice.Execute(refillTrans, 1);
magDevice.Execute(setTrans, 1);
magDevice.Execute(resetTrans, 1);
magDevice.Execute(takeTrans, 1);

Checking reading is ready (Status): 0Ms - 40Ms

while (((statusBit[0] & 0x01) != 1))
{
     magDevice.Execute(statusTrans, 1);
}

Reading the 6byte reading: 40Ms

magDevice.Execute(getReadings, 1);

//#Definition from outside loop:
//byte[] dataXYZ = new byte[6];
//I2CDevice.I2CTransaction[] getReadings = new I2CDevice.I2CTransaction[2];
//getReadings[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x00 });
//getReadings[1] = I2CDevice.CreateReadTransaction(dataXYZ);

Assigning to the Byte Structure 0Ms

magData.mag0Xl = dataXYZ[0];
magData.mag0Xh = dataXYZ[1];
magData.mag0Yl = dataXYZ[2];
magData.mag0Yh = dataXYZ[3];
magData.mag0Zl = dataXYZ[4];
magData.mag0Zh = dataXYZ[5];

The entire loop of the 3 sensors takes: 600Ms - 650Ms

 

In order to get to the arduino # of readings I need the 3 sensors to take about 30 milliseconds, which I'm thinking might not be near possible?  Unless I'm still doing some really dumb things, which is always possible LOL.




#59605 Slow I2C Sensor Reads, is this normal?

Posted by berr08 on 08 August 2014 - 12:41 PM in Netduino Plus 2 (and Netduino Plus 1)

Thanks again for the help, I have changed the way I am doing this up to take your suggestions.  It is still only geting 2 or 3 reads (of all the sensors) a second, an improvement over the 1 a second but the arduino is getting 25 to 35 reads, so I'm still not where I need it to be.

 

I've changed the code to use the 1 main i2cdevice and swap the config, I created all the transactions outside of the loop and am reading all the data registers in one transaction.  Any other input would be great **braces for newb jokes**  Code below for the MemSic MMC3416xPJ sensor:

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;

namespace UDPMag_NetduinoPlus2
{
    class MagSensor
    {
        private MagDataStruct magData = new MagDataStruct();
        private I2CDevice magDevice = null;
        private bool collect = false;
        public struct MagDataStruct
        {
            public byte mag0Xh;
            public byte mag0Yh;
            public byte mag0Zh;
            public byte mag0Xl;
            public byte mag0Yl;
            public byte mag0Zl;

            public byte mag1Xh;
            public byte mag1Yh;
            public byte mag1Zh;
            public byte mag1Xl;
            public byte mag1Yl;
            public byte mag1Zl;

            public byte mag2Xh;
            public byte mag2Yh;
            public byte mag2Zh;
            public byte mag2Xl;
            public byte mag2Yl;
            public byte mag2Zl;
        }

        public delegate void DataReceived(MagDataStruct data);

        public event DataReceived OnDataReceived = null;

        public bool SensorRunning
        {
            get { return collect; }
        }

        public MagSensor()
        {
            // Create a delegate of type "ThreadStart", which is a pointer to the 
            // worker thread's main function
            ThreadStart delegateWorkerThread = new ThreadStart(Main);

            // Next create the actual thread, passing it the delegate to the main function
            Thread threadWorker = new Thread(delegateWorkerThread);

            // Now start the thread.
            threadWorker.Start();

        }

        public void StartCollecting()
        {
            collect = true;
        }
        public void StopCollecting()
        {
            collect = false;
        }

        #region The actual worker thread code
        /// <summary>
        /// This is a method which does the work of the worker thread.
        /// </summary>
        private void Main()
        {
            magDevice = new I2CDevice(null);
            I2CDevice.Configuration mag0 = new I2CDevice.Configuration(0x30, 400);
            I2CDevice.Configuration mag1 = new I2CDevice.Configuration(0x31, 400);
            I2CDevice.Configuration mag2 = new I2CDevice.Configuration(0x32, 400);
            
            I2CDevice.I2CTransaction[] refillTrans = new I2CDevice.I2CTransaction[1];
            refillTrans[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x07, 0x80 });

            I2CDevice.I2CTransaction[] setTrans = new I2CDevice.I2CTransaction[1];
            setTrans[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x07, 0x20 });

            I2CDevice.I2CTransaction[] resetTrans = new I2CDevice.I2CTransaction[1];
            resetTrans[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x07, 0x40 });

            I2CDevice.I2CTransaction[] takeTrans = new I2CDevice.I2CTransaction[1];
            takeTrans[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x07, 0x01 });
            
            byte[] statusBit = new byte[1];
            I2CDevice.I2CTransaction[] statusTrans = new I2CDevice.I2CTransaction[2];
            statusTrans[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x06 });
            statusTrans[1] = I2CDevice.CreateReadTransaction(statusBit);
            
            byte[] dataXl = new byte[1];
            byte[] dataXh = new byte[1];
            byte[] dataYl = new byte[1];
            byte[] dataYh = new byte[1];
            byte[] dataZl = new byte[1];
            byte[] dataZh = new byte[1];
            I2CDevice.I2CTransaction[] getReadings = new I2CDevice.I2CTransaction[12];
            getReadings[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x00 });
            getReadings[1] = I2CDevice.CreateReadTransaction(dataXl);
            getReadings[2] = I2CDevice.CreateWriteTransaction(new byte[] { 0x01 });
            getReadings[3] = I2CDevice.CreateReadTransaction(dataXh);
            getReadings[4] = I2CDevice.CreateWriteTransaction(new byte[] { 0x02 });
            getReadings[5] = I2CDevice.CreateReadTransaction(dataYl);
            getReadings[6] = I2CDevice.CreateWriteTransaction(new byte[] { 0x03 });
            getReadings[7] = I2CDevice.CreateReadTransaction(dataYh);
            getReadings[8] = I2CDevice.CreateWriteTransaction(new byte[] { 0x04 });
            getReadings[9] = I2CDevice.CreateReadTransaction(dataZl);
            getReadings[10] = I2CDevice.CreateWriteTransaction(new byte[] { 0x05 });
            getReadings[11] = I2CDevice.CreateReadTransaction(dataZh);

            // Loop forever
            while (true)
            {
                if (collect)
                {
                    //DateTime t1 = DateTime.Now;

                    //Sensor 0:
                    magDevice.Config = mag0;
                    magDevice.Execute(refillTrans, 1);
                    magDevice.Execute(setTrans, 1);
                    magDevice.Execute(resetTrans, 1);
                    magDevice.Execute(takeTrans, 1);
                    while ((statusBit[0] & 0x01) != 1)
                    {
                        magDevice.Execute(statusTrans, 1);
                    }
                    magDevice.Execute(getReadings, 1);

                    magData.mag0Xl = dataXl[0];
                    magData.mag0Xh = dataXh[0];
                    magData.mag0Yl = dataYl[0];
                    magData.mag0Yh = dataYh[0];
                    magData.mag0Zl = dataZl[0];
                    magData.mag0Zh = dataZh[0];

                    //Sensor 1:
                    magDevice.Config = mag1;
                    magDevice.Execute(refillTrans, 1);
                    magDevice.Execute(setTrans, 1);
                    magDevice.Execute(resetTrans, 1);
                    magDevice.Execute(takeTrans, 1);
                    while ((statusBit[0] & 0x01) != 1)
                    {
                        magDevice.Execute(statusTrans, 1);
                    }
                    magDevice.Execute(getReadings, 1);

                    magData.mag1Xl = dataXl[0];
                    magData.mag1Xh = dataXh[0];
                    magData.mag1Yl = dataYl[0];
                    magData.mag1Yh = dataYh[0];
                    magData.mag1Zl = dataZl[0];
                    magData.mag1Zh = dataZh[0];

                    //Sensor 2:
                    magDevice.Config = mag2;
                    magDevice.Execute(refillTrans, 1);
                    magDevice.Execute(setTrans, 1);
                    magDevice.Execute(resetTrans, 1);
                    magDevice.Execute(takeTrans, 1);
                    while ((statusBit[0] & 0x01) != 1)
                    {
                        magDevice.Execute(statusTrans, 1);
                    }
                    magDevice.Execute(getReadings, 1);

                    magData.mag2Xl = dataXl[0];
                    magData.mag2Xh = dataXh[0];
                    magData.mag2Yl = dataYl[0];
                    magData.mag2Yh = dataYh[0];
                    magData.mag2Zl = dataZl[0];
                    magData.mag2Zh = dataZh[0];
                    
                    //DateTime t2 = DateTime.Now;
                    //TimeSpan ts = t2 - t1;
                    //Debug.Print(ts.Minutes.ToString() + ":" + ts.Seconds.ToString() + ":" + ts.Milliseconds.ToString());
                    
                    // Call Event!
                    if (OnDataReceived != null)
                        OnDataReceived(magData);
                }
            }
        }
        #endregion
    }
}




#59599 Slow I2C Sensor Reads, is this normal?

Posted by berr08 on 07 August 2014 - 07:53 PM in Netduino Plus 2 (and Netduino Plus 1)

Thanks for the reply.  I tried making each device 1x and when making a second i2cdevice I get an 'System.InvalidOperationException'.  So after toying with it for a while the only way I got it to work was with the using, which I know isn't officient which is why I asked what I can do.  I'm on here to hopefully learn more about this device and working with this compact library.  The way I do things, which I assume is differently that you, is to get things to work and then see what can be done to make it better.  Especially in an instance where the community isn't super responsive yet and there are only a handfull of examples I came across which all appearantly did things the wrong way.

 

I assume what I am doing is possible without a library, I see the example you linked to used the M2Mqtt library, was hoping to not use libraries...




#59597 Slow I2C Sensor Reads, is this normal?

Posted by berr08 on 07 August 2014 - 05:26 PM in Netduino Plus 2 (and Netduino Plus 1)

Let me start by saying I have the same code logic wise on an arduino.

 

Trying to read a set of 3 magnet sensors via I2c.  For some reason it is taking almost half a second to got through the read cycle for each sensor, as you will see by the code it takes a few commands to complete a reading.  So I'm getting a full 3 sensor read in 1.3 so not even a full read per second.  On the arduino I am getting around 25-35 reads per second.  I remember reading that certain things are slower on the netduino, but I don't think that meant that huge a difference.  So I assume I am doing something wrong with the I2C maybe?  Can anyone point me in the correct direction?  Code Below: **Note I changed to a using in the loop as it would error out if I tried to make mulitple I2C devices at once...

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;

namespace UDPMag_NetduinoPlus2
{
    class MagSensor
    {
        private MagDataStruct magData = new MagDataStruct();

        private bool collect = false;
        public struct MagDataStruct
        {
            public byte mag0Xh;
            public byte mag0Yh;
            public byte mag0Zh;
            public byte mag0Xl;
            public byte mag0Yl;
            public byte mag0Zl;

            public byte mag1Xh;
            public byte mag1Yh;
            public byte mag1Zh;
            public byte mag1Xl;
            public byte mag1Yl;
            public byte mag1Zl;

            public byte mag2Xh;
            public byte mag2Yh;
            public byte mag2Zh;
            public byte mag2Xl;
            public byte mag2Yl;
            public byte mag2Zl;
        }

        public delegate void DataReceived(MagDataStruct data);

        public event DataReceived OnDataReceived = null;

        public bool SensorRunning
        {
            get { return collect; }
        }

        public MagSensor()
        {
            // Create a delegate of type "ThreadStart", which is a pointer to the 
            // worker thread's main function
            ThreadStart delegateWorkerThread = new ThreadStart(Main);

            // Next create the actual thread, passing it the delegate to the main function
            Thread threadWorker = new Thread(delegateWorkerThread);

            // Now start the thread.
            threadWorker.Start();

        }

        public void StartCollecting()
        {
            collect = true;
        }
        public void StopCollecting()
        {
            collect = false;
        }

        #region The actual worker thread code
        /// <summary>
        /// This is a method which does the work of the worker thread.
        /// It waits (sleeps) for a UDP message to be received and passes it using the 
        /// supplied Interface.
        /// </summary>
        private void Main()
        {

            // Loop forever
            while (true)
            {
                if (collect)
                {
                    magData = new MagDataStruct();
                    DateTime t1 = DateTime.Now;

                    for (int i = 0; i < 3; i++)
                    {
                        ushort addy = 0x30; //Mag 0
                        if (i == 1)
                        {
                            addy = 0x31; //Mag 1
                        }
                        else
                        {
                            addy = 0x32; //Mag 2
                        }
                        using (I2CDevice mag = new I2CDevice(new I2CDevice.Configuration(addy, 400)))
                        {
                            runSensor(mag, i);
                        }
                    }

                    DateTime t2 = DateTime.Now;
                    TimeSpan ts = t2 - t1;
                    Debug.Print(ts.Minutes.ToString() + ":" + ts.Seconds.ToString() + ":" + ts.Milliseconds.ToString());
                    
                    // Call Event!
                    if (OnDataReceived != null)
                        OnDataReceived(magData);
                }
            }
        }

        private void runSensor(I2CDevice device, int id)
        {
            i2c_write(device, 0x07, 0x80);                      // Refill Charge Cap
            i2c_write(device, 0x07, 0x20);                      // SET Instruction
            i2c_write(device, 0x07, 0x40);                      // RESET Instruction
            i2c_write(device, 0x07, 0x01);                      // Take Measurement TM Flag == 1
            
            while ((i2c_read(device, 0x06) & 0x01) != 1) { };   // Wait formeasurment to be Done.

            switch (id) //Set byes in data struct.
            {
                case 0:
                    magData.mag0Xl = i2c_read(device, 0x00);
                    magData.mag0Xh = i2c_read(device, 0x01);
                    magData.mag0Yl = i2c_read(device, 0x02);
                    magData.mag0Yh = i2c_read(device, 0x03);
                    magData.mag0Zl = i2c_read(device, 0x04);
                    magData.mag0Zh = i2c_read(device, 0x05);
                    break;
                case 1:
                    magData.mag1Xl = i2c_read(device, 0x00);
                    magData.mag1Xh = i2c_read(device, 0x01);
                    magData.mag1Yl = i2c_read(device, 0x02);
                    magData.mag1Yh = i2c_read(device, 0x03);
                    magData.mag1Zl = i2c_read(device, 0x04);
                    magData.mag1Zh = i2c_read(device, 0x05);
                    break;
                case 2:
                    magData.mag2Xl = i2c_read(device, 0x00);
                    magData.mag2Xh = i2c_read(device, 0x01);
                    magData.mag2Yl = i2c_read(device, 0x02);
                    magData.mag2Yh = i2c_read(device, 0x03);
                    magData.mag2Zl = i2c_read(device, 0x04);
                    magData.mag2Zh = i2c_read(device, 0x05);
                    break;
            }
        }

        private void i2c_write(I2CDevice device, byte register, byte data)
        {
            byte[] trans = { register, data };
            I2CDevice.I2CTransaction[] i2cTx = new I2CDevice.I2CTransaction[1];
            i2cTx[0] = I2CDevice.CreateWriteTransaction(trans);
            device.Execute(i2cTx, 1);
        }

        private byte i2c_read(I2CDevice device, byte register)
        {
            byte[] trans = { register };
            byte[] read = new byte[1];

            I2CDevice.I2CTransaction[] i2cTx = new I2CDevice.I2CTransaction[2];
            i2cTx[0] = I2CDevice.CreateWriteTransaction(trans);
            i2cTx[1] = I2CDevice.CreateReadTransaction(read);

            device.Execute(i2cTx,1);

            return read[0]; //Return 1 byte...
        }
        #endregion
    }
}




#59596 Trying to recreate Arduino Code for Netduino, running into issues.

Posted by berr08 on 07 August 2014 - 04:59 PM in Netduino Plus 2 (and Netduino Plus 1)

To Update I have removed the Debug.print statments and changed a bunch of different things that seemed trivial (basically banging my head on the keyboard) and it started to continue to read after the first message.  Don't know why but it did...code is below incase anyone needs it.

 

At this point the only issue that remains is how to get the IP of the UDP message sender.  Any one know how to get that? It's not coming back in the Socket.RemoteEndPoint, so for testing I hard coded my IP to get the messages back....Pretty please? :D

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using EthernetSocketDefs;

namespace UDPMag_NetduinoPlus2
{
    public class UDPReceiver
    {
        public delegate void MessageReceived(string message, IPEndPoint sender);

        public event MessageReceived OnMessageReceived = null;


        private IPEndPoint localEndPoint = null;
        private IPEndPoint remoteEndPoint = null;
        public UDPReceiver(IPEndPoint ipeo)
        {
            this.localEndPoint = ipeo;

            // Create a delegate of type "ThreadStart", which is a pointer to the 
            // worker thread's main function
            ThreadStart delegateWorkerThread = new ThreadStart(Main);

            // Next create the actual thread, passing it the delegate to the main function
            Thread threadWorker = new Thread(delegateWorkerThread);

            // Now start the thread.
            threadWorker.Start();
        }

        #region The actual worker thread code
        /// <summary>
        /// This is a method which does the work of the worker thread.
        /// It waits for a UDP message to be received and passes it using the 
        /// supplied Event.
        /// </summary>
        private void Main()
        {
            int bytes = 0;              // Holds number of bytes received
            byte[] rxBuff = null;       // Holds received message

            // Create a "UDP" socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            // Bind the socket to the local endpoint and listen for incoming UDP datagrams.
            try
            {
                listener.Bind(localEndPoint);
            }
            catch (SocketException se)
            {
                SocketErrorCodes errorCode = (SocketErrorCodes)se.ErrorCode;

                switch (errorCode)
                {
                    case SocketErrorCodes.NetworkIsDown:
                        Debug.Print("Socket Exception on creation: NetworkIsDown");
                        break;
                    default:
                        Debug.Print("Socket Exception error: " + errorCode);
                        break;
                }
            }
            listener.ReceiveTimeout = 1000;
            listener.Listen(16);
            
            // Loop forever
            while (true)
            {
                bytes = 0;
                rxBuff = new byte[4];
                string cause = "unknown";

                try
                {
                    //Debug.Print("Attempt to listen on " + localEndPoint.ToString());
                    if (listener.Available >= 4 && listener.Poll(1000, SelectMode.SelectRead))
                    {
                        bytes = listener.Receive(rxBuff, 4, SocketFlags.None);
                    }
                    else
                    {
                        cause = "No Data Available";
                    }
                }
                catch (Exception ge)
                {
                    if (ge is SocketException)
                    {
                        SocketErrorCodes errorCode = (SocketErrorCodes)((SocketException)ge).ErrorCode;

                        switch (errorCode)
                        {
                            case SocketErrorCodes.NetworkIsDown:
                                // The network is not connected.
                                cause = "NetworkIsDown";
                                break;

                            case SocketErrorCodes.ConnectionTimedOut:
                                // Connection timed out - e.g. nothing received
                                cause = "ConnectionTimedOut";
                                break;

                            default:
                                Debug.Print("Socket Exception error: " + errorCode);
                                break;
                        }
                    } 
                    else 
                        cause = ge.Message;
                }

                if (bytes == 0)
                {
                    //Debug.Print("Nothing received: reason - " + cause);
                }
                else
                {
                    // set the remote end point so we know who sent us the data.
                    remoteEndPoint = new IPEndPoint(IPAddress.Parse("10.201.1.24"), 8888);//listener.RemoteEndPoint as IPEndPoint;

                    //Convert to string.
                    System.Text.UTF8Encoding e = new System.Text.UTF8Encoding();
                    string txtMessage = new string(e.GetChars(rxBuff));

                    // Call Event!
                    if (OnMessageReceived != null)
                        OnMessageReceived(txtMessage, remoteEndPoint);


                }
            }
        }
        #endregion
    }
}




#59581 Trying to recreate Arduino Code for Netduino, running into issues.

Posted by berr08 on 06 August 2014 - 03:34 PM in Netduino Plus 2 (and Netduino Plus 1)

I've had more time with this, so I started pulling the code apart making it simplier to understand (for the way I think atleast).  Starting with the receiving part, have the code done, but I'm having 2 issues.

  1. The RemoteEndPoint IP is still always 0.0.0.0, I need to figure out the IP that is sending the message so I can send the results back to that same IP.
  2. I have it working to read 1 message, but then everything craps out and even though it says there are 4 bytes available to read (once I send another message) the 'bytes = listener.Receive(rxBuff);' always return 0 and leaves the byte array empty.  Am I missing a step?

If anyone can help at all it would be much appreciated, hopefully I'm just missing a step somewhere?

 

Program.cs

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

using System.IO;
using Microsoft.SPOT.Net.NetworkInformation;

namespace UDPMag_NetduinoPlus2
{
    public class Program
    {
        private static IPAddress myIPAddress = null;
        private static int dataPort = 8888;
        private static UDPReceiver udpReceiver = null;
        public static void Main()
        {
            //Make Sure Network is setup.
            SetupTCPIPFromSD();

            //Setup Listener to handle incoming Commands, this runs a listener thread.
            udpReceiver = new UDPReceiver(new IPEndPoint(myIPAddress, dataPort));
            udpReceiver.OnMessageReceived += new UDPReceiver.MessageReceived(udpReceiver_OnMessageReceived);

            
            //The sender event is going to be created when we get our first message in the OnMessageReceived Handler.


            //Keep the thread alive as we are using all listeners and events.
            Thread.Sleep(Timeout.Infinite);
        }

        static void udpReceiver_OnMessageReceived(string message, IPEndPoint sender)
        {
            Debug.Print(sender.Address.ToString() + ": " + message);
        }

        private static void SetupTCPIPFromSD()
        {
            NetworkInterface ethernet1 = NetworkInterface.GetAllNetworkInterfaces()[0];
            if (ethernet1.IPAddress == "192.168.5.100")
            {
                //Setup Defaults as SD Card is not working currently...
                string LocalIPAddress = "10.201.1.99";
                string SubNetMask = "255.255.255.0";
                string Gateway = "10.201.1.254";

                if (File.Exists(@"IPData.txt"))
                {
                    using (FileStream filestream = new FileStream(@"IPData.txt", FileMode.Open))
                    {
                        StreamReader reader = new StreamReader(filestream);
                        Debug.Print(reader.ReadToEnd());
                        reader.Close();
                    }
                }
                ethernet1.EnableStaticIP(LocalIPAddress, SubNetMask, Gateway);
            }

            myIPAddress = IPAddress.Parse(ethernet1.IPAddress);
        }
    }
}

UDPReceiver.cs [Class]

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using EthernetSocketDefs;

namespace UDPMag_NetduinoPlus2
{
    public class UDPReceiver
    {
        public delegate void MessageReceived(string message, IPEndPoint sender);

        public event MessageReceived OnMessageReceived = null;


        private IPEndPoint localEndPoint = null;
        private IPEndPoint remoteEndPoint = null;
        public UDPReceiver(IPEndPoint ipeo)
        {
            this.localEndPoint = ipeo;

            // Create a delegate of type "ThreadStart", which is a pointer to the 
            // worker thread's main function
            ThreadStart delegateWorkerThread = new ThreadStart(Main);

            // Next create the actual thread, passing it the delegate to the main function
            Thread threadWorker = new Thread(delegateWorkerThread);

            // Now start the thread.
            threadWorker.Start();
        }

        #region The actual worker thread code
        /// <summary>
        /// This is a method which does the work of the worker thread.
        /// </summary>
        private void Main()
        {
            int bytes = 0;              // Holds number of bytes received
            byte[] rxBuff = null;       // Holds received message

            // Create a "UDP" socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            // Bind the socket to the local endpoint and listen for incoming UDP datagrams.
            try
            {
                listener.Bind(localEndPoint);
            }
            catch (SocketException se)
            {
                SocketErrorCodes errorCode = (SocketErrorCodes)se.ErrorCode;

                switch (errorCode)
                {
                    case SocketErrorCodes.NetworkIsDown:
                        Debug.Print("Socket Exception on creation: NetworkIsDown");
                        break;
                    default:
                        Debug.Print("Socket Exception error: " + errorCode);
                        break;
                }
            }
            listener.ReceiveTimeout = 1000;
            
            // Loop forever
            while (true)
            {
                bytes = 0;
                string cause = "unknown";

                try
                {
                    //Debug.Print("Attempt to listen on " + localEndPoint.ToString());
                    if (listener.Available > 0)
                    {
                        rxBuff = new byte[listener.Available];
                        bytes = listener.Receive(rxBuff);
                    }
                    else
                    {
                        cause = "No Data Available";
                    }
                }
                catch (Exception ge)
                {
                    if (ge is SocketException)
                    {
                        SocketErrorCodes errorCode = (SocketErrorCodes)((SocketException)ge).ErrorCode;

                        switch (errorCode)
                        {
                            case SocketErrorCodes.NetworkIsDown:
                                // The network is not connected.
                                cause = "NetworkIsDown";
                                break;

                            case SocketErrorCodes.ConnectionTimedOut:
                                // Connection timed out - e.g. nothing received
                                cause = "ConnectionTimedOut";
                                break;

                            default:
                                Debug.Print("Socket Exception error: " + errorCode);
                                break;
                        }
                    } 
                    else 
                        cause = ge.Message;
                }

                if (bytes == 0)
                {
                    Debug.Print("Nothing received: reason - " + cause);
                }
                else
                {
                    // set the remote end point so we know who sent us the data.
                    remoteEndPoint = listener.RemoteEndPoint as IPEndPoint;

                    //Convert to string.
                    System.Text.UTF8Encoding e = new System.Text.UTF8Encoding();
                    string txtMessage = new string(e.GetChars(rxBuff));

                    // Call Event!
                    if (OnMessageReceived != null)
                        OnMessageReceived(txtMessage, remoteEndPoint);
                }
            }
        }

        private bool SocketConnected(Socket s)
        {
            return !(s.Poll(1000, SelectMode.SelectRead) & (s.Available == 0));
        }
        #endregion
    }
}




#59573 Trying to recreate Arduino Code for Netduino, running into issues.

Posted by berr08 on 05 August 2014 - 07:41 PM in Netduino Plus 2 (and Netduino Plus 1)

Basically trying to setup my base functionality that I have used in all my arduino setups. 

 

I listen for a UDP message, then store the IP of the sender to send data back...idea is the application sends a GO commands over UDP the sensors start blaring and send json back to the application.

 

My issue iss the my socket.RemoteEndPoint is always saying the IPAddress is 0.0.0.0, so now I don't know where to send these messages to.

 

I'm using an example that I found on here for sending a receiving messages, it might be more than I need but just trying to get this working then remove the overkill.  So with the example below the listener.RemoteEndPoint is always saying 0.0.0.0 for the IP address.  Please help, just to better explain what I am doing I will put the arduino code below as well.

 

Thanks everyone, loving the netduino so far happy to get away from c/c++ mashup of the arduino!!!

#region The actual worker thread code
        /// <summary>
        /// This is a method which does the work of the worker thread.
        /// It is a bit like the program's main() function (but is not static).
        /// It waits (sleeps) for a UDP message to be received and passes it using the 
        /// supplied Interface.
        /// </summary>
        private void Main()
        {
            int bytes = 0;              // Holds number of bytes received
            var rxBuff = new byte[100]; // Holds received message

            // Convert IP address and port to an EndPoint
            IPEndPoint localEndPoint = new IPEndPoint(localIpAddress, port);

            // Create a "UDP" socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            // Bind the socket to the local endpoint and listen for incoming UDP datagrams.
            try
            {
                listener.Bind(localEndPoint);
            }

            #region Catch exceptions
            catch (SocketException se)
            {
                SocketErrorCodes errorCode = (SocketErrorCodes)se.ErrorCode;

                switch (errorCode)
                {
                    case SocketErrorCodes.NetworkIsDown:
                        Debug.Print("Socket Exception on creation: NetworkIsDown");
                        break;
                    default:
                        Debug.Print("Socket Exception error: " + errorCode);
                        break;
                }
            }
            #endregion

            // TODO: If the network was down set up a timer to try again in a while.

            // Now that we have bound the socket to liste on the port, set a timeout for receive operations
            // We could just wait for ever, but having a timeout may be useful.
            listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);

            // Loop forever
            while (true)
            {
                bytes = 0;
                string cause = "unknown";

                // TODO: Currently we assume that one whole message will be received in one go
                // This may not be the case - consider using a length for the first byte and just 
                // read the length at first, followed by the correct amount of following bytes.
                // Without doing this we might receive less than a whole message or even 
                // parts of two messages.

                try
                {
                    //Debug.Print("Attempt to listen on " + localEndPoint.ToString());
                    bytes = listener.Receive(rxBuff);
                }
                #region catch exceptions
                catch (SocketException se)
                {
                    SocketErrorCodes errorCode = (SocketErrorCodes)se.ErrorCode;

                    switch (errorCode)
                    {
                        case SocketErrorCodes.NetworkIsDown:
                            // The network is not connected.
                            cause = "NetworkIsDown";
                            //Debug.Print("Socket Exception on receive: NetworkIsDown");
                            // Ignore error and carry on
                            break;

                        case SocketErrorCodes.ConnectionTimedOut:
                            // Connection timed out - e.g. nothing received
                            cause = "ConnectionTimedOut";
                            //Debug.Print("Socket Exception on receive: ConnectionTimedOut");
                            // Ignore error and carry on
                            break;

                        default:
                            Debug.Print("Socket Exception error: " + errorCode);
                            break;
                    }
                }
                #endregion

                if (bytes == 0)
                {
                    // Nothing may have been received if a timeout or an error occured.
                    Debug.Print("Nothing received: reason - " + cause);
                }
                else
                {
                    // Create a copy of the message that is the correct length
                    var msg = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        msg[i] = rxBuff[i];
                    }
                    // Use interface to pass message to main thread
                    IPEndPoint ip = listener.RemoteEndPoint as IPEndPoint;
                    receiver.SetRemoteIP(ip.Address);
                    receiver.MsgRx(msg);
                }
            }
        }
        #endregion
void receiveData()
{ 
  remoteAddress = udp.remoteIP();            // Store IP as Remote IP
  
  udp.read(packetBuffer,5);                  // Read the packet into buffer
  
  // **For Testing Only**
  Serial.println(F("Contents:"));
  Serial.println(packetBuffer);
  
  // **Process Messages**
  if (strcmp(packetBuffer,"GOGO") == 0)
  {
      receivedStart = true;
  }
  else if (strcmp(packetBuffer,"STOP") == 0)
  {
      receivedStart = false;
  }
}




home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.