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

Member Since 04 Aug 2014
Offline Last Active Aug 11 2014 08:17 PM
-----

Topics I've Started

Slow I2C Sensor Reads, is this normal?

07 August 2014 - 05:26 PM

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
    }
}


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

05 August 2014 - 07:41 PM

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.