Cerberus hangs after a while when using ENC28 and Music modules

I thought with the MicroFramework I could not hang the device. (not even the debugger can connect)
My application uses a TCP connection to stream MP3 to the music module.
Could it be a problem that those two modules share some lines of the SPI interface?
Also it seems to be a timing problem since sometimes it works only for 1 second and sometimes event for up to 10s.
Is there any known issue with SPI on the cerberus or with the two modules?
Thanks
Uwe

Interesting example. It should work but we can look into it if you see a problem. Perhaps a simplified example.

Welcome to the community

I used the modified Music class that acepts streams for the Play method.
Then I created an own stream implementation that works on a TCP IP Socket:


    class AudioNetworkStream : Stream
    {
        Socket socket;
        public AudioNetworkStream(Socket socket)
        {
            this.socket = socket;
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            while (true)
            {
                if (socket.Poll(-1, SelectMode.SelectRead))
                {
                    if (socket.Available < count)
                    {
                        Debug.Print("too few data from the socket");
                        Thread.Sleep(1);
                        continue;
                    }
                    return socket.Receive(buffer, offset, count, SocketFlags.None);
                }
                Thread.Sleep(1);
            }
        }
        public override bool CanRead
        {
            get { throw new NotImplementedException(); }
        }
        // all other methods are not used => no implementation

With this class the program can be quite simple:


            Debug.Print("Initializing network...");
            NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
            if (interfaces != null && interfaces.Length > 0)
                interfaces[0].EnableStaticIP("192.168.178.100", "255.255.255.0", "192.168.178.1");
            else
                Debug.Print("No network device found.");

            Debug.Print("Free mem : " + Debug.GC(false).ToString());
            music.SetVolume(255);
            serversocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serversocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 2000);
            serversocket.Bind(localEndPoint);
            serversocket.Listen(1);
            AudioNetworkStream audioStream;
            Socket clientSocket = serversocket.Accept();
            audioStream = new AudioNetworkStream(clientSocket);
            music.Play(audioStream);

On the windows PC I also used a socket to stream the a simple mp3 file:


            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint DestinationEndPoint = new IPEndPoint(new IPAddress(new byte[] { 192, 168, 178, 100 }), 2000);

            try
            {
                socket.Connect(DestinationEndPoint);
                byte[] buffer = new byte[960];

                using (var file = File.OpenRead(@ "music.mp3"))
                {
                    while (0 != file.Read(buffer, 0, buffer.Length))
                    {
                        Thread.Sleep(50);
                        socket.SendTo(buffer, DestinationEndPoint);
                    }
                }
            }
            catch (SocketException ex)
            {
                MessageBox.Show(ex.ToString());
            }

I haven’t been following the network issue discussions very close, but I have a couple observations:
[ol]The framework provides a Stream implementation that works over a socket: System.Net.NetworkStream
The Socket.Receive() method should either block if no data is available (if the socket is in blocking mode) or throw an exception if no data is available (if the socket is in non-blocking mode). The only time it would return zero bytes is if the other side has shut down the connection. That means that your technique of calling Poll() is unnecessary. While you may not get as much data as you ask for, you’ll get everything that’s available, and that’s how streams are supposed to work (int count is the maximum number to return, not the absolute number to return)[/ol]

Hi godefroi,
thank you for the comments on the code.
I did not use the NetworkStream implementation because I think that I will need some special buffering for a reliable audio stream. I also played with UDP broadcasts instead of TCP. (I plan to have cerberus with music modules in my bath rooms and in the kitchen and they all should play the same audio signal in sync)
Of cause you are right that socket.Receive() returns only as much as available but with the extra check “socket.Available < Count” this should work.
The code is a stripped down version just to reproduce my issue. Even if socket.Receive does not return the requested bytes this should not freeze the device.

@ Gus - is the code ok in this form?
Meawhile I found two other threads with a similar Problem:

[ol]Using Music Shield with Cerbuino Bee (http://www.tinyclr.com/forum/topic?id=9098&page=1)
Problem with MP3+Network on Hydra (http://www.tinyclr.com/forum/topic?id=6666&page=1)[/ol]

in all cases the device seems to crash after the music playes for a while.
In my case this happens it the device receives an additional packet that does not belong to my data (e.g. ARP or some IPV6 stuff)
It does not matter what packet and it does not always stop with such a packet. But when it stops such a packet was the last thing sent to the device.
Uwe

We will run some testing and get back to you

This is fixed and will be available in next release in few weeks.

Just curious what was the issue?

ENC and C# conflict when using SPI

That sounds great!
Where can I look for the new Firmware?
Meanwhile i bought a Fez Hydra. Does this issu aplly for that board as well?

Thanks
Uwe

Gus will the new version contain a fix for the playing a mp3 file from a sdcard as currently it hangs when you try to play the second file.

The SD problem is different. That is a big project that we will tackle once we cover all the little issue.

bummer I had a cool YouTube project that used the music module and Justin’s Spectrum module and a couple of LED Array Modules, but with it hanging on the second file I can’t post it and I haven’t gotten around to looking into the problem in detail, but now it sounds like a bit of a beast.

1 Like

@ Gus, you mentioned that a fix was forthcoming. Just curious, it’s been a while, any ETA?

Thanks

Any day now

Wait… this is the first I’m hearing of this. What exactly is the problem Duke was talking about?

If I use the Cerb to open a filestream from SD and play an MP3… stop playback… close stream then open a new one and try to play, will that work?

I’ve got a ton of work into porting a project to Cerb40… if I can’t play multiple MP3s this would kill my project.

the problem is in SPI vs ENC28 module (which also uses SPI). Use one or another and you will be fine.

1 Like

Ok thanks! Mini panic attack there lol. I remember hearing of SPI sharing problems, but all I saw in this thread was the second page and Duke’s post about changing MP3s.

I downloaded the new firmware and everything works fine.
Thank you very much!
Uwe