Main Site Documentation

WIFI transmission Speed


#1

Hello, I am using a Fez Cobra with ZeroG Wifi module and I need to comunicate via socket 64Kbps, the problem, and I have already tested with ethernet socket comunication (aprox. 100Kbps) is that I only can achieve aprox. 40Kbps. By the way, I am using a TCP stream socket.
Is there a way to change the module SPI comunication speed, I think thats the only way to speed up things?
Thanks.


#2

The Ethernet speed with TCP socket on FEZ Cobra is about 1Mbps. which is 10 times more that you are seeing.
Make sure that you send big chunks of data in every transfer. The ethernet packet accpet more 1200KByte payload.

After you enhance the performance of you application then test it with WiFi.

The WiFi on FEZ Cobra works on the maximum speed possible.


#3

Thanks a lot Joe,
Yes your absolutely right, I made a mistake with the bits and bytes, sorry. I am getting in ethernet connection about 850000bps, but in WIFI exactly with the same socket structure about 340000bps.
Do you think that if I change the protocol to UDP will speed things?


#4

I am trying to transmit the all 64KBytes at a time.
Do you think that if I use the Chipworkx will improve the WIFI performance?


#5

Personally I am not sure if using ChipworkX will give you a big change is speed with WiFi since it is SPI interface at the end. But I guess it will be like 1.2 to 1.4 times faster.
Do you have a simple code that we can try. we can do that test for you on ChipworkX.


#6

Probably yes. but would your application access data loss?


#7

What is the max speed of the SPI interface? That is the limiting factor.


#8

[quote]What is the max speed of the SPI interface? That is the limiting factor.
[/quote]
ZeroG module SPI speed with ChipworkX is set to 25MHz.
ZeroG module SPI speed with EMX is set to 18MHz.


#9

Hello again Joe, and thanks a lot for the reply.
So, I have made realy dificult to understand, in real fact a lot dificult, so my problem is that I need to send 64KBytes of data, 512000bps. In ethernet Iam getting an average of 1Mbps but in WIFI iam only getting around 340Kbps. I want to send 32, 16 bits ADC readings per second, and i am just making some tests to the speed. The code that i am using is.

using System;
using System.IO.Ports;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Socket = System.Net.Sockets.Socket;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Net;

namespace Auticko
{
public class Program
{
public static bool wifi_event = false;
public static bool wifi_last_status = false;
public static bool network_is_read = false;

    public static ManualResetEvent NetworkAvailablityBlocking = null;

    public static void Main()
    {
        NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
        if (!WiFi.IsEnabled)
        {
            WiFi.Enable(SPI.SPI_module.SPI2, (Cpu.Pin)FEZ_Pin.Digital.IO2, (Cpu.Pin)FEZ_Pin.Interrupt.IO26);
        }
        
        // WiFi settings
        NetworkInterface[] netif = NetworkInterface.GetAllNetworkInterfaces();
        Wireless80211 WiFiSettings = null;
        for (int index = 0; index < netif.Length; ++index)
        {
            if (netif[index] is Wireless80211)
            {
                WiFiSettings = (Wireless80211)netif[index];

            }
        }


        WiFiSettings.Ssid = "TMN-ZTE";
        WiFiSettings.Encryption = Wireless80211.EncryptionType.None;
        WiFiSettings.Authentication = Wireless80211.AuthenticationType.Open;
        Wireless80211.SaveConfiguration(new Wireless80211[] { WiFiSettings }, false);
        NetworkAvailablityBlocking = new ManualResetEvent(false);
        if (!WiFi.IsLinkConnected)
        {
            Debug.Print("Waiting for WiFi link!");
            NetworkAvailablityBlocking.Reset();
            while (!NetworkAvailablityBlocking.WaitOne(5000, false))
            {
                if (!WiFi.IsLinkConnected)
                {
                    Debug.Print("WiFi link is not available yet! Wrong AP settings?Still waiting.");
                    Debug.Print("Still waiting.");
                }
                else
                    break;
            }
        }

        try
        {
            if (!WiFiSettings.IsDhcpEnabled)
                WiFiSettings.EnableDhcp();// This function is blocking
            else
            {
                WiFiSettings.RenewDhcpLease();// This function is blocking
            }
            network_is_read = true;
            Debug.Print("Network settings:");
            Debug.Print("IP Address: " + WiFiSettings.IPAddress);
            Debug.Print("Subnet Mask: " + WiFiSettings.SubnetMask);
            Debug.Print(" efault Getway: " + WiFiSettings.GatewayAddress);
            Debug.Print(" NS Server: " + WiFiSettings.DnsAddresses[0]);
        }
        catch
        {
            Debug.Print(" HCP Failed");
        }

        Debug.Print("WiFi link is ready!");


        const Int32 c_port = 12000;

        // Create a socket, bind it to the server's port, and listen for client 
        // connections.
        Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, c_port);
        server.Bind(localEndPoint);
        server.Listen(Int32.MaxValue);

        while (true)
        {
            // Wait for a client to connect.
            Socket clientSocket = server.Accept();

            // Process the client request.  true means asynchronous.
            new ProcessClientRequest(clientSocket, true);
        }   
    }

    
    internal sealed class ProcessClientRequest
    {
        private Socket m_clientSocket;

        /// <summary>
        /// The constructor calls another method to handle the request, but can 
        /// optionally do so in a new thread.
        /// </summary>
        /// <param name="clientSocket"></param>
        /// <param name="asynchronously"></param>
        public ProcessClientRequest(Socket clientSocket, Boolean asynchronously)
        {
            m_clientSocket = clientSocket;

            if (asynchronously)
                // Spawn a new thread to handle the request.
                new Thread(ProcessRequest).Start();
            else new Thread(ProcessRequest).Start();
        }

        /// <summary>
        /// Processes the request.
        /// </summary>
        private void ProcessRequest()
        {
            DateTime start_time;
            DateTime end_time;
            TimeSpan ts;
            const Int32 c_microsecondsPerSecond = 1000000;

            // 'using' ensures that the client's socket gets closed.
            using (m_clientSocket)
            {
                // Wait for the client request to start to arrive.
                Byte[] buffer = new Byte[1];
                if (m_clientSocket.Poll(5 * c_microsecondsPerSecond,
                    SelectMode.SelectRead))
                {
                    // If 0 bytes in buffer, then the connection has been closed, 
                    // reset, or terminated.
                    if (m_clientSocket.Available == 0)
                        return;

                    // Read the first chunk of the request (we don't actually do 
                    // anything with it).
                   // Int32 bytesRead = m_clientSocket.Receive(buffer,m_clientSocket.Available, SocketFlags.None);

                    // Return a static HTML document to the client.
                    byte[] dados=new byte[64000];
                    for (int i = 0; i < 64000; i++)
                    {
                        dados[i]=(byte)'c';
                        if (i==63999)
                        {
                            dados[i] = (byte)'a';
                        }
                    }
                    
                    start_time = DateTime.Now;
                    
                        m_clientSocket.Send(dados);

                        int counter = 0;
                        while (counter++ < 10)
                        {
                            end_time = DateTime.Now;
                            ts = end_time - start_time;
                            Debug.Print("Write Speed >>>");
                            Debug.Print("Total time: " + ts.ToString());
                            Debug.Print("Total time in seconds: " + ((float)ts.Ticks / TimeSpan.TicksPerSecond).ToString() + " seconds");
                            Debug.Print("Speed: " + (((float)64) / ((float)ts.Ticks / TimeSpan.TicksPerSecond)).ToString() + " KBytes/s");
                        }
                    }
            }
        }
    }
    static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
    {
        if (e.IsAvailable)
        {
            if (WiFi.IsLinkConnected)
            {
                if (wifi_last_status != true)
                {
                    wifi_last_status = true;
                    NetworkAvailablityBlocking.Set();
                }
            }
        }
        else
        {
            if (!WiFi.IsLinkConnected)
            {
                if (wifi_last_status != false)
                {
                    wifi_last_status = false;
                    network_is_read = false;
                }
            }
        }
    }
}

}

I am using the variable counter to performe 10 transmitions to make the average of them after.
I am using the byte ‘c’ to fill the array of data to send and putting an byte ‘a’ in the end to see if all the data is being transmited.
Could you try the code in Chipworkx to see if the comunication speed is the same?
Do you think in UDP protocol I will loose a lot of data?
thanks a lot…


#10

Can you please use “Code” button from the toolbar.


#11

I have adapt some code I found to my needs, ok.

Thanks.


#12
using System;
using System.IO.Ports;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Socket = System.Net.Sockets.Socket;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Net;

namespace Auticko
{
    public class Program
    {
        public static bool wifi_event = false;
        public static bool wifi_last_status = false;
        public static bool network_is_read = false;

        public static ManualResetEvent NetworkAvailablityBlocking = null;

        public static void Main()
        {
            NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
            if (!WiFi.IsEnabled)
            {
                WiFi.Enable(SPI.SPI_module.SPI2, (Cpu.Pin)FEZ_Pin.Digital.IO2, (Cpu.Pin)FEZ_Pin.Interrupt.IO26);
            }
            
            // WiFi settings
            NetworkInterface[] netif = NetworkInterface.GetAllNetworkInterfaces();
            Wireless80211 WiFiSettings = null;
            for (int index = 0; index < netif.Length; ++index)
            {
                if (netif[index] is Wireless80211)
                {
                    WiFiSettings = (Wireless80211)netif[index];

                }
            }

            //WPAPSK v HK
            //WiFiSettings.Ssid = "thomas";
            //WiFiSettings.NetworkKey = new byte[] { 0x36, 0x3e, 0x65, 0x19, 0x9d, 0xa4, 0x29, 0x3d, 0x19, 0x87, 0xb1, 0xe5, 0x99, 0x29, 0x1e, 0x51, 0xc5, 0xc2, 0xfa, 0x93, 0x5b, 0x40, 0xbc, 0x4f, 0x61, 0x4f, 0x98, 0x24, 0x49, 0xf3, 0xf1, 0x28 };
            //WiFiSettings.Encryption = Wireless80211.EncryptionType.WPAPSK;
            //WiFiSettings.Authentication = Wireless80211.AuthenticationType.Shared;

            WiFiSettings.Ssid = "TMN-ZTE";
            WiFiSettings.Encryption = Wireless80211.EncryptionType.None;
            WiFiSettings.Authentication = Wireless80211.AuthenticationType.Open;
            Wireless80211.SaveConfiguration(new Wireless80211[] { WiFiSettings }, false);
            NetworkAvailablityBlocking = new ManualResetEvent(false);
            if (!WiFi.IsLinkConnected)
            {
                Debug.Print("Waiting for WiFi link!");
                NetworkAvailablityBlocking.Reset();
                while (!NetworkAvailablityBlocking.WaitOne(5000, false))
                {
                    if (!WiFi.IsLinkConnected)
                    {
                        Debug.Print("WiFi link is not available yet! Wrong AP settings?Still waiting.");
                        Debug.Print("Still waiting.");
                    }
                    else
                        break;
                }
            }

            try
            {
                if (!WiFiSettings.IsDhcpEnabled)
                    WiFiSettings.EnableDhcp();// This function is blocking
                else
                {
                    WiFiSettings.RenewDhcpLease();// This function is blocking
                }
                network_is_read = true;
                Debug.Print("Network settings:");
                Debug.Print("IP Address: " + WiFiSettings.IPAddress);
                Debug.Print("Subnet Mask: " + WiFiSettings.SubnetMask);
                Debug.Print(" efault Getway: " + WiFiSettings.GatewayAddress);
                Debug.Print(" NS Server: " + WiFiSettings.DnsAddresses[0]);
            }
            catch
            {
                Debug.Print(" HCP Failed");
            }

            Debug.Print("WiFi link is ready!");


            const Int32 c_port = 12000;

            // Create a socket, bind it to the server's port, and listen for client 
            // connections.
            Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, c_port);
            server.Bind(localEndPoint);
            server.Listen(Int32.MaxValue);

            while (true)
            {
                // Wait for a client to connect.
                Socket clientSocket = server.Accept();

                // Process the client request.  true means asynchronous.
                new ProcessClientRequest(clientSocket, true);
            }   
        }

        
        internal sealed class ProcessClientRequest
        {
            private Socket m_clientSocket;

            /// <summary>
            /// The constructor calls another method to handle the request, but can 
            /// optionally do so in a new thread.
            /// </summary>
            /// <param name="clientSocket"></param>
            /// <param name="asynchronously"></param>
            public ProcessClientRequest(Socket clientSocket, Boolean asynchronously)
            {
                m_clientSocket = clientSocket;

                if (asynchronously)
                    // Spawn a new thread to handle the request.
                    new Thread(ProcessRequest).Start();
                else new Thread(ProcessRequest).Start();
            }

            /// <summary>
            /// Processes the request.
            /// </summary>
            private void ProcessRequest()
            {
                DateTime start_time;
                DateTime end_time;
                TimeSpan ts;
                const Int32 c_microsecondsPerSecond = 1000000;

                // 'using' ensures that the client's socket gets closed.
                using (m_clientSocket)
                {
                    // Wait for the client request to start to arrive.
                    Byte[] buffer = new Byte[1];
                    if (m_clientSocket.Poll(5 * c_microsecondsPerSecond,
                        SelectMode.SelectRead))
                    {
                        // If 0 bytes in buffer, then the connection has been closed, 
                        // reset, or terminated.
                        if (m_clientSocket.Available == 0)
                            return;

                        // Read the first chunk of the request (we don't actually do 
                        // anything with it).
                       // Int32 bytesRead = m_clientSocket.Receive(buffer,m_clientSocket.Available, SocketFlags.None);

                        // Return a static HTML document to the client.
                        byte[] dados=new byte[64000];
                        for (int i = 0; i < 64000; i++)
                        {
                            dados[i]=(byte)'c';
                            if (i==63999)
                            {
                                dados[i] = (byte)'a';
                            }
                        }
                        
                        start_time = DateTime.Now;
                        
                            m_clientSocket.Send(dados);

                            int counter = 0;
                            while (counter++ < 10)
                            {
                                end_time = DateTime.Now;
                                ts = end_time - start_time;
                                Debug.Print("Write Speed >>>");
                                Debug.Print("Total time: " + ts.ToString());
                                Debug.Print("Total time in seconds: " + ((float)ts.Ticks / TimeSpan.TicksPerSecond).ToString() + " seconds");
                                Debug.Print("Speed: " + (((float)64) / ((float)ts.Ticks / TimeSpan.TicksPerSecond)).ToString() + " KBytes/s");
                            }
                        }
                }
            }
        }
        static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            if (e.IsAvailable)
            {
                if (WiFi.IsLinkConnected)
                {
                    if (wifi_last_status != true)
                    {
                        wifi_last_status = true;
                        NetworkAvailablityBlocking.Set();
                    }
                }
            }
            else
            {
                if (!WiFi.IsLinkConnected)
                {
                    if (wifi_last_status != false)
                    {
                        wifi_last_status = false;
                        network_is_read = false;
                    }
                }
            }
        }
    }
}

#13

You can modify existing post. the code tags should wrap the actual code.


#14

After you send the 64K block of data once, you are going into a loop and writting out the performance calculations 10 times. I think you are missing a while/for loop.

I suggest your calculate the send speed at the remote end. Get the time that the first data appears at the remote socket, and then the time that last of the data appears. You can then calculate the speed. The true throughput number is how fast the data can get to the remote end.


#15

I dont understand. You said you want to transfer 32 Adc conversion of 16 bits each per second, that is 32*16 = 512 bps which is ridicully slow. Why you bother to measure speed ?

Maybe you want 32 Adc of 16 bits per millisecond… that would be 512 kbps.


#16

Iam sorry, 32 channels, 16bits, 1000 samples per second.
Sorry :-[


#17

I am sorri, when i passed the code something wrong appened, because i am using the start and stop variables right before and after the send function, so i think iam calculating right the speed of the transmition.


#18

Ok, so i understand that i must calculate the speed in the endpoint side, but can you answer this question, if the SPI max speed in Fez Cobra is about 25MHz, this shouldn’t be enought to transmit 512000bps? Is my problem in the ZeroG module’s comunication header?


#19

there are many factors that will change the speed here, and I think you just need to reset your expectations.

  1. Wifi isn’t a guaranteed bandwidth. You can’t guarantee you’ll connect at a fast speed, you may end up negotiating to a low speed. There are lots of dependencies there, not all you can control.

  2. SPI is a SERIAL interface. That means to send a byte of data it shifts out 8 bits of date, individually.

  3. SPI on EMX module (what the Cobra uses) was pointed out at 18mhz not 25mhz.

Do I think you have anything “wrong”? Not really. Do I think you are getting all that you can out of this? Probably not, but it’s probably close.


#20

Ok, thanks a lot to you all for helping me to understand better the limitations. Does anyone have a Chipworkx with Wifi that could experiment my code and tell me the satistics? I would like to know if is it faster to comunicate than Fez Cobra.
Thanks.