Hello all,
I am new to the NETMF and the Panda II, and I am trying to write a driver for some flight control hardware. Basically, this is a prototyping effort to explore the feasibility of using the FEZ devices for a new product line of flight controller hardware (yokes, radio panels, etc). I purchased a Panda II kit, and have been leaning the NETMF for the past 1-2 months. After much discussion with the engineers, I started writing the driver and server applications earlier this week. I’ve read completely through the beginner’s guide to NETMF, as well as the “Internet of Things;” and I’ve re-read the sections most pertinent to the problem I’m having, several times.
While not new to programming, I am new to using sockets and UDP. However the examples in the texts were fairly straightforward, and I have gotten several of them to run. In the application I’ve been working on this week, I’ve been able to write from the Panda to the server app…but not vice-versa. I believe I am initializing and using the UDP socket correctly, but when I try to send a packet from the server, I will get a “connection forcibly closed” exception from the Panda. As this post will have a lengthy code section, I’ll post the exact exception output in a post to follow. But I was hoping that someone might see something I’ve missed. Although I am not entirely certain, I think the issue seems to be in the “mySocket.SendTo()” method. I’ve run it through the debugger many times, but cannot seem to get a grasp on the problem, no doubt due to my limited (by rapidly-expanding) knowledge of UDP sockets.
Note that the project has grown somewhat lengthy, so I’ve only pasted the code that I feel to be most germane to this problem. The remaining code seems to work fine, although I can certainly post more if anyone needs to see it.
Finally, a million thanks to anyone who can help me figure this out, as I’m really stuck here…
Panda Code:
using System;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Net;
using GHIElectronics.NETMF.Net.Sockets;
using GHIElectronics.NETMF.Net.NetworkInformation;
using Socket = GHIElectronics.NETMF.Net.Sockets.Socket;
namespace PandaHardware
}
public class InitializeUDP
{
// Set IP, subnet, gateway and MAC addresses for the FEZ Connect
private byte[] ip;
private byte[] subnet;
private byte[] gateway;
private byte[] mac;
private byte[] data;
public Socket mySocket;
public EndPoint serverEndPoint;
public IPEndPoint pandaEndPoint;
public void ConfigureUDP()
{
ip = new byte[] { 192, 168, 1, 100 };
subnet = new byte[] { 255, 255, 255, 0 };
gateway = new byte[] { 192, 168, 1, 254 };
mac = new byte[] { 0x00, 0x26, 0x1C, 0x7B, 0x29, 0xE8 };
data = new byte[UdpDataInStruct.INPUT_STRUCT_SIZE];
// Enable the WIZnet interface on FEZ Connect
WIZnet_W5100.Enable(SPI.SPI_module.SPI1, (Cpu.Pin)FEZ_Pin.Digital.Di10, (Cpu.Pin)FEZ_Pin.Digital.Di7, true);
// Enable the program to set and use a static IP address
NetworkInterface.EnableStaticIP(ip, subnet, gateway, mac);
// I don't think we need this, if we aren't on the Internet with the device...
NetworkInterface.EnableStaticDns(new byte[] { 192, 168, 1, 254 });
// Create a UDP socket
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// Configure the receiving endpoint
pandaEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.100"), 2000);
// Set up the destination as the P3D client/server device
serverEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.254"), 2000);
}
} // end clas InitializeUDP
}
Server Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace UDPServer
{
class UDPServer
{
private static int count;
private static Socket mySocket;
private static IPEndPoint serverEndPoint;
private static EndPoint pandaEndPoint;
private static UdpDataInStruct dataStructFromPanda;
private static UdpDataOutStruct dataStructToPanda;
private static byte[] byteArrayFromPanda;
private static byte[] byteArrayToPanda;
static void Main(string[] args)
{
// DEBUG CODE
count = 1;
try
{
// Create the actual socket
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
catch (SocketException se)
{
Console.WriteLine("Could not establish socket connection");
Console.WriteLine(se.ToString());
mySocket.Close();
}
// Define and bind a desired IP and port number to this application, for this machine
serverEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.254"), 2000);
mySocket.Bind(serverEndPoint);
// Create a byte array of sufficient size to hold the available data
byteArrayFromPanda = new byte[UdpDataInStruct.INPUT_STRUCT_SIZE];
byteArrayToPanda = new byte[UdpDataOutStruct.OUTPUT_STRUCT_SIZE];
// Define the endpoint from which to receive data
pandaEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.100"), 2000);
// Wait for 0.2s to see if an error results from no data being available on the socket
if (mySocket.Poll(200000, SelectMode.SelectError))
{
Console.WriteLine("Socket Error");
return;
}
// Forever loop to continuously process outgoing and incoming UDP data
while (true)
{
// Read data from Panda
ReadFromPanda();
Thread.Sleep(200); // Debug code
// Write data to Panda
WriteToPanda();
Thread.Sleep(200); // Debug code
// Output the value of the count variable, then increment it
Console.WriteLine("Count = {0}", count);
count++;
// Debug
// Console.Read();
}
} // end Main
// **********************************************************************************************
// METHOD DEFINITIONS *
// **********************************************************************************************
public static void ReadFromPanda()
{
if (mySocket.Available > 0)
{
// Fetch the data from PandaII
try
{
mySocket.ReceiveFrom(byteArrayFromPanda, byteArrayFromPanda.Length, SocketFlags.None, ref pandaEndPoint);
}
catch (SocketException se)
{
Console.WriteLine(se.ToString());
}
// Populate the data structure from the serialized array just read from the Panda device
dataStructFromPanda.DeserializeArray(byteArrayFromPanda);
// Output the struct's data to the console
Console.WriteLine("Message From " + ((IPEndPoint)pandaEndPoint).Address.ToString());
Console.WriteLine("aileronVoltage: {0}", dataStructFromPanda.aileronValue);
Console.WriteLine();
}
} // end ReadFromPanda()
public static void WriteToPanda()
{
// Load the output buffer array
byteArrayToPanda = dataStructToPanda.SerializeStruct();
try
{
mySocket.SendTo(byteArrayToPanda, byteArrayToPanda.Length, SocketFlags.None, pandaEndPoint);
}
catch (SocketException se)
{
Console.WriteLine(se.ToString());
}
// DEBUG CODE: Send output struct data
Console.WriteLine("Sending to " + ((IPEndPoint)pandaEndPoint).Address.ToString());
Console.WriteLine("Nose Gear light: {0}", dataStructToPanda.gearLightNose);
Console.WriteLine();
} // end WriteToPanda()
} // end class UDPServer
}
Thanks again!
TB
EDIT: Well, I did forget the exception, and then I screwed up the first attempt to edit, lol…