ENC28 transfer limit

Hey all

Are there a transfer limit at the ENC28 module?
I receive 48 packets in 14 ms. but I can’t read it on the G120HDR board. Every packets has a Length at 156 bytes. There are no data available and I think it could be the transfer rate.

I can read and write between my G120HDR board and my PC with the ENC28 module. So I don’t understand why I can’t communicate with other things like a camera.

Someone who can help me?

Where do you receive the 48 packets? On the PC?
Which protocol are you using, TCP or UDP?
A couple of years ago I learned that it’s quite likely to loose UDP packets, when you don’t read them fast enough, even on a Windows PC.

If I remember right, with G120 und ENC28, it takes me between 3 and 5 ms to send a single packet, depending on it’s size.

Generally you can calculate the maximum bandwith roughly by the SPI speed, which s set to 8000 kHz by default I think. You can increase it up to 12000 or 18000 kHz, which works fine for me on any hardware I tried so far.

The packets comes from a Camera and the protocol is UDP.

I receive 48 packets @ 156 bytes in 14 ms. The there are a pause at 400 ms. Then the next 48 packets are send from the camera. I can’t change the data rate of the camera.

And how can I change the SPI speed?

If you use a gadgeteer project (with gadgeteer designer) the I don’t know.
If you use plain netmf, its an optional parameter in the ENC28… constructor (where you also define the SPI channel, and other pins).

But no matter how fast your camera sends. you should receive at least something.

Could you post how your camera sends the data (broadcast, specific IP, …) and the code by which you initialize the ENC28 and how you receive the UPD messages?

My code on G120:

while (true)
            {
               
                while (socket.Poll(1000, SelectMode.SelectRead))
                {
                    if (socket.Available > 0)
                    {
                        byte[] inBuf = new byte[socket.Available];
                        EndPoint recEndPoint = new IPEndPoint(IPAddress.Any, 0);
                        socket.ReceiveFrom(inBuf, ref recEndPoint);              
                        Debug.Print(new String(Encoding.UTF8.GetChars(inBuf)));
                    }
                }
            }

My camera is sending from IP: 192.168.1.254
G120 board IP set to: 192.168.1.150
The camera is sending broadcast UDP.

I tried to make a case where the PC should symbolize the camera. So I’m sending some data packets from the PC and the G120 is reading it.

Dou you send from PC also as broadcast? are you sure you use the correct port?
How do you open the UDP socket for reading?

I am reading from port 50828… Is that only from the PC I can use that?
Normally I use that port when I read the camera data on the computer. And I used the same port when I communicated from my PC to the G120 board.
Could it be another port when it is between the G120 board (ENC28) to the camera? And how can I check this?

I am sending a packets to the camera at the start to enable the data communication. This is working fine, so it is only the reading part that doesn’t work.
The ENC28 module is blinking with the yellow LED and that is when data is received to the module. So the data is there, but I just can’t read it.

And then I am connected to the ENC28 like this:

            Eth1 = new EthernetENC28J60(SPI.SPI_module.SPI2, GHI.Hardware.G120.Pin.P1_17, GHI.Hardware.G120.Pin.P0_5, GHI.Hardware.G120.Pin.P1_14, 20000);

And I open the UDP socket like this:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 254 });
            int port = 50828;
            IPEndPoint endPoint = new IPEndPoint(ip, port);
            socket.Connect(endPoint);

Then I send the enable command to the camera. And at last I use the while loop I showed before.

I just had a closer look at your receive code:
I think that:

EndPoint recEndPoint = new IPEndPoint(IPAddress.Any, 0);
socket.ReceiveFrom(inBuf, ref recEndPoint);

tries to read what comes in on port 0.

I usually prepare a separate receive socket like this:

var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Any, port));

And then read from it similar to you:

while (socket.Poll(1000, SelectMode.SelectRead))
{
   if (socket.Available > 0)
   {
      byte[] inBuf = new byte[socket.Available];
      socket.Receive(inBuf, 0, inBuf .Length, SocketFlags.None);
      Debug.Print(new String(Encoding.UTF8.GetChars(inBuf)));
   }
}

Also: For performance and garbage collector reasons, you should create the buffer only once outside the loops at a size that is large enough for every expected packet, like this.

;
while (socket.Poll(1000, SelectMode.SelectRead))
{
   int n = System.Math.Min(socket.Available, inBuf.Length);
   if (n > 0)
   {
      socket.Receive(inBuf, 0, n, SocketFlags.None);
      Debug.Print(new String(Encoding.UTF8.GetChars(inBuf)));
   }
}
1 Like

Oh thank you Reinhard Ostermeier :slight_smile: I think I just missed the Bind command. It is almost working now. I receive “c”, so I just need to read the rest of the packets now.

If anybody else have the same problem in the future I will share that part of my code:


Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint endPoint = new IPEndPoint(ip, port);
            socket.Connect(endPoint);
            byte[] bytesToSend = { "Enable Camera" };
            socket.SendTo(bytesToSend, bytesToSend.Length, SocketFlags.None, endPoint);
            byte[] inBuf = new byte[1024];
            socket.Bind(new IPEndPoint(IPAddress.Any, port));

            while (true)
            {
                while (socket.Poll(400, SelectMode.SelectRead))
                {
                    if (socket.Available > 0)
                    {
                        socket.Receive(inBuf, inBuf.Length, SocketFlags.None);
                        Debug.Print(new String(Encoding.UTF8.GetChars(inBuf)));
                    }
                }
            }

I might be wrong, but if I remember right, you don’t need to use SendTo, if you call connect before. Just Send should be enough, because the socket already knows where to send to.

Yeah I think you are right… I just did it to be sure :wink:

And there are another problem…

I receive the first 30 packets great and the data is OK. I think it is because of the available stack. It is going to be full after just a little time. (the available stack is about 3400). If we devide this by 114 bytes (my receiving bytes) we get about 30.
After the first 30 packets I only receive every third packets. So it i:
1 - 2 - 3 - … - 30 - 33 - 36 - 39 - 42 - …

How can I fix this problem?
My code can be seen in this tread.